@gtkx/components 2.0.0-beta.12 → 2.0.0-beta.13
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/README.md +1 -1
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +7 -3
- package/dist/column-view.js.map +1 -1
- package/dist/combo-row.d.ts.map +1 -1
- package/dist/combo-row.js +3 -1
- package/dist/combo-row.js.map +1 -1
- package/dist/grid-view.d.ts.map +1 -1
- package/dist/grid-view.js +3 -2
- package/dist/grid-view.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/cells.d.ts +5 -2
- package/dist/internal/cells.d.ts.map +1 -1
- package/dist/internal/cells.js +86 -43
- package/dist/internal/cells.js.map +1 -1
- package/dist/internal/collection-index.d.ts +3 -5
- package/dist/internal/collection-index.d.ts.map +1 -1
- package/dist/internal/collection-index.js +3 -7
- package/dist/internal/collection-index.js.map +1 -1
- package/dist/internal/collection-model.d.ts +15 -4
- package/dist/internal/collection-model.d.ts.map +1 -1
- package/dist/internal/collection-model.js +154 -73
- package/dist/internal/collection-model.js.map +1 -1
- package/dist/internal/collection.d.ts +3 -3
- package/dist/internal/collection.d.ts.map +1 -1
- package/dist/internal/collection.js +11 -9
- package/dist/internal/collection.js.map +1 -1
- package/dist/internal/controlled-sync.d.ts +2 -1
- package/dist/internal/controlled-sync.d.ts.map +1 -1
- package/dist/internal/controlled-sync.js +6 -1
- package/dist/internal/controlled-sync.js.map +1 -1
- package/dist/internal/drop-down.d.ts +10 -4
- package/dist/internal/drop-down.d.ts.map +1 -1
- package/dist/internal/drop-down.js +60 -8
- package/dist/internal/drop-down.js.map +1 -1
- package/dist/internal/expansion.d.ts.map +1 -1
- package/dist/internal/expansion.js +46 -19
- package/dist/internal/expansion.js.map +1 -1
- package/dist/internal/first-header.d.ts +11 -0
- package/dist/internal/first-header.d.ts.map +1 -0
- package/dist/internal/first-header.js +21 -0
- package/dist/internal/first-header.js.map +1 -0
- package/dist/internal/level-splice.d.ts +27 -0
- package/dist/internal/level-splice.d.ts.map +1 -0
- package/dist/internal/level-splice.js +98 -0
- package/dist/internal/level-splice.js.map +1 -0
- package/dist/internal/selection.d.ts.map +1 -1
- package/dist/internal/selection.js +23 -16
- package/dist/internal/selection.js.map +1 -1
- package/dist/internal/tree-expansion.d.ts +3 -1
- package/dist/internal/tree-expansion.d.ts.map +1 -1
- package/dist/internal/tree-expansion.js +31 -2
- package/dist/internal/tree-expansion.js.map +1 -1
- package/dist/internal/tree-order.d.ts +1 -0
- package/dist/internal/tree-order.d.ts.map +1 -1
- package/dist/internal/tree-order.js +2 -1
- package/dist/internal/tree-order.js.map +1 -1
- package/dist/internal/use-collection.d.ts +1 -0
- package/dist/internal/use-collection.d.ts.map +1 -1
- package/dist/internal/use-collection.js +6 -2
- package/dist/internal/use-collection.js.map +1 -1
- package/dist/list-item-factory.d.ts +1 -1
- package/dist/list-item-factory.d.ts.map +1 -1
- package/dist/list-item-factory.js +2 -2
- package/dist/list-item-factory.js.map +1 -1
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +8 -3
- package/dist/list-view.js.map +1 -1
- package/dist/types.d.ts +37 -47
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +8 -8
- package/src/column-view.tsx +8 -4
- package/src/combo-row.tsx +4 -1
- package/src/grid-view.tsx +3 -2
- package/src/index.ts +0 -4
- package/src/internal/cells.tsx +141 -53
- package/src/internal/collection-index.ts +7 -14
- package/src/internal/collection-model.ts +211 -76
- package/src/internal/collection.ts +14 -13
- package/src/internal/controlled-sync.ts +8 -1
- package/src/internal/drop-down.tsx +111 -14
- package/src/internal/expansion.ts +52 -20
- package/src/internal/first-header.ts +23 -0
- package/src/internal/level-splice.ts +157 -0
- package/src/internal/selection.tsx +24 -19
- package/src/internal/tree-expansion.ts +52 -2
- package/src/internal/tree-order.ts +3 -1
- package/src/internal/use-collection.tsx +8 -2
- package/src/list-item-factory.tsx +2 -1
- package/src/list-view.tsx +10 -2
- package/src/types.ts +39 -51
- package/dist/tab-collection.d.ts +0 -9
- package/dist/tab-collection.d.ts.map +0 -1
- package/dist/tab-collection.js +0 -114
- package/dist/tab-collection.js.map +0 -1
- package/src/tab-collection.tsx +0 -124
|
@@ -3,7 +3,7 @@ import * as Gtk from "@gtkx/gi/gtk";
|
|
|
3
3
|
import { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from "@gtkx/jsx/gtk";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { isCollectionIdle } from "./collection.js";
|
|
6
|
-
import { useControlledSync } from "./controlled-sync.js";
|
|
6
|
+
import { hasSameIds, useControlledSync } from "./controlled-sync.js";
|
|
7
7
|
import { joinParts } from "./keys.js";
|
|
8
8
|
function contiguousPositions(bitset, size) {
|
|
9
9
|
const first = bitset.getMinimum();
|
|
@@ -34,9 +34,6 @@ function plannedSelection(context, ids) {
|
|
|
34
34
|
return null;
|
|
35
35
|
}
|
|
36
36
|
const rows = collection.rowsFor(ids);
|
|
37
|
-
if (ids.length > 0 && rows.positions.length === 0) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
37
|
if (selection instanceof Gtk.SingleSelection) {
|
|
41
38
|
return { positions: rows.positions.slice(0, 1), ids: rows.ids.slice(0, 1) };
|
|
42
39
|
}
|
|
@@ -80,14 +77,25 @@ function applySelection(selection, positions) {
|
|
|
80
77
|
}
|
|
81
78
|
return selected;
|
|
82
79
|
}
|
|
83
|
-
function
|
|
80
|
+
function rememberSelection(context, ids) {
|
|
84
81
|
const key = joinParts(ids);
|
|
85
|
-
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
82
|
+
const isKnown = context.last.selection === context.selection && context.last.key === key;
|
|
88
83
|
context.last.selection = context.selection;
|
|
89
84
|
context.last.key = key;
|
|
90
|
-
|
|
85
|
+
return isKnown;
|
|
86
|
+
}
|
|
87
|
+
function reportSelection(context, ids) {
|
|
88
|
+
if (!rememberSelection(context, ids)) {
|
|
89
|
+
context.onSelectionChanged?.(ids);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function settleSelection(context, ids, selectedIds) {
|
|
93
|
+
if (hasSameIds(ids, selectedIds)) {
|
|
94
|
+
rememberSelection(context, ids);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
reportSelection(context, ids);
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
100
|
function hasSelectionDrifted(actual, planned) {
|
|
93
101
|
return actual.length !== planned.length || planned.some((position, index) => actual[index] !== position);
|
|
@@ -117,12 +125,13 @@ function applyControlledSelection(context, selectedIds) {
|
|
|
117
125
|
if (selection === null) {
|
|
118
126
|
return;
|
|
119
127
|
}
|
|
120
|
-
const
|
|
128
|
+
const requested = selectedIds ?? [];
|
|
129
|
+
const planned = plannedSelection(context, requested);
|
|
121
130
|
if (planned !== null && didApplyPlanned(context, selection, planned.positions)) {
|
|
122
|
-
|
|
131
|
+
settleSelection(context, planned.ids, requested);
|
|
123
132
|
return;
|
|
124
133
|
}
|
|
125
|
-
|
|
134
|
+
settleSelection(context, collection.idsAt(selectedPositions(selection)), requested);
|
|
126
135
|
}
|
|
127
136
|
function reportDrift(context, selectedIds, positions, onDrift) {
|
|
128
137
|
const planned = plannedSelection(context, selectedIds ?? []);
|
|
@@ -132,14 +141,12 @@ function reportDrift(context, selectedIds, positions, onDrift) {
|
|
|
132
141
|
}
|
|
133
142
|
function observeSelection(context, selectedIds, onDrift) {
|
|
134
143
|
const { selection, collection, state } = context;
|
|
135
|
-
if (selection === null || state.isApplying) {
|
|
144
|
+
if (selection === null || state.isApplying || !isCollectionIdle(collection)) {
|
|
136
145
|
return;
|
|
137
146
|
}
|
|
138
147
|
const positions = selectedPositions(selection);
|
|
139
148
|
reportSelection(context, collection.idsAt(positions));
|
|
140
|
-
|
|
141
|
-
reportDrift(context, selectedIds, positions, onDrift);
|
|
142
|
-
}
|
|
149
|
+
reportDrift(context, selectedIds, positions, onDrift);
|
|
143
150
|
}
|
|
144
151
|
function newLastSelection() {
|
|
145
152
|
return { selection: null, key: null };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/internal/selection.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactElement } from \"react\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from \"@gtkx/jsx/gtk\";\nimport { useState } from \"react\";\nimport type { Collection } from \"./collection.js\";\nimport type { ItemsChangeHandler } from \"./expansion.js\";\nimport type { MatchedRows } from \"./tree-order.js\";\nimport { isCollectionIdle } from \"./collection.js\";\nimport { useControlledSync } from \"./controlled-sync.js\";\nimport { joinParts } from \"./keys.js\";\n\ntype SelectionOptions = {\n collection: Collection;\n model: ReactElement;\n selectedIds?: string[] | null | undefined;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n selectionMode?: Gtk.SelectionMode | null | undefined;\n onItemsChanged: ItemsChangeHandler;\n};\n\ntype LastSelection = {\n selection: Gtk.SelectionModel | null;\n key: string | null;\n};\n\ntype ApplyState = {\n isApplying: boolean;\n};\n\ntype SelectionContext = {\n selection: Gtk.SelectionModel | null;\n collection: Collection;\n last: LastSelection;\n state: ApplyState;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n};\n\ntype PositionRun = {\n start: number;\n length: number;\n};\n\ntype SelectionElementProps = {\n ref: (value: Gtk.SelectionModel | null) => void;\n model: ReactElement;\n onSelectionChanged: () => void;\n onItemsChanged: ItemsChangeHandler;\n};\n\nfunction contiguousPositions(bitset: Gtk.Bitset, size: number): number[] | null {\n const first = bitset.getMinimum();\n\n if (bitset.getMaximum() - first + 1 !== size) {\n return null;\n }\n\n return Array.from({ length: size }, (_, offset) => first + offset);\n}\n\nfunction selectedPositions(selection: Gtk.SelectionModel): number[] {\n const bitset = selection.getSelection();\n const size = Number(bitset.getSize());\n\n if (size === 0) {\n return [];\n }\n\n const contiguous = contiguousPositions(bitset, size);\n\n if (contiguous !== null) {\n return contiguous;\n }\n\n const positions: number[] = [];\n\n for (let index = 0; index < size; index++) {\n positions.push(bitset.getNth(index));\n }\n\n return positions;\n}\n\nfunction plannedSelection(context: SelectionContext, ids: string[]): MatchedRows | null {\n const { selection, collection } = context;\n\n if (selection === null || selection instanceof Gtk.NoSelection) {\n return null;\n }\n\n const rows = collection.rowsFor(ids);\n\n if (ids.length > 0 && rows.positions.length === 0) {\n return null;\n }\n\n if (selection instanceof Gtk.SingleSelection) {\n return { positions: rows.positions.slice(0, 1), ids: rows.ids.slice(0, 1) };\n }\n\n return rows;\n}\n\nfunction applySingleSelection(selection: Gtk.SingleSelection, positions: number[]): void {\n const [first] = positions;\n\n if (first === undefined) {\n selection.unselectAll();\n\n return;\n }\n\n selection.selectItem(first, true);\n}\n\nfunction positionRuns(positions: number[]): PositionRun[] {\n const runs: PositionRun[] = [];\n\n for (const position of positions) {\n const last = runs.at(-1);\n\n if (last !== undefined && last.start + last.length === position) {\n last.length += 1;\n } else {\n runs.push({ start: position, length: 1 });\n }\n }\n\n return runs;\n}\n\nfunction positionBitset(positions: number[]): Gtk.Bitset {\n const selected = Gtk.Bitset.newEmpty();\n\n for (const run of positionRuns(positions)) {\n selected.addRange(run.start, run.length);\n }\n\n return selected;\n}\n\nfunction applySelection(selection: Gtk.SelectionModel, positions: number[]): Gtk.Bitset {\n const selected = positionBitset(positions);\n\n if (selection instanceof Gtk.SingleSelection) {\n applySingleSelection(selection, positions);\n } else {\n selection.setSelection(selected, Gtk.Bitset.newRange(0, selection.getNItems()));\n }\n\n return selected;\n}\n\nfunction reportSelection(context: SelectionContext, ids: string[]): void {\n const key = joinParts(ids);\n\n if (context.last.selection === context.selection && context.last.key === key) {\n return;\n }\n\n context.last.selection = context.selection;\n context.last.key = key;\n context.onSelectionChanged?.(ids);\n}\n\nfunction hasSelectionDrifted(actual: number[], planned: number[]): boolean {\n return actual.length !== planned.length || planned.some((position, index) => actual[index] !== position);\n}\n\nfunction selectionElement(mode: Gtk.SelectionMode | null | undefined, props: SelectionElementProps): ReactElement {\n if (mode === Gtk.SelectionMode.MULTIPLE) {\n return <GtkMultiSelection {...props} />;\n }\n\n if (mode === Gtk.SelectionMode.NONE) {\n return <GtkNoSelection {...props} />;\n }\n\n return <GtkSingleSelection {...props} autoselect={false} canUnselect />;\n}\n\nfunction didApplyPlanned(context: SelectionContext, selection: Gtk.SelectionModel, positions: number[]): boolean {\n const { state } = context;\n state.isApplying = true;\n\n try {\n const selected = applySelection(selection, positions);\n\n return selection.getSelection().equals(selected);\n } finally {\n state.isApplying = false;\n }\n}\n\nfunction applyControlledSelection(context: SelectionContext, selectedIds: string[] | null | undefined): void {\n const { selection, collection } = context;\n\n if (selection === null) {\n return;\n }\n\n const planned = plannedSelection(context, selectedIds ?? []);\n\n if (planned !== null && didApplyPlanned(context, selection, planned.positions)) {\n reportSelection(context, planned.ids);\n\n return;\n }\n\n reportSelection(context, collection.idsAt(selectedPositions(selection)));\n}\n\nfunction reportDrift(\n context: SelectionContext,\n selectedIds: string[] | null | undefined,\n positions: number[],\n onDrift: () => void,\n): void {\n const planned = plannedSelection(context, selectedIds ?? []);\n\n if (planned !== null && hasSelectionDrifted(positions, planned.positions)) {\n onDrift();\n }\n}\n\nfunction observeSelection(\n context: SelectionContext,\n selectedIds: string[] | null | undefined,\n onDrift: () => void,\n): void {\n const { selection, collection, state } = context;\n\n if (selection === null || state.isApplying) {\n return;\n }\n\n const positions = selectedPositions(selection);\n reportSelection(context, collection.idsAt(positions));\n\n if (isCollectionIdle(collection)) {\n reportDrift(context, selectedIds, positions, onDrift);\n }\n}\n\nfunction newLastSelection(): LastSelection {\n return { selection: null, key: null };\n}\n\nfunction newApplyState(): ApplyState {\n return { isApplying: false };\n}\n\nfunction useSelection(options: SelectionOptions): ReactElement {\n const { collection, selectedIds, onSelectionChanged, selectionMode } = options;\n const [selection, setSelection] = useState<Gtk.SelectionModel | null>(null);\n const [last] = useState<LastSelection>(newLastSelection);\n const [state] = useState<ApplyState>(newApplyState);\n const context: SelectionContext = { selection, collection, last, state, onSelectionChanged };\n\n const markDrift = useControlledSync({\n value: selectedIds,\n source: collection,\n target: selection,\n apply: (value) => {\n applyControlledSelection(context, value);\n },\n });\n\n return selectionElement(selectionMode, {\n ref: setSelection,\n model: options.model,\n onSelectionChanged: () => {\n observeSelection(context, selectedIds, markDrift);\n },\n onItemsChanged: options.onItemsChanged,\n });\n}\n\nexport { useSelection };\n"]}
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/internal/selection.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAIjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAwCtC,SAAS,mBAAmB,CAAC,MAAkB,EAAE,IAAY;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAElC,IAAI,MAAM,CAAC,UAAU,EAAE,GAAG,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA6B;IACpD,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAEtC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAErD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAyB,EAAE,GAAa;IAC9D,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE1C,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,YAAY,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAErC,IAAI,SAAS,YAAY,GAAG,CAAC,eAAe,EAAE,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAChF,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,oBAAoB,CAAC,SAA8B,EAAE,SAAmB;IAC7E,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IAE1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,SAAS,CAAC,WAAW,EAAE,CAAC;QAExB,OAAO;IACX,CAAC;IAED,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,YAAY,CAAC,SAAmB;IACrC,MAAM,IAAI,GAAkB,EAAE,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC9D,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,SAAmB;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAEvC,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,cAAc,CAAC,SAA6B,EAAE,SAAmB;IACtE,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE3C,IAAI,SAAS,YAAY,GAAG,CAAC,eAAe,EAAE,CAAC;QAC3C,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACJ,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAyB,EAAE,GAAa;IAC/D,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC;IACzF,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAEvB,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,OAAyB,EAAE,GAAa;IAC7D,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,OAAyB,EAAE,GAAa,EAAE,WAAqB;IACpF,IAAI,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;QAC/B,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACJ,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAgB,EAAE,OAAiB;IAC5D,OAAO,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC;AAC7G,CAAC;AAED,SAAS,gBAAgB,CAAC,IAA0C,EAAE,KAA4B;IAC9F,IAAI,IAAI,KAAK,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,KAAC,iBAAiB,OAAK,KAAK,GAAI,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI,KAAK,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAClC,OAAO,KAAC,cAAc,OAAK,KAAK,GAAI,CAAC;IACzC,CAAC;IAED,OAAO,KAAC,kBAAkB,OAAK,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,SAAG,CAAC;AAC5E,CAAC;AAED,SAAS,eAAe,CAAC,OAAyB,EAAE,SAA6B,EAAE,SAAmB;IAClG,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAExB,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAEtD,OAAO,SAAS,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;YAAS,CAAC;QACP,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;IAC7B,CAAC;AACL,CAAC;AAED,SAAS,wBAAwB,CAAC,OAAyB,EAAE,WAAwC;IACjG,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE1C,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,IAAI,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAErD,IAAI,OAAO,KAAK,IAAI,IAAI,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7E,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAEjD,OAAO;IACX,CAAC;IAED,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,WAAW,CAChB,OAAyB,EACzB,WAAwC,EACxC,SAAmB,EACnB,OAAmB;IAEnB,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;IAE7D,IAAI,OAAO,KAAK,IAAI,IAAI,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACxE,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CACrB,OAAyB,EACzB,WAAwC,EACxC,OAAmB;IAEnB,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEjD,IAAI,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1E,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC/C,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,gBAAgB;IACrB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,aAAa;IAClB,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,YAAY,CAAC,OAAyB;IAC3C,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAC/E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAA4B,IAAI,CAAC,CAAC;IAC5E,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAgB,gBAAgB,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAa,aAAa,CAAC,CAAC;IACpD,MAAM,OAAO,GAAqB,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAE7F,MAAM,SAAS,GAAG,iBAAiB,CAAC;QAChC,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,UAAU;QAClB,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;YACb,wBAAwB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;KACJ,CAAC,CAAC;IAEH,OAAO,gBAAgB,CAAC,aAAa,EAAE;QACnC,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,kBAAkB,EAAE,GAAG,EAAE;YACrB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACtD,CAAC;QACD,cAAc,EAAE,OAAO,CAAC,cAAc;KACzC,CAAC,CAAC;AACP,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import type { ReactElement } from \"react\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from \"@gtkx/jsx/gtk\";\nimport { useState } from \"react\";\nimport type { Collection } from \"./collection.js\";\nimport type { ItemsChangeHandler } from \"./expansion.js\";\nimport type { MatchedRows } from \"./tree-order.js\";\nimport { isCollectionIdle } from \"./collection.js\";\nimport { hasSameIds, useControlledSync } from \"./controlled-sync.js\";\nimport { joinParts } from \"./keys.js\";\n\ntype SelectionOptions = {\n collection: Collection;\n model: ReactElement;\n selectedIds?: string[] | null | undefined;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n selectionMode?: Gtk.SelectionMode | null | undefined;\n onItemsChanged: ItemsChangeHandler;\n};\n\ntype LastSelection = {\n selection: Gtk.SelectionModel | null;\n key: string | null;\n};\n\ntype ApplyState = {\n isApplying: boolean;\n};\n\ntype SelectionContext = {\n selection: Gtk.SelectionModel | null;\n collection: Collection;\n last: LastSelection;\n state: ApplyState;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n};\n\ntype PositionRun = {\n start: number;\n length: number;\n};\n\ntype SelectionElementProps = {\n ref: (value: Gtk.SelectionModel | null) => void;\n model: ReactElement;\n onSelectionChanged: () => void;\n onItemsChanged: ItemsChangeHandler;\n};\n\nfunction contiguousPositions(bitset: Gtk.Bitset, size: number): number[] | null {\n const first = bitset.getMinimum();\n\n if (bitset.getMaximum() - first + 1 !== size) {\n return null;\n }\n\n return Array.from({ length: size }, (_, offset) => first + offset);\n}\n\nfunction selectedPositions(selection: Gtk.SelectionModel): number[] {\n const bitset = selection.getSelection();\n const size = Number(bitset.getSize());\n\n if (size === 0) {\n return [];\n }\n\n const contiguous = contiguousPositions(bitset, size);\n\n if (contiguous !== null) {\n return contiguous;\n }\n\n const positions: number[] = [];\n\n for (let index = 0; index < size; index++) {\n positions.push(bitset.getNth(index));\n }\n\n return positions;\n}\n\nfunction plannedSelection(context: SelectionContext, ids: string[]): MatchedRows | null {\n const { selection, collection } = context;\n\n if (selection === null || selection instanceof Gtk.NoSelection) {\n return null;\n }\n\n const rows = collection.rowsFor(ids);\n\n if (selection instanceof Gtk.SingleSelection) {\n return { positions: rows.positions.slice(0, 1), ids: rows.ids.slice(0, 1) };\n }\n\n return rows;\n}\n\nfunction applySingleSelection(selection: Gtk.SingleSelection, positions: number[]): void {\n const [first] = positions;\n\n if (first === undefined) {\n selection.unselectAll();\n\n return;\n }\n\n selection.selectItem(first, true);\n}\n\nfunction positionRuns(positions: number[]): PositionRun[] {\n const runs: PositionRun[] = [];\n\n for (const position of positions) {\n const last = runs.at(-1);\n\n if (last !== undefined && last.start + last.length === position) {\n last.length += 1;\n } else {\n runs.push({ start: position, length: 1 });\n }\n }\n\n return runs;\n}\n\nfunction positionBitset(positions: number[]): Gtk.Bitset {\n const selected = Gtk.Bitset.newEmpty();\n\n for (const run of positionRuns(positions)) {\n selected.addRange(run.start, run.length);\n }\n\n return selected;\n}\n\nfunction applySelection(selection: Gtk.SelectionModel, positions: number[]): Gtk.Bitset {\n const selected = positionBitset(positions);\n\n if (selection instanceof Gtk.SingleSelection) {\n applySingleSelection(selection, positions);\n } else {\n selection.setSelection(selected, Gtk.Bitset.newRange(0, selection.getNItems()));\n }\n\n return selected;\n}\n\nfunction rememberSelection(context: SelectionContext, ids: string[]): boolean {\n const key = joinParts(ids);\n const isKnown = context.last.selection === context.selection && context.last.key === key;\n context.last.selection = context.selection;\n context.last.key = key;\n\n return isKnown;\n}\n\nfunction reportSelection(context: SelectionContext, ids: string[]): void {\n if (!rememberSelection(context, ids)) {\n context.onSelectionChanged?.(ids);\n }\n}\n\nfunction settleSelection(context: SelectionContext, ids: string[], selectedIds: string[]): void {\n if (hasSameIds(ids, selectedIds)) {\n rememberSelection(context, ids);\n } else {\n reportSelection(context, ids);\n }\n}\n\nfunction hasSelectionDrifted(actual: number[], planned: number[]): boolean {\n return actual.length !== planned.length || planned.some((position, index) => actual[index] !== position);\n}\n\nfunction selectionElement(mode: Gtk.SelectionMode | null | undefined, props: SelectionElementProps): ReactElement {\n if (mode === Gtk.SelectionMode.MULTIPLE) {\n return <GtkMultiSelection {...props} />;\n }\n\n if (mode === Gtk.SelectionMode.NONE) {\n return <GtkNoSelection {...props} />;\n }\n\n return <GtkSingleSelection {...props} autoselect={false} canUnselect />;\n}\n\nfunction didApplyPlanned(context: SelectionContext, selection: Gtk.SelectionModel, positions: number[]): boolean {\n const { state } = context;\n state.isApplying = true;\n\n try {\n const selected = applySelection(selection, positions);\n\n return selection.getSelection().equals(selected);\n } finally {\n state.isApplying = false;\n }\n}\n\nfunction applyControlledSelection(context: SelectionContext, selectedIds: string[] | null | undefined): void {\n const { selection, collection } = context;\n\n if (selection === null) {\n return;\n }\n\n const requested = selectedIds ?? [];\n const planned = plannedSelection(context, requested);\n\n if (planned !== null && didApplyPlanned(context, selection, planned.positions)) {\n settleSelection(context, planned.ids, requested);\n\n return;\n }\n\n settleSelection(context, collection.idsAt(selectedPositions(selection)), requested);\n}\n\nfunction reportDrift(\n context: SelectionContext,\n selectedIds: string[] | null | undefined,\n positions: number[],\n onDrift: () => void,\n): void {\n const planned = plannedSelection(context, selectedIds ?? []);\n\n if (planned !== null && hasSelectionDrifted(positions, planned.positions)) {\n onDrift();\n }\n}\n\nfunction observeSelection(\n context: SelectionContext,\n selectedIds: string[] | null | undefined,\n onDrift: () => void,\n): void {\n const { selection, collection, state } = context;\n\n if (selection === null || state.isApplying || !isCollectionIdle(collection)) {\n return;\n }\n\n const positions = selectedPositions(selection);\n reportSelection(context, collection.idsAt(positions));\n reportDrift(context, selectedIds, positions, onDrift);\n}\n\nfunction newLastSelection(): LastSelection {\n return { selection: null, key: null };\n}\n\nfunction newApplyState(): ApplyState {\n return { isApplying: false };\n}\n\nfunction useSelection(options: SelectionOptions): ReactElement {\n const { collection, selectedIds, onSelectionChanged, selectionMode } = options;\n const [selection, setSelection] = useState<Gtk.SelectionModel | null>(null);\n const [last] = useState<LastSelection>(newLastSelection);\n const [state] = useState<ApplyState>(newApplyState);\n const context: SelectionContext = { selection, collection, last, state, onSelectionChanged };\n\n const markDrift = useControlledSync({\n value: selectedIds,\n source: collection,\n target: selection,\n apply: (value) => {\n applyControlledSelection(context, value);\n },\n });\n\n return selectionElement(selectionMode, {\n ref: setSelection,\n model: options.model,\n onSelectionChanged: () => {\n observeSelection(context, selectedIds, markDrift);\n },\n onItemsChanged: options.onItemsChanged,\n });\n}\n\nexport { useSelection };\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CollectionIndex } from "./collection-index.js";
|
|
2
2
|
import type { SlotMap } from "./slots.js";
|
|
3
3
|
import type { VisibleOrder } from "./tree-order.js";
|
|
4
|
+
import type { Relocate } from "./level-splice.js";
|
|
4
5
|
type TreeExpansion = {
|
|
5
6
|
index: CollectionIndex;
|
|
6
7
|
expanded: Set<string>;
|
|
@@ -13,7 +14,8 @@ declare function createTreeExpansion(index: CollectionIndex): TreeExpansion;
|
|
|
13
14
|
declare function orderFor(expansion: TreeExpansion): VisibleOrder;
|
|
14
15
|
declare function adoptOrder(expansion: TreeExpansion, order: VisibleOrder): void;
|
|
15
16
|
declare function pruneSlots(expansion: TreeExpansion, levelPath: string, isPruned: (slot: number) => boolean): void;
|
|
17
|
+
declare function relocateSlots(expansion: TreeExpansion, levelPath: string, relocate: Relocate): void;
|
|
16
18
|
declare function markExpanded(expansion: TreeExpansion, path: string, isExpanded: boolean): void;
|
|
17
19
|
declare function adoptIndex(expansion: TreeExpansion, index: CollectionIndex): void;
|
|
18
|
-
export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots, type TreeExpansion };
|
|
20
|
+
export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots, relocateSlots, type TreeExpansion, };
|
|
19
21
|
//# sourceMappingURL=tree-expansion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-expansion.d.ts","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"tree-expansion.d.ts","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKlD,KAAK,aAAa,GAAG;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAiBF,iBAAS,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,CAElE;AAED,iBAAS,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,YAAY,CAIxD;AAED,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAIvE;AAaD,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAiB1G;AAsBD,iBAAS,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAkB5F;AAED,iBAAS,YAAY,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAUvF;AAED,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAG1E;AAED,OAAO,EACH,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,aAAa,EACb,KAAK,aAAa,GACrB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { encodePart } from "./keys.js";
|
|
1
|
+
import { decodePartAt, encodePart } from "./keys.js";
|
|
2
2
|
import { getSlotKey, trackPath, trackPaths } from "./slots.js";
|
|
3
3
|
import { walkVisible } from "./tree-order.js";
|
|
4
4
|
function dropSubtree(expansion, path) {
|
|
@@ -46,6 +46,35 @@ function pruneSlots(expansion, levelPath, isPruned) {
|
|
|
46
46
|
}
|
|
47
47
|
expansion.order = null;
|
|
48
48
|
}
|
|
49
|
+
function relocatePath(path, levelPath, relocate) {
|
|
50
|
+
if (path.length === levelPath.length || !path.startsWith(levelPath)) {
|
|
51
|
+
return path;
|
|
52
|
+
}
|
|
53
|
+
const part = decodePartAt(path, levelPath.length);
|
|
54
|
+
if (part === null) {
|
|
55
|
+
return path;
|
|
56
|
+
}
|
|
57
|
+
const slot = relocate(Number(part));
|
|
58
|
+
if (slot === undefined) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return levelPath + encodePart(String(slot)) + path.slice(levelPath.length + encodePart(part).length);
|
|
62
|
+
}
|
|
63
|
+
function relocateSlots(expansion, levelPath, relocate) {
|
|
64
|
+
if (expansion.expanded.size === 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const expanded = new Set();
|
|
68
|
+
for (const path of expansion.expanded) {
|
|
69
|
+
const relocated = relocatePath(path, levelPath, relocate);
|
|
70
|
+
if (relocated !== null) {
|
|
71
|
+
expanded.add(relocated);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
expansion.expanded = expanded;
|
|
75
|
+
expansion.slots = trackPaths(expanded);
|
|
76
|
+
expansion.order = null;
|
|
77
|
+
}
|
|
49
78
|
function markExpanded(expansion, path, isExpanded) {
|
|
50
79
|
if (isExpanded) {
|
|
51
80
|
expansion.expanded.add(path);
|
|
@@ -59,5 +88,5 @@ function adoptIndex(expansion, index) {
|
|
|
59
88
|
expansion.index = index;
|
|
60
89
|
expansion.order = null;
|
|
61
90
|
}
|
|
62
|
-
export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots };
|
|
91
|
+
export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots, relocateSlots, };
|
|
63
92
|
//# sourceMappingURL=tree-expansion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-expansion.js","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tree-expansion.js","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CollectionIndex } from \"./collection-index.js\";\nimport type { SlotMap } from \"./slots.js\";\nimport type { VisibleOrder } from \"./tree-order.js\";\nimport type { Relocate } from \"./level-splice.js\";\nimport { decodePartAt, encodePart } from \"./keys.js\";\nimport { getSlotKey, trackPath, trackPaths } from \"./slots.js\";\nimport { walkVisible } from \"./tree-order.js\";\n\ntype TreeExpansion = {\n index: CollectionIndex;\n expanded: Set<string>;\n slots: SlotMap;\n order: VisibleOrder | null;\n isApplying: boolean;\n isSyncing: boolean;\n};\n\nfunction dropSubtree(expansion: TreeExpansion, path: string): void {\n expansion.expanded.delete(path);\n const level = expansion.slots.get(path);\n\n if (level === undefined) {\n return;\n }\n\n expansion.slots.delete(path);\n\n for (const slot of level) {\n dropSubtree(expansion, path + encodePart(String(slot)));\n }\n}\n\nfunction createTreeExpansion(index: CollectionIndex): TreeExpansion {\n return { index, expanded: new Set(), slots: new Map(), order: null, isApplying: false, isSyncing: false };\n}\n\nfunction orderFor(expansion: TreeExpansion): VisibleOrder {\n expansion.order ??= walkVisible({ index: expansion.index, slots: expansion.slots });\n\n return expansion.order;\n}\n\nfunction adoptOrder(expansion: TreeExpansion, order: VisibleOrder): void {\n expansion.expanded = new Set(order.expandedPaths);\n expansion.slots = trackPaths(order.expandedPaths);\n expansion.order = order;\n}\n\nfunction prunePath(expansion: TreeExpansion, path: string): void {\n const key = getSlotKey(path);\n\n if (key !== null) {\n expansion.slots.get(key.levelPath)?.delete(key.slot);\n }\n\n dropSubtree(expansion, path);\n expansion.order = null;\n}\n\nfunction pruneSlots(expansion: TreeExpansion, levelPath: string, isPruned: (slot: number) => boolean): void {\n const level = expansion.slots.get(levelPath);\n\n if (level === undefined) {\n return;\n }\n\n for (const slot of level) {\n if (!isPruned(slot)) {\n continue;\n }\n\n level.delete(slot);\n dropSubtree(expansion, levelPath + encodePart(String(slot)));\n }\n\n expansion.order = null;\n}\n\nfunction relocatePath(path: string, levelPath: string, relocate: Relocate): string | null {\n if (path.length === levelPath.length || !path.startsWith(levelPath)) {\n return path;\n }\n\n const part = decodePartAt(path, levelPath.length);\n\n if (part === null) {\n return path;\n }\n\n const slot = relocate(Number(part));\n\n if (slot === undefined) {\n return null;\n }\n\n return levelPath + encodePart(String(slot)) + path.slice(levelPath.length + encodePart(part).length);\n}\n\nfunction relocateSlots(expansion: TreeExpansion, levelPath: string, relocate: Relocate): void {\n if (expansion.expanded.size === 0) {\n return;\n }\n\n const expanded: Set<string> = new Set();\n\n for (const path of expansion.expanded) {\n const relocated = relocatePath(path, levelPath, relocate);\n\n if (relocated !== null) {\n expanded.add(relocated);\n }\n }\n\n expansion.expanded = expanded;\n expansion.slots = trackPaths(expanded);\n expansion.order = null;\n}\n\nfunction markExpanded(expansion: TreeExpansion, path: string, isExpanded: boolean): void {\n if (isExpanded) {\n expansion.expanded.add(path);\n trackPath(expansion.slots, path);\n expansion.order = null;\n\n return;\n }\n\n prunePath(expansion, path);\n}\n\nfunction adoptIndex(expansion: TreeExpansion, index: CollectionIndex): void {\n expansion.index = index;\n expansion.order = null;\n}\n\nexport {\n adoptIndex,\n adoptOrder,\n createTreeExpansion,\n markExpanded,\n orderFor,\n pruneSlots,\n relocateSlots,\n type TreeExpansion,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-order.d.ts","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAS,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,KAAK,UAAU,GAAG;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tree-order.d.ts","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAS,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,KAAK,UAAU,GAAG;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,KAAK,WAAW,GAAG;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;AAE5C,KAAK,WAAW,GAAG;IACf,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAClC,CAAC;AA+BF,iBAAS,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CAQvD;AAiBD,iBAAS,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAY/E;AAED,iBAAS,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,CAkBvF;AAED,iBAAS,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAgBzF;AAED,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,CAAC"}
|
|
@@ -3,6 +3,7 @@ function walkLevel(options, level, state) {
|
|
|
3
3
|
const marked = options.marks?.get(level.path);
|
|
4
4
|
for (const [slot, item] of level.items.entries()) {
|
|
5
5
|
const isOpen = open?.has(slot) ?? false;
|
|
6
|
+
state.order.positions.set(item.id, state.position);
|
|
6
7
|
options.visit?.({ item, position: state.position, isOpen, isMarked: marked?.has(slot) ?? false });
|
|
7
8
|
state.position += 1;
|
|
8
9
|
if (!isOpen) {
|
|
@@ -17,7 +18,7 @@ function walkLevel(options, level, state) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
function walkVisible(options) {
|
|
20
|
-
const state = { position: 0, order: { expandedPaths: [], expandedIds: [] } };
|
|
21
|
+
const state = { position: 0, order: { expandedPaths: [], expandedIds: [], positions: new Map() } };
|
|
21
22
|
for (const level of options.index.groups) {
|
|
22
23
|
walkLevel(options, level, state);
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-order.js","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tree-order.js","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem } from \"../types.js\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport type { SlotMap } from \"./slots.js\";\n\ntype VisibleRow = {\n item: ListItem;\n position: number;\n isOpen: boolean;\n isMarked: boolean;\n};\n\ntype VisibleOrder = {\n expandedPaths: string[];\n expandedIds: string[];\n positions: Map<string, number>;\n};\n\ntype MatchedRows = {\n positions: number[];\n ids: string[];\n};\n\ntype RowVisitor = (row: VisibleRow) => void;\n\ntype WalkOptions = {\n index: CollectionIndex;\n slots: SlotMap;\n marks?: SlotMap | undefined;\n visit?: RowVisitor | undefined;\n};\n\ntype WalkState = {\n position: number;\n order: VisibleOrder;\n};\n\nfunction walkLevel(options: WalkOptions, level: Level, state: WalkState): void {\n const open = options.slots.get(level.path);\n const marked = options.marks?.get(level.path);\n\n for (const [slot, item] of level.items.entries()) {\n const isOpen = open?.has(slot) ?? false;\n state.order.positions.set(item.id, state.position);\n options.visit?.({ item, position: state.position, isOpen, isMarked: marked?.has(slot) ?? false });\n state.position += 1;\n\n if (!isOpen) {\n continue;\n }\n\n const child = options.index.childLevel(level, slot);\n\n if (child !== undefined) {\n state.order.expandedPaths.push(child.path);\n state.order.expandedIds.push(item.id);\n walkLevel(options, child, state);\n }\n }\n}\n\nfunction walkVisible(options: WalkOptions): VisibleOrder {\n const state: WalkState = { position: 0, order: { expandedPaths: [], expandedIds: [], positions: new Map() } };\n\n for (const level of options.index.groups) {\n walkLevel(options, level, state);\n }\n\n return state.order;\n}\n\nfunction expandLevel(index: CollectionIndex, level: Level, ids: Set<string>, paths: Set<string>): void {\n for (const [slot, item] of level.items.entries()) {\n if (!ids.has(item.id)) {\n continue;\n }\n\n const child = index.childLevel(level, slot);\n\n if (child !== undefined) {\n paths.add(child.path);\n expandLevel(index, child, ids, paths);\n }\n }\n}\n\nfunction expandedPathsFor(index: CollectionIndex, ids: Set<string>): Set<string> {\n const paths: Set<string> = new Set();\n\n if (ids.size === 0 || !index.isTree) {\n return paths;\n }\n\n for (const level of index.groups) {\n expandLevel(index, level, ids, paths);\n }\n\n return paths;\n}\n\nfunction findRows(index: CollectionIndex, slots: SlotMap, ids: Set<string>): MatchedRows {\n const positions: number[] = [];\n const found: string[] = [];\n\n walkVisible({\n index,\n slots,\n visit: (row) => {\n if (!ids.has(row.item.id)) {\n return;\n }\n\n positions.push(row.position);\n found.push(row.item.id);\n },\n });\n\n return { positions, ids: found };\n}\n\nfunction findIds(index: CollectionIndex, slots: SlotMap, positions: Set<number>): string[] {\n const found: string[] = [];\n\n walkVisible({\n index,\n slots,\n visit: (row) => {\n if (!positions.has(row.position)) {\n return;\n }\n\n found.push(row.item.id);\n },\n });\n\n return found;\n}\n\nexport { expandedPathsFor, findIds, findRows, walkVisible, type MatchedRows, type VisibleOrder, type WalkOptions };\n"]}
|
|
@@ -5,6 +5,7 @@ type CollectionDataOptions = {
|
|
|
5
5
|
items?: ListItem[] | undefined;
|
|
6
6
|
sections?: ListSection[] | undefined;
|
|
7
7
|
isFlat?: boolean | undefined;
|
|
8
|
+
onSectionsFilled?: (() => void) | undefined;
|
|
8
9
|
};
|
|
9
10
|
type CollectionOptions = CollectionDataOptions & SelectionProps & ExpansionProps;
|
|
10
11
|
type CollectionResult = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-collection.d.ts","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-collection.d.ts","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,KAAK,qBAAqB,GAAG;IACzB,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,gBAAgB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,cAAc,GAAG,cAAc,CAAC;AAEjF,KAAK,gBAAgB,GAAG;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,iBAAS,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CA4B/E;AAED,iBAAS,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAmBnE;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { GtkFlattenListModel } from "@gtkx/jsx/gtk";
|
|
3
|
+
import { useLatestRef } from "@gtkx/react/internal";
|
|
3
4
|
import { useLayoutEffect, useMemo, useState } from "react";
|
|
4
5
|
import { createCollectionIndex } from "./collection-index.js";
|
|
5
6
|
import { CollectionRoot, createCollectionModel } from "./collection-model.js";
|
|
@@ -19,9 +20,12 @@ function useCollectionData(options) {
|
|
|
19
20
|
}
|
|
20
21
|
return gtkModel.clear;
|
|
21
22
|
}, [gtkModel, root, model]);
|
|
23
|
+
const onSectionsFilled = useLatestRef(options.onSectionsFilled);
|
|
22
24
|
useLayoutEffect(() => {
|
|
23
|
-
gtkModel.sync(index)
|
|
24
|
-
|
|
25
|
+
gtkModel.sync(index, () => {
|
|
26
|
+
onSectionsFilled.current?.();
|
|
27
|
+
});
|
|
28
|
+
}, [gtkModel, index, root, model, onSectionsFilled]);
|
|
25
29
|
return {
|
|
26
30
|
collection,
|
|
27
31
|
model: _jsx(GtkFlattenListModel, { ref: setModel, model: _jsx(CollectionRoot, { ref: setRoot }) }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-collection.js","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAA4B,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-collection.js","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"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","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ReactElement } from \"react\";\nimport { GtkFlattenListModel } from \"@gtkx/jsx/gtk\";\nimport { useLatestRef } from \"@gtkx/react/internal\";\nimport { useLayoutEffect, useMemo, useState } from \"react\";\nimport type { ExpansionProps, ListItem, ListSection, SelectionProps } from \"../types.js\";\nimport type { Collection } from \"./collection.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport { CollectionRoot, type CollectionRootStore, createCollectionModel } from \"./collection-model.js\";\nimport { createCollection } from \"./collection.js\";\nimport { useExpansion } from \"./expansion.js\";\nimport { useSelection } from \"./selection.js\";\n\ntype CollectionDataOptions = {\n items?: ListItem[] | undefined;\n sections?: ListSection[] | undefined;\n isFlat?: boolean | undefined;\n onSectionsFilled?: (() => void) | undefined;\n};\n\ntype CollectionOptions = CollectionDataOptions & SelectionProps & ExpansionProps;\n\ntype CollectionResult = {\n collection: Collection;\n selection: ReactElement;\n};\n\ntype CollectionDataResult = {\n collection: Collection;\n model: ReactElement;\n};\n\nfunction useCollectionData(options: CollectionDataOptions): CollectionDataResult {\n const { items, sections, isFlat } = options;\n const [gtkModel] = useState(createCollectionModel);\n const [root, setRoot] = useState<CollectionRootStore | null>(null);\n const [model, setModel] = useState<Gtk.FlattenListModel | null>(null);\n const index = useMemo(() => createCollectionIndex(items, sections, isFlat === true), [items, sections, isFlat]);\n const collection = useMemo(() => createCollection(gtkModel, index, model), [gtkModel, index, model]);\n\n useLayoutEffect(() => {\n if (root !== null && model !== null) {\n gtkModel.bind(root, model);\n }\n\n return gtkModel.clear;\n }, [gtkModel, root, model]);\n\n const onSectionsFilled = useLatestRef(options.onSectionsFilled);\n\n useLayoutEffect(() => {\n gtkModel.sync(index, () => {\n onSectionsFilled.current?.();\n });\n }, [gtkModel, index, root, model, onSectionsFilled]);\n\n return {\n collection,\n model: <GtkFlattenListModel ref={setModel} model={<CollectionRoot ref={setRoot} />} />,\n };\n}\n\nfunction useCollection(options: CollectionOptions): CollectionResult {\n const { collection, model } = useCollectionData(options);\n\n const onItemsChanged = useExpansion({\n collection,\n expandedIds: options.expandedIds,\n onExpandedChange: options.onExpandedChange,\n });\n\n const selection = useSelection({\n collection,\n model,\n selectedIds: options.selectedIds,\n onSelectionChanged: options.onSelectionChanged,\n selectionMode: options.selectionMode,\n onItemsChanged,\n });\n\n return { collection, selection };\n}\n\nexport { useCollection, useCollectionData };\n"]}
|
|
@@ -5,6 +5,6 @@ import type { ListItemFactoryProps } from "./types.js";
|
|
|
5
5
|
* Creates a Gtk.SignalListItemFactory that renders objects from an existing native model with React.
|
|
6
6
|
* Estimated dimensions keep cells stable until their content mounts.
|
|
7
7
|
*/
|
|
8
|
-
declare function ListItemFactory<T extends GObject.Object>({ renderItem, estimatedItemHeight, estimatedItemWidth, }: ListItemFactoryProps<T>): ReactNode;
|
|
8
|
+
declare function ListItemFactory<T extends GObject.Object>({ renderItem, rowProps, estimatedItemHeight, estimatedItemWidth, }: ListItemFactoryProps<T>): ReactNode;
|
|
9
9
|
export { ListItemFactory };
|
|
10
10
|
//# sourceMappingURL=list-item-factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-item-factory.d.ts","sourceRoot":"","sources":["../src/list-item-factory.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGvD;;;GAGG;AACH,iBAAS,eAAe,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE,EAC/C,UAAU,EACV,mBAAwB,EACxB,kBAAuB,GAC1B,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAAS,CAUrC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"list-item-factory.d.ts","sourceRoot":"","sources":["../src/list-item-factory.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGvD;;;GAGG;AACH,iBAAS,eAAe,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE,EAC/C,UAAU,EACV,QAAQ,EACR,mBAAwB,EACxB,kBAAuB,GAC1B,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAAS,CAUrC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -5,10 +5,10 @@ import { NativeItemPortals, useItemCells } from "./internal/cells.js";
|
|
|
5
5
|
* Creates a Gtk.SignalListItemFactory that renders objects from an existing native model with React.
|
|
6
6
|
* Estimated dimensions keep cells stable until their content mounts.
|
|
7
7
|
*/
|
|
8
|
-
function ListItemFactory({ renderItem, estimatedItemHeight = -1, estimatedItemWidth = -1, }) {
|
|
8
|
+
function ListItemFactory({ renderItem, rowProps, estimatedItemHeight = -1, estimatedItemWidth = -1, }) {
|
|
9
9
|
const size = { width: estimatedItemWidth, height: estimatedItemHeight };
|
|
10
10
|
const cells = useItemCells(size);
|
|
11
|
-
return (_jsxs(_Fragment, { children: [_jsx(GtkSignalListItemFactory, { ...cells.handlers }), _jsx(NativeItemPortals, { registry: cells, render: renderItem, size: size })] }));
|
|
11
|
+
return (_jsxs(_Fragment, { children: [_jsx(GtkSignalListItemFactory, { ...cells.handlers }), _jsx(NativeItemPortals, { registry: cells, render: renderItem, rowProps: rowProps, size: size })] }));
|
|
12
12
|
}
|
|
13
13
|
export { ListItemFactory };
|
|
14
14
|
//# sourceMappingURL=list-item-factory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-item-factory.js","sourceRoot":"","sources":["../src/list-item-factory.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEtE;;;GAGG;AACH,SAAS,eAAe,CAA2B,EAC/C,UAAU,EACV,mBAAmB,GAAG,CAAC,CAAC,EACxB,kBAAkB,GAAG,CAAC,CAAC,GACD;IACtB,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEjC,OAAO,CACH,8BACI,KAAC,wBAAwB,OAAK,KAAK,CAAC,QAAQ,GAAI,EAChD,KAAC,iBAAiB,IAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAI,
|
|
1
|
+
{"version":3,"file":"list-item-factory.js","sourceRoot":"","sources":["../src/list-item-factory.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEtE;;;GAGG;AACH,SAAS,eAAe,CAA2B,EAC/C,UAAU,EACV,QAAQ,EACR,mBAAmB,GAAG,CAAC,CAAC,EACxB,kBAAkB,GAAG,CAAC,CAAC,GACD;IACtB,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEjC,OAAO,CACH,8BACI,KAAC,wBAAwB,OAAK,KAAK,CAAC,QAAQ,GAAI,EAChD,KAAC,iBAAiB,IAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAI,IAC3F,CACN,CAAC;AACN,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import type * as GObject from \"@gtkx/gi/gobject\";\nimport type { ReactNode } from \"react\";\nimport { GtkSignalListItemFactory } from \"@gtkx/jsx/gtk\";\nimport type { ListItemFactoryProps } from \"./types.js\";\nimport { NativeItemPortals, useItemCells } from \"./internal/cells.js\";\n\n/**\n * Creates a Gtk.SignalListItemFactory that renders objects from an existing native model with React.\n * Estimated dimensions keep cells stable until their content mounts.\n */\nfunction ListItemFactory<T extends GObject.Object>({\n renderItem,\n rowProps,\n estimatedItemHeight = -1,\n estimatedItemWidth = -1,\n}: ListItemFactoryProps<T>): ReactNode {\n const size = { width: estimatedItemWidth, height: estimatedItemHeight };\n const cells = useItemCells(size);\n\n return (\n <>\n <GtkSignalListItemFactory {...cells.handlers} />\n <NativeItemPortals registry={cells} render={renderItem} rowProps={rowProps} size={size} />\n </>\n );\n}\n\nexport { ListItemFactory };\n"]}
|
package/dist/list-view.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-view.d.ts","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list-view.d.ts","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAwBhD;;;GAGG;AACH,iBAAS,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CA8BjF;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/list-view.js
CHANGED
|
@@ -2,13 +2,16 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { GtkListView, GtkSignalListItemFactory } from "@gtkx/jsx/gtk";
|
|
3
3
|
import { omit } from "@gtkx/utils";
|
|
4
4
|
import { ItemPortals, useItemCells, useSectionHeader } from "./internal/cells.js";
|
|
5
|
+
import { showFirstHeader } from "./internal/first-header.js";
|
|
5
6
|
import { useCollection } from "./internal/use-collection.js";
|
|
7
|
+
import { useWidgetRef } from "./internal/use-widget-ref.js";
|
|
6
8
|
const LIST_VIEW_PROPS = [
|
|
7
9
|
"items",
|
|
8
10
|
"sections",
|
|
9
11
|
"isFlat",
|
|
10
12
|
"renderItem",
|
|
11
13
|
"renderHeader",
|
|
14
|
+
"rowProps",
|
|
12
15
|
"selectedIds",
|
|
13
16
|
"onSelectionChanged",
|
|
14
17
|
"selectionMode",
|
|
@@ -17,20 +20,22 @@ const LIST_VIEW_PROPS = [
|
|
|
17
20
|
"expanderDescriptions",
|
|
18
21
|
"estimatedItemHeight",
|
|
19
22
|
"estimatedItemWidth",
|
|
23
|
+
"ref",
|
|
20
24
|
];
|
|
21
25
|
/**
|
|
22
26
|
* Renders a Gtk.ListView from declarative items or sections, with per-row rendering,
|
|
23
27
|
* controlled selection, controlled tree expansion, and estimated item sizing.
|
|
24
28
|
*/
|
|
25
29
|
function ListView(props) {
|
|
26
|
-
const { renderItem, renderHeader, expandedIds, expanderDescriptions } = props;
|
|
30
|
+
const { renderItem, renderHeader, rowProps, expandedIds, expanderDescriptions, ref } = props;
|
|
27
31
|
const { estimatedItemHeight, estimatedItemWidth } = props;
|
|
28
32
|
const rest = omit(props, LIST_VIEW_PROPS);
|
|
29
33
|
const size = { width: estimatedItemWidth ?? -1, height: estimatedItemHeight ?? -1 };
|
|
30
|
-
const
|
|
34
|
+
const [view, refCallback] = useWidgetRef(ref);
|
|
35
|
+
const { collection, selection } = useCollection({ ...props, onSectionsFilled: () => showFirstHeader(view) });
|
|
31
36
|
const itemCells = useItemCells(size);
|
|
32
37
|
const header = useSectionHeader(renderHeader, collection, size);
|
|
33
|
-
return (_jsxs(_Fragment, { children: [_jsx(GtkListView, { model: selection, factory: _jsx(GtkSignalListItemFactory, { ...itemCells.handlers }), ...header.factoryProps, ...rest }), _jsx(ItemPortals, { registry: itemCells, render: renderItem, collection: collection, expandedIds: expandedIds, expanderDescriptions: expanderDescriptions }), header.portals] }));
|
|
38
|
+
return (_jsxs(_Fragment, { children: [_jsx(GtkListView, { ref: refCallback, model: selection, factory: _jsx(GtkSignalListItemFactory, { ...itemCells.handlers }), ...header.factoryProps, ...rest }), _jsx(ItemPortals, { registry: itemCells, render: renderItem, rowProps: rowProps, collection: collection, expandedIds: expandedIds, expanderDescriptions: expanderDescriptions }), header.portals] }));
|
|
34
39
|
}
|
|
35
40
|
export { ListView };
|
|
36
41
|
//# sourceMappingURL=list-view.js.map
|
package/dist/list-view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-view.js","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"list-view.js","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,eAAe,GAAG;IACpB,OAAO;IACP,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,cAAc;IACd,UAAU;IACV,aAAa;IACb,oBAAoB;IACpB,eAAe;IACf,aAAa;IACb,kBAAkB;IAClB,sBAAsB;IACtB,qBAAqB;IACrB,oBAAoB;IACpB,KAAK;CACmC,CAAC;AAE7C;;;GAGG;AACH,SAAS,QAAQ,CAA2B,KAA0B;IAClE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAC7F,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,kBAAkB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,mBAAmB,IAAI,CAAC,CAAC,EAAE,CAAC;IACpF,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,YAAY,CAAe,GAAG,CAAC,CAAC;IAC5D,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7G,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAEhE,OAAO,CACH,8BACI,KAAC,WAAW,IACR,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,KAAC,wBAAwB,OAAK,SAAS,CAAC,QAAQ,GAAI,KACzD,MAAM,CAAC,YAAY,KACnB,IAAI,GACV,EACF,KAAC,WAAW,IACR,QAAQ,EAAE,SAAS,EACnB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,oBAAoB,GAC5C,EACD,MAAM,CAAC,OAAO,IAChB,CACN,CAAC;AACN,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ReactNode } from \"react\";\nimport { GtkListView, GtkSignalListItemFactory } from \"@gtkx/jsx/gtk\";\nimport { omit } from \"@gtkx/utils\";\nimport type { ListViewProps } from \"./types.js\";\nimport { ItemPortals, useItemCells, useSectionHeader } from \"./internal/cells.js\";\nimport { showFirstHeader } from \"./internal/first-header.js\";\nimport { useCollection } from \"./internal/use-collection.js\";\nimport { useWidgetRef } from \"./internal/use-widget-ref.js\";\n\nconst LIST_VIEW_PROPS = [\n \"items\",\n \"sections\",\n \"isFlat\",\n \"renderItem\",\n \"renderHeader\",\n \"rowProps\",\n \"selectedIds\",\n \"onSelectionChanged\",\n \"selectionMode\",\n \"expandedIds\",\n \"onExpandedChange\",\n \"expanderDescriptions\",\n \"estimatedItemHeight\",\n \"estimatedItemWidth\",\n \"ref\",\n] as const satisfies (keyof ListViewProps)[];\n\n/**\n * Renders a Gtk.ListView from declarative items or sections, with per-row rendering,\n * controlled selection, controlled tree expansion, and estimated item sizing.\n */\nfunction ListView<T = unknown, S = unknown>(props: ListViewProps<T, S>): ReactNode {\n const { renderItem, renderHeader, rowProps, expandedIds, expanderDescriptions, ref } = props;\n const { estimatedItemHeight, estimatedItemWidth } = props;\n const rest = omit(props, LIST_VIEW_PROPS);\n const size = { width: estimatedItemWidth ?? -1, height: estimatedItemHeight ?? -1 };\n const [view, refCallback] = useWidgetRef<Gtk.ListView>(ref);\n const { collection, selection } = useCollection({ ...props, onSectionsFilled: () => showFirstHeader(view) });\n const itemCells = useItemCells(size);\n const header = useSectionHeader(renderHeader, collection, size);\n\n return (\n <>\n <GtkListView\n ref={refCallback}\n model={selection}\n factory={<GtkSignalListItemFactory {...itemCells.handlers} />}\n {...header.factoryProps}\n {...rest}\n />\n <ItemPortals\n registry={itemCells}\n render={renderItem}\n rowProps={rowProps}\n collection={collection}\n expandedIds={expandedIds}\n expanderDescriptions={expanderDescriptions}\n />\n {header.portals}\n </>\n );\n}\n\nexport { ListView };\n"]}
|