{"id":26552069,"url":"https://github.com/xcfox/react-tile-pane","last_synced_at":"2025-03-22T08:23:34.309Z","repository":{"id":61773426,"uuid":"330589940","full_name":"xcfox/react-tile-pane","owner":"xcfox","description":" A React tiling pane manager ","archived":false,"fork":false,"pushed_at":"2023-11-23T07:20:30.000Z","size":2679,"stargazers_count":26,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-24T23:42:13.452Z","etag":null,"topics":["react","splitter","tiling-window","window-manager"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xcfox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-18T07:40:02.000Z","updated_at":"2024-04-15T12:43:05.000Z","dependencies_parsed_at":"2022-10-21T00:00:20.415Z","dependency_job_id":null,"html_url":"https://github.com/xcfox/react-tile-pane","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xcfox%2Freact-tile-pane","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xcfox%2Freact-tile-pane/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xcfox%2Freact-tile-pane/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xcfox%2Freact-tile-pane/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xcfox","download_url":"https://codeload.github.com/xcfox/react-tile-pane/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244926880,"owners_count":20533205,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","splitter","tiling-window","window-manager"],"created_at":"2025-03-22T08:23:33.779Z","updated_at":"2025-03-22T08:23:34.298Z","avatar_url":"https://github.com/xcfox.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Tile Pane\n\nA React tiling pane manager\n\n## preview\n\nAn online demo is available at https://xcfox.github.io/react-tile-pane/demo/\n\n## install\n\n```shell\nnpm install @use-gesture/react react-use-measure react-tile-pane\n```\n\nor use yarn\n\n```shell\nyarn add @use-gesture/react react-use-measure react-tile-pane\n```\n\nreact-tile-pane use [@use-gesture/react](https://www.npmjs.com/package/@use-gesture/react), [react-use-measure](https://www.npmjs.com/package/react-use-measure) as peerDependencies, you need to install them at the same time.\n\n## Quick Start\n\n### Create Tile Panes\n\nFirst you need to create the Tile Panes List:\n\n```tsx\nconst [paneList, names] = createTilePanes({\n  arbutus: \u003cArbutus /\u003e,\n  cherry: \u003cdiv style={paneStyle}\u003echerry\u003c/div\u003e,\n  apple: \u003cApple /\u003e,\n  banana: \u003cdiv style={paneStyle}\u003ebanana🍌\u003c/div\u003e,\n  lemon: \u003cdiv style={paneStyle}\u003elemon\u003c/div\u003e,\n  mango: \u003cdiv style={paneStyle}\u003emango\u003c/div\u003e,\n  pomelo: \u003cdiv style={paneStyle}\u003epomelo\u003c/div\u003e,\n})\n```\n\nAs above, `createTilePanes` accepts a dictionary containing `ReactNode`, and return a `paneList` and a `names` dictionary. The structure of the output dictionary is consistent with the input, each item in the dictionary is essentially a string.\n\n### Describe Layout\n\n```tsx\nconst rootPane: TileBranchSubstance = {\n  children: [\n    { children: [names.apple, names.cherry] },\n    {\n      isRow: true,\n      grow: 2,\n      children: [\n        { children: names.arbutus },\n        { children: names.lemon },\n        {\n          children: [\n            { children: names.mango, grow: 3 },\n            { children: names.pomelo },\n          ],\n        },\n      ],\n    },\n  ],\n}\n```\n\nAs above, we place items in the same level into the same children's array.  \n`grow` is same as [flex-grow](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow), This property specifies how much of the remaining space in the `TileBranch` should be assigned to the item. Its default value is 1.  \n`isRow` is used to declare whether the panes is displayed as a row or a column.  \nIf the item of `names` dictionary in children's array, it displayed as a Multi-Tag Pane.\n\n\u003e Note: Each name can only appear in the layout at most once.\n\n### Container\n\n```tsx\nconst App: React.FC = () =\u003e {\n  return (\n    \u003cTileProvider tilePanes={paneList} rootNode={rootPane}\u003e\n      \u003cdiv className=\"App\"\u003e\n        \u003cdiv style={{ height: 30 }} /\u003e\n        \u003cdiv style={{ border: '#afafaf solid 2px', width: 1000, height: 600 }}\u003e\n          \u003cTileContainer /\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n      \u003cDraggableTitle name={names.banana}\u003eDrag this banana🍌\u003c/DraggableTitle\u003e\n    \u003c/TileProvider\u003e\n  )\n}\n```\n\nAs above, we input `paneList` and `rootNode` into `TileProvider` as prop `tilePanes` and prop `rootNode`.  \nThen, we put `TileContainer` in `TileProvider`. `DraggableTitle` can also be put in `TileProvider`.\n\n### Full Example File\n\nApp.tsc\n\n```tsx\nimport React, { useState } from 'react'\nimport {\n  createTilePanes,\n  DraggableTitle,\n  TileBranchSubstance,\n  TileContainer,\n  TileProvider,\n} from 'react-tile-pane'\nimport './App.css'\n\nconst paneStyle: React.CSSProperties = {\n  width: '100%',\n  height: ' 100%',\n  display: 'flex',\n  justifyContent: 'center',\n  alignItems: 'center',\n}\n\nfunction Arbutus() {\n  const [number, count] = useState(1)\n  return (\n    \u003cdiv onClick={() =\u003e count((n) =\u003e n + 1)} style={paneStyle}\u003e\n      {number} catties of arbutus\n    \u003c/div\u003e\n  )\n}\n\nfunction Apple() {\n  return \u003cdiv style={paneStyle}\u003eapple\u003c/div\u003e\n}\n\nconst [paneList, names] = createTilePanes({\n  arbutus: \u003cArbutus /\u003e,\n  cherry: \u003cdiv style={paneStyle}\u003echerry\u003c/div\u003e,\n  apple: \u003cApple /\u003e,\n  banana: \u003cdiv style={paneStyle}\u003ebanana\u003c/div\u003e,\n  lemon: \u003cdiv style={paneStyle}\u003elemon\u003c/div\u003e,\n  mango: \u003cdiv style={paneStyle}\u003emango\u003c/div\u003e,\n  pomelo: \u003cdiv style={paneStyle}\u003epomelo\u003c/div\u003e,\n})\n\nconst rootPane: TileBranchSubstance = {\n  children: [\n    { children: [names.apple, names.cherry] },\n    {\n      isRow: true,\n      grow: 2,\n      children: [\n        { children: names.arbutus },\n        { children: names.lemon },\n        {\n          children: [\n            { children: names.mango, grow: 3 },\n            { children: names.pomelo },\n          ],\n        },\n      ],\n    },\n  ],\n}\n\nconst App: React.FC = () =\u003e {\n  return (\n    \u003cTileProvider tilePanes={paneList} rootNode={rootPane}\u003e\n      \u003cdiv className=\"App\"\u003e\n        \u003cdiv style={{ height: 30 }} /\u003e\n        \u003cdiv style={{ border: '#afafaf solid 2px', width: 1000, height: 600 }}\u003e\n          \u003cTileContainer /\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n      \u003cDraggableTitle name={names.banana}\u003eDrag this banana🍌\u003c/DraggableTitle\u003e\n    \u003c/TileProvider\u003e\n  )\n}\n\nexport default App\n```\n\n## Custom Styles\n\n`React Tile Pane` does not focus on styles.\nIt is recommended to use custom styles.\n\nA complete example is available at https://github.com/xcfox/react-tile-pane/tree/main/src/App/demo/left-tab  \nTo customize the style, the `TileProvider` accepts the following properties:\n\n### pane\n\n`pane` is the basic unit of layout.  \nIt accepts `style` and `className` attributes.\n\n### preBox\n\nWhen you drag the title, a box will appear inside the container to help you determine the position of the pane after releasing the mouse, this box is called `preBox`.  \nIt accepts `style`, `className`, `child` attributes.\n\n### stretchBar\n\nThe stretchBar is in between the pane and is used to resize the pane.  \nIt accepts `style`, `className`, `child` attributes.\n\n### tabBar\n\nTabBar for managing overlapping panes.  \nIt accepts `render`, `thickness`, `position` attributes.\n\n- `render`: To customize how the TabsBar is rendered\n- `thickness`: Accepts a CSS length attribute, which defaults to px if number is passed in\n- `position`: Where to position the TabsBar in the pane\n\n## Hooks and Components\n\nHooks and components help you do more complex operations.\n\n\u003e Note: Hooks and Components only work inside the `TileContainer`\n\nExamples can be viewed at https://github.com/xcfox/react-tile-pane/blob/main/src/App/demo/left-tab/index.tsx\n\n### DraggableTitle\n\n`DraggableTitle` used to open a new pane from outside the container.\nIt accepts `style`, `className`, `children` attributes.\n\n- `name`: Associate a pane from the paneList by the name\n\n- `dragConfig`: Drag behavior, see more information in [use-gesture doc](https://use-gesture.netlify.app/docs/options/)\n- `onDrag`: Actions triggered when dragging, see more information in [use-gesture doc](https://use-gesture.netlify.app/docs/gestures/#about-the-drag-gesture)\n- `onDragEnd`: Actions triggered when drag ends\n- `onDragStart`: Actions triggered when drag starts\n\n#### Example\n\n```tsx\nfunction PaneIcon({ name }: { name: keyof typeof icons }) {\n  const getLeaf = useGetLeaf()\n  const move = useMovePane()\n  const leaf = getLeaf(name)\n  const isShowing = !!leaf\n  return (\n    \u003cdiv\u003e\n      \u003cdiv style={{ width: 40, height: 40, cursor: 'move' }}\u003e\n        \u003cDraggableTitle name={name}\u003e{icons[name]}\u003c/DraggableTitle\u003e\n      \u003c/div\u003e\n      \u003cdiv onClick={() =\u003e move(name, isShowing ? null : [0.99, 0.5])} /\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n### useGetLeaf\n\nGet a function to get pane by name.\n\n```tsx\n// Used in a React Function Components\nconst getLeaf = useGetLeaf()\n// get a leaf by its name, when the pane is not displayed, it will return undefined\nconst leaf = getLeaf(names.apple)\n```\n\n### useMove\n\nGet a function to move the pane.\n\n```tsx\n// Used in a React Function Components\nconst move = useMovePane()\nreturn (\n  \u003cdiv\u003e\n    \u003cdiv\n      // When an array of length 2 is passed in, the pane will be moved to that position in the container.\n      // When null is passed in, the pane will be closed.\n      onClick={() =\u003e move(name, isShowing ? null : [0.99, 0.5])}\n      style={{\n        cursor: 'pointer',\n        background: isShowing ? color.primary : color.secondary,\n        width: 14,\n        height: 14,\n        borderRadius: 99,\n      }}\n    /\u003e\n  \u003c/div\u003e\n)\n```\n\n### useGetRootNode\n\nGet a function to get `RootNode`, used to persist the current layout.\n\n```tsx\nconst localStorageKey = 'react-tile-pane-left-tab-layout'\n\nfunction AutoSaveLayout() {\n  const getRootNode = useGetRootNode()\n  localStorage.setItem(localStorageKey, JSON.stringify(getRootNode()))\n  return \u003c\u003e\u003c/\u003e\n}\n\nexport const LeftTabDemo: React.FC = () =\u003e {\n  const localRoot = localStorage.getItem(localStorageKey)\n  const root = localRoot\n    ? (JSON.parse(localRoot) as TileBranchSubstance)\n    : rootPane\n  return (\n    \u003cTileProvider tilePanes={nodeList} rootNode={root} tabBar={tabBarConfig}\u003e\n      \u003cTileContainer style={styles.container} /\u003e\n      \u003cAutoSaveLayout /\u003e\n    \u003c/TileProvider\u003e\n  )\n}\n```\n\n### useReset\n\nGet a function to reset layout.\n\n```tsx\nconst reset = useReset()\nconst handleClick = useCallback(() =\u003e reset(rootPane), [])\n```\n\n## Some similar projects\n\n- [react-mosaic](https://github.com/nomcopter/react-mosaic)\n- [FlexLayout](https://github.com/caplin/FlexLayout)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxcfox%2Freact-tile-pane","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxcfox%2Freact-tile-pane","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxcfox%2Freact-tile-pane/lists"}