@bimetal/tree-svelte-components 0.36.0 → 0.37.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/dist/Tree.svelte CHANGED
@@ -2,7 +2,7 @@
2
2
  import { onDestroy, untrack, type Snippet } from 'svelte';
3
3
  import { createTreeControllerBinding } from '@bimetal/svelte';
4
4
  import type { TreeStore } from '@bimetal/tree-data';
5
- import type { TreeConfigInput, TreeController, TreeControllerSnapshot, TreeRowView , TreeControllerOptions } from '@bimetal/tree-headless';
5
+ import type { TreeConfigInput, TreeController, TreeControllerSnapshot, TreeRowView , TreeControllerOptions, TreeScrollAnchor } from '@bimetal/tree-headless';
6
6
  import { treeRowIndent, treeCssVars, reportUnroutedTreeError } from '@bimetal/tree-headless';
7
7
  import TreeDialog from './TreeDialog.svelte';
8
8
  import { isEditableTarget } from '@bimetal/a11y-dom';
@@ -46,7 +46,11 @@
46
46
  config?: TreeConfigInput;
47
47
  /** Apply the dark token set (`data-theme="dark"`). */
48
48
  darkMode?: boolean;
49
- /** Text/layout direction, applied as `dir` on the root (`ltr`/`rtl`). */
49
+ /** Text/layout direction, applied as `dir` on the root (`ltr`/`rtl`).
50
+ * Seit mcp-93 steuert sie zusaetzlich die TASTATUR: unter `rtl` sind die
51
+ * horizontalen Pfeiltasten getauscht, wie das ARIA-Tree-Pattern es verlangt.
52
+ * Sie speist `config.direction`; ein ausdruecklich gesetztes `config.direction`
53
+ * hat Vorrang. */
50
54
  dir?: 'ltr' | 'rtl';
51
55
  /** Optional toolbar heading. Omitted → no heading is rendered. */
52
56
  title?: string;
@@ -73,14 +77,40 @@
73
77
  // created/destroyed/setConfig here); standalone creates one ONCE under `untrack`.
74
78
  // bimetal-181: der GETTER ist die Aussage — er liest die `$props()`-Bindungen bei
75
79
  // jedem Callback-Aufruf erneut, statt den Stand des `untrack`-Aufbaus festzunageln.
76
- const binding = untrack(() => (controller ? null : createTreeControllerBinding(() => ({ store: store!, treeId: treeId!, config, onError: (err) => (onError ?? reportUnroutedTreeError)(err), onSelectionChange, onCheckedChange, loadChildren }))));
80
+ // mcp-93: `dir` ist die SICHTBARE Schreibrichtung unter RTL verlangt das
81
+ // ARIA-Tree-Pattern getauschte horizontale Pfeiltasten, und die Tastatur-Semantik
82
+ // sitzt im Controller. Deshalb speist `dir` `config.direction`; ein ausdruecklich
83
+ // gesetztes `config.direction` hat Vorrang. Gibt bei fehlendem `dir` die
84
+ // Original-Referenz zurueck — ein neues Objekt je Aufruf waere ein unnoetiger
85
+ // `setConfig`-Anlauf. Begruendung im Detail: tree-react.
86
+ const mitRichtung = (c: TreeConfigInput | undefined, d: 'ltr' | 'rtl' | undefined): TreeConfigInput | undefined =>
87
+ d && c?.direction === undefined ? { ...c, direction: d } : c;
88
+
89
+ const binding = untrack(() => (controller ? null : createTreeControllerBinding(() => ({ store: store!, treeId: treeId!, config: mitRichtung(config, dir), onError: (err) => (onError ?? reportUnroutedTreeError)(err), onSelectionChange, onCheckedChange, loadChildren }))));
77
90
  const ctrl = controller ?? binding!.ctrl;
91
+ // bimetal-225: der Mount wird gemeldet, sonst raeumt das Binding sich per Microtask
92
+ // selbst ab (der Controller entsteht im untrack-Aufbau und haelt ab da ein Store-Abo,
93
+ // und bei einer nie gemounteten Instanz laeuft KEIN Aufraeum-Haken). Ein $effect
94
+ // laeuft im Mount-Flush, also vor dem Microtask — gemessen.
95
+ binding?.erwarteMount(); // bimetal-225: Selbstabraeumung armieren (Opt-in)
96
+ $effect(() => { binding?.markMounted(); });
78
97
  // Snapshot store — sourced from `ctrl` so it works for both API halves (both are
79
98
  // a `SnapshotSource`); the bound path never touches the owned controller's lifecycle.
80
99
  const snapshotStore = { subscribe: (run: (s: TreeControllerSnapshot) => void) => { run(ctrl.getSnapshot()); return ctrl.subscribe(() => run(ctrl.getSnapshot())); } };
81
100
 
82
101
  let listEl: HTMLDivElement | null = $state(null);
83
102
 
103
+ // Scroll-Anker (bimetal-138): EINMAL je Anker-Objekt den absoluten
104
+ // Ziel-scrollTop setzen — `$effect` laeuft nach dem DOM-Update.
105
+ let angewandterAnker: TreeScrollAnchor | null = null;
106
+ $effect(() => {
107
+ const a = $snapshotStore.virtual?.anchor ?? null;
108
+ const el = listEl;
109
+ if (!a || !el || angewandterAnker === a) return;
110
+ angewandterAnker = a;
111
+ if (el.scrollTop !== a.scrollTop) el.scrollTop = a.scrollTop;
112
+ });
113
+
84
114
  // Virtualization: REPORT the viewport; the controller owns the window math
85
115
  // (mcp-60, list parity).
86
116
  $effect(() => {
@@ -16,7 +16,11 @@ type $$ComponentProps = {
16
16
  config?: TreeConfigInput;
17
17
  /** Apply the dark token set (`data-theme="dark"`). */
18
18
  darkMode?: boolean;
19
- /** Text/layout direction, applied as `dir` on the root (`ltr`/`rtl`). */
19
+ /** Text/layout direction, applied as `dir` on the root (`ltr`/`rtl`).
20
+ * Seit mcp-93 steuert sie zusaetzlich die TASTATUR: unter `rtl` sind die
21
+ * horizontalen Pfeiltasten getauscht, wie das ARIA-Tree-Pattern es verlangt.
22
+ * Sie speist `config.direction`; ein ausdruecklich gesetztes `config.direction`
23
+ * hat Vorrang. */
20
24
  dir?: 'ltr' | 'rtl';
21
25
  /** Optional toolbar heading. Omitted → no heading is rendered. */
22
26
  title?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.svelte.d.ts","sourceRoot":"","sources":["../src/Tree.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAA0B,WAAW,EAAG,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAO1I,KAAK,gBAAgB,GAAI;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACpB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;mFAC+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iFAAiF;IACjF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,oGAAoG;IACpG,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D;8EAC0E;IAC1E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1D,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACrD,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;CACrC,CAAC;AAmMJ,QAAA,MAAM,IAAI,sDAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Tree.svelte.d.ts","sourceRoot":"","sources":["../src/Tree.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAA0B,WAAW,EAAG,qBAAqB,EAAoB,MAAM,wBAAwB,CAAC;AAO5J,KAAK,gBAAgB,GAAI;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;uBAImB;IACnB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACpB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;mFAC+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iFAAiF;IACjF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,oGAAoG;IACpG,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D;8EAC0E;IAC1E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1D,YAAY,CAAC,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACrD,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;CACrC,CAAC;AA6NJ,QAAA,MAAM,IAAI,sDAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bimetal/tree-svelte-components",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "description": "Default Svelte 5 tree / treeview — multi-select, expand/collapse, tri-state checkboxes, drag-reorder, rename, undo, theming. A thin binding over the canonical tree controller.",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",
@@ -30,11 +30,11 @@
30
30
  "prepublishOnly": "npm run build"
31
31
  },
32
32
  "dependencies": {
33
- "@bimetal/svelte": "^0.36.0",
34
- "@bimetal/tree-data": "^0.36.0",
35
- "@bimetal/tree-headless": "^0.36.0",
36
- "@bimetal/tree-themes": "^0.36.0",
37
- "@bimetal/a11y-dom": "^0.36.0"
33
+ "@bimetal/svelte": "^0.37.0",
34
+ "@bimetal/tree-data": "^0.37.0",
35
+ "@bimetal/tree-headless": "^0.37.0",
36
+ "@bimetal/tree-themes": "^0.37.0",
37
+ "@bimetal/a11y-dom": "^0.37.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "svelte": "^5.46.4"
@@ -47,7 +47,9 @@
47
47
  "svelte": "^5.46.4",
48
48
  "svelte-check": "^4.0.0",
49
49
  "typescript": "~5.9.3",
50
- "vitest": "^3.2.4"
50
+ "@types/node": "^25.8.0",
51
+ "vitest": "^5.0.0",
52
+ "vite": "^8.0.1"
51
53
  },
52
54
  "sideEffects": [
53
55
  "**/*.css"