{"id":44432268,"url":"https://github.com/x0k/svelte-tiler","last_synced_at":"2026-04-02T12:06:57.181Z","repository":{"id":335130074,"uuid":"1133959509","full_name":"x0k/svelte-tiler","owner":"x0k","description":"A small, unstyled library for building tiling UI's.","archived":false,"fork":false,"pushed_at":"2026-03-24T20:49:41.000Z","size":633,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-25T16:17:21.024Z","etag":null,"topics":["layout","svelte","svelte5","tiling"],"latest_commit_sha":null,"homepage":"http://x0k.dev/svelte-tiler/","language":"Svelte","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/x0k.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-14T03:39:21.000Z","updated_at":"2026-03-24T20:44:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/x0k/svelte-tiler","commit_stats":null,"previous_names":["x0k/svelte-tiler"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/x0k/svelte-tiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0k%2Fsvelte-tiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0k%2Fsvelte-tiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0k%2Fsvelte-tiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0k%2Fsvelte-tiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/x0k","download_url":"https://codeload.github.com/x0k/svelte-tiler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x0k%2Fsvelte-tiler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31305973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","svelte","svelte5","tiling"],"created_at":"2026-02-12T13:30:22.331Z","updated_at":"2026-04-02T12:06:57.163Z","avatar_url":"https://github.com/x0k.png","language":"Svelte","funding_links":[],"categories":[],"sub_categories":[],"readme":"# svelte-tiler\n\nA small, unstyled library for building tiling user interfaces.\n\n```sh\nnpm i svelte-tiler\n```\n\n**Features**:\n\n- Serializable state\n- Type-safe model extension\n- No external dependencies\n\n## Usage\n\n```svelte\n\u003cscript\u003e\n  import { fromConstant } from 'svelte-tiler/shared/registry';\n  import { Tiler, type Tiles } from 'svelte-tiler';\n  import * as Leaf from 'svelte-tiler/tiles/leaf.svelte';\n  import * as Tabs from 'svelte-tiler/tiles/tabs.svelte';\n\n  const createLeaf = Leaf.setup(fromConstant(leaf));\n\n  let layout = $state(\n    Tabs.create({\n      tabs: [\n        ['Foo', createLeaf('foo')],\n        ['Bar', createLeaf('bar')],\n        ['Baz', createLeaf('baz')],\n      ],\n    })\n  );\n\u003c/script\u003e\n\n\u003cTiler bind:layout definitions={{ leaf: Leaf, tabs: Tabs }} /\u003e\n\n{#snippet leaf(tile: Tiles['leaf'])}\n  {tile.name}\n{/snippet}\n\n\u003cstyle\u003e\n  :global {\n    [data-tabs] {\n      display: flex;\n      flex-direction: column;\n    }\n    [data-tabs-bar] {\n      display: flex;\n    }\n    [data-tabs-list] {}\n    [data-tabs-header] {\n      \u0026[aria-selected='true'] {}\n      \u0026[data-over='true'] {}\n    }\n    [data-tabs-content] {\n      flex-grow: 1;\n      \u0026[data-over='true'] {}\n    }\n  }\n\u003c/style\u003e\n```\n\n## Mental Model\n\nThis section explains the conceptual model behind the library and how its core pieces fit together.\n\n### Tile\n\nA **Tile** is the fundamental unit of the system. Everything in the layout is represented as a tree of tiles.\n\nBase type definition:\n\n```ts\nexport interface TileBase\u003cT extends TileType\u003e {\n  id: string;\n  type: T;\n  children: Tile[];\n}\n\nexport interface TileRegistry {}\n\nexport type TileType = keyof TileRegistry;\n\nexport type Tiles = {\n  [T in TileType]: TileBase\u003cT\u003e \u0026 TileRegistry[T];\n};\n\nexport type Tile = Tiles[TileType];\n```\n\nThis definition:\n\n- Establishes a minimal structural contract (`id`, `type`, `children`)\n- Enables type-safe model extension via `TileRegistry` interface augmentation\n- Produces a discriminated union (`Tile`) based on registered tile types\n\nBy augmenting `TileRegistry`, you extend the model in a fully type-safe way without modifying the core types.\n\n### TileDefinition\n\nIn addition to its type definition, every tile must provide a behavioral definition.\n\nEach tile exposes lifecycle hooks that are invoked by the tiler in order to perform structural mutations:\n\n- `onInsert` - invoked to perform insertion of a child tile at the specified index.\n- `onRemoveChild` - invoked to remove a child tile at the specified index.\n- `onClear` - invoked when the tile itself cannot be removed (e.g. the root tile) and must reset or clear its internal state instead.\n\nTogether with the Svelte component (`export default`), these hooks form a `TileDefinition`:\n\n```ts\nexport type TileProps\u003cT extends TileType\u003e = {\n  tile: Tiles[T];\n  parent: Tile | undefined;\n  index: number;\n  child: Snippet\u003c[number]\u003e;\n};\n\nexport type TileComponent\u003cT extends TileType\u003e = Component\u003c\n  TileProps\u003cT\u003e,\n  {},\n  'tile'\n\u003e;\n\nexport interface TileDefinition\u003cT extends TileType\u003e {\n  default: TileComponent\u003cT\u003e;\n  onInsert: (\n    ctx: TilerContext,\n    tile: Tiles[T],\n    index: number,\n    data: TileInsertData\u003cT\u003e\n  ) =\u003e void;\n  onRemoveChild: (ctx: TilerContext, tile: Tiles[T], index: number) =\u003e void;\n  onClear: (ctx: TilerContext, tile: Tiles[T]) =\u003e void;\n}\n```\n\nThe tiler requests a structural change, but the tile fully controls how the mutation is performed.\n\nFor example, a Tabs tile may decide that when its last child is removed, it should remove itself instead by calling `ctx.remove(tile)`. This mirrors the behavior of tab panels in editors such as VS Code.\n\nThis design keeps structural semantics inside the tile while the context provides the mutation primitives.\n\n### Layout\n\nA **Layout** is a state tree that describes the UI structure.\n\nTiles form a hierarchical tree representing the entire arrangement.\nMutations to this tree update the rendered structure reactively.\n\nStandard tiles are designed so that layouts remain fully serializable.\nTo support the serializable pattern, tiles typically export:\n\n- `setup` - installs runtime data into context and returns a parameterized `create` function.\n- `create` - produces tile data used in the layout.\n\nExample:\n\n```ts\nexport function setup\u003cR extends string\u003e(ctx: SplitContext\u003cR\u003e) {\n  setContext(SPLIT_CONTEXT_KEY, ctx);\n  return create\u003cR\u003e;\n}\n```\n\n### Context\n\nThe Tiler component internally works with a `TilerContext`, but you can also create and manage it manually.\n\n\u003e [!NOTE]\n\u003e You can use a single `TilerContext` instance for multiple `Panel` components.\n\nExample:\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { Panel, TilerContext, setTilerContext } from 'svelte-tiler';\n\n  const ctx = new TilerContext({\n    definitions: {\n      /* your tiles */\n    },\n  });\n\n  setTilerContext(ctx);\n\u003c/script\u003e\n\n\u003cPanel bind:layout /\u003e\n```\n\nUsing a custom TilerContext allows you to:\n\n- Programmatically manipulate the layout\n- Interact directly with tile operations\n- Extend or wrap the context class to inject custom logic\n- Centralize control over layout behavior\n\nThis makes the system flexible while keeping the layout model predictable and strongly typed.\n\n### Customization\n\nStandard tiles are intentionally shipped unstyled. All visual design decisions - must be implemented by the consumer after reviewing:\n\n- DOM hierarchy\n- Available `data-*` attributes\n- CSS custom properties\n\nThis approach keeps the core layout engine independent of styling concerns and ensures predictable integration into any design system.\n\nIf the standard tiles do not meet your requirements, you can freely copy the tile’s source code into your own project,\napply the necessary modifications, and replace the import with your customized version.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx0k%2Fsvelte-tiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fx0k%2Fsvelte-tiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx0k%2Fsvelte-tiler/lists"}