{"id":19636736,"url":"https://github.com/mizchi/react-unite","last_synced_at":"2025-10-24T19:09:34.714Z","repository":{"id":137923841,"uuid":"157458323","full_name":"mizchi/react-unite","owner":"mizchi","description":"Editable layout system","archived":false,"fork":false,"pushed_at":"2019-12-09T09:11:22.000Z","size":386,"stargazers_count":14,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-05T08:03:53.187Z","etag":null,"topics":["layout-engine","react","unity"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mizchi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-13T22:57:42.000Z","updated_at":"2024-02-05T09:52:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"dc208cb5-1fe0-44c5-98a1-b6fa3423a5e5","html_url":"https://github.com/mizchi/react-unite","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/mizchi%2Freact-unite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizchi%2Freact-unite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizchi%2Freact-unite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizchi%2Freact-unite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mizchi","download_url":"https://codeload.github.com/mizchi/react-unite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251284876,"owners_count":21564687,"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":["layout-engine","react","unity"],"created_at":"2024-11-11T12:31:05.340Z","updated_at":"2025-10-24T19:09:34.708Z","avatar_url":"https://github.com/mizchi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-unite\n\nEditable Grid \u0026 Layout\n\n![](https://i.gyazo.com/a4781fc08dd2dd96b0db5aea61563d57.gif)\n\n```\nyarn add react-unite\n```\n\nCAUTION: `react-unite` require `react@16.7.0-alpha.0` \u0026 `react-dom@16.7.0-alpha.0` to use react-hooks.\n\nSample project https://github.com/mizchi-sandbox/react-unite-example\n\n## Concept\n\n- inspired by Unity3D layout system\n- `react-unite` generates `display: grid` properties.\n\nSee also https://mizchi-sandbox.github.io/grid-generator/\n\n## EditableGrid (typescript)\n\n```tsx\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { EditableGrid, GridArea } from \"react-unite\";\n\nconst rows = [\"1fr\", \"2fr\", \"1fr\"];\nconst columns = [\"100px\", \"1fr\", \"1fr\", \"100px\"];\nconst areas = [\n  [\"a\", \"b\", \"c\", \"d\"],\n  [\"e\", \"f\", \"g\", \"h\"],\n  [\"j\", \"k\", \"l\", \"m\"]\n];\n\nconst root = document.querySelector(\".root\");\nReactDOM.render(\n  \u003cEditableGrid\n    width={640}\n    height={480}\n    spacerSize={16}\n    rows={rows}\n    columns={columns}\n    areas={areas}\n  \u003e\n    \u003cGridArea name=\"a\"\u003e\n      \u003cdiv\u003ea\u003c/div\u003e\n    \u003c/GridArea\u003e\n    \u003cGridArea name=\"b\"\u003e\n      \u003cdiv\u003eb\u003c/div\u003e\n    \u003c/GridArea\u003e\n    \u003cGridArea name=\"d\"\u003e\n      \u003cdiv\u003ed\u003c/div\u003e\n    \u003c/GridArea\u003e\n    \u003cGridArea name=\"f\"\u003e\n      \u003cdiv\u003ef\u003c/div\u003e\n    \u003c/GridArea\u003e\n    \u003cGridArea name=\"h\"\u003e\n      \u003cdiv\u003eh\u003c/div\u003e\n    \u003c/GridArea\u003e\n    \u003cGridArea name=\"l\"\u003e\n      \u003cdiv\u003el\u003c/div\u003e\n    \u003c/GridArea\u003e\n  \u003c/EditableGrid\u003e,\n  root\n);\n```\n\n## EditableLayout (typescript)\n\n```tsx\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { LayoutData, Windowed, EditableLayout } from \"react-unite\";\n\nconst initialLayoutData: LayoutData = {\n  grid: {\n    columns: [\"1fr\", \"1fr\"],\n    rows: [\"40px\", \"1fr\", \"1fr\"],\n    areas: [\n      [\"header\", \"header\"],\n      [\"preview\", \"inspector\"],\n      [\"assets\", \"inspector\"]\n    ]\n  },\n  windows: {\n    \"#scene\": { displayName: \"Scene\", id: \"#scene\" },\n    \"#project\": { displayName: \"Project\", id: \"#project\" },\n    \"#hierachy\": { displayName: \"Hierachy\", id: \"#hierachy\" },\n    \"#inspector\": { displayName: \"Inspector\", id: \"#inspector\" },\n    \"#services\": { displayName: \"Services\", id: \"#services\" }\n  },\n  panes: [\n    {\n      id: \"preview\",\n      displayName: \"Preview\",\n      selectedId: \"#scene\",\n      windowIds: [\"#scene\"]\n    },\n    {\n      id: \"assets\",\n      displayName: \"Preview\",\n      selectedId: \"#project\",\n      windowIds: [\"#project\", \"#hierachy\"]\n    },\n    {\n      id: \"inspector\",\n      displayName: \"Inspector\",\n      selectedId: \"#inspector\",\n      windowIds: [\"#inspector\", \"#services\"]\n    }\n  ]\n};\n\n// To fill window, Set css `html, body { margin: 0;}`\nconst MyLayout = () =\u003e {\n  return (\n    \u003cWindowed\u003e\n      {(width, height) =\u003e (\n        \u003cEditableLayout\n          width={width}\n          height={height}\n          layout={initialLayoutData}\n          renderTab={data =\u003e {\n            return \u003cspan\u003e{data.displayName}\u003c/span\u003e;\n          }}\n          renderWindow={win =\u003e {\n            return (\n              \u003cdiv\u003e\n                {win.id}: {win.displayName}\n              \u003c/div\u003e\n            );\n          }}\n        /\u003e\n      )}\n    \u003c/Windowed\u003e\n  );\n};\n\nconst root = document.querySelector(\".root\");\nReactDOM.render(\u003cMyLayout /\u003e, root);\n```\n\n## How to dev\n\n- `yarn build`: Generate `dist` by rollup\n- `yarn test`: Run jest\n\n## Write your own grid renderer\n\n```tsx\nimport styled from \"styled-components\";\nexport const Grid: React.ComponentClass\u003cGridProps\u003e = styled.div`\n  display: grid;\n  width: ${(p: GridProps) =\u003e p.width || \"100%\"};\n  height: ${(p: GridProps) =\u003e p.height || \"100%\"};\n  grid-template-columns: ${(p: GridProps) =\u003e p.columns.join(\" \")};\n  grid-template-rows: ${(p: GridProps) =\u003e p.rows.join(\" \")};\n  grid-template-areas: ${(p: GridProps) =\u003e\n    p.areas.map(row =\u003e \"'\" + row.join(\" \") + \"'\").join(\" \")};\n`;\n```\n\n## TODO\n\n- [x] Publish\n- [x] Swap window on drop\n- [x] Remove div in src\n- [x] `renderTab`\n- [x] Visual Effect on dragStart and dragEnd\n- [x] Fill Component\n- [ ] `containerType`: one | tabs | nest\n- [ ] ResizableBox\n- [ ] Option: `resizableRows`\n- [ ] Option: `resizableColumns`\n- [ ] Option: `minimumWindowWidth`\n- [ ] Option: `minimumWindowHeight`\n- [ ] Option: `editable: boolean`\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmizchi%2Freact-unite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmizchi%2Freact-unite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmizchi%2Freact-unite/lists"}