├── .npmignore ├── .nvmrc ├── package ├── .npmignore ├── src │ ├── Pane │ │ ├── index.ts │ │ ├── SplitPane.module.css │ │ ├── SplitPane.story.tsx │ │ └── SplitPane.tsx │ ├── Resizer │ │ ├── index.ts │ │ ├── SplitResizer.story.tsx │ │ └── SplitResizer.module.css │ ├── Split.module.css │ ├── Split.errors.ts │ ├── index.ts │ ├── Split.test.tsx │ ├── hooks │ │ └── use-split-resizer-orientation.ts │ ├── Split.context.ts │ └── Split.tsx └── package.json ├── .stylelintignore ├── docs ├── components │ ├── Shell │ │ ├── index.ts │ │ ├── Shell.module.css │ │ └── Shell.tsx │ ├── Footer │ │ ├── index.ts │ │ ├── AnimateBadge │ │ │ ├── index.ts │ │ │ ├── AnimateBadge.module.css │ │ │ └── AnimateBadge.tsx │ │ ├── links.ts │ │ ├── resources.ts │ │ ├── highlights.ts │ │ ├── Footer.module.css │ │ ├── ecosystem.ts │ │ └── Footer.tsx │ ├── DocsTabs │ │ ├── index.ts │ │ ├── DocsTabs.module.css │ │ └── DocsTabs.tsx │ ├── PageHeader │ │ ├── index.ts │ │ ├── PageHeader.module.css │ │ ├── PageHeaderLink │ │ │ ├── PageHeaderLink.module.css │ │ │ └── PageHeaderLink.tsx │ │ └── PageHeader.tsx │ ├── TableError │ │ ├── index.ts │ │ └── TableError.tsx │ ├── TableInlineCode │ │ ├── index.ts │ │ ├── TableInlineCode.module.css │ │ └── TableInlineCode.tsx │ ├── TableOfContents │ │ ├── index.ts │ │ ├── TableOfContents.tsx │ │ └── TableOfContents.module.css │ ├── MdxElements │ │ ├── index.ts │ │ ├── MdxElements.module.css │ │ └── MdxElements.tsx │ ├── PropsTable │ │ ├── index.ts │ │ ├── getComponentName.ts │ │ ├── PropsTablesList.module.css │ │ ├── PropsTablesList.tsx │ │ └── PropsTable.tsx │ ├── StylesApiTable │ │ ├── index.ts │ │ ├── StylesApiTable.module.css │ │ ├── SelectorsTable.tsx │ │ ├── StylesApiTablesList.tsx │ │ ├── VariablesTable.tsx │ │ ├── StylesApiTable.tsx │ │ └── ModifiersTable.tsx │ ├── InstallScript │ │ ├── InstallScript.tsx │ │ ├── MdxNpmScript.module.css │ │ └── MdxNpmScript.tsx │ ├── MdxInfo │ │ ├── MdxInfo.tsx │ │ └── MdxInfo.module.css │ └── styles-api.types.ts ├── mdx-components.tsx ├── theme.ts ├── README.md ├── styles-api │ ├── index.ts │ ├── SplitPane.styles-api.ts │ ├── Split.styles-api.ts │ └── SplitResizer.styles-api.ts ├── overrides.d.ts ├── postcss.config.js ├── tsconfig.json ├── pages │ ├── _document.tsx │ ├── index.tsx │ └── _app.tsx ├── assets │ └── favicon.svg ├── next.config.mjs ├── demos │ ├── index.ts │ ├── Split.demo.reset.tsx │ ├── Split.demo.responsiveOrientation.tsx │ ├── Split.demo.store.tsx │ ├── Split.demo.doubleclick.tsx │ ├── Split.demo.nested.tsx │ ├── Split.demo.nestedprops.tsx │ ├── Split.demo.initials.tsx │ ├── Split.demo.multiple.tsx │ ├── Split.demo.inline.tsx │ ├── Split.demo.accessibility.tsx │ ├── Split.demo.resizer.tsx │ ├── Split.demo.gradient.tsx │ ├── Split.demo.events.tsx │ ├── Split.demo.pane.tsx │ ├── Split.demo.resizerEvents.tsx │ ├── Split.demo.max.tsx │ ├── Split.demo.grow.tsx │ └── Split.demo.configurator.tsx ├── package.json └── data.ts ├── .yarnrc.yml ├── .github ├── FUNDING.yml └── workflows │ └── pull_request.yml ├── .vscode └── settings.json ├── postcss.config.js ├── tsconfig.eslint.json ├── scripts ├── nojekyll.ts ├── docgen.ts ├── update-version.ts ├── generate-dts.ts ├── run.ts ├── prepare-css.ts └── release.ts ├── .gitattributes ├── vite.config.ts ├── .editorconfig ├── eslint.config.mjs ├── tsconfig.build.json ├── jest.config.cjs ├── @types └── overrides.d.ts ├── tsconfig.json ├── .storybook ├── main.ts └── preview.tsx ├── jsdom.mocks.cjs ├── .prettierrc.mjs ├── .syncpackrc.cjs ├── .stylelintrc.json ├── LICENSE ├── CONTRIBUTING.md ├── rollup.config.mjs ├── .gitignore ├── README.md ├── package.json └── CODE_OF_CONDUCT.md /.npmignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v24.3.0 2 | -------------------------------------------------------------------------------- /package/.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | src 3 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | docs/.next 2 | docs/out 3 | package/dist 4 | -------------------------------------------------------------------------------- /docs/components/Shell/index.ts: -------------------------------------------------------------------------------- 1 | export { Shell } from './Shell'; 2 | -------------------------------------------------------------------------------- /docs/components/Footer/index.ts: -------------------------------------------------------------------------------- 1 | export { Footer } from './Footer'; 2 | -------------------------------------------------------------------------------- /docs/components/DocsTabs/index.ts: -------------------------------------------------------------------------------- 1 | export { DocsTabs } from './DocsTabs'; 2 | -------------------------------------------------------------------------------- /docs/components/PageHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { PageHeader } from './PageHeader'; 2 | -------------------------------------------------------------------------------- /docs/components/TableError/index.ts: -------------------------------------------------------------------------------- 1 | export { TableError } from './TableError'; 2 | -------------------------------------------------------------------------------- /docs/mdx-components.tsx: -------------------------------------------------------------------------------- 1 | export { useMDXComponents } from './components/MdxElements'; 2 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-4.12.0.cjs 4 | -------------------------------------------------------------------------------- /docs/components/Footer/AnimateBadge/index.ts: -------------------------------------------------------------------------------- 1 | export { AnimateBadge } from './AnimateBadge'; 2 | -------------------------------------------------------------------------------- /docs/components/TableInlineCode/index.ts: -------------------------------------------------------------------------------- 1 | export { TableInlineCode } from './TableInlineCode'; 2 | -------------------------------------------------------------------------------- /docs/components/TableOfContents/index.ts: -------------------------------------------------------------------------------- 1 | export { TableOfContents } from './TableOfContents'; 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [gfazioli,wpbones] 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.prettierPath": "", 3 | "prettier.configPath": "./.prettierrc.mjs" 4 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-preset-mantine': {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /package/src/Pane/index.ts: -------------------------------------------------------------------------------- 1 | export { SplitPane } from './SplitPane'; 2 | export type { SplitPaneProps } from './SplitPane'; 3 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["./**/*.tsx", "./**/*.ts", "./**/*.js"] 4 | } 5 | -------------------------------------------------------------------------------- /docs/components/MdxElements/index.ts: -------------------------------------------------------------------------------- 1 | export { MdxPre, MdxTitle, MdxParagraph, MdxLi, MdxUl, useMDXComponents } from './MdxElements'; 2 | -------------------------------------------------------------------------------- /package/src/Resizer/index.ts: -------------------------------------------------------------------------------- 1 | export { SplitResizer } from './SplitResizer'; 2 | export type { SplitResizerProps } from './SplitResizer'; 3 | -------------------------------------------------------------------------------- /scripts/nojekyll.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'fs-extra'; 3 | 4 | fs.writeFileSync(path.join(process.cwd(), 'docs/out/.nojekyll'), ''); 5 | -------------------------------------------------------------------------------- /docs/components/Footer/links.ts: -------------------------------------------------------------------------------- 1 | export { ecosystem } from './ecosystem'; 2 | export { highlights } from './highlights'; 3 | export { resources } from './resources'; 4 | -------------------------------------------------------------------------------- /docs/theme.ts: -------------------------------------------------------------------------------- 1 | import { createTheme } from '@mantine/core'; 2 | 3 | export const theme = createTheme({ 4 | headings: { fontFamily: 'Outfit, sans-serif' }, 5 | }); 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/** linguist-vendored 2 | /.yarn/releases/* binary 3 | /.yarn/plugins/**/* binary 4 | /.pnp.* binary linguist-generated 5 | -------------------------------------------------------------------------------- /package/src/Split.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | display: var(--split-inline, 'flex'); 3 | 4 | &[data-orientation='horizontal'] { 5 | flex-direction: column; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.{js,json,yml}] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /docs/components/PropsTable/index.ts: -------------------------------------------------------------------------------- 1 | export { PropsTable } from './PropsTable'; 2 | export { PropsTablesList } from './PropsTablesList'; 3 | export { getComponentName } from './getComponentName'; 4 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Mantine Next Template 2 | 3 | Get started with the template by clicking `Use this template` button on the top of the page. 4 | 5 | [Documentation](https://mantine.dev/guides/next/) 6 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import mantine from 'eslint-config-mantine'; 2 | import tseslint from 'typescript-eslint'; 3 | 4 | export default tseslint.config(...mantine, { ignores: ['**/.next/**', '**/*.{mjs,cjs,js,d.ts,d.mts}'] }); 5 | -------------------------------------------------------------------------------- /docs/components/TableInlineCode/TableInlineCode.module.css: -------------------------------------------------------------------------------- 1 | .code { 2 | font-family: var(--mantine-font-family-monospace); 3 | font-size: var(--mantine-font-size-xs); 4 | color: light-dark(var(--mantine-color-indigo-filled), var(--mantine-color-red-filled)); 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["package", "@types"], 4 | "exclude": ["**/*.test.tsx", "**/*.test.ts", "**/*.story.tsx", "**/*.story.ts", "package/dist"], 5 | "compilerOptions": { 6 | "emitDeclarationOnly": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package/src/Split.errors.ts: -------------------------------------------------------------------------------- 1 | export const SPLIT_ERRORS = { 2 | context: 'Split component was not found in the tree', 3 | children: 4 | 'Split.Pane component children should be an element or a component that accepts ref, fragments, strings, numbers and other primitive values are not supported', 5 | }; 6 | -------------------------------------------------------------------------------- /docs/components/StylesApiTable/index.ts: -------------------------------------------------------------------------------- 1 | export { StylesApiTable } from './StylesApiTable'; 2 | export { StylesApiTablesList } from './StylesApiTablesList'; 3 | export { ModifiersTable } from './ModifiersTable'; 4 | export { SelectorsTable } from './SelectorsTable'; 5 | export { VariablesTable } from './VariablesTable'; 6 | -------------------------------------------------------------------------------- /jest.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'jest-environment-jsdom', 3 | transform: { 4 | '^.+\\.tsx?$': 'esbuild-jest', 5 | }, 6 | testMatch: ['**/?(*.)+(spec|test).ts?(x)'], 7 | setupFilesAfterEnv: ['./jsdom.mocks.cjs'], 8 | moduleNameMapper: { 9 | '\\.(css)$': 'identity-obj-proxy', 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /package/src/Pane/SplitPane.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | position: relative; 3 | z-index: 1; 4 | overflow: hidden; 5 | flex: var(--split-pane-grow, initial); 6 | /* display: flex; */ 7 | 8 | &[data-orientation='vertical'] { 9 | flex-direction: row; 10 | } 11 | 12 | &[data-orientation='horizontal'] { 13 | flex-direction: column; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/styles-api/index.ts: -------------------------------------------------------------------------------- 1 | import { SplitStylesApi } from './Split.styles-api'; 2 | import { SplitPaneStylesApi } from './SplitPane.styles-api'; 3 | import { SplitResizerStylesApi } from './SplitResizer.styles-api'; 4 | 5 | export const STYLES_API_DATA = { 6 | Split: SplitStylesApi, 7 | SplitPane: SplitPaneStylesApi, 8 | SplitResizer: SplitResizerStylesApi, 9 | }; 10 | -------------------------------------------------------------------------------- /docs/components/Footer/AnimateBadge/AnimateBadge.module.css: -------------------------------------------------------------------------------- 1 | @keyframes pulse { 2 | 0% { 3 | box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.7); 4 | } 5 | 6 | 70% { 7 | box-shadow: 0 0 0 10px rgba(255, 0, 0, 0); 8 | } 9 | 10 | 100% { 11 | box-shadow: 0 0 0 0 rgba(255, 0, 0, 0); 12 | } 13 | } 14 | 15 | .badgeNew { 16 | animation: pulse 1.5s infinite; 17 | } 18 | -------------------------------------------------------------------------------- /@types/overrides.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.gql'; 2 | declare module '*.md'; 3 | declare module '*.graphql'; 4 | declare module '*.svg'; 5 | declare module '*.png'; 6 | declare module '*.webp'; 7 | declare module '*.jpg'; 8 | declare module '*.gif'; 9 | declare module '*.woff'; 10 | declare module '*.woff2'; 11 | declare module '*.mdx'; 12 | declare module '*.webp'; 13 | declare module '*.css'; 14 | declare module 'is-directory'; 15 | -------------------------------------------------------------------------------- /docs/overrides.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.gql'; 2 | declare module '*.md'; 3 | declare module '*.graphql'; 4 | declare module '*.svg'; 5 | declare module '*.png'; 6 | declare module '*.webp'; 7 | declare module '*.jpg'; 8 | declare module '*.gif'; 9 | declare module '*.woff'; 10 | declare module '*.woff2'; 11 | declare module '*.mdx'; 12 | declare module '*.webp'; 13 | declare module '*.css'; 14 | declare module 'is-directory'; 15 | -------------------------------------------------------------------------------- /package/src/index.ts: -------------------------------------------------------------------------------- 1 | export { useSplitContext } from './Split.context'; 2 | 3 | export { Split } from './Split'; 4 | export type { SplitCssVariables, SplitFactory, SplitProps } from './Split'; 5 | 6 | export type { SPLIT_PANE_SIZE, SplitPaneFactory, SplitPaneProps } from './Pane/SplitPane'; 7 | 8 | export type { 9 | SPLIT_PANE_RESIZE_SIZES, 10 | SplitResizerFactory, 11 | SplitResizerProps, 12 | } from './Resizer/SplitResizer'; 13 | -------------------------------------------------------------------------------- /docs/components/PropsTable/getComponentName.ts: -------------------------------------------------------------------------------- 1 | interface GetComponentNameInput { 2 | component: string; 3 | componentPrefix: string | undefined; 4 | } 5 | 6 | export function getComponentName({ component, componentPrefix }: GetComponentNameInput) { 7 | return componentPrefix 8 | ? componentPrefix === component 9 | ? component 10 | : `${componentPrefix}.${component.replace(componentPrefix, '')}` 11 | : component; 12 | } 13 | -------------------------------------------------------------------------------- /docs/styles-api/SplitPane.styles-api.ts: -------------------------------------------------------------------------------- 1 | import type { SplitPaneFactory } from '@gfazioli/mantine-split-pane'; 2 | import type { StylesApiData } from '../components/styles-api.types'; 3 | 4 | export const SplitPaneStylesApi: StylesApiData = { 5 | selectors: { 6 | root: 'Root element', 7 | }, 8 | 9 | vars: {}, 10 | 11 | modifiers: [{ modifier: 'data-orientation', selector: 'root', value: 'horizontal | vertical' }], 12 | }; 13 | -------------------------------------------------------------------------------- /docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-preset-mantine': {}, 4 | 'postcss-simple-vars': { 5 | variables: { 6 | 'mantine-breakpoint-xs': '36em', 7 | 'mantine-breakpoint-sm': '48em', 8 | 'mantine-breakpoint-md': '62em', 9 | 'mantine-breakpoint-lg': '75em', 10 | 'mantine-breakpoint-xl': '88em', 11 | 'docs-mdx-breakpoint': '67.5em', 12 | }, 13 | }, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /package/src/Split.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@mantine-tests/core'; 3 | import { Split } from './Split'; 4 | 5 | describe('Split', () => { 6 | it('renders without crashing', () => { 7 | const { container } = render( 8 | 9 | Pane 1 10 | 11 | Pane 2 12 | 13 | ); 14 | expect(container).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /package/src/hooks/use-split-resizer-orientation.ts: -------------------------------------------------------------------------------- 1 | import { useMatches } from '@mantine/core'; 2 | import type { SplitResizerOrientation } from '../Resizer/SplitResizer'; 3 | 4 | export function useSplitResizerOrientation(orientation: SplitResizerOrientation) { 5 | const responsiveOrientation = useMatches(typeof orientation === 'string' ? {} : orientation); 6 | 7 | if (typeof orientation === 'string') { 8 | return orientation; 9 | } 10 | return responsiveOrientation; 11 | } 12 | -------------------------------------------------------------------------------- /docs/components/TableInlineCode/TableInlineCode.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import cx from 'clsx'; 3 | import { ElementProps, Text, TextProps } from '@mantine/core'; 4 | import classes from './TableInlineCode.module.css'; 5 | 6 | interface TableInlineCodeProps extends TextProps, ElementProps<'span', 'color'> {} 7 | 8 | export function TableInlineCode({ className, ...others }: TableInlineCodeProps) { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /package/src/Split.context.ts: -------------------------------------------------------------------------------- 1 | import { createOptionalContext, MantineSpacing } from '@mantine/core'; 2 | import { SplitResizerContextProps, SplitResizerVariant } from './Resizer/SplitResizer'; 3 | 4 | interface SplitContext extends SplitResizerContextProps { 5 | /** Resizer Variant */ 6 | variant?: SplitResizerVariant; 7 | 8 | /** Spacing between resizer and pane */ 9 | spacing?: MantineSpacing; 10 | } 11 | 12 | export const [SplitContextProvider, useSplitContext] = createOptionalContext(); 13 | -------------------------------------------------------------------------------- /docs/styles-api/Split.styles-api.ts: -------------------------------------------------------------------------------- 1 | import type { SplitFactory } from '@gfazioli/mantine-split-pane'; 2 | import type { StylesApiData } from '../components/styles-api.types'; 3 | 4 | export const SplitStylesApi: StylesApiData = { 5 | selectors: { 6 | root: 'Root element', 7 | }, 8 | 9 | vars: { 10 | root: { 11 | '--split-inline': 'Make main split container inline`', 12 | }, 13 | }, 14 | 15 | modifiers: [{ modifier: 'data-orientation', selector: 'root', value: 'horizontal | vertical' }], 16 | }; 17 | -------------------------------------------------------------------------------- /scripts/docgen.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { generateDeclarations } from 'mantine-docgen-script'; 3 | 4 | const getComponentPath = (componentPath: string) => 5 | path.join(process.cwd(), 'package/src', componentPath); 6 | 7 | generateDeclarations({ 8 | componentsPaths: [ 9 | getComponentPath('Split.tsx'), 10 | getComponentPath('Pane/SplitPane.tsx'), 11 | getComponentPath('Resizer/SplitResizer.tsx'), 12 | ], 13 | tsConfigPath: path.join(process.cwd(), 'tsconfig.json'), 14 | outputPath: path.join(process.cwd(), 'docs'), 15 | }); 16 | -------------------------------------------------------------------------------- /docs/components/Footer/resources.ts: -------------------------------------------------------------------------------- 1 | export const resources = [ 2 | { 3 | key: 'mantine-discord', 4 | title: 'Mantine Discord', 5 | href: 'https://discord.gg/wbH82zuWMN', 6 | }, 7 | { 8 | key: 'mantine-components', 9 | title: 'Mantine Components', 10 | href: 'https://mantine.dev/getting-started/', 11 | }, 12 | { 13 | key: 'mantine-ui', 14 | title: 'Mantine UI', 15 | href: 'https://ui.mantine.dev/', 16 | }, 17 | { 18 | key: 'mantine-help', 19 | title: 'Mantine Help Center', 20 | href: 'https://help.mantine.dev/', 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /scripts/update-version.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'fs-extra'; 3 | 4 | export async function updateVersion(version: string) { 5 | const packageJsonPath = path.join(process.cwd(), 'package/package.json'); 6 | const originalPackageJson = await fs.readJson(packageJsonPath); 7 | 8 | const updatedPackageJson = { ...originalPackageJson }; 9 | updatedPackageJson.version = version; 10 | 11 | await fs.writeJson(packageJsonPath, updatedPackageJson, { spaces: 2 }); 12 | 13 | return () => fs.writeJson(packageJsonPath, originalPackageJson, { spaces: 2 }); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/generate-dts.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'fs-extra'; 3 | import signale from 'signale'; 4 | import { $ } from 'zx'; 5 | 6 | async function generateDts() { 7 | try { 8 | await $`yarn tsc --project tsconfig.build.json`; 9 | await fs.copy( 10 | path.join(process.cwd(), 'package/dist/types/index.d.ts'), 11 | path.join(process.cwd(), 'package/dist/types/index.d.mts') 12 | ); 13 | } catch (err) { 14 | signale.error('Failed to generate d.ts files'); 15 | signale.error(err); 16 | process.exit(1); 17 | } 18 | } 19 | 20 | generateDts(); 21 | -------------------------------------------------------------------------------- /docs/components/Footer/AnimateBadge/AnimateBadge.tsx: -------------------------------------------------------------------------------- 1 | import { Badge, MantineColor } from '@mantine/core'; 2 | import classes from './AnimateBadge.module.css'; 3 | 4 | type AnimateBadgeProps = { 5 | label?: string; 6 | color?: MantineColor; 7 | size?: string; 8 | fontSize?: number; 9 | }; 10 | 11 | export function AnimateBadge({ 12 | label = 'New', 13 | color = 'red', 14 | size = 'xs', 15 | fontSize = 10, 16 | }: AnimateBadgeProps) { 17 | return ( 18 | 19 | {label} 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["package", "scripts", "@types"], 3 | "compilerOptions": { 4 | "types": ["node", "jest", "@testing-library/jest-dom"], 5 | "target": "ES2015", 6 | "lib": ["DOM", "ESNext"], 7 | "module": "ESNext", 8 | "moduleResolution": "Node", 9 | "jsx": "react", 10 | "skipLibCheck": true, 11 | "outDir": "temp", 12 | "declaration": true, 13 | "declarationMap": false, 14 | "resolveJsonModule": true, 15 | "declarationDir": "package/dist/types", 16 | "allowSyntheticDefaultImports": true, 17 | "esModuleInterop": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scripts/run.ts: -------------------------------------------------------------------------------- 1 | import signale from 'signale'; 2 | 3 | interface RunMessages { 4 | info: string; 5 | success: string; 6 | error: string; 7 | } 8 | 9 | export async function run( 10 | script: Promise, 11 | messages: RunMessages, 12 | onError?: () => Promise 13 | ) { 14 | signale.info(messages.info); 15 | try { 16 | const response = await script; 17 | signale.success(messages.success); 18 | return response; 19 | } catch (err) { 20 | signale.error(messages.error); 21 | signale.error(err); 22 | 23 | if (onError) { 24 | await onError(); 25 | } 26 | 27 | process.exit(1); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import { dirname, join } from 'path'; 2 | import type { StorybookConfig } from '@storybook/react-vite'; 3 | 4 | function getAbsolutePath(value: string): any { 5 | return dirname(require.resolve(join(value, 'package.json'))); 6 | } 7 | 8 | const config: StorybookConfig = { 9 | stories: ['../package/src/**/*.story.@(js|jsx|mjs|ts|tsx)'], 10 | addons: [getAbsolutePath('@storybook/addon-essentials'), getAbsolutePath('storybook-dark-mode')], 11 | framework: { 12 | name: getAbsolutePath('@storybook/react-vite'), 13 | options: {}, 14 | }, 15 | docs: { 16 | autodocs: false, 17 | }, 18 | }; 19 | 20 | export default config; 21 | -------------------------------------------------------------------------------- /docs/components/InstallScript/InstallScript.tsx: -------------------------------------------------------------------------------- 1 | import { MdxNpmScript } from './MdxNpmScript'; 2 | 3 | interface MdxInstallScriptProps { 4 | packages: string; 5 | dev?: boolean; 6 | } 7 | 8 | export function InstallScript({ packages, dev }: MdxInstallScriptProps) { 9 | // Hello good sir/lady. Seems like you are interested in adding pnpm here. 10 | // Please do not do that, this contribution is not welcome. 11 | // https://github.com/mantinedev/mantine/pulls?q=is%3Apr+pnpm 12 | 13 | return ( 14 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /jsdom.mocks.cjs: -------------------------------------------------------------------------------- 1 | require('@testing-library/jest-dom'); 2 | 3 | const { getComputedStyle } = window; 4 | window.getComputedStyle = (elt) => getComputedStyle(elt); 5 | 6 | Object.defineProperty(window, 'matchMedia', { 7 | writable: true, 8 | value: jest.fn().mockImplementation((query) => ({ 9 | matches: false, 10 | media: query, 11 | onchange: null, 12 | addListener: jest.fn(), 13 | removeListener: jest.fn(), 14 | addEventListener: jest.fn(), 15 | removeEventListener: jest.fn(), 16 | dispatchEvent: jest.fn(), 17 | })), 18 | }); 19 | 20 | class ResizeObserver { 21 | observe() {} 22 | unobserve() {} 23 | disconnect() {} 24 | } 25 | 26 | window.ResizeObserver = ResizeObserver; 27 | -------------------------------------------------------------------------------- /docs/components/TableError/TableError.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Anchor, Text } from '@mantine/core'; 3 | 4 | interface TableErrorProps { 5 | errorOf: string; 6 | } 7 | 8 | export function TableError({ errorOf }: TableErrorProps) { 9 | return ( 10 | 11 | 12 | Error loading component {errorOf} data.{' '} 13 | 14 | If you see this message please let us know by{' '} 15 | 19 | opening an issue on GitHub 20 | 21 | . 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /docs/components/MdxInfo/MdxInfo.tsx: -------------------------------------------------------------------------------- 1 | import { IconInfoCircle } from '@tabler/icons-react'; 2 | import cx from 'clsx'; 3 | import { Blockquote, BlockquoteProps, rgba, useMantineTheme } from '@mantine/core'; 4 | import classes from './MdxInfo.module.css'; 5 | 6 | export function MdxInfo({ className, ...others }: BlockquoteProps) { 7 | const theme = useMantineTheme(); 8 | return ( 9 |
} 12 | radius="md" 13 | __vars={{ 14 | '--docs-bq-code-bg-light': rgba(theme.colors.blue[6], 0.2), 15 | '--docs-bq-code-bg-dark': rgba(theme.colors.blue[4], 0.2), 16 | }} 17 | {...others} 18 | /> 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /docs/components/Shell/Shell.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | background-color: alpha(var(--mantine-color-body), 0.85); 3 | backdrop-filter: blur(5px); 4 | } 5 | 6 | .inner { 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-between; 10 | height: 100%; 11 | } 12 | 13 | .main { 14 | padding-bottom: 120px; 15 | } 16 | 17 | .logo { 18 | & > svg { 19 | display: block; 20 | } 21 | } 22 | 23 | .sponsor { 24 | border-radius: 7px; 25 | border-width: 1px; 26 | border-style: solid; 27 | border-color: transparent; 28 | 29 | /* glow effect */ 30 | 31 | @mixin light { 32 | box-shadow: 0 0 5px 0 rgb(51, 154, 240, 0.2); 33 | } 34 | 35 | @mixin dark { 36 | box-shadow: 0 0 5px 0 rgba(255, 255, 255, 0.1); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Head, Html, Main, NextScript } from 'next/document'; 3 | import { ColorSchemeScript } from '@mantine/core'; 4 | 5 | export default function Document() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /scripts/prepare-css.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'fs-extra'; 3 | import signale from 'signale'; 4 | 5 | const rollupCssFilePath = path.join(process.cwd(), './package/dist/esm/index.css'); 6 | 7 | if (!fs.existsSync(rollupCssFilePath)) { 8 | signale.error('CSS file not found. Please run `yarn build` first.'); 9 | process.exit(1); 10 | } 11 | 12 | const content = fs.readFileSync(rollupCssFilePath, 'utf-8'); 13 | 14 | fs.writeFileSync(path.join(process.cwd(), './package/dist/styles.css'), content); 15 | fs.writeFileSync( 16 | path.join(process.cwd(), './package/dist/styles.layer.css'), 17 | `@layer mantine-split-pane {${content}}` 18 | ); 19 | 20 | fs.removeSync(rollupCssFilePath); 21 | fs.removeSync(path.join(process.cwd(), './package/dist/cjs/index.css')); 22 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: Pull request workflow 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - '**' 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.number || github.sha }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | test_pull_request: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: actions/setup-node@v3 18 | with: 19 | node-version: '20.9.0' 20 | cache: 'yarn' 21 | cache-dependency-path: '**/yarn.lock' 22 | - name: Install dependencies 23 | run: yarn 24 | - name: Build package 25 | run: npm run build 26 | - name: Build docs 27 | run: npm run docs:build 28 | - name: Run tests 29 | run: npm test 30 | -------------------------------------------------------------------------------- /docs/components/PageHeader/PageHeader.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | padding-top: 60px; 3 | padding-bottom: 40px; 4 | background-color: var(--mantine-color-body); 5 | } 6 | 7 | .title { 8 | color: var(--mantine-color-bright); 9 | font-size: 32px; 10 | letter-spacing: -0.5px; 11 | font-weight: 500; 12 | 13 | @mixin smaller-than $mantine-breakpoint-sm { 14 | font-size: 24px; 15 | } 16 | } 17 | 18 | .description { 19 | margin-top: var(--mantine-spacing-md); 20 | max-width: 600px; 21 | font-size: var(--mantine-font-size-lg); 22 | color: var(--mantine-color-dimmed); 23 | 24 | @mixin smaller-than $mantine-breakpoint-sm { 25 | margin-top: var(--mantine-spacing-xs); 26 | font-size: var(--mantine-font-size-sm); 27 | } 28 | } 29 | 30 | .links { 31 | margin-top: var(--mantine-spacing-lg); 32 | } 33 | -------------------------------------------------------------------------------- /docs/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { DocsTabs } from '../components/DocsTabs'; 2 | import { PageHeader } from '../components/PageHeader'; 3 | import { Shell } from '../components/Shell'; 4 | import { PACKAGE_DATA } from '../data'; 5 | import docgen from '../docgen.json'; 6 | import Docs from '../docs.mdx'; 7 | import { STYLES_API_DATA } from '../styles-api'; 8 | 9 | export default function HomePage() { 10 | return ( 11 | 12 | 13 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /docs/components/Footer/highlights.ts: -------------------------------------------------------------------------------- 1 | export const highlights = [ 2 | { 3 | key: 'undolog', 4 | title: 'News', 5 | href: 'https://undolog.com', 6 | }, 7 | { 8 | key: 'mantine-extensions', 9 | title: 'Mantine Extensions HUB', 10 | href: 'https://mantine-extensions.vercel.app', 11 | }, 12 | { 13 | key: 'mantine-nextra-template', 14 | title: 'Mantine Nextra template', 15 | href: 'https://github.com/gfazioli/next-app-nextra-template', 16 | new: true, 17 | }, 18 | { 19 | key: 'mantine-extension-template', 20 | title: 'Extension Template', 21 | href: 'https://github.com/mantinedev/extension-template', 22 | }, 23 | { 24 | key: 'youtube', 25 | title: 'YouTube', 26 | href: 'https://www.youtube.com/playlist?list=PL85tTROKkZrWyqCcmNCdWajpx05-cTal4', 27 | }, 28 | ]; 29 | -------------------------------------------------------------------------------- /.prettierrc.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import("@ianvs/prettier-plugin-sort-imports").PrettierConfig} */ 2 | const config = { 3 | printWidth: 100, 4 | singleQuote: true, 5 | trailingComma: 'es5', 6 | plugins: ['@ianvs/prettier-plugin-sort-imports'], 7 | importOrder: [ 8 | '.*styles.css$', 9 | '', 10 | 'dayjs', 11 | '^react$', 12 | '^next$', 13 | '^next/.*$', 14 | '', 15 | '', 16 | '^@mantine/(.*)$', 17 | '^@mantinex/(.*)$', 18 | '^@mantine-tests/(.*)$', 19 | '^@docs/(.*)$', 20 | '^@/.*$', 21 | '^../(?!.*.css$).*$', 22 | '^./(?!.*.css$).*$', 23 | '\\.css$', 24 | ], 25 | overrides: [ 26 | { 27 | files: '*.mdx', 28 | options: { 29 | printWidth: 70, 30 | }, 31 | }, 32 | ], 33 | }; 34 | 35 | export default config; 36 | -------------------------------------------------------------------------------- /docs/components/InstallScript/MdxNpmScript.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | margin-inline-end: 5px; 3 | } 4 | 5 | .tab { 6 | display: flex; 7 | align-items: center; 8 | font-family: var(--mantine-font-family-monospace); 9 | font-weight: 700; 10 | font-size: 12px; 11 | border-radius: var(--mantine-radius-md); 12 | border-end-end-radius: 0; 13 | border-end-start-radius: 0; 14 | 15 | @mixin hover { 16 | background-color: transparent; 17 | } 18 | 19 | &[data-active] { 20 | background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8)); 21 | color: var(--mantine-color-bright); 22 | } 23 | } 24 | 25 | .code { 26 | margin-top: 0; 27 | background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-8)); 28 | 29 | &[data-without-radius] { 30 | border-start-start-radius: 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.syncpackrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("syncpack").RcFile} */ 2 | const config = { 3 | dependencyTypes: ['dev', 'prod'], 4 | source: ['package.json', 'package/package.json', 'docs/package.json'], 5 | sortFirst: [ 6 | 'name', 7 | 'version', 8 | 'description', 9 | 'homepage', 10 | 'packageManager', 11 | 'license', 12 | 'private', 13 | 'author', 14 | 'keywords', 15 | 'sideEffects', 16 | 'main', 17 | 'module', 18 | 'types', 19 | 'exports', 20 | 'repository', 21 | 'engines', 22 | 'workspaces', 23 | 'scripts', 24 | 'peerDependencies', 25 | 'dependencies', 26 | 'devDependencies', 27 | ], 28 | sortAz: [ 29 | 'contributors', 30 | 'dependencies', 31 | 'devDependencies', 32 | 'keywords', 33 | 'peerDependencies', 34 | 'resolutions', 35 | ], 36 | }; 37 | 38 | module.exports = config; 39 | -------------------------------------------------------------------------------- /docs/assets/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/PageHeader/PageHeaderLink/PageHeaderLink.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | display: flex; 3 | align-items: center; 4 | font-size: var(--mantine-font-size-sm); 5 | gap: var(--mantine-spacing-md); 6 | 7 | & + & { 8 | margin-top: var(--mantine-spacing-xs); 9 | } 10 | } 11 | 12 | .label { 13 | color: var(--mantine-color-dimmed); 14 | flex: 0 0 80px; 15 | 16 | @mixin smaller-than $mantine-breakpoint-sm { 17 | display: none; 18 | } 19 | } 20 | 21 | .body { 22 | display: flex; 23 | align-items: center; 24 | line-height: 1; 25 | text-decoration: none; 26 | color: var(--mantine-color-text); 27 | gap: var(--mantine-spacing-xs); 28 | 29 | @mixin hover { 30 | text-decoration: underline; 31 | } 32 | 33 | @mixin smaller-than $mantine-breakpoint-sm { 34 | min-height: 24px; 35 | } 36 | } 37 | 38 | .icon { 39 | width: 18px; 40 | 41 | & svg { 42 | display: block; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /docs/next.config.mjs: -------------------------------------------------------------------------------- 1 | import createMDX from '@next/mdx'; 2 | import fs from 'fs-extra'; 3 | import remarkSlug from 'remark-slug'; 4 | import signale from 'signale'; 5 | 6 | const withMDX = createMDX({ 7 | options: { 8 | remarkPlugins: [remarkSlug], 9 | }, 10 | }); 11 | 12 | let repository; 13 | 14 | try { 15 | const packageJson = fs.readJsonSync('../package/package.json'); 16 | repository = packageJson.repository.split('/').at(-1).replace('.git', ''); 17 | } catch { 18 | signale.error('Failed to read repository field of package/package.json\n'); 19 | process.exit(1); 20 | } 21 | 22 | /** @type {import('next').NextConfig} */ 23 | const nextConfig = { 24 | reactStrictMode: true, 25 | output: 'export', 26 | basePath: process.env.NODE_ENV === 'production' ? `/${repository}` : undefined, 27 | pageExtensions: ['ts', 'tsx', 'mdx'], 28 | eslint: { 29 | ignoreDuringBuilds: true, 30 | }, 31 | }; 32 | 33 | export default withMDX(nextConfig); 34 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard-scss"], 3 | "rules": { 4 | "custom-property-pattern": null, 5 | "selector-class-pattern": null, 6 | "scss/no-duplicate-mixins": null, 7 | "declaration-empty-line-before": null, 8 | "declaration-block-no-redundant-longhand-properties": null, 9 | "alpha-value-notation": null, 10 | "custom-property-empty-line-before": null, 11 | "property-no-vendor-prefix": null, 12 | "color-function-notation": null, 13 | "length-zero-no-unit": null, 14 | "selector-not-notation": null, 15 | "no-descending-specificity": null, 16 | "comment-empty-line-before": null, 17 | "scss/at-mixin-pattern": null, 18 | "scss/at-rule-no-unknown": null, 19 | "value-keyword-case": null, 20 | "media-feature-range-notation": null, 21 | "selector-pseudo-class-no-unknown": [ 22 | true, 23 | { 24 | "ignorePseudoClasses": ["global"] 25 | } 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docs/components/PageHeader/PageHeaderLink/PageHeaderLink.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './PageHeaderLink.module.css'; 3 | 4 | interface PageHeaderLinkProps { 5 | link?: string; 6 | label: React.ReactNode; 7 | icon: React.ReactNode; 8 | children: React.ReactNode; 9 | } 10 | 11 | export function PageHeaderLink({ label, icon, children, link }: PageHeaderLinkProps) { 12 | const content = link ? ( 13 | 14 |
{icon}
15 |
{children}
16 |
17 | ) : ( 18 |
19 |
{icon}
20 |
{children}
21 |
22 | ); 23 | 24 | return ( 25 |
26 |
{label}
27 | {content} 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /docs/demos/index.ts: -------------------------------------------------------------------------------- 1 | export { accessibility } from './Split.demo.accessibility'; 2 | export { configurator } from './Split.demo.configurator'; 3 | export { doubleclick } from './Split.demo.doubleclick'; 4 | export { events } from './Split.demo.events'; 5 | export { gradient } from './Split.demo.gradient'; 6 | export { growFirst, growHorizontal, growSecond, growThreePanes } from './Split.demo.grow'; 7 | export { initials } from './Split.demo.initials'; 8 | export { inline } from './Split.demo.inline'; 9 | export { max } from './Split.demo.max'; 10 | export { multiple } from './Split.demo.multiple'; 11 | export { nested } from './Split.demo.nested'; 12 | export { nestedprops } from './Split.demo.nestedprops'; 13 | export { pane } from './Split.demo.pane'; 14 | export { reset } from './Split.demo.reset'; 15 | export { resizer } from './Split.demo.resizer'; 16 | export { resizerEvents } from './Split.demo.resizerEvents'; 17 | export { responsiveOrientation } from './Split.demo.responsiveOrientation'; 18 | export { store } from './Split.demo.store'; 19 | -------------------------------------------------------------------------------- /docs/components/styles-api.types.ts: -------------------------------------------------------------------------------- 1 | import type { EmptyObject } from 'type-fest'; 2 | import type { FactoryPayload, TransformVars } from '@mantine/core'; 3 | 4 | export interface Modifier { 5 | modifier: string; 6 | selector: StylesNames | StylesNames[]; 7 | condition?: string; 8 | value?: string; 9 | } 10 | 11 | export interface Selectors { 12 | selectors: Factory['stylesNames'] extends string ? Record : never; 13 | } 14 | 15 | export interface Vars { 16 | vars: TransformVars; 17 | } 18 | 19 | export interface Modifiers { 20 | modifiers?: Factory['stylesNames'] extends string ? Modifier[] : never; 21 | } 22 | 23 | export type StylesApiData = (Factory['stylesNames'] extends string 24 | ? Selectors 25 | : EmptyObject) & 26 | Vars & 27 | (Factory['stylesNames'] extends string ? Modifiers : EmptyObject); 28 | -------------------------------------------------------------------------------- /docs/components/MdxElements/MdxElements.module.css: -------------------------------------------------------------------------------- 1 | .paragraph { 2 | line-height: 1.65; 3 | font-size: 15px; 4 | } 5 | 6 | .link { 7 | font-size: 15px; 8 | } 9 | 10 | .ul { 11 | line-height: 1.65; 12 | margin-bottom: 20px; 13 | margin-top: 10px; 14 | font-size: 15px; 15 | padding-left: var(--mantine-spacing-xl); 16 | } 17 | 18 | .li { 19 | margin-top: 4px; 20 | font-size: 15px; 21 | } 22 | 23 | .title { 24 | margin-top: calc(var(--mantine-spacing-xl) * 1.2); 25 | margin-bottom: var(--mantine-spacing-md); 26 | overflow-wrap: break-word; 27 | font-weight: 500; 28 | color: var(--mantine-color-bright); 29 | 30 | &[data-order='1'] { 31 | font-size: 40px; 32 | margin-top: 0; 33 | } 34 | } 35 | 36 | .titleLink { 37 | text-decoration: none; 38 | color: inherit; 39 | } 40 | 41 | .titleOffset { 42 | position: relative; 43 | top: -62px; 44 | } 45 | 46 | .code { 47 | border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); 48 | border-radius: var(--mantine-radius-md); 49 | margin-top: var(--mantine-spacing-md); 50 | margin-bottom: var(--mantine-spacing-md); 51 | } 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Giovambattista Fazioli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/components/PropsTable/PropsTablesList.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | & code { 3 | font-family: var(--mantine-font-family-monospace); 4 | line-height: var(--mantine-line-height); 5 | padding: 2px calc(var(--mantine-spacing-xs) / 2); 6 | border-radius: var(--mantine-radius-sm); 7 | font-size: var(--mantine-font-size-xs); 8 | margin: 0; 9 | background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5)); 10 | color: var(--mantine-color-bright); 11 | } 12 | } 13 | 14 | .searchIcon { 15 | width: 22px; 16 | height: 22px; 17 | color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3)); 18 | } 19 | 20 | .title { 21 | margin-bottom: var(--mantine-spacing-lg); 22 | font-weight: 500; 23 | color: var(--mantine-color-bright); 24 | } 25 | 26 | .section { 27 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 28 | border-radius: var(--mantine-radius-md); 29 | padding: var(--mantine-spacing-sm); 30 | padding-bottom: 0; 31 | padding-top: var(--mantine-spacing-md); 32 | 33 | & + & { 34 | margin-top: 50px; 35 | } 36 | } 37 | 38 | .search { 39 | margin-bottom: var(--mantine-spacing-xl); 40 | } 41 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 👏 Thank you for considering contributing to the this project. 4 | 5 | ## Bug Reports 6 | 7 | When encountering issues with software or applications, submitting a detailed bug report can significantly help developers in understanding and resolving the problem efficiently. A well-written bug report should include clear steps to reproduce the issue, the expected behavior, and the actual outcome. 8 | 9 | Furthermore, providing information such as system specifications, error messages, and screenshots can aid in pinpointing the root cause of the bug. By utilizing platforms like GitHub, users can create issue tickets with relevant details, facilitating effective communication between users and developers. Remember, a comprehensive bug report not only assists in bug resolution but also improves the overall quality of the software. 10 | 11 | 🐛 [GitHub issue](https://github.com/gfazioli/mantine-split-pane/issues) 12 | 13 | 14 | ## Code contributors 15 | 16 | Here's a list of all the people who have contributed to the codebase of this project so far: 17 | 18 | [![Contributors list](https://contrib.rocks/image?repo=gfazioli/mantine-split-pane)](https://github.com/gfazioli/mantine-split-pane/graphs/contributors) 19 | -------------------------------------------------------------------------------- /docs/components/StylesApiTable/StylesApiTable.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | & code { 3 | font-family: var(--mantine-font-family-monospace); 4 | line-height: var(--mantine-line-height); 5 | padding: 2px calc(var(--mantine-spacing-xs) / 2); 6 | border-radius: var(--mantine-radius-sm); 7 | font-size: var(--mantine-font-size-xs); 8 | margin: 0; 9 | background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5)); 10 | color: var(--mantine-color-bright); 11 | } 12 | } 13 | 14 | .groupsHeader { 15 | margin-bottom: 30px; 16 | } 17 | 18 | .group { 19 | & + & { 20 | margin-top: 40px; 21 | padding-top: 40px; 22 | border-top: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-3)); 23 | } 24 | } 25 | 26 | .title { 27 | margin-bottom: var(--mantine-spacing-sm); 28 | font-weight: 500; 29 | color: var(--mantine-color-bright); 30 | } 31 | 32 | .section { 33 | border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); 34 | border-radius: var(--mantine-radius-md); 35 | padding: var(--mantine-spacing-sm); 36 | padding-bottom: 0; 37 | padding-top: var(--mantine-spacing-md); 38 | 39 | & + & { 40 | margin-top: 40px; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extension-template-docs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "next build", 7 | "dev": "next dev --port 9281", 8 | "start": "next start", 9 | "typecheck": "tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "@gfazioli/mantine-split-pane": "workspace:*", 13 | "@mantine/code-highlight": "8.3.10", 14 | "@mantine/core": "8.3.10", 15 | "@mantine/hooks": "8.3.10", 16 | "@mantinex/demo": "^2.0.0", 17 | "@mantinex/dev-icons": "^2.0.0", 18 | "@mantinex/mantine-header": "^2.0.0", 19 | "@mantinex/mantine-logo": "^2.0.0", 20 | "@mantinex/mantine-meta": "^2.0.0", 21 | "@mantinex/shiki": "^1.1.0", 22 | "@mdx-js/loader": "^3.1.1", 23 | "@mdx-js/react": "^3.1.1", 24 | "@next/mdx": "^15.5.9", 25 | "@tabler/icons-react": "^3.35.0", 26 | "@types/mdx": "^2.0.13", 27 | "next": "15.5.9", 28 | "react": "19.2.3", 29 | "react-dom": "19.2.3", 30 | "remark-slug": "^7.0.1", 31 | "shiki": "^3.20.0", 32 | "type-fest": "^4.41.0" 33 | }, 34 | "devDependencies": { 35 | "@types/node": "^22.19.2", 36 | "@types/react": "^19.2.7", 37 | "@types/react-dom": "^19.2.3", 38 | "typescript": "5.9.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.storybook/preview.tsx: -------------------------------------------------------------------------------- 1 | import type { Preview } from '@storybook/react'; 2 | 3 | import '@mantine/core/styles.css'; 4 | 5 | import React, { useEffect } from 'react'; 6 | import { addons } from '@storybook/preview-api'; 7 | import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode'; 8 | import { MantineProvider, useMantineColorScheme } from '@mantine/core'; 9 | 10 | const channel = addons.getChannel(); 11 | 12 | function ColorSchemeWrapper({ children }: { children: React.ReactNode }) { 13 | const { setColorScheme } = useMantineColorScheme(); 14 | const handleColorScheme = (value: boolean) => setColorScheme(value ? 'dark' : 'light'); 15 | 16 | useEffect(() => { 17 | channel.on(DARK_MODE_EVENT_NAME, handleColorScheme); 18 | return () => channel.off(DARK_MODE_EVENT_NAME, handleColorScheme); 19 | }, [channel]); 20 | 21 | return <>{children}; 22 | } 23 | 24 | export const decorators = [ 25 | (renderStory: any) => {renderStory()}, 26 | (renderStory: any) => {renderStory()}, 27 | ]; 28 | 29 | const preview: Preview = { 30 | parameters: { 31 | actions: { argTypesRegex: '^on[A-Z].*' }, 32 | controls: { 33 | matchers: { 34 | color: /(background|color)$/i, 35 | date: /Date$/i, 36 | }, 37 | }, 38 | }, 39 | }; 40 | 41 | export default preview; 42 | -------------------------------------------------------------------------------- /docs/components/Footer/Footer.module.css: -------------------------------------------------------------------------------- 1 | .contentFooter { 2 | padding-top: 32px; 3 | background: var(--mantine-color-body); 4 | box-shadow: inset 0px 4px 32px 0px #00000032; 5 | } 6 | 7 | .footer { 8 | padding-bottom: 32px; 9 | } 10 | 11 | .title { 12 | font-size: 14px !important; 13 | font-weight: 300; 14 | } 15 | 16 | .columnAnchor { 17 | font-size: 12.8px !important; 18 | font-weight: 500 !important; 19 | } 20 | 21 | @keyframes pulse { 22 | 0% { 23 | box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.7); 24 | } 25 | 26 | 70% { 27 | box-shadow: 0 0 0 10px rgba(255, 0, 0, 0); 28 | } 29 | 30 | 100% { 31 | box-shadow: 0 0 0 0 rgba(255, 0, 0, 0); 32 | } 33 | } 34 | 35 | .badgeNew { 36 | animation: pulse 1.5s infinite; 37 | } 38 | 39 | .lastDivider { 40 | @mixin light { 41 | box-shadow: 0 0px 20px 2px rgba(0, 0, 0, 0.2); 42 | } 43 | 44 | @mixin dark { 45 | box-shadow: 0 3px 8px 2px rgba(0, 0, 0, 0.5); 46 | } 47 | } 48 | 49 | .nextraIcon { 50 | width: 16px; 51 | height: 16px; 52 | display: inline-block; 53 | background-size: cover; 54 | color: red; 55 | 56 | @mixin light { 57 | background-image: url('https://github.com/shuding/nextra/blob/main/docs/public/favicon.svg?raw=true'); 58 | } 59 | 60 | @mixin dark { 61 | background-image: url('https://github.com/shuding/nextra/blob/main/docs/public/favicon-dark.svg?raw=true'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /docs/components/MdxInfo/MdxInfo.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | margin-top: calc(var(--mantine-spacing-xl) * 1.5); 3 | margin-bottom: var(--mantine-spacing-lg); 4 | 5 | & > p { 6 | line-height: 1.65; 7 | font-size: rem(15px); 8 | } 9 | 10 | /* Considered to be a heading of the info */ 11 | & > p > strong:only-child { 12 | font-family: var(--docs-font-primary); 13 | font-size: var(--mantine-font-size-lg); 14 | 15 | @mixin light { 16 | color: var(--mantine-color-black); 17 | } 18 | 19 | @mixin dark { 20 | color: var(--mantine-color-white); 21 | } 22 | 23 | & > code { 24 | font-size: 80%; 25 | } 26 | } 27 | 28 | & > p:first-of-type { 29 | margin-top: 0; 30 | } 31 | 32 | & > p:last-of-type { 33 | margin-bottom: 0; 34 | } 35 | 36 | & :global(.mantine-Code-root) { 37 | @mixin light { 38 | background-color: var(--docs-bq-code-bg-light); 39 | } 40 | 41 | @mixin dark { 42 | background-color: var(--docs-bq-code-bg-dark); 43 | } 44 | } 45 | 46 | & :global(.mantine-CodeHighlight-root) { 47 | margin-top: var(--mantine-spacing-md); 48 | 49 | @mixin light { 50 | background-color: var(--mantine-color-white); 51 | } 52 | 53 | @mixin dark { 54 | background-color: var(--mantine-color-dark-7); 55 | } 56 | } 57 | } 58 | 59 | .icon { 60 | width: rem(28px); 61 | height: rem(28px); 62 | } 63 | -------------------------------------------------------------------------------- /docs/styles-api/SplitResizer.styles-api.ts: -------------------------------------------------------------------------------- 1 | import type { SplitResizerFactory } from '@gfazioli/mantine-split-pane'; 2 | import type { StylesApiData } from '../components/styles-api.types'; 3 | 4 | export const SplitResizerStylesApi: StylesApiData = { 5 | selectors: { 6 | root: 'Root element', 7 | }, 8 | 9 | vars: { 10 | root: { 11 | '--split-resizer-size': 'Controls resizer size', 12 | '--split-resizer-color': 'Controls resizer color', 13 | '--split-resizer-hover-color': 'Controls resizer color', 14 | '--split-resizer-opacity': 'Controls resizer opacity', 15 | '--split-resizer-radius': 'Controls resizer border-radius', 16 | '--split-resizer-knob-size': 'Controls resizer knob size', 17 | '--split-resizer-knob-opacity': 'Controls resizer knob opacity', 18 | '--split-resizer-knob-radius': 'Controls resizer knob border-radius', 19 | '--split-resizer-knob-color': 'Controls resizer knob color', 20 | '--split-resizer-knob-hover-color': 'Controls resizer knob hover color', 21 | '--split-resizer-spacing': 'Controls resizer spacing', 22 | '--split-resizer-cursor-vertical': 'Controls resizer cursor in vertical mode', 23 | '--split-resizer-cursor-horizontal': 'Controls resizer cursor in horizontal mode', 24 | }, 25 | }, 26 | 27 | //modifiers: [{ modifier: 'data-mode', selector: 'pane', value: 'horizontal | vertical' }], 28 | }; 29 | -------------------------------------------------------------------------------- /docs/components/PropsTable/PropsTablesList.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { IconSearch } from '@tabler/icons-react'; 3 | import { TextInput, Title } from '@mantine/core'; 4 | import { getComponentName } from './getComponentName'; 5 | import { PropsTable } from './PropsTable'; 6 | import classes from './PropsTablesList.module.css'; 7 | 8 | export interface PropsTablesListProps { 9 | components: string[]; 10 | data: any; 11 | componentPrefix?: string; 12 | } 13 | 14 | export function PropsTablesList({ components, componentPrefix, data }: PropsTablesListProps) { 15 | const [query, setQuery] = useState(''); 16 | 17 | const tables = components.map((component) => ( 18 |
19 | 20 | {getComponentName({ component, componentPrefix })} component props 21 | 22 | 23 |
24 | )); 25 | 26 | return ( 27 |
28 | setQuery(event.currentTarget.value)} 32 | leftSection={} 33 | placeholder="Search props" 34 | radius="md" 35 | size="lg" 36 | autoFocus 37 | /> 38 | {tables} 39 |
40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /docs/data.ts: -------------------------------------------------------------------------------- 1 | export interface PackageData { 2 | /** Package name as in npm, for example, `mantine-extension-template` */ 3 | packageName: string; 4 | 5 | /** Description of the package, displayed below the title in documentation */ 6 | packageDescription: string; 7 | 8 | /** Link to the documentation mdx file, used in "Edit this page button" */ 9 | mdxFileUrl: string; 10 | 11 | /** Link to the repository on GitHub, used in header github icon and in "View source code button" */ 12 | repositoryUrl: string; 13 | 14 | /** Link to the license file */ 15 | licenseUrl?: string; 16 | 17 | /** Information about the author of the package */ 18 | author: { 19 | /** Package author name, for example, `John Doe` */ 20 | name: string; 21 | 22 | /** Author GitHub username, for example, `rtivital` */ 23 | githubUsername: string; 24 | }; 25 | } 26 | 27 | export const PACKAGE_DATA: PackageData = { 28 | packageName: '@gfazioli/mantine-split-pane', 29 | packageDescription: 30 | 'A Mantine component that manages split panes allows users to divide and resize content areas within a layout efficiently', 31 | mdxFileUrl: 'https://github.com/gfazioli/mantine-split-pane/blob/master/docs/docs.mdx', 32 | repositoryUrl: 'https://github.com/gfazioli/mantine-split-pane', 33 | licenseUrl: 'https://github.com/gfazioli/mantine-split-pane/blob/master/LICENSE', 34 | author: { 35 | name: 'Giovambattista Fazioli', 36 | githubUsername: 'gfazioli', 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gfazioli/mantine-split-pane", 3 | "version": "2.5.6", 4 | "description": "A React component that manages split panes allows users to divide and resize content areas within a layout efficiently.", 5 | "homepage": "https://gfazioli.github.io/mantine-split-pane/", 6 | "packageManager": "yarn@4.0.1", 7 | "license": "MIT", 8 | "author": "Giovambattista Fazioli ", 9 | "keywords": [ 10 | "extension", 11 | "mantine", 12 | "pane", 13 | "react", 14 | "react-component", 15 | "resizer", 16 | "split", 17 | "typescript" 18 | ], 19 | "main": "./dist/cjs/index.cjs", 20 | "module": "./dist/esm/index.mjs", 21 | "types": "./dist/types/index.d.ts", 22 | "exports": { 23 | ".": { 24 | "import": { 25 | "types": "./dist/types/index.d.mts", 26 | "default": "./dist/esm/index.mjs" 27 | }, 28 | "require": { 29 | "types": "./dist/types/index.d.ts", 30 | "default": "./dist/cjs/index.cjs" 31 | } 32 | }, 33 | "./styles.css": "./dist/styles.css", 34 | "./styles.layer.css": "./dist/styles.layer.css" 35 | }, 36 | "repository": "https://github.com/gfazioli/mantine-split-pane.git", 37 | "peerDependencies": { 38 | "@mantine/core": ">=7.0.0", 39 | "@mantine/hooks": ">=7.0.0", 40 | "react": "^18.x || ^19.x", 41 | "react-dom": "^18.x || ^19.x" 42 | }, 43 | "bugs": "https://github.com/gfazioli/mantine-split-pane/issues" 44 | } 45 | -------------------------------------------------------------------------------- /docs/components/StylesApiTable/SelectorsTable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Table, TableProps, Text } from '@mantine/core'; 3 | import { TableInlineCode } from '../TableInlineCode'; 4 | import type { StylesApiData } from './StylesApiTable'; 5 | 6 | interface SelectorsTableProps extends Omit { 7 | data: StylesApiData; 8 | component: string; 9 | fixedLayout?: boolean; 10 | } 11 | 12 | export function SelectorsTable({ 13 | data, 14 | component, 15 | fixedLayout = true, 16 | ...others 17 | }: SelectorsTableProps) { 18 | const rows = Object.keys(data.selectors).map((selector) => ( 19 | 20 | {selector} 21 | 22 | 23 | .mantine-{component}-{selector} 24 | 25 | 26 | 27 | {data.selectors[selector]} 28 | 29 | 30 | )); 31 | 32 | return ( 33 | 34 | 35 | 36 | 37 | Selector 38 | Static selector 39 | Description 40 | 41 | 42 | {rows} 43 |
44 |
45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /docs/components/InstallScript/MdxNpmScript.tsx: -------------------------------------------------------------------------------- 1 | import { CodeHighlight } from '@mantine/code-highlight'; 2 | import { Group, Tabs } from '@mantine/core'; 3 | import { useLocalStorage } from '@mantine/hooks'; 4 | import { NpmIcon, YarnIcon } from '@mantinex/dev-icons'; 5 | import classes from './MdxNpmScript.module.css'; 6 | 7 | interface MdxNpmScriptProps { 8 | yarnScript: string; 9 | npmScript: string; 10 | } 11 | 12 | export function MdxNpmScript({ yarnScript, npmScript }: MdxNpmScriptProps) { 13 | const [tab, setTab] = useLocalStorage({ key: 'script-tab-value', defaultValue: 'yarn' }); 14 | 15 | return ( 16 | setTab(val!)} variant="pills" classNames={classes}> 17 | 18 | 19 | 20 | 21 | yarn 22 | 23 | 24 | 25 | 26 | 27 | npm 28 | 29 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /docs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '@mantine/core/styles.css'; 2 | import '@mantine/code-highlight/styles.css'; 3 | import '@mantinex/mantine-logo/styles.css'; 4 | import '@mantinex/mantine-header/styles.css'; 5 | import '@mantinex/demo/styles.css'; 6 | import '@gfazioli/mantine-split-pane/styles.css'; 7 | 8 | import { AppProps } from 'next/app'; 9 | import Head from 'next/head'; 10 | import { CodeHighlightAdapterProvider, createShikiAdapter } from '@mantine/code-highlight'; 11 | import { MantineProvider } from '@mantine/core'; 12 | import favicon from '../assets/favicon.svg'; 13 | import { Footer } from '../components/Footer'; 14 | import { theme } from '../theme'; 15 | 16 | async function loadShiki() { 17 | const { createHighlighter } = await import('shiki'); 18 | const shiki = await createHighlighter({ 19 | langs: ['tsx', 'scss', 'html', 'bash', 'json'], 20 | themes: [], 21 | }); 22 | 23 | return shiki; 24 | } 25 | 26 | const shikiAdapter = createShikiAdapter(loadShiki); 27 | 28 | export default function App({ Component, pageProps }: AppProps) { 29 | return ( 30 | 31 | 32 | Mantine Split Pane 33 | 37 | 38 | 39 | 40 | 41 | 42 |