@n-uf/hypr-tiling 26.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +145 -0
- package/README.md +242 -0
- package/dist/chunk-ZCGZOWOY.mjs +9871 -0
- package/dist/devtools.cjs +12001 -0
- package/dist/devtools.d.mts +111 -0
- package/dist/devtools.d.ts +111 -0
- package/dist/devtools.mjs +2286 -0
- package/dist/drag-easing-5WbK3T82.d.ts +605 -0
- package/dist/drag-easing-KxPPNNZT.d.mts +605 -0
- package/dist/engine.cjs +9899 -0
- package/dist/engine.d.mts +314 -0
- package/dist/engine.d.ts +314 -0
- package/dist/engine.mjs +116 -0
- package/dist/index.cjs +9833 -0
- package/dist/index.d.mts +74 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.mjs +125 -0
- package/dist/tiling-renderer-kTlSm4H4.d.mts +2185 -0
- package/dist/tiling-renderer-kTlSm4H4.d.ts +2185 -0
- package/package.json +96 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@n-uf/hypr-tiling` are documented here.
|
|
4
|
+
|
|
5
|
+
This package uses calendar-aligned versioning (`YY.M.R`), which cannot signal a
|
|
6
|
+
SemVer "major" bump. **Read the per-release notes below for breaking changes** —
|
|
7
|
+
the version number alone does not flag them.
|
|
8
|
+
|
|
9
|
+
## 26.7.0 — initial public release
|
|
10
|
+
|
|
11
|
+
First published release of `@n-uf/hypr-tiling`, a dynamic tiling layout engine
|
|
12
|
+
for React. This entry is the baseline: earlier working versions were never
|
|
13
|
+
published, so the changelog tracks the package from this release forward.
|
|
14
|
+
|
|
15
|
+
### Entry points
|
|
16
|
+
|
|
17
|
+
The package exposes three import paths through `package.json#exports`
|
|
18
|
+
(`"sideEffects": false`):
|
|
19
|
+
|
|
20
|
+
- **`@n-uf/hypr-tiling`** (`.`) — the **public API**. A small, hand-authored
|
|
21
|
+
facade of explicit named exports (never `export *`); this is the ONLY
|
|
22
|
+
consumer surface and the one tracked for compatibility.
|
|
23
|
+
- **`@n-uf/hypr-tiling/devtools`** — opt-in observability overlays, on their own
|
|
24
|
+
entry so a renderer-only consumer never bundles them.
|
|
25
|
+
- **`@n-uf/hypr-tiling/engine`** — a `@beta` escape hatch that re-exports the
|
|
26
|
+
engine-grade, framework-free internals (layout-tree reducers, low-level tree
|
|
27
|
+
walkers, keymap and drag-adjacent math) for power users driving the tree
|
|
28
|
+
headlessly. **No stability guarantees** — it may change or disappear in any
|
|
29
|
+
release and is kept off the consumer documentation site.
|
|
30
|
+
|
|
31
|
+
### Public API surface (`.`)
|
|
32
|
+
|
|
33
|
+
- **`TilingRenderer`** — the layout renderer: controlled layout tree, focus and
|
|
34
|
+
maximize, drag-and-drop with FLIP animation and self-healing recovery,
|
|
35
|
+
multi-select grouping (Alt/Opt+G), pane switching, and per-tile accents. A
|
|
36
|
+
custom `renderTile` receives the clean, debug-free `TilingRenderTileProps`
|
|
37
|
+
contract (tile payload + pane state flags + interaction handlers) — the
|
|
38
|
+
drag/drop observability + debug fields are OFF this surface (they route through
|
|
39
|
+
the internal default pane and `/devtools`).
|
|
40
|
+
- **Custom-pane helper primitives** — optional, unstyled conveniences layered
|
|
41
|
+
over `renderTile` that encode the pane wiring rules so a custom pane can't get
|
|
42
|
+
them wrong: `TilingPaneRoot` (`data-leaf-id` root + focus/hover handlers),
|
|
43
|
+
`TilingDragHandle` (drag pickup + `touch-action: none` + Alt/Opt group toggle),
|
|
44
|
+
`TilingPaneAction` (action button that stops propagation), and `TilingPaneBody`
|
|
45
|
+
(renders children only in `render-content` mode). The raw `renderTile` args
|
|
46
|
+
stay the full escape hatch.
|
|
47
|
+
- **Theming** — `TilingThemeProvider` / `TilingTheme` for token-driven styling.
|
|
48
|
+
- **Layout inspection & mutation** — the layout is a recursive tree of
|
|
49
|
+
`TilingLayoutNode` (`TilingLeafNode` / `TilingSplitNode` / `TilingGroupNode`).
|
|
50
|
+
Read it with `queryTilingLayout` (a `TilingLayoutQuery` view: leaf ids, splits,
|
|
51
|
+
groups, tile order, directional-neighbor lookup). Mutate it declaratively via
|
|
52
|
+
`onLayoutChange` or imperatively by dispatching a typed `TilingCommand` through
|
|
53
|
+
the renderer's `TilingCommandHandle` (gated by `isCommandEnabled`). The raw pure
|
|
54
|
+
reducers (`groupLeaves`, `insertLeafAdjacent`, `updateSplitRatio`, …) are NOT on
|
|
55
|
+
the public entry — they live on `@n-uf/hypr-tiling/engine`.
|
|
56
|
+
- **Interaction & presets** — `TilingInteractionCapabilities`,
|
|
57
|
+
`resolveInteractionCapabilities`, `TILING_DASHBOARD_PRESET`, and the theming
|
|
58
|
+
registry constants. Every interaction is **on by default** and narrowed by
|
|
59
|
+
passing a partial `interaction` prop; the single opt-IN exception is the group
|
|
60
|
+
tab strip's dev/demo "show pane body" checkbox
|
|
61
|
+
(`paneSwitching.showContentToggle`, default `false`), so a consumer that
|
|
62
|
+
renders its own pane content never surfaces an end-user control that blanks it
|
|
63
|
+
and panes paint content at rest with no wiring.
|
|
64
|
+
|
|
65
|
+
### Consumer theming & chrome contract
|
|
66
|
+
|
|
67
|
+
Every painted pixel is reachable from a consumer-authored `TilingTheme` or
|
|
68
|
+
routed through the consumer `renderTile` — no renderer state paints chrome the
|
|
69
|
+
consumer didn't choose. Defaults stay zero-config (built-in themes,
|
|
70
|
+
`DefaultTilingTile`, the built-in group strip). Concretely:
|
|
71
|
+
|
|
72
|
+
- **`theme` prop on `TilingRendererProps`** — a full consumer-authored
|
|
73
|
+
`TilingTheme`; takes precedence over `themeId`. `TilingTheme.id` is open
|
|
74
|
+
(`TilingThemeId | (string & {})`) so a consumer mints its own theme id;
|
|
75
|
+
`TILING_THEME_REGISTRY` stays keyed by the closed built-in union, and the
|
|
76
|
+
built-in theme switcher (`onThemeChange`, typed `TilingThemeId`) remains
|
|
77
|
+
built-ins-only — consumers running a custom theme simply don't wire it.
|
|
78
|
+
- **`grouping` capability object form** — `boolean | TilingGroupingCapability`
|
|
79
|
+
(`{ enable?, showGroupTabStrip? }`; bare boolean = `{ enable }`,
|
|
80
|
+
`showGroupTabStrip` default `true`). `showGroupTabStrip: false` suppresses
|
|
81
|
+
the built-in per-group tab strip so a consumer paints its own group chrome;
|
|
82
|
+
keyboard group commands stay live. `paneSwitching.showTabStrip` governs the
|
|
83
|
+
TOP-LEVEL tab strip only.
|
|
84
|
+
- **`surface` discriminator on `TilingRenderTileProps`**
|
|
85
|
+
(`TilingRenderSurface`: `"pane" | "drag-ghost" | "drag-cancel"`). The two
|
|
86
|
+
drag surfaces carry the REAL resolved capability display flags (no mid-drag
|
|
87
|
+
silhouette pop) with inert no-op handlers; a custom pane that wants different
|
|
88
|
+
drag chrome branches on `surface`.
|
|
89
|
+
- **`group` context on `TilingRenderTileProps`** —
|
|
90
|
+
`TilingRenderTileGroupContext | null`, populated for a tabbed group's ACTIVE
|
|
91
|
+
member: the `TilingGroupMemberView` member list (leaf/tile ids, resolved
|
|
92
|
+
tile, 1-based `memberNumber`, `isActive`) plus `activateMember` /
|
|
93
|
+
`removeMember` / `ungroup` callbacks that route through the same internal
|
|
94
|
+
command router as the built-in strip and the keyboard layer. `null` for
|
|
95
|
+
loose leaves and drag surfaces.
|
|
96
|
+
- **Cancel fly-back fidelity** — the drag-cancel overlay renders through the
|
|
97
|
+
consumer `renderTile` (`surface: "drag-cancel"`) when one is supplied, so a
|
|
98
|
+
custom skin keeps its own chrome for the whole cancel glide; the built-in
|
|
99
|
+
shell remains the no-`renderTile` fallback.
|
|
100
|
+
- **Hand-authored facade** — 104 public API items. Engine-grade internals are
|
|
101
|
+
physically layered under `engine/` and reached only through the `.` facade (via
|
|
102
|
+
`react/`) or the explicit `./engine` entry. An
|
|
103
|
+
[API Extractor](https://api-extractor.com/) report per entry is checked in
|
|
104
|
+
(`etc/hypr-tiling{,.devtools,.engine}.api.md`); `pnpm api:check` fails CI if the
|
|
105
|
+
`.` surface drifts or an unexported type leaks onto it, and an architectural
|
|
106
|
+
guardrail keeps the `engine/` layer framework-free and blocks deep consumer
|
|
107
|
+
imports.
|
|
108
|
+
|
|
109
|
+
### Developer / observability tooling — `@n-uf/hypr-tiling/devtools`
|
|
110
|
+
|
|
111
|
+
The observability panel, its seed defaults, and the whole debug/observability
|
|
112
|
+
input surface live on a separate `/devtools` subpath, so a renderer-only consumer
|
|
113
|
+
never pulls them into its bundle:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import {
|
|
117
|
+
TilingObservabilityPanel,
|
|
118
|
+
ANIMATION_CONTROL_DEFAULTS,
|
|
119
|
+
TilingRenderer, // the observability-instrumented view of the same renderer
|
|
120
|
+
} from "@n-uf/hypr-tiling/devtools";
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The renderer's observability inputs — overlay colors
|
|
124
|
+
(`observabilityColors` / `observabilityColorEnables`), the hit-zone / drop-intent
|
|
125
|
+
debug flags, and the `onDropIntentChange` / `onLiveHitLogChange` /
|
|
126
|
+
`onProjectedOverlayCountChange` telemetry hooks — are collected into
|
|
127
|
+
`TilingRendererObservabilityProps` and kept OFF the consumer `TilingRendererProps`
|
|
128
|
+
contract. `/devtools` exports both those props and the observability-typed view of
|
|
129
|
+
the SAME `TilingRenderer` component that accepts them, plus the debug/observability
|
|
130
|
+
snapshot **types** they reference (`TilingDropIntentDebugState`,
|
|
131
|
+
`TilingLiveHitLogState`, `TilingObservabilityColorConfig`, `TilingPaneHitZone*`,
|
|
132
|
+
…). The consumer `.` surface carries none of them.
|
|
133
|
+
|
|
134
|
+
### Documentation
|
|
135
|
+
|
|
136
|
+
Guides and a generated API reference are published at
|
|
137
|
+
[hypr-tiling.n-uf.com/docs](https://hypr-tiling.n-uf.com/docs). Every public symbol
|
|
138
|
+
carries TSDoc (coverage enforced in CI), so summaries and examples surface in
|
|
139
|
+
editor hover-docs.
|
|
140
|
+
|
|
141
|
+
### Tailwind requirement
|
|
142
|
+
|
|
143
|
+
The package ships no CSS — it emits Tailwind utility classes. Add
|
|
144
|
+
`@n-uf/hypr-tiling` to your Tailwind `content` glob or the renderer is unstyled.
|
|
145
|
+
See the README "Tailwind content requirement" section.
|
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="../../assets/hypr-tiling-logo-transparent.png" alt="hypr-tiling" width="48" align="center" />
|
|
3
|
+
@n-uf/hypr-tiling
|
|
4
|
+
</h1>
|
|
5
|
+
<p align="center">Dynamic tiling for React</p>
|
|
6
|
+
|
|
7
|
+
Dynamic tiling for React: a recursive split-tree renderer for drag/drop,
|
|
8
|
+
resizable, keyboard-controlled panes — inspired by
|
|
9
|
+
[Hyprland](https://hypr.land).
|
|
10
|
+
|
|
11
|
+
Reach for it when users need to rearrange dense, multi-panel screens at runtime
|
|
12
|
+
— IDE-like tools, trading and operator consoles, analytics dashboards — while
|
|
13
|
+
your app keeps strict, controlled ownership of the layout state.
|
|
14
|
+
|
|
15
|
+
## Quick links
|
|
16
|
+
|
|
17
|
+
- Documentation homepage: <https://hypr-tiling.n-uf.com/>
|
|
18
|
+
- Interactive showcase route: <https://hypr-tiling.n-uf.com/showcase>
|
|
19
|
+
- API report index: [`etc/hypr-tiling.api.md`](etc/hypr-tiling.api.md)
|
|
20
|
+
- Repository issues: <https://github.com/n-uf/hypr-tiling/issues>
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add @n-uf/hypr-tiling react react-dom
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @n-uf/hypr-tiling react react-dom
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @n-uf/hypr-tiling react react-dom
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`react` and `react-dom` are peer dependencies (version `^19`).
|
|
37
|
+
|
|
38
|
+
## Compatibility
|
|
39
|
+
|
|
40
|
+
- React: `^19`
|
|
41
|
+
- React DOM: `^19`
|
|
42
|
+
- Tailwind scanning: required (`content` glob or v4 `@source`)
|
|
43
|
+
- Runtime: browser DOM (React renderer package)
|
|
44
|
+
|
|
45
|
+
### Tailwind content requirement
|
|
46
|
+
|
|
47
|
+
This package **ships no CSS**. The renderer styles itself by emitting Tailwind
|
|
48
|
+
utility class strings (via `clsx` + `tailwind-merge`) — those classes only
|
|
49
|
+
resolve to real styles if Tailwind scans this package's built output and
|
|
50
|
+
generates the matching CSS. If you do not register the package in your Tailwind
|
|
51
|
+
`content` glob, the component renders **completely unstyled**.
|
|
52
|
+
|
|
53
|
+
Add `@n-uf/hypr-tiling` to your Tailwind `content` configuration:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// tailwind.config.js
|
|
57
|
+
export default {
|
|
58
|
+
content: [
|
|
59
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
60
|
+
"./node_modules/@n-uf/hypr-tiling/dist/**/*.{js,mjs}",
|
|
61
|
+
],
|
|
62
|
+
// ...
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For Tailwind v4 (CSS-first config), declare the same path as a source in your
|
|
67
|
+
stylesheet:
|
|
68
|
+
|
|
69
|
+
```css
|
|
70
|
+
@import "tailwindcss";
|
|
71
|
+
@source "../node_modules/@n-uf/hypr-tiling/dist/**/*.{js,mjs}";
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
75
|
+
|
|
76
|
+
The renderer is a **controlled component**: you own the layout tree in state and
|
|
77
|
+
apply every change it reports through `onLayoutChange`. Nothing about the layout
|
|
78
|
+
is hidden inside the component — the tree is yours to persist, diff, and restore.
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import {
|
|
82
|
+
TilingRenderer,
|
|
83
|
+
DEFAULT_TILING_LAYOUT_CONFIG,
|
|
84
|
+
type TilingLayoutNode,
|
|
85
|
+
type TilingTile,
|
|
86
|
+
} from "@n-uf/hypr-tiling";
|
|
87
|
+
import { useState } from "react";
|
|
88
|
+
|
|
89
|
+
const tiles: TilingTile[] = [
|
|
90
|
+
{ id: "a", title: "editor", content: <Editor /> },
|
|
91
|
+
{ id: "b", title: "preview", content: <Preview /> },
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const initialLayout: TilingLayoutNode = {
|
|
95
|
+
kind: "split",
|
|
96
|
+
id: "root",
|
|
97
|
+
axis: "vertical",
|
|
98
|
+
ratio: 0.5,
|
|
99
|
+
first: { kind: "leaf", id: "l", tileId: "a" },
|
|
100
|
+
second: { kind: "leaf", id: "r", tileId: "b" },
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export function Workspace(): JSX.Element {
|
|
104
|
+
const [layout, setLayout] = useState<TilingLayoutNode>(initialLayout);
|
|
105
|
+
return (
|
|
106
|
+
<TilingRenderer
|
|
107
|
+
layout={layout}
|
|
108
|
+
tiles={tiles}
|
|
109
|
+
config={DEFAULT_TILING_LAYOUT_CONFIG}
|
|
110
|
+
onLayoutChange={setLayout}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Programmatic layout API
|
|
117
|
+
|
|
118
|
+
Because you own the layout tree, you can mutate it from your own code — not just
|
|
119
|
+
through drag/keyboard interaction. The package exports a set of pure layout
|
|
120
|
+
reducers (each takes a layout node and returns a new one, never mutating in
|
|
121
|
+
place) as supported public API. Use these to script layout changes, build custom
|
|
122
|
+
commands, or restore persisted arrangements:
|
|
123
|
+
|
|
124
|
+
| Reducer | Purpose |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| `findLeafById` | Locate a leaf node within the tree by its id. |
|
|
127
|
+
| `insertLeafAdjacent` | Insert a new leaf next to an existing one along an axis. |
|
|
128
|
+
| `moveLeafToRoot` | Detach a leaf and re-seat it against the layout root. |
|
|
129
|
+
| `moveLeafToSplitContainer` | Move a leaf into a target split container. |
|
|
130
|
+
| `swapLeafTiles` | Exchange the tiles occupying two leaves. |
|
|
131
|
+
| `removeLeafTile` | Remove a leaf and collapse its parent split. |
|
|
132
|
+
| `updateSplitRatio` | Set the ratio of a binary split. |
|
|
133
|
+
| `toggleSplitAxis` | Flip a split between horizontal and vertical. |
|
|
134
|
+
| `setLeafSizing` | Set a leaf's sizing mode (static pixel extent vs. flexible). |
|
|
135
|
+
| `groupLeaves` | Collapse several leaves into one stacked/tabbed group. |
|
|
136
|
+
| `ungroupNode` | Expand a group back into individual leaves. |
|
|
137
|
+
| `collectGroups` | Enumerate the group nodes in a layout. |
|
|
138
|
+
| `isStructurallyValidLayout` | Validate a layout tree's structural invariants. |
|
|
139
|
+
|
|
140
|
+
All reducers are re-exported from the package root:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import {
|
|
144
|
+
findLeafById,
|
|
145
|
+
insertLeafAdjacent,
|
|
146
|
+
swapLeafTiles,
|
|
147
|
+
isStructurallyValidLayout,
|
|
148
|
+
} from "@n-uf/hypr-tiling";
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Other layout-tree helpers are exported for advanced/internal use, but the
|
|
152
|
+
reducers above are the stable, documented surface for application code.
|
|
153
|
+
|
|
154
|
+
For complete generated API signatures, see
|
|
155
|
+
[`etc/hypr-tiling.api.md`](etc/hypr-tiling.api.md).
|
|
156
|
+
|
|
157
|
+
## Features
|
|
158
|
+
|
|
159
|
+
- **Drag/drop rearrange** — Hyprland-style live drag; the move commits on
|
|
160
|
+
release, resolving to swap, edge-insert, split-container-insert, or
|
|
161
|
+
group-merge.
|
|
162
|
+
- **Resizable split dividers** — drag dividers, or pin a pane to a measured pixel
|
|
163
|
+
extent (static) versus ratio-distributed (flexible).
|
|
164
|
+
- **Group / stack tabs** — collapse several leaves into one slot as a stacked
|
|
165
|
+
group with a tab strip; only the active member renders.
|
|
166
|
+
- **Maximize** — promote any pane to fill the viewport and restore it back.
|
|
167
|
+
- **Keyboard-driven focus** — directional focus, a pane switcher
|
|
168
|
+
(cycle / jump / overlay), keyboard move-mode, and master/group commands behind
|
|
169
|
+
a remappable keymap.
|
|
170
|
+
- **Theming engine** — two built-in themes (`neon-terminal`, `clean-flat`),
|
|
171
|
+
eight accent hues, and live theme switching with no remount.
|
|
172
|
+
- **Self-healing drag recovery** — a frame-deadline backstop, an idle watchdog,
|
|
173
|
+
transient-style teardown, and a `visibilitychange` reconcile so a drag never
|
|
174
|
+
strands the tree mid-transition.
|
|
175
|
+
|
|
176
|
+
## Use cases
|
|
177
|
+
|
|
178
|
+
hypr-tiling is built for screens where users live across multiple panels and
|
|
179
|
+
rearrange them as the work demands:
|
|
180
|
+
|
|
181
|
+
- **Dynamic / content sites** — real, SEO-indexable content arranged as tiles
|
|
182
|
+
instead of a single scroll, with docs living in prerendered panes.
|
|
183
|
+
- **Dashboards** — analytics, metrics, and monitoring consoles where several
|
|
184
|
+
resizable panes share one screen.
|
|
185
|
+
- **IDE-like tools** — editor, preview, and terminal workspaces a user splits,
|
|
186
|
+
stacks, and rearranges at runtime.
|
|
187
|
+
- **Trading & operator consoles** — dense, keyboard-driven control surfaces that
|
|
188
|
+
pack many live panels into a fixed viewport.
|
|
189
|
+
- **Admin & data apps** — table, detail, and activity panes side by side, resized
|
|
190
|
+
to fit the task at hand.
|
|
191
|
+
- **Observability & log explorers** — query, results, and trace panes rearranged
|
|
192
|
+
on the fly while chasing an incident.
|
|
193
|
+
- **Web terminals & consoles** — browser-based shells, multiplexed sessions, and
|
|
194
|
+
live log streams split and resized Hyprland-style — the tiling homage made
|
|
195
|
+
literal, in the terminal.
|
|
196
|
+
- **Realtime trading terminals** — Bloomberg-style desks: live charts, order
|
|
197
|
+
books, watchlists, and order entry packed into dense panes that stream and
|
|
198
|
+
rearrange in realtime.
|
|
199
|
+
|
|
200
|
+
## Roadmap
|
|
201
|
+
|
|
202
|
+
Where hypr-tiling is headed. These are **planned** directions, not shipped
|
|
203
|
+
features today — the library currently renders to the DOM and ships a React
|
|
204
|
+
adapter only. The items below describe where the project is going:
|
|
205
|
+
|
|
206
|
+
- **Framework-agnostic core** — a dependency-free vanilla TypeScript core so the
|
|
207
|
+
tiling engine runs without any framework: the layout tree, the drag/FLIP state
|
|
208
|
+
machine, and the self-healing recovery logic decoupled from React, ready to
|
|
209
|
+
drive any view layer.
|
|
210
|
+
- **First-class adapters for every major framework** — React ships today;
|
|
211
|
+
planned official adapters for Vue, Svelte, Solid, Angular, and standard Web
|
|
212
|
+
Components, each a thin binding over the same vanilla core so behavior stays
|
|
213
|
+
identical across frameworks.
|
|
214
|
+
- **Canvas rendering backend** — an optional canvas / GPU-accelerated render path
|
|
215
|
+
for very high pane counts and animation-heavy scenes where DOM reflow is the
|
|
216
|
+
bottleneck; the semantic DOM path stays the default and canvas is opt-in for
|
|
217
|
+
density.
|
|
218
|
+
- **Rust + WebAssembly core** — porting the hot layout, drag, and geometry math
|
|
219
|
+
to a Rust → WebAssembly core for deterministic, high-frame-rate behavior,
|
|
220
|
+
unlocking more window-manager-like UX: virtual workspaces, snap zones,
|
|
221
|
+
persistent session layouts, fully keyboard-driven tiling, and
|
|
222
|
+
per-monitor-style multi-viewport arrangements.
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
hypr-tiling is built in the open and welcomes collaboration — framework
|
|
227
|
+
adapters, rendering backends, bug reports, and ideas from the roadmap above are
|
|
228
|
+
all welcome. To get involved, email
|
|
229
|
+
[metelin@gmail.com](mailto:metelin@gmail.com).
|
|
230
|
+
|
|
231
|
+
## Links
|
|
232
|
+
|
|
233
|
+
- Homepage: <https://hypr-tiling.n-uf.com>
|
|
234
|
+
- Showcase: <https://hypr-tiling.n-uf.com/showcase>
|
|
235
|
+
- Repository: <https://github.com/n-uf/hypr-tiling>
|
|
236
|
+
- Issues: <https://github.com/n-uf/hypr-tiling/issues>
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
Source-available under
|
|
241
|
+
[PolyForm Perimeter 1.0.1](https://polyformproject.org/licenses/perimeter/1.0.1)
|
|
242
|
+
— business use allowed, but no competing product built from this software.
|