{"id":31931116,"url":"https://github.com/spren9er/tilez","last_synced_at":"2025-10-14T04:17:43.754Z","repository":{"id":64683768,"uuid":"576909305","full_name":"spren9er/tilez","owner":"spren9er","description":"A generic layout engine for Svelte components","archived":false,"fork":false,"pushed_at":"2025-05-17T05:40:19.000Z","size":4333,"stargazers_count":24,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-17T06:27:30.362Z","etag":null,"topics":["chart","composition","data-visualization","layout","svelte","svg"],"latest_commit_sha":null,"homepage":"https://tilez.spren9er.de","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/spren9er.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2022-12-11T11:42:46.000Z","updated_at":"2025-03-25T22:51:16.000Z","dependencies_parsed_at":"2024-02-07T17:42:33.135Z","dependency_job_id":"cdd3a72d-7210-4ec7-9908-62b8fcf275e9","html_url":"https://github.com/spren9er/tilez","commit_stats":{"total_commits":178,"total_committers":1,"mean_commits":178.0,"dds":0.0,"last_synced_commit":"43eb8ee0e4a0e61c15cd88c0c10911777065efeb"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/spren9er/tilez","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spren9er%2Ftilez","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spren9er%2Ftilez/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spren9er%2Ftilez/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spren9er%2Ftilez/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spren9er","download_url":"https://codeload.github.com/spren9er/tilez/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spren9er%2Ftilez/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017978,"owners_count":26086213,"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","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["chart","composition","data-visualization","layout","svelte","svg"],"created_at":"2025-10-14T04:17:28.247Z","updated_at":"2025-10-14T04:17:43.746Z","avatar_url":"https://github.com/spren9er.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Tests-Badge](https://github.com/spren9er/tilez/actions/workflows/test.yml/badge.svg)\n![Coverage-Badge](https://img.shields.io/badge/Coverage-100%25-success?logo=vitest\u0026logoColor=959da5\u0026labelColor=2b3138\u0026style=flat)\n![NPM-Badge](https://img.shields.io/npm/v/tilez?label=npm\u0026logo=npm\u0026logoColor=%23959da6\u0026labelColor=2b3138\u0026style=flat)\n\n# ![Tilez-Logo](https://github.com/spren9er/tilez/blob/main/docs/images/tilez_logo.svg?raw=true) tilez\n\n**_tilez_** is a generic layout engine for Svelte components.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_example.gif?raw=true\" width=\"305px\" height=\"207px\"\u003e\n\u003c/p\u003e\n\n_Above layout was generated by **_tilez_**, where root tile props (width, height and padding) are changing over time.\nBoxes shown are a mixture of HTML, SVG, Canvas and WebGL elements._\n\nBy default, all tiles – the building blocks of a layout – are renderless components. A layout is defined via nested, stackable tiles, where each tile has its own coordinate space, which is accessible through Svelte stores within a tile's context.\n\n**_tilez_** is\n\n- easy-to-use – _declare your layout in a simple manner_\n- flexible – _can be used with SVG, HTML, Canvas, WebGL or renderless components_\n- reactive – _changing props of a tile will update all subtiles_\n- free of dependencies – _except for Svelte_\n- opinionated – _the way the layout algorithm works (see [here](#how-does-the-layout-algorithm-work))_\n- robust – _handles edge cases very well_\n- light-weight – _does not add more than a few bytes to your Svelte application_\n\nThe main application of **_tilez_** is to use it as abstraction layer for creating compositions and layers of arbitrary SVG charts for data visualization. As SVG is lacking a layout engine, **_tilez_** fills that gap. However, it can be used with HTML, Canvas and WebGL, too.\n\nHere is an example of a composition of several different [Observable Plot](https://github.com/observablehq/plot) charts, which makes up an [UpSet plot](https://upset.app). Individual charts are embedded in a simple **_tilez_** layout.\nThe final result is one single SVG chart (w/o HTML).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_upset.svg?raw=true\" width=\"550px\"\u003e\n\u003c/p\u003e\n\n**_tilez_** is also helpful for building dashboards. It can easily create _open_, _table_, _stratified_ and _grouped_ layouts (see also [Dashboard Design Patterns](https://dashboarddesignpatterns.github.io/patterns.html#page-layout)).\nWith **_tilez_**, pure SVG dashboards can be implemented effortlessly.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_dashboard.png?raw=true\" width=\"800px\"\u003e\n\u003c/p\u003e\n\n_Above dashboard in open layout contains charts using [Apache ECharts](https://github.com/apache/echarts) library._\n\nLook at accompanying packages\n\n- [tilez-vega-lite](https://github.com/spren9er/tilez-vega-lite)\n- [tilez-observable-plot](https://github.com/spren9er/tilez-observable-plot)\n- [tilez-echarts](https://github.com/spren9er/tilez-echarts)\n\nfor using chart libraries with **_tilez_**.\n\n## Table of contents\n\n- [Installation](#installation)\n- [How to specify layouts?](#how-to-specify-layouts)\n- [How to access tile information?](#how-to-access-tile-information)\n- [How does the layout algorithm work?](#how-does-the-layout-algorithm-work)\n- [API Reference](#api-reference)\n\n\n## Installation\n\nInstall **_tilez_** as npm package via\n\n```\nnpm install tilez\n```\n\n\n## How to specify layouts?\n\nA **Tile** component is a building block of a layout.\n\n### Import Tile Component\n\nA **Tile** component can be imported by\n\n```javascript\nimport { Tile } from 'tilez';\n```\n\n### Tile Component Props\n\nA **Tile** component has following available props (see [API Tile Props](#tile-props) for details)\n\n```svelte\n\u003cTile\n  stack=\"horizontal\"\n  width=\"800px\"\n  height=\"600px\"\n  innerPadding=\"10px\"\n  outerPadding=\"5px\"\n  hAlign=\"left\"\n  vAlign=\"top\"\n  type=\"plain\"\n  mode=\"spacing\"\n\u003e\n  ...\n\u003c/Tile\u003e\n```\n\nAll props are optional, i.e. you can have tiles with no props at all\n\n```svelte\n\u003cTile\u003e\n  ...\n\u003c/Tile\u003e\n```\n\n**Tile** props are reactive (except for [stack](#props_stack) and [type](#props_type)), i.e. if you change props for an arbitrary tile in tile hierarchy, whole subtree of tiles is rerendered according to updated props.\n\nIf you want to know exactly what happens, when you alter these props in a given layout – without reading through [API Tile Props](#tile-props) – take a look at [tilez.spren9er.de](https://tilez.spren9er.de) and play around with an interactive example layout.\n\n### Stacking Tiles\n\nThe main concept of **_tilez_** is stacking tiles in _horizontal_ or _vertical_ direction, recursively.\nWithin a stack, a tile starts at the point where the last tile ends. For stacking, you use the property [stack](#props_stack), which defines in which direction children tiles should be stacked.\n\nFor convenience, there are following shortcuts available\n\n- **HTile** for _horizontal_ stacking\n- **VTile** for _vertical_ stacking\n\nThese components have the same props available as a basic **Tile** component (except for [stack](#props_stack) property).\n\n### Layering Tiles\n\nAssuming no stack is given for a tile, then all children tiles will be layered. They share the same coordinate space like their parent tile. Also, they are rendered in the specified order. Thus, first tile will be displayed in the back, last tile in the front.\n\n### Tile Layouts\n\nLayouts can be described in a declarative way, by defining props of nested tiles. Here is an example of a simple layout\n\n```svelte\n\u003cHTile width=\"400px\" height=\"300px\" innerPadding=\"10px\" outerPadding=\"5px\"\u003e\n  \u003cTile width=\"180px\"\u003e\n    \u003cMyComponent1 /\u003e\n  \u003c/Tile\u003e\n\n  \u003cTile height=\"60%\" vAlign=\"center\"\u003e\n    \u003cMyComponent2 /\u003e\n  \u003c/Tile\u003e\n\n  \u003cTile width=\"30%\"\u003e\n    \u003cMyComponent3 /\u003e\n  \u003c/Tile\u003e\n\u003c/HTile\u003e\n```\n\n\u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_layout_example.png?raw=true\" width=\"225px\" height=\"170px\" /\u003e\n\nCheck out a similar example in [Svelte REPL](https://svelte.dev/playground/1a8e45baea624a079255275a1473374b?version=5.1.1)!\n\n\n## How to access tile information?\n\nAfter defining a layout, arbitrary Svelte components can be embedded in your tiles. In your components you get access to tile specs, linear scales of local coordinate system and a reference to HTML/SVG/Canvas/WebGL element by adding the following lines\n\n```javascript\nimport { getTileContext } from 'tilez';\n\nconst {specs, xScale, yScale, element } = getTileContext();\n```\n\nAll objects – which you obtain from a tile's context – are Svelte stores. See [API Tile Context](#tile-context) for details.\n\nAlternatively, you can use `getContext` from Svelte\n\n```javascript\nimport { getContext } from 'svelte';\n\nconst {specs, xScale, yScale, element } = getContext('tilez');\n```\n\nFor Canvas or WebGL elements you can retrieve additionally _CanvasRenderingContext2D_ or _WebGLRenderingContext_, respectively as Svelte store `context` from `getTileContext`.\n\n\n### Tile Specs from Tile Context\n\nTile specs give you information about [_width_](#specs_width) and [_height_](#specs_height) of tile, as well as relative positions w.r.t. root, subroot and parent tile.\n\nFor further specs information see [API Tile Specs](#tile-specs).\n\n\n### Linear Scales from Tile Context\n\nFor each tile, there are two linear scales `$xScale` and `$yScale` available, one for _x_-axis and one for _y_-axis.\nTheir domain is `[0, 1]` and their range is `[0, $specs.width]` or `[0, $specs.height]`, respectively.\nYou can modify the domain for each scale.\n\n```javascript\nimport { getTileContext } from 'tilez';\n\nconst { xScale, yScale } = getTileContext();\n\nconst x = $xScale.domain([-5, 5]);\nconst y = $yScale.domain([0, 400]);\n\nconst sampleCoords = [x(0.5), y(150)];\n```\n\n_**Note:** If you need non-linear scales, consider using _d3-scale_ with given tile specs._\n\nSee also [API Linear Scale](#linear-scale).\n\n### Access HTML, SVG or Canvas element\n\nThere are following ways to get a reference to the underlying HTML, SVG, Canvas or WebGL element of a tile.\n\n#### Get Element from Tile Context\n\nWithin your component – which is embedded in a **Tile** component – you can get access to an element store by using `getTileContext`.\n\n```javascript\nimport { getTileContext } from 'tilez';\n\nconst { element } = getTileContext();\n\n$effect(() =\u003e {\n  doSomethingWith($element);\n});\n```\n\n#### Bind Element from Tile\n\nElements can also be accessed from outside of tile scope using `bind`\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\nimport { Tile } from 'tilez';\n\nlet element: SVGElement;\n\n$effect(() =\u003e {\n  doSomethingWith(element);\n});\n\u003c/script\u003e\n\n\u003cTile type=\"svg\" bind:element\u003e\n  ...\n\u003cTile\u003e\n```\n\n#### Get Canvas or WebGL Context from Tile\n\nFor Canvas and WebGL elements, you retrieve context for drawing from [getTileContext](#get_tile_context).\nHere is an example of using Canvas in your component\n\n```javascript\nconst { specs, context } = getTileContext();\n\n$effect.pre(() =\u003e {\n  if ($context) {\n    const ctx = $context as CanvasRenderingContext2D;\n    const dpr = window.devicePixelRatio || 1;\n    const thickness = 1 * dpr;\n\n    const offset = thickness / 2;\n    const width = $specs.width * dpr - thickness;\n    const height = $specs.height * dpr - thickness;\n\n    ctx.beginPath();\n    ctx.strokeStyle = '#cccccc';\n    ctx.lineWidth = thickness;\n    ctx.rect(offset, offset, width, height);\n    ctx.stroke();\n    ctx.closePath();\n  }\n});\n```\n\n_**Note:** When using Canvas tiles, make sure that you multiply specs coordinates with `window.devicePixelRatio`._\n\n\n### Tile Specs from Tile Component\n\nTile specs can also be accessed directly via `children` snippet\n\n```svelte\n\u003cHTile width=\"400px\" height=\"300px\" innerPadding=\"10px\" outerPadding=\"5px\"\u003e\n  \u003cTile width=\"180px\"\u003e\n    {#snippet children({ specs: { width, height } = {} })}\n      \u003cMyComponent1 {width} {height} /\u003e\n    {/snippet}\n  \u003c/Tile\u003e\n\n  \u003cTile\u003e\n    ...\n  \u003c/Tile\u003e\n\u003c/HTile\u003e\n```\n\nor from outside of tile scope using `bind`\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\nimport { Tile, type TileSpecs } from 'tilez';\n\nlet specs: TileSpecs | undefined;\n\n$effect(() =\u003e {\n  doSomethingWith(specs);\n});\n\u003c/script\u003e\n\n\u003cTile type=\"svg\" bind:specs\u003e\n  ...\n\u003cTile\u003e\n```\n\n## How does the layout algorithm work?\n\nThe underlying layout algorithm should behave well in all circumstances, especially when there is not enough space to render all given tiles.\n\nBut which tiles should be rendered and which should be ignored?\n\nIn the following, we take a closer look at an opinionated rendering algorithm, which is implemented in **_tilez_**. We consider the algorithm for a single tile with a non-trivial stack direction (_'horizontal'_ or _'vertical'_) and its direct children tiles. This algorithm then can be applied to each stack of the tiles hierarchy.\n\n### Tiles Prioritization\n\nBefore tiles are rendered within a stack, they are sorted according to following order\n\n1. Tiles of absolute sizes\n2. Tiles of relative sizes\n3. Tiles of flex sizes (no size specification)\n\nWithin each group, tiles are sorted according to the natural order given (ascending order of children tiles within parent tile).\nThe order gives information about the priority for rendering. First tiles of above order have high priority and will be rendered first, while last tiles have low priority and won't be rendered at all, if there is not enough space left.\n\n_**Note:** Alignment props are **not** taken into consideration when sorting!\nThus, tile _B_ which comes **after** tile _A_ in natural order and belongs to same group, could be aligned as such that it appears **before** tile _A_. This fact can be used to take influence in the rendering behavior._\n\n### Layout Algorithm\n\n1. We take one tile after the other of first sorted group above (tiles of absolute sizes) and for each tile we determine its size, as long as enough space is available. A tile which doesn't fit completely in available space is cut off. Then, rest of tiles will have zero size.\n2. For determining other tiles sizes, we have to look at each specific layout mode separately (see [API Layout Mode](#props_mode))\n   1. **Spacing Mode:** If sizes of all tiles of first group are determined and there is still space left, the available space will be distributed between all remaining tiles in the following way\n      1. Filter out tiles of relative size which can't be rendered, because their calculated size is less than _1px_.\n      2. For all remaining tiles of second group (tiles of relative sizes), we will process tiles like in first step: Resulting sizes will be determined one by one. If there is not enough space available, tile will be cut off and all remaining tiles will have zero size.\n      3. If sizes of all tiles of relative sizes are determined and there is still space left, we consider the last group of tiles (flex tiles w/o size specification). Assuming there are _n_ flex tiles left. Their size will be calculated by distributing remaining space equally across flex tiles (each flex tile will have same size). If sizes are less than _1px_, we try to distribute remaining space across _n - 1_ flex tiles, then _n - 2_ flex tiles, and so on. Finally, we either have some flex tiles with large enough sizes to render or all flex tiles will have zero size.\n   2. **Sizing Mode:** Let _m_ be the number of tiles with relative and flex sizes. We want to distribute _k \u003c= m_ tiles (with _k_ max.) and start with _k = m_.\n      1. We try to determine _k_ tiles with non-zero relative and flex sizes.\n      2. We subtract _(k - 1) x inner padding_ from available space.\n      3. For remaining space we apply above steps of _'spacing'_ mode. Assuming _p_ tiles of relative size have non-zero size,  then in last step we only check if _n = k - p_ flex tiles can be rendered or not.\n      4. If previous step is not successful (there aren't _k_ tiles in total which have non-zero size), then we decrement _k_ and repeat steps above. Algorithm stops at the latest when _k = 0_ and all tiles have zero size.\n\nSo far, we only computed the resulting size for each tile.\nNow, we consider the rendering algorithm. When all sizes are determined with the process above, tiles are grouped according to their alignment w.r.t. stack direction (_'hAlign'_ for _'horizontal'_ and _'vAlign'_ for _'vertical'_).\nThis will generate three groups. We process them in the following way\n\n1. Render all tiles of _'left'_ or _'top'_ group according to their natural order from left to right or top to bottom.\n2. Render all tiles of _'right'_ or _'bottom'_ group according to their natural order (here descending) from right to left or bottom to top.\n3. Render all tiles of _'center'_ group according to their natural order in the middle of parent tile. If there is an  overlap with tiles from first or last group, we shift the center group to the right or left (this group then won't appear in the center).\n\nIn each step above, zero-sized tiles are ignored.\n\n\n## API Reference\n\n- [Tile Props](#tile-props)\n- [Tile Context](#tile-context)\n- [Tile Specs](#tile-specs)\n- [Linear Scale](#linear-scale)\n\n### Tile Props\n\n\u003ca name=\"props_stack\" href=\"#props_stack\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003estack\u003c/i\u003e · (_'horizontal'_ | _'vertical'_) [default: `undefined`]\n\nWhen this property is not given, all children tiles will have the same coordinate space like current tile and they are layered in the natural order given. Otherwise, children tiles will be distributed within current tile according to their props in _'horizontal'_ or _'vertical'_ direction.\n\n---\n\n\u003ca name=\"props_width\" href=\"#props_width\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003ewidth\u003c/i\u003e\n\nArgument can be an absolute or relative number. Accepts strings like _\"500px\"_, _\"500\"_, _\"50%\"_, _\"0.5\"_ or numbers like _500_ or _0.5_. Numbers between _0_ and _1_ are interpreted as percentages, otherwise they represent absolute widths.\nThe given width will result in different tile widths, depending on the layout [mode](#props_mode).\nRelative widths refer to the width you obtain when you subtract all absolute tile widths from full width.\nWhen there is no width given (default), remaining width in parent tile – after rendering tiles with absolute and relative width – will be distributed equally between current tile and other tiles having no width specification.\nFor root tile relative widths are not allowed. When no width is given in root tile, parent container needs to have explicit width specified, otherwise nothing is rendered.\n\n---\n\n\u003ca name=\"props_height\" href=\"#props_height\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003eheight\u003c/i\u003e\n\nAnalog to [width](#props_width) above.\n\n---\n\n\u003ca name=\"props_inner_padding\" href=\"#props_inner_padding\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003einnerPadding\u003c/i\u003e · [default: 0] [inherits]\n\nDefines the padding **between** children tiles of current tile. Format must be either a string like _\"10px\"_, _\"10\"_ or a number like _10_. Relative values are not supported.\nFor layout mode _'spacing'_ it adds half of the given inner padding to the left and right of the outer tiles (or tile if there is only one).\nThis property will be inherited, thus all children tiles will have the same inner padding for their children unless not specified explicitly in children tile. In other words, if inner padding of children tile is given, this value will be considered instead of inner padding of parent tile.\n\n---\n\n\u003ca name=\"props_outer_padding\" href=\"#props_outer_padding\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003eouterPadding\u003c/i\u003e · [default: 0]\n\nDefines the padding **around** children tile(s) of current tile. It is similar to CSS padding of a HTML container.\nThis property won't be inherited.\n\n---\n\n\u003ca name=\"props_h_align\" href=\"#props_h_align\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003ehAlign\u003c/i\u003e · (_'left'_ | _'center'_ | _'right'_) [default: _'left'_]\n\nDefines the horizontal alignment w.r.t. parent tile. Accepts _'left'_, _'center'_ and _'right'_.\nWhen several children tiles share the same alignment property, they will be positioned as a group according to their given order within parent tile. For _'center'_ applies: If centered group can't be positioned in the center because there will be an overlap with _'left'_ or _'right'_ groups, it will be shifted to the right or left, respectively.\n\n---\n\n\u003ca name=\"props_v_align\" href=\"#props_v_align\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003evAlign\u003c/i\u003e · (_'top'_ |  _'center'_ | _'bottom'_) [default: _'top'_]\n\nDefines the vertical alignment w.r.t. parent tile. Accepts _'top'_, _'center'_ and _'bottom'_.\nIt behaves like [hAlign](#props_h_align), but in vertical direction.\n\n---\n\n\u003ca name=\"props_type\" href=\"#props_type\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003etype\u003c/i\u003e · (_'plain'_ | _'svg'_ |  _'html'_ | _'canvas'_ | _'webgl'_) [default: _'plain'_] [inherits]\n\nThis property sets the document type of current tile. Available types are _'plain'_, _'svg'_, _'html'_, _'canvas'_ and _'webgl'_.\nType inherits from parent tile unless not specified explicitly. Otherwise, given type will be taken into consideration.\n\n#### Plain Tile (Renderless Component)\n\nBy default, using **_tilez_** won't create any containers, i.e. all components are renderless components (_type_ is _'plain'_).\n\n#### SVG Tile\n\nUsing type _'svg'_, (sub)root tile will be an SVG container `\u003csvg\u003e` and all children tiles will be rendered as SVG group `\u003cg\u003e`.\n\n#### HTML Tile\n\nFor _'html'_ tiles, all `\u003cdiv\u003e` containers are implicitly absolute positioned. If you want to have a pure HTML layout, you should probably consider using CSS flexbox and CSS grid, as they are more powerful and flexible.\n\n#### Canvas Tile\n\nIf you use _'canvas'_ tiles, (sub)root tile creates a `\u003ccanvas\u003e` container. Within this container coordinate system is translated to each tile's origin. All children tiles will share the same `\u003ccanvas\u003e` element.\n\n#### WebGL Tile\n\nIf you use _'webgl'_ tiles, (sub)root tile creates a `\u003ccanvas\u003e` container. All children tiles will share the same `\u003ccanvas\u003e` element and also the same coordinate system, even they are placed in a stack.\n\n#### Mixing Tile Types\n\nYou can mix tile types, e.g. start with an HTML tile and add various subroot SVG, Canvas and/or WebGL tiles. Plain tiles can be added at each level in the tile hierarchy. However, there are following restrictions:\n\n- An _'html'_ tile can't be embedded into an _'svg'_, _'canvas'_ or _'webgl'_ tile.\n- An _'svg'_ tile can't be embedded into a _'canvas'_ or _'webgl'_ tile and vice versa.\n- A _'canvas'_ tile can't be embedded into a _'webgl'_ tile and vice versa.\n\n---\n\n\u003ca name=\"props_mode\" href=\"#props_mode\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003emode\u003c/i\u003e · (_'spacing'_ | _'sizing'_ ) [default: _'spacing'_] [inherits]\n\nThere are two layout modes available: one which is optimized for _'spacing'_ and one for _'sizing'_. They differ on how to interpret sizes when you specify a non-zero inner padding. When no inner padding is given, both modes produce the same layout.\n\n#### Tile Layout Mode _Spacing_\n\nIn layout mode _'spacing'_ (default mode), inner padding is part of the size specification of a tile. For a given width of _100px_ and an inner padding of _20px_, the resulting width of the tile is _80px_. On each side of a tile, there is an empty space of _50% of inner padding_, in our example _10px_. The consequence is that in this layout spacings are aligned properly across stacks, e.g. the first gap of a tile with _50%_ width is aligned with the fifth gap of five stacked tiles with _10%_ width each.\n\n\u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_layout_spacing.png?raw=true\" width=\"225px\" height=\"170px\" /\u003e\n\n_**Note:** There will be empty space of _50% inner padding_ on all sides of the most outer tile. If you want equidistant paddings throughout the whole tile hierarchy, you can add an outer padding in root tile of _inner padding / 2_._\n\nWhen you use absolute sizes together with relative sizes to define your layout, make sure to add outer padding to your size beforehand. As an example: You want to work with a width of _200px_ and outer padding is given as _10px_. Then a tile of width _100px_ corresponds to a tile of _50%_ only when the initial width is defined as _220px_, not _200px_.\n\n#### Tile Layout Mode _Sizing_\n\nWhen layout mode _'sizing'_ is used, all tiles have exactly the size which is specified in tile props, i.e. for a given width of _100px_, the tile has exactly a width of _100px_ (when there is enough space to render). Also, a tile of width _50%_ has _5_ times the width of a tile of width _10%_ (if they are in the same stack!), which generally does not apply to _'spacing'_ layout mode.\n\n\u003cimg src=\"https://github.com/spren9er/tilez/blob/main/docs/images/tilez_layout_sizing.png?raw=true\" width=\"225px\" height=\"170px\" /\u003e\n\nIt depends on your use case, which mode you choose. You can also mix modes, start with one mode and change to the other mode in an inner tile.\n\n---\n\n\u003ca name=\"props_specs\" href=\"#props_specs\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003especs\u003c/i\u003e\n\nA reference to tile specs.\n\n---\n\n\u003ca name=\"props_element\" href=\"#props_element\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003eelement\u003c/i\u003e\n\nA reference to an HTML, SVG or Canvas element (depending on the [type](#props_type)). For renderless components (_'plain'_ type), element is `undefined`. See also [this section](#access-html-svg-or-canvas-element).\n\n---\n\n\u003ca name=\"props_wrapper\" href=\"#props_wrapper\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTile\u003c/b\u003e.\u003ci\u003ewrapper\u003c/i\u003e\n\nA reference to the wrapper element (`HTMLDivElement`) containing all tiles. This can be used to add styles via\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\nimport { onMount } from 'svelte';\nimport { Tile } from 'tilez';\n\nlet wrapper: HTMLDivElement;\n\nonMount(() =\u003e {\n  if (wrapper) wrapper.style.border = '2px solid red';\n});\n\u003c/script\u003e\n\n\u003cTile bind:wrapper\u003e\n  ...\n\u003cTile\u003e\n```\n\nOnly applicable for root tile.\n\n### Tile Context\n\n\u003ca name=\"get_tile_context\" href=\"#get_tile_context\"\u003e#\u003c/a\u003e tilez.\u003cb\u003egetTileContext()\u003c/b\u003e\n\nReturns an object containing following Svelte stores\n\n- _specs_ of class **Writable\\\u003cTileSpecs\\\u003e**\n- _xScale_ of class **Writable\\\u003cLinearScale\\\u003e**\n- _yScale_ of class **Writable\\\u003cLinearScale\\\u003e**\n- _element_ of class **Writable\\\u003cHTMLElement | SVGElement | HTMLCanvasElement | null\\\u003e**\n- _context_ of class **Writable\\\u003cCanvasRenderingContext2D | WebGLRenderingContext | null\\\u003e**\n\n\n### Tile Specs\n\n\u003ca name=\"specs_width\" href=\"#specs_width\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003ewidth\u003c/i\u003e\n\nWidth of tile\n\n---\n\n\u003ca name=\"specs_height\" href=\"#specs_height\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003eheight\u003c/i\u003e\n\nHeight of tile\n\n---\n\n\u003ca name=\"specs_root_x\" href=\"#specs_root_x\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003erootX\u003c/i\u003e\n\nThe _x_-coordinate w.r.t. root tile\n\n---\n\n\u003ca name=\"specs_root_y\" href=\"#specs_root_y\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003erootY\u003c/i\u003e\n\nThe _y_-coordinate w.r.t. root tile\n\n---\n\n\u003ca name=\"specs_subroot_x\" href=\"#specs_subroot_x\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003esubRootX\u003c/i\u003e\n\nThe _x_-coordinate w.r.t. subroot tile. When type of tile changes when going from parent to child tile, there will be a new subtree in tiles hierarchy. The root tile of this subtree is called a subroot tile. The _x_ value is the distance between the left position of subroot tile and the left position of given tile in horizontal direction.\n\n---\n\n\u003ca name=\"specs_subroot_y\" href=\"#specs_subroot_y\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003esubRootY\u003c/i\u003e\n\nThe _y_-coordinate w.r.t. subroot tile. See [subRootX](#specs_subroot_x) for definition of a subroot.\n\n---\n\n\u003ca name=\"specs_parent_x\" href=\"#specs_parent_x\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003eparentX\u003c/i\u003e\n\nThe _x_-coordinate w.r.t. parent tile\n\n---\n\n\u003ca name=\"specs_parent_y\" href=\"#specs_parent_y\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003eparentY\u003c/i\u003e\n\nThe _y_-coordinate w.r.t. parent tile\n\n---\n\n\u003ca name=\"specs_inner_padding\" href=\"#specs_inner_padding\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003einnerPadding\u003c/i\u003e\n\nPadding between children tiles\n\n---\n\n\u003ca name=\"specs_outer_padding\" href=\"#specs_outer_padding\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003eouterPadding\u003c/i\u003e\n\nPadding around children tiles\n\n---\n\n\u003ca name=\"specs_h_align\" href=\"#specs_h_align\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003ehAlign\u003c/i\u003e · (_'left'_ |  _'center'_ | _'right'_)\n\nHorizontal alignment w.r.t. parent tile\n\n---\n\n\u003ca name=\"specs_v_align\" href=\"#specs_v_align\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003evAlign\u003c/i\u003e · (_'top'_ |  _'center'_ | _'bottom'_)\n\nVertical alignment w.r.t. parent tile\n\n---\n\n\u003ca name=\"specs_aspect_ratio\" href=\"#specs_aspect_ratio\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eTileSpecs\u003c/b\u003e.\u003ci\u003easpectRatio\u003c/i\u003e\n\nAspect ratio (width / height) of tile\n\n### Linear Scale\n\n\u003ca name=\"linear_scale_domain\" href=\"#linear_scale_domain\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eLinearScale\u003c/b\u003e.\u003ci\u003edomain(domain: [number, number])\u003c/i\u003e · [default: `[0, 1]`]\n\nYou can set a _domain_ which will be mapped to the tile range. Domains are also supported, where upper bound is less than lower bound, e.g. for `$xScale` or `$yScale` using `[1, 0]` will map `0` to full width or height and `1` to `0`.\n\n---\n\n\u003ca name=\"linear_scale_range\" href=\"#linear_scale_range\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eLinearScale\u003c/b\u003e.\u003ci\u003erange(range: [number, number])\u003c/i\u003e\n\nEven though `$xScale` and `$yScale` from a tile's context are coming with predefined ranges, such that they span the full width or height of a tile, you can override the _range_ with this method.\n\n---\n\n\u003ca name=\"linear_scale_call\" href=\"#linear_scale_call\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eLinearScale\u003c/b\u003e.\u003ci\u003e(x: number)\u003c/i\u003e\n\nThe class itself is directly callable. It computes the function value for a given _x_ value.\n\n---\n\n\u003ca name=\"linear_scale_inv\" href=\"#linear_scale_inv\"\u003e#\u003c/a\u003e tilez.\u003cb\u003eLinearScale\u003c/b\u003e.\u003ci\u003einv(y: number)\u003c/i\u003e\n\nMethod `inv` computes the _x_ value for a given _y_ value w.r.t. the inverse function. This can be useful for working with coords of mouse position.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspren9er%2Ftilez","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspren9er%2Ftilez","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspren9er%2Ftilez/lists"}