@gtkx/components 1.0.0-rc.1 → 1.0.0-rc.2
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/adw/index.d.ts +3 -0
- package/dist/adw/index.d.ts.map +1 -0
- package/dist/adw/index.js +2 -0
- package/dist/adw/index.js.map +1 -0
- package/dist/adw/toast.d.ts +10 -0
- package/dist/adw/toast.d.ts.map +1 -0
- package/dist/adw/toast.js +51 -0
- package/dist/adw/toast.js.map +1 -0
- package/dist/adw/types.d.ts +28 -0
- package/dist/adw/types.d.ts.map +1 -0
- package/dist/adw/types.js +2 -0
- package/dist/adw/types.js.map +1 -0
- package/dist/column-view.d.ts +7 -29
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +98 -70
- package/dist/column-view.js.map +1 -1
- package/dist/drop-down.d.ts +8 -27
- package/dist/drop-down.d.ts.map +1 -1
- package/dist/drop-down.js +112 -81
- package/dist/drop-down.js.map +1 -1
- package/dist/grid-view.d.ts +6 -16
- package/dist/grid-view.d.ts.map +1 -1
- package/dist/grid-view.js +25 -33
- package/dist/grid-view.js.map +1 -1
- package/dist/index.d.ts +6 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/internal/cells.d.ts +50 -0
- package/dist/internal/cells.d.ts.map +1 -0
- package/dist/internal/cells.js +185 -0
- package/dist/internal/cells.js.map +1 -0
- package/dist/internal/collection-index.d.ts +21 -0
- package/dist/internal/collection-index.d.ts.map +1 -0
- package/dist/internal/collection-index.js +106 -0
- package/dist/internal/collection-index.js.map +1 -0
- package/dist/internal/collection-model.d.ts +12 -0
- package/dist/internal/collection-model.d.ts.map +1 -0
- package/dist/internal/collection-model.js +164 -0
- package/dist/internal/collection-model.js.map +1 -0
- package/dist/internal/collection.d.ts +18 -0
- package/dist/internal/collection.d.ts.map +1 -0
- package/dist/internal/collection.js +64 -0
- package/dist/internal/collection.js.map +1 -0
- package/dist/internal/expansion.d.ts +9 -0
- package/dist/internal/expansion.d.ts.map +1 -0
- package/dist/internal/expansion.js +75 -0
- package/dist/internal/expansion.js.map +1 -0
- package/dist/internal/selection.d.ts +12 -0
- package/dist/internal/selection.d.ts.map +1 -0
- package/dist/internal/selection.js +99 -0
- package/dist/internal/selection.js.map +1 -0
- package/dist/internal/use-collection.d.ts +18 -0
- package/dist/internal/use-collection.d.ts.map +1 -0
- package/dist/internal/use-collection.js +42 -0
- package/dist/internal/use-collection.js.map +1 -0
- package/dist/internal/use-widget-ref.d.ts +4 -0
- package/dist/internal/use-widget-ref.d.ts.map +1 -0
- package/dist/internal/use-widget-ref.js +8 -0
- package/dist/internal/use-widget-ref.js.map +1 -0
- package/dist/list-view.d.ts +5 -20
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +32 -53
- package/dist/list-view.js.map +1 -1
- package/dist/size-group.d.ts +8 -16
- package/dist/size-group.d.ts.map +1 -1
- package/dist/size-group.js +35 -51
- package/dist/size-group.js.map +1 -1
- package/dist/types.d.ts +97 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +17 -6
- package/src/adw/index.ts +2 -0
- package/src/adw/toast.tsx +74 -0
- package/src/adw/types.ts +32 -0
- package/src/column-view.tsx +176 -160
- package/src/drop-down.tsx +180 -167
- package/src/grid-view.tsx +29 -73
- package/src/index.ts +18 -25
- package/src/internal/cells.tsx +345 -0
- package/src/internal/collection-index.ts +168 -0
- package/src/internal/collection-model.ts +246 -0
- package/src/internal/collection.ts +104 -0
- package/src/internal/expansion.ts +123 -0
- package/src/internal/selection.tsx +159 -0
- package/src/internal/use-collection.tsx +70 -0
- package/src/internal/use-widget-ref.ts +11 -0
- package/src/list-view.tsx +43 -139
- package/src/size-group.tsx +63 -82
- package/src/types.ts +155 -24
- package/dist/cell.d.ts +0 -30
- package/dist/cell.d.ts.map +0 -1
- package/dist/cell.js +0 -45
- package/dist/cell.js.map +0 -1
- package/dist/column-view-column.d.ts +0 -27
- package/dist/column-view-column.d.ts.map +0 -1
- package/dist/column-view-column.js +0 -30
- package/dist/column-view-column.js.map +0 -1
- package/dist/constraint-layout-apply.d.ts +0 -55
- package/dist/constraint-layout-apply.d.ts.map +0 -1
- package/dist/constraint-layout-apply.js +0 -107
- package/dist/constraint-layout-apply.js.map +0 -1
- package/dist/constraint-layout.d.ts +0 -20
- package/dist/constraint-layout.d.ts.map +0 -1
- package/dist/constraint-layout.js +0 -88
- package/dist/constraint-layout.js.map +0 -1
- package/dist/fixed.d.ts +0 -26
- package/dist/fixed.d.ts.map +0 -1
- package/dist/fixed.js +0 -40
- package/dist/fixed.js.map +0 -1
- package/dist/grid.d.ts +0 -27
- package/dist/grid.d.ts.map +0 -1
- package/dist/grid.js +0 -48
- package/dist/grid.js.map +0 -1
- package/dist/hooks/use-cell-containers.d.ts +0 -18
- package/dist/hooks/use-cell-containers.d.ts.map +0 -1
- package/dist/hooks/use-cell-containers.js +0 -67
- package/dist/hooks/use-cell-containers.js.map +0 -1
- package/dist/hooks/use-collection-model.d.ts +0 -26
- package/dist/hooks/use-collection-model.d.ts.map +0 -1
- package/dist/hooks/use-collection-model.js +0 -35
- package/dist/hooks/use-collection-model.js.map +0 -1
- package/dist/hooks/use-collection-widget.d.ts +0 -28
- package/dist/hooks/use-collection-widget.d.ts.map +0 -1
- package/dist/hooks/use-collection-widget.js +0 -21
- package/dist/hooks/use-collection-widget.js.map +0 -1
- package/dist/hooks/use-drop-down-selection.d.ts +0 -16
- package/dist/hooks/use-drop-down-selection.d.ts.map +0 -1
- package/dist/hooks/use-drop-down-selection.js +0 -35
- package/dist/hooks/use-drop-down-selection.js.map +0 -1
- package/dist/hooks/use-expansion-model.d.ts +0 -12
- package/dist/hooks/use-expansion-model.d.ts.map +0 -1
- package/dist/hooks/use-expansion-model.js +0 -71
- package/dist/hooks/use-expansion-model.js.map +0 -1
- package/dist/hooks/use-header-menu.d.ts +0 -4
- package/dist/hooks/use-header-menu.d.ts.map +0 -1
- package/dist/hooks/use-header-menu.js +0 -20
- package/dist/hooks/use-header-menu.js.map +0 -1
- package/dist/hooks/use-installed-model.d.ts +0 -4
- package/dist/hooks/use-installed-model.d.ts.map +0 -1
- package/dist/hooks/use-installed-model.js +0 -15
- package/dist/hooks/use-installed-model.js.map +0 -1
- package/dist/hooks/use-list-model.d.ts +0 -19
- package/dist/hooks/use-list-model.d.ts.map +0 -1
- package/dist/hooks/use-list-model.js +0 -97
- package/dist/hooks/use-list-model.js.map +0 -1
- package/dist/hooks/use-placed-child.d.ts +0 -18
- package/dist/hooks/use-placed-child.d.ts.map +0 -1
- package/dist/hooks/use-placed-child.js +0 -47
- package/dist/hooks/use-placed-child.js.map +0 -1
- package/dist/hooks/use-selection-model.d.ts +0 -13
- package/dist/hooks/use-selection-model.d.ts.map +0 -1
- package/dist/hooks/use-selection-model.js +0 -103
- package/dist/hooks/use-selection-model.js.map +0 -1
- package/dist/hooks/use-sort-handler.d.ts +0 -17
- package/dist/hooks/use-sort-handler.d.ts.map +0 -1
- package/dist/hooks/use-sort-handler.js +0 -87
- package/dist/hooks/use-sort-handler.js.map +0 -1
- package/dist/menu-items.d.ts +0 -5
- package/dist/menu-items.d.ts.map +0 -1
- package/dist/menu-items.js +0 -48
- package/dist/menu-items.js.map +0 -1
- package/dist/menu.d.ts +0 -14
- package/dist/menu.d.ts.map +0 -1
- package/dist/menu.js +0 -24
- package/dist/menu.js.map +0 -1
- package/dist/overlay.d.ts +0 -24
- package/dist/overlay.d.ts.map +0 -1
- package/dist/overlay.js +0 -49
- package/dist/overlay.js.map +0 -1
- package/dist/utils/cell-container-store.d.ts +0 -28
- package/dist/utils/cell-container-store.d.ts.map +0 -1
- package/dist/utils/cell-container-store.js +0 -98
- package/dist/utils/cell-container-store.js.map +0 -1
- package/dist/utils/item-models.d.ts +0 -10
- package/dist/utils/item-models.d.ts.map +0 -1
- package/dist/utils/item-models.js +0 -82
- package/dist/utils/item-models.js.map +0 -1
- package/dist/utils/item-resolver.d.ts +0 -25
- package/dist/utils/item-resolver.d.ts.map +0 -1
- package/dist/utils/item-resolver.js +0 -102
- package/dist/utils/item-resolver.js.map +0 -1
- package/dist/utils/list-item-flatten.d.ts +0 -24
- package/dist/utils/list-item-flatten.d.ts.map +0 -1
- package/dist/utils/list-item-flatten.js +0 -68
- package/dist/utils/list-item-flatten.js.map +0 -1
- package/src/cell.tsx +0 -144
- package/src/column-view-column.tsx +0 -82
- package/src/constraint-layout-apply.ts +0 -173
- package/src/constraint-layout.tsx +0 -135
- package/src/fixed.tsx +0 -86
- package/src/grid.tsx +0 -88
- package/src/hooks/use-cell-containers.ts +0 -93
- package/src/hooks/use-collection-model.ts +0 -60
- package/src/hooks/use-collection-widget.ts +0 -47
- package/src/hooks/use-drop-down-selection.ts +0 -52
- package/src/hooks/use-expansion-model.ts +0 -82
- package/src/hooks/use-header-menu.ts +0 -34
- package/src/hooks/use-installed-model.ts +0 -20
- package/src/hooks/use-list-model.ts +0 -161
- package/src/hooks/use-placed-child.ts +0 -79
- package/src/hooks/use-selection-model.ts +0 -114
- package/src/hooks/use-sort-handler.ts +0 -107
- package/src/menu-items.ts +0 -48
- package/src/menu.tsx +0 -32
- package/src/overlay.tsx +0 -88
- package/src/utils/cell-container-store.ts +0 -114
- package/src/utils/item-models.ts +0 -113
- package/src/utils/item-resolver.ts +0 -138
- package/src/utils/list-item-flatten.ts +0 -90
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
-
import { type ReactNode, useCallback } from "react";
|
|
3
|
-
import type { ItemNode, SectionNode } from "../types.js";
|
|
4
|
-
import { type ItemResolver, rowIdOf } from "../utils/item-resolver.js";
|
|
5
|
-
import { useExpansionModel } from "./use-expansion-model.js";
|
|
6
|
-
import { useListModel } from "./use-list-model.js";
|
|
7
|
-
import { useSelectionModel } from "./use-selection-model.js";
|
|
8
|
-
|
|
9
|
-
type CollectionModelInput<T, S> = {
|
|
10
|
-
items: ItemNode<T>[] | undefined;
|
|
11
|
-
sections: SectionNode<S, T>[] | undefined;
|
|
12
|
-
selectionMode: Gtk.SelectionMode | null | undefined;
|
|
13
|
-
selectedIds: string[] | null | undefined;
|
|
14
|
-
onSelectionChanged: ((ids: string[]) => void) | null | undefined;
|
|
15
|
-
expandedIds?: string[] | null | undefined;
|
|
16
|
-
onExpandedChange?: ((ids: string[]) => void) | null | undefined;
|
|
17
|
-
renderHeader: ((info: { section: S }) => ReactNode) | null | undefined;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type CollectionModelResult<T, S> = {
|
|
21
|
-
resolver: ItemResolver<T, S>;
|
|
22
|
-
headerResolver: ItemResolver<T, S>;
|
|
23
|
-
installedModel: Gtk.SelectionModel;
|
|
24
|
-
useHeader: boolean;
|
|
25
|
-
rowId: (row: Gtk.TreeListRow) => string | undefined;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const useCollectionModel = <T, S>(input: CollectionModelInput<T, S>): CollectionModelResult<T, S> => {
|
|
29
|
-
const listModel = useListModel<T, S>({
|
|
30
|
-
items: input.items,
|
|
31
|
-
sections: input.sections,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
useExpansionModel<T>({
|
|
35
|
-
treeModel: listModel.treeModel,
|
|
36
|
-
rowValues: listModel.rowValues,
|
|
37
|
-
expandedIds: input.expandedIds,
|
|
38
|
-
onExpandedChange: input.onExpandedChange,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const installedModel = useSelectionModel<T, S>({
|
|
42
|
-
base: listModel.model,
|
|
43
|
-
resolver: listModel.resolver,
|
|
44
|
-
selectionMode: input.selectionMode,
|
|
45
|
-
selectedIds: input.selectedIds,
|
|
46
|
-
onSelectionChanged: input.onSelectionChanged,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const useHeader = typeof input.renderHeader === "function";
|
|
50
|
-
const { rowValues } = listModel;
|
|
51
|
-
const rowId = useCallback((row: Gtk.TreeListRow): string | undefined => rowIdOf(rowValues, row), [rowValues]);
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
resolver: listModel.resolver,
|
|
55
|
-
headerResolver: listModel.headerResolver,
|
|
56
|
-
installedModel,
|
|
57
|
-
useHeader,
|
|
58
|
-
rowId,
|
|
59
|
-
};
|
|
60
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
-
import { useMergeRefs } from "@gtkx/react/internal";
|
|
3
|
-
import { type ReactNode, type Ref, type RefCallback, type RefObject, useRef } from "react";
|
|
4
|
-
import type { ItemNode, SectionNode } from "../types.js";
|
|
5
|
-
import { type CollectionModelResult, useCollectionModel } from "./use-collection-model.js";
|
|
6
|
-
import { useInstalledModel } from "./use-installed-model.js";
|
|
7
|
-
|
|
8
|
-
type CollectionWidget = Gtk.Widget & {
|
|
9
|
-
setModel(model: Gtk.SelectionModel | null): void;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type CollectionWidgetInput<W extends CollectionWidget, T, S> = {
|
|
13
|
-
ref?: Ref<W | null> | undefined;
|
|
14
|
-
items?: ItemNode<T>[] | undefined;
|
|
15
|
-
sections?: SectionNode<S, T>[] | undefined;
|
|
16
|
-
selectionMode?: Gtk.SelectionMode | null | undefined;
|
|
17
|
-
selectedIds?: string[] | null | undefined;
|
|
18
|
-
onSelectionChanged?: ((ids: string[]) => void) | null | undefined;
|
|
19
|
-
expandedIds?: string[] | null | undefined;
|
|
20
|
-
onExpandedChange?: ((ids: string[]) => void) | null | undefined;
|
|
21
|
-
renderHeader?: ((info: { section: S }) => ReactNode) | null | undefined;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type CollectionWidgetResult<W extends CollectionWidget, T, S> = {
|
|
25
|
-
widgetRef: RefObject<W | null>;
|
|
26
|
-
setRef: RefCallback<W>;
|
|
27
|
-
collection: CollectionModelResult<T, S>;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const useCollectionWidget = <W extends CollectionWidget, T, S>(
|
|
31
|
-
props: CollectionWidgetInput<W, T, S>,
|
|
32
|
-
): CollectionWidgetResult<W, T, S> => {
|
|
33
|
-
const widgetRef = useRef<W | null>(null);
|
|
34
|
-
const setRef = useMergeRefs<W>(props.ref, widgetRef);
|
|
35
|
-
const collection = useCollectionModel<T, S>({
|
|
36
|
-
items: props.items,
|
|
37
|
-
sections: props.sections,
|
|
38
|
-
selectionMode: props.selectionMode,
|
|
39
|
-
selectedIds: props.selectedIds,
|
|
40
|
-
onSelectionChanged: props.onSelectionChanged,
|
|
41
|
-
expandedIds: props.expandedIds,
|
|
42
|
-
onExpandedChange: props.onExpandedChange,
|
|
43
|
-
renderHeader: props.renderHeader,
|
|
44
|
-
});
|
|
45
|
-
useInstalledModel(widgetRef, collection.installedModel, (widget, model) => widget.setModel(model));
|
|
46
|
-
return { widgetRef, setRef, collection };
|
|
47
|
-
};
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
-
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
-
import { useSignal } from "@gtkx/react";
|
|
4
|
-
import { type ObjectProp, resolveObjectProp, useObjectValue } from "@gtkx/react/internal";
|
|
5
|
-
import { useLayoutEffect, useRef } from "react";
|
|
6
|
-
import type { ItemResolver } from "../utils/item-resolver.js";
|
|
7
|
-
|
|
8
|
-
type DropDownSelectionObject = GObject.Object & {
|
|
9
|
-
getSelected(): number;
|
|
10
|
-
setSelected(position: number): void;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type DropDownSelectionOptions<T, S> = {
|
|
14
|
-
widget: ObjectProp<DropDownSelectionObject>;
|
|
15
|
-
resolver: ItemResolver<T, S>;
|
|
16
|
-
selectedId: string | null | undefined;
|
|
17
|
-
onSelectionChanged: ((id: string) => void) | null | undefined;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const normalizeSelected = (position: number): number =>
|
|
21
|
-
position === Gtk.INVALID_LIST_POSITION || position < 0 ? -1 : position;
|
|
22
|
-
|
|
23
|
-
export const useDropDownSelection = <T, S>(options: DropDownSelectionOptions<T, S>): number => {
|
|
24
|
-
const { widget, resolver, selectedId, onSelectionChanged } = options;
|
|
25
|
-
const resolved = resolveObjectProp(widget);
|
|
26
|
-
|
|
27
|
-
const selectedPosition = useObjectValue(widget, "notify::selected", (object) =>
|
|
28
|
-
object === null ? -1 : normalizeSelected(object.getSelected()),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
const resolverRef = useRef(resolver);
|
|
32
|
-
resolverRef.current = resolver;
|
|
33
|
-
const onSelectionChangedRef = useRef(onSelectionChanged);
|
|
34
|
-
onSelectionChangedRef.current = onSelectionChanged;
|
|
35
|
-
|
|
36
|
-
useLayoutEffect(() => {
|
|
37
|
-
if (resolved === null || selectedId === undefined || selectedId === null) return;
|
|
38
|
-
const position = resolverRef.current.positionOfId(selectedId);
|
|
39
|
-
if (position < 0) return;
|
|
40
|
-
if (normalizeSelected(resolved.getSelected()) !== position) resolved.setSelected(position);
|
|
41
|
-
}, [resolved, selectedId, resolver]);
|
|
42
|
-
|
|
43
|
-
useSignal(widget, "notify::selected", () => {
|
|
44
|
-
if (resolved === null) return;
|
|
45
|
-
const position = normalizeSelected(resolved.getSelected());
|
|
46
|
-
if (position < 0) return;
|
|
47
|
-
const id = resolverRef.current.idOf(position);
|
|
48
|
-
if (id !== undefined) onSelectionChangedRef.current?.(id);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
return selectedPosition;
|
|
52
|
-
};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
-
import { useSignal } from "@gtkx/react";
|
|
4
|
-
import { isSameArray } from "@gtkx/utils";
|
|
5
|
-
import { useLayoutEffect, useRef } from "react";
|
|
6
|
-
import { type RowValue, rowIdOf } from "../utils/item-resolver.js";
|
|
7
|
-
|
|
8
|
-
type ExpansionModelOptions<T> = {
|
|
9
|
-
treeModel: Gtk.TreeListModel | null;
|
|
10
|
-
rowValues: WeakMap<GObject.Object, RowValue<T>>;
|
|
11
|
-
expandedIds: string[] | null | undefined;
|
|
12
|
-
onExpandedChange: ((ids: string[]) => void) | null | undefined;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const readExpandedIds = <T>(model: Gtk.TreeListModel, rowValues: WeakMap<GObject.Object, RowValue<T>>): string[] => {
|
|
16
|
-
const ids: string[] = [];
|
|
17
|
-
const count = model.getNItems();
|
|
18
|
-
for (let position = 0; position < count; position++) {
|
|
19
|
-
const row = model.getRow(position);
|
|
20
|
-
if (row?.getExpanded()) {
|
|
21
|
-
const id = rowIdOf(rowValues, row);
|
|
22
|
-
if (id !== undefined) ids.push(id);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return ids;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const applyExpanded = <T>(
|
|
29
|
-
model: Gtk.TreeListModel,
|
|
30
|
-
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
31
|
-
ids: string[],
|
|
32
|
-
): void => {
|
|
33
|
-
const target = new Set(ids);
|
|
34
|
-
let changed = true;
|
|
35
|
-
while (changed) {
|
|
36
|
-
changed = false;
|
|
37
|
-
const count = model.getNItems();
|
|
38
|
-
for (let position = 0; position < count; position++) {
|
|
39
|
-
const row = model.getRow(position);
|
|
40
|
-
if (row === null || !row.isExpandable()) continue;
|
|
41
|
-
const id = rowIdOf(rowValues, row);
|
|
42
|
-
if (id === undefined) continue;
|
|
43
|
-
const desired = target.has(id);
|
|
44
|
-
if (row.getExpanded() !== desired) {
|
|
45
|
-
row.setExpanded(desired);
|
|
46
|
-
changed = true;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const useExpansionModel = <T>(options: ExpansionModelOptions<T>): void => {
|
|
53
|
-
const { treeModel, rowValues, expandedIds, onExpandedChange } = options;
|
|
54
|
-
const onChangeRef = useRef(onExpandedChange);
|
|
55
|
-
onChangeRef.current = onExpandedChange;
|
|
56
|
-
const rowValuesRef = useRef(rowValues);
|
|
57
|
-
rowValuesRef.current = rowValues;
|
|
58
|
-
const lastReportedRef = useRef<string[] | null>(null);
|
|
59
|
-
const applyingRef = useRef(false);
|
|
60
|
-
|
|
61
|
-
const report = (): void => {
|
|
62
|
-
if (treeModel === null || applyingRef.current) return;
|
|
63
|
-
const callback = onChangeRef.current;
|
|
64
|
-
if (!callback) return;
|
|
65
|
-
const ids = readExpandedIds(treeModel, rowValuesRef.current);
|
|
66
|
-
if (lastReportedRef.current !== null && isSameArray(lastReportedRef.current, ids)) return;
|
|
67
|
-
lastReportedRef.current = ids;
|
|
68
|
-
callback(ids);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
useSignal(treeModel, "items-changed", report);
|
|
72
|
-
|
|
73
|
-
useLayoutEffect(() => {
|
|
74
|
-
if (treeModel === null) return;
|
|
75
|
-
if (expandedIds !== undefined && expandedIds !== null) {
|
|
76
|
-
applyingRef.current = true;
|
|
77
|
-
applyExpanded(treeModel, rowValuesRef.current, expandedIds);
|
|
78
|
-
applyingRef.current = false;
|
|
79
|
-
}
|
|
80
|
-
report();
|
|
81
|
-
}, [treeModel, expandedIds]);
|
|
82
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/gi/gio";
|
|
2
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
-
import { createPortal, rootElement } from "@gtkx/react";
|
|
4
|
-
import { useMergeRefs } from "@gtkx/react/internal";
|
|
5
|
-
import {
|
|
6
|
-
cloneElement,
|
|
7
|
-
isValidElement,
|
|
8
|
-
type ReactElement,
|
|
9
|
-
type ReactNode,
|
|
10
|
-
type Ref,
|
|
11
|
-
type RefCallback,
|
|
12
|
-
useCallback,
|
|
13
|
-
useLayoutEffect,
|
|
14
|
-
useRef,
|
|
15
|
-
} from "react";
|
|
16
|
-
|
|
17
|
-
type MenuElement = ReactElement<{ ref?: Ref<Gio.MenuModel | null> }>;
|
|
18
|
-
|
|
19
|
-
export const useHeaderMenu = (column: Gtk.ColumnViewColumn | null, headerMenu: ReactNode): ReactNode => {
|
|
20
|
-
const modelRef = useRef<Gio.MenuModel | null>(null);
|
|
21
|
-
const setModel = useCallback<RefCallback<Gio.MenuModel>>((model) => {
|
|
22
|
-
modelRef.current = model;
|
|
23
|
-
}, []);
|
|
24
|
-
const element = isValidElement(headerMenu) ? (headerMenu as MenuElement) : null;
|
|
25
|
-
const mergedRef = useMergeRefs<Gio.MenuModel>(setModel, element?.props.ref);
|
|
26
|
-
|
|
27
|
-
useLayoutEffect(() => {
|
|
28
|
-
if (column === null) return;
|
|
29
|
-
column.setHeaderMenu(headerMenu == null ? null : modelRef.current);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (element === null) return null;
|
|
33
|
-
return createPortal(cloneElement(element, { ref: mergedRef }), rootElement);
|
|
34
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
-
import { useObjectAttachment } from "@gtkx/react/internal";
|
|
3
|
-
import { type RefObject, useRef } from "react";
|
|
4
|
-
|
|
5
|
-
export const useInstalledModel = <W extends Gtk.Widget, M>(
|
|
6
|
-
object: RefObject<W | null>,
|
|
7
|
-
model: M,
|
|
8
|
-
install: (widget: W, model: M) => void,
|
|
9
|
-
): void => {
|
|
10
|
-
const installRef = useRef(install);
|
|
11
|
-
installRef.current = install;
|
|
12
|
-
useObjectAttachment<W, { widget: W; model: M }>(object, {
|
|
13
|
-
attach: (widget) => {
|
|
14
|
-
installRef.current(widget, model);
|
|
15
|
-
return { widget, model };
|
|
16
|
-
},
|
|
17
|
-
detach: () => {},
|
|
18
|
-
isSame: (attachment, widget) => attachment.widget === widget && attachment.model === model,
|
|
19
|
-
});
|
|
20
|
-
};
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/gi/gio";
|
|
2
|
-
import type * as GObject from "@gtkx/gi/gobject";
|
|
3
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import { useLayoutEffect, useMemo, useRef } from "react";
|
|
5
|
-
import type { ItemNode, SectionNode } from "../types.js";
|
|
6
|
-
import {
|
|
7
|
-
createFlatModel,
|
|
8
|
-
createSectionModel,
|
|
9
|
-
createTreeModel,
|
|
10
|
-
resizeFlatModel,
|
|
11
|
-
retagRows,
|
|
12
|
-
} from "../utils/item-models.js";
|
|
13
|
-
import {
|
|
14
|
-
createItemResolver,
|
|
15
|
-
createSectionHeaderResolver,
|
|
16
|
-
createTreeResolver,
|
|
17
|
-
type ItemResolver,
|
|
18
|
-
type RowValue,
|
|
19
|
-
} from "../utils/item-resolver.js";
|
|
20
|
-
import { detectStructure, type ListStructure, structuralSignature } from "../utils/list-item-flatten.js";
|
|
21
|
-
|
|
22
|
-
type ListModelInput<T, S> = {
|
|
23
|
-
items: ItemNode<T>[] | undefined;
|
|
24
|
-
sections?: SectionNode<S, T>[] | undefined;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type ListModelResult<T, S> = {
|
|
28
|
-
model: Gio.ListModel;
|
|
29
|
-
treeModel: Gtk.TreeListModel | null;
|
|
30
|
-
resolver: ItemResolver<T, S>;
|
|
31
|
-
headerResolver: ItemResolver<T, S>;
|
|
32
|
-
rowValues: WeakMap<GObject.Object, RowValue<T>>;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type ListModelStructure = "sections" | ListStructure;
|
|
36
|
-
|
|
37
|
-
type ListModelState<T, S> = {
|
|
38
|
-
model: Gio.ListModel;
|
|
39
|
-
treeModel: Gtk.TreeListModel | null;
|
|
40
|
-
flatModel: Gtk.StringList | undefined;
|
|
41
|
-
items: ItemNode<T>[] | undefined;
|
|
42
|
-
sections: SectionNode<S, T>[] | undefined;
|
|
43
|
-
structure: ListModelStructure;
|
|
44
|
-
signature: string;
|
|
45
|
-
rowValues: WeakMap<GObject.Object, RowValue<T>>;
|
|
46
|
-
placeholdersById: Map<string, GObject.Object>;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const sectionRows = <T, S>(sections: SectionNode<S, T>[] | undefined): ItemNode<T>[] => {
|
|
50
|
-
if (sections === undefined) return [];
|
|
51
|
-
const rows: ItemNode<T>[] = [];
|
|
52
|
-
for (const section of sections) rows.push(...section.data);
|
|
53
|
-
return rows;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const sectionSignature = <T, S>(sections: SectionNode<S, T>[] | undefined): string => {
|
|
57
|
-
if (sections === undefined) return "";
|
|
58
|
-
const parts: string[] = [];
|
|
59
|
-
for (const section of sections) {
|
|
60
|
-
parts.push(`${section.id}{${structuralSignature(section.data)}}`);
|
|
61
|
-
}
|
|
62
|
-
return parts.join(",");
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const signatureOf = <T, S>(
|
|
66
|
-
structure: ListModelStructure,
|
|
67
|
-
items: ItemNode<T>[] | undefined,
|
|
68
|
-
sections: SectionNode<S, T>[] | undefined,
|
|
69
|
-
): string => {
|
|
70
|
-
if (structure === "sections") return `sections|${sectionSignature(sections)}`;
|
|
71
|
-
return structure === "flat" ? "" : `${structure}|${structuralSignature(items)}`;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
type ListModelInternalInput<T, S> = {
|
|
75
|
-
items: ItemNode<T>[] | undefined;
|
|
76
|
-
sections: SectionNode<S, T>[] | undefined;
|
|
77
|
-
structure: ListModelStructure;
|
|
78
|
-
signature: string;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const buildState = <T, S>(input: ListModelInternalInput<T, S>): ListModelState<T, S> => {
|
|
82
|
-
const { items, sections, structure, signature } = input;
|
|
83
|
-
const rowValues = new WeakMap<GObject.Object, RowValue<T>>();
|
|
84
|
-
const placeholdersById = new Map<string, GObject.Object>();
|
|
85
|
-
let model: Gio.ListModel;
|
|
86
|
-
let treeModel: Gtk.TreeListModel | null = null;
|
|
87
|
-
let flatModel: Gtk.StringList | undefined;
|
|
88
|
-
if (structure === "sections") {
|
|
89
|
-
model = createSectionModel(sections ?? []);
|
|
90
|
-
} else if (structure === "tree") {
|
|
91
|
-
treeModel = createTreeModel(items ?? [], rowValues, placeholdersById);
|
|
92
|
-
model = treeModel;
|
|
93
|
-
} else {
|
|
94
|
-
flatModel = createFlatModel(items?.length ?? 0);
|
|
95
|
-
model = flatModel;
|
|
96
|
-
}
|
|
97
|
-
return { model, treeModel, flatModel, items, sections, structure, signature, rowValues, placeholdersById };
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const resolveState = <T, S>(
|
|
101
|
-
prev: ListModelState<T, S> | null,
|
|
102
|
-
items: ItemNode<T>[] | undefined,
|
|
103
|
-
sections: SectionNode<S, T>[] | undefined,
|
|
104
|
-
): ListModelState<T, S> => {
|
|
105
|
-
if (prev !== null && prev.items === items && prev.sections === sections) {
|
|
106
|
-
return prev;
|
|
107
|
-
}
|
|
108
|
-
const structure: ListModelStructure = sections !== undefined ? "sections" : detectStructure(items);
|
|
109
|
-
const signature = signatureOf(structure, items, sections);
|
|
110
|
-
const input: ListModelInternalInput<T, S> = { items, sections, structure, signature };
|
|
111
|
-
if (prev === null || prev.structure !== structure) {
|
|
112
|
-
return buildState(input);
|
|
113
|
-
}
|
|
114
|
-
if (structure !== "flat" && prev.signature !== signature) {
|
|
115
|
-
return buildState(input);
|
|
116
|
-
}
|
|
117
|
-
if (structure === "tree") {
|
|
118
|
-
retagRows(items ?? [], prev.rowValues, prev.placeholdersById);
|
|
119
|
-
}
|
|
120
|
-
prev.items = items;
|
|
121
|
-
prev.sections = sections;
|
|
122
|
-
prev.signature = signature;
|
|
123
|
-
return prev;
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export const useListModel = <T, S>(input: ListModelInput<T, S>): ListModelResult<T, S> => {
|
|
127
|
-
const { items, sections } = input;
|
|
128
|
-
const stateRef = useRef<ListModelState<T, S> | null>(null);
|
|
129
|
-
const state = resolveState(stateRef.current, items, sections);
|
|
130
|
-
stateRef.current = state;
|
|
131
|
-
const { structure, flatModel } = state;
|
|
132
|
-
|
|
133
|
-
useLayoutEffect(() => {
|
|
134
|
-
if (flatModel !== undefined) {
|
|
135
|
-
resizeFlatModel(flatModel, items?.length ?? 0);
|
|
136
|
-
}
|
|
137
|
-
}, [flatModel, items]);
|
|
138
|
-
|
|
139
|
-
const resolver = useMemo(() => {
|
|
140
|
-
if (structure === "sections") {
|
|
141
|
-
return createItemResolver<T, S>(sectionRows(sections), true, state.rowValues);
|
|
142
|
-
}
|
|
143
|
-
if (structure === "tree" && state.treeModel !== null) {
|
|
144
|
-
return createTreeResolver<T, S>(items, state.rowValues, state.treeModel);
|
|
145
|
-
}
|
|
146
|
-
return createItemResolver<T, S>(items, false, state.rowValues);
|
|
147
|
-
}, [items, sections, structure, state.rowValues, state.treeModel]);
|
|
148
|
-
|
|
149
|
-
const headerResolver = useMemo(
|
|
150
|
-
() => createSectionHeaderResolver<T, S>(structure === "sections" ? sections : undefined),
|
|
151
|
-
[sections, structure],
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
model: state.model,
|
|
156
|
-
treeModel: state.treeModel,
|
|
157
|
-
resolver,
|
|
158
|
-
headerResolver,
|
|
159
|
-
rowValues: state.rowValues,
|
|
160
|
-
};
|
|
161
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
-
import { createPortal, rootElement } from "@gtkx/react";
|
|
3
|
-
import { useMergeRefs } from "@gtkx/react/internal";
|
|
4
|
-
import {
|
|
5
|
-
type Context,
|
|
6
|
-
createContext,
|
|
7
|
-
type ReactNode,
|
|
8
|
-
type Ref,
|
|
9
|
-
type RefCallback,
|
|
10
|
-
type RefObject,
|
|
11
|
-
useCallback,
|
|
12
|
-
useContext,
|
|
13
|
-
useLayoutEffect,
|
|
14
|
-
useRef,
|
|
15
|
-
} from "react";
|
|
16
|
-
|
|
17
|
-
export type ParentContext<T> = {
|
|
18
|
-
Context: Context<RefObject<T | null> | null>;
|
|
19
|
-
useParentRef: () => RefObject<T | null>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const createParentContext = <T>(orphanMessage: string): ParentContext<T> => {
|
|
23
|
-
const context = createContext<RefObject<T | null> | null>(null);
|
|
24
|
-
return {
|
|
25
|
-
Context: context,
|
|
26
|
-
useParentRef: (): RefObject<T | null> => {
|
|
27
|
-
const ref = useContext(context);
|
|
28
|
-
if (!ref) throw new Error(orphanMessage);
|
|
29
|
-
return ref;
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export type PlacedChildRender<T> = (ref: RefCallback<T>) => ReactNode;
|
|
35
|
-
|
|
36
|
-
export type PlacedChildOptions<T extends GObject.Object, P> = {
|
|
37
|
-
render: PlacedChildRender<T>;
|
|
38
|
-
ref?: Ref<T | null> | undefined;
|
|
39
|
-
placement: P;
|
|
40
|
-
samePlacement: (a: P, b: P) => boolean;
|
|
41
|
-
place: (object: T, placement: P, previous: P | undefined) => void;
|
|
42
|
-
release: (object: T) => void;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const usePlacedChild = <T extends GObject.Object, P>(options: PlacedChildOptions<T, P>): ReactNode => {
|
|
46
|
-
const { render, ref, placement, samePlacement, place, release } = options;
|
|
47
|
-
const objectRef = useRef<T | null>(null);
|
|
48
|
-
const appliedRef = useRef<{ object: T; placement: P } | null>(null);
|
|
49
|
-
const captureObject = useCallback<RefCallback<T>>((object) => {
|
|
50
|
-
objectRef.current = object;
|
|
51
|
-
}, []);
|
|
52
|
-
const setObjectRef = useMergeRefs<T>(ref, captureObject);
|
|
53
|
-
|
|
54
|
-
useLayoutEffect(() => {
|
|
55
|
-
const object = objectRef.current;
|
|
56
|
-
const applied = appliedRef.current;
|
|
57
|
-
if (applied !== null && applied.object !== object) {
|
|
58
|
-
release(applied.object);
|
|
59
|
-
appliedRef.current = null;
|
|
60
|
-
}
|
|
61
|
-
if (object === null) return;
|
|
62
|
-
const current = appliedRef.current;
|
|
63
|
-
if (current === null || !samePlacement(current.placement, placement)) {
|
|
64
|
-
place(object, placement, current?.placement);
|
|
65
|
-
appliedRef.current = { object, placement };
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
useLayoutEffect(
|
|
70
|
-
() => () => {
|
|
71
|
-
const applied = appliedRef.current;
|
|
72
|
-
if (applied !== null) release(applied.object);
|
|
73
|
-
appliedRef.current = null;
|
|
74
|
-
},
|
|
75
|
-
[],
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
return createPortal(render(setObjectRef), rootElement);
|
|
79
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/gi/gio";
|
|
2
|
-
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
-
import { useSignal } from "@gtkx/react";
|
|
4
|
-
import { isSameArray } from "@gtkx/utils";
|
|
5
|
-
import { useLayoutEffect, useRef } from "react";
|
|
6
|
-
import type { ItemResolver } from "../utils/item-resolver.js";
|
|
7
|
-
|
|
8
|
-
type SelectionModelOptions<T, S> = {
|
|
9
|
-
base: Gio.ListModel;
|
|
10
|
-
selectionMode: Gtk.SelectionMode | null | undefined;
|
|
11
|
-
selectedIds: string[] | null | undefined;
|
|
12
|
-
onSelectionChanged: ((ids: string[]) => void) | null | undefined;
|
|
13
|
-
resolver: ItemResolver<T, S>;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type WrappingSelectionModel = (Gtk.SingleSelection | Gtk.MultiSelection | Gtk.NoSelection) & Gtk.SelectionModel;
|
|
17
|
-
|
|
18
|
-
const createSelectionModel = (mode: Gtk.SelectionMode, base: Gio.ListModel): WrappingSelectionModel => {
|
|
19
|
-
if (mode === Gtk.SelectionMode.MULTIPLE) return Gtk.MultiSelection.new(base);
|
|
20
|
-
if (mode === Gtk.SelectionMode.NONE) return Gtk.NoSelection.new(base);
|
|
21
|
-
return new Gtk.SingleSelection({ model: base, autoselect: false, canUnselect: true });
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const bitsetOf = (positions: number[]): Gtk.Bitset => {
|
|
25
|
-
const bitset = Gtk.Bitset.newEmpty();
|
|
26
|
-
for (const position of positions) {
|
|
27
|
-
if (position >= 0) bitset.add(position);
|
|
28
|
-
}
|
|
29
|
-
return bitset;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const applySelectedPositions = (model: Gtk.SelectionModel, positions: number[]): void => {
|
|
33
|
-
if (model instanceof Gtk.MultiSelection) {
|
|
34
|
-
if (positions.length === 0) {
|
|
35
|
-
const current = model.getSelection();
|
|
36
|
-
if (!current.isEmpty()) model.unselectAll();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const requested = bitsetOf(positions);
|
|
40
|
-
const changed = model.getSelection().copy();
|
|
41
|
-
changed.difference(requested);
|
|
42
|
-
if (changed.isEmpty()) return;
|
|
43
|
-
model.setSelection(requested, changed);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
if (positions.length === 0) {
|
|
47
|
-
model.unselectAll();
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const first = positions[0];
|
|
51
|
-
if (first !== undefined && first >= 0) model.selectItem(first, true);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const readSelectedIds = <T, S>(model: Gtk.SelectionModel, resolver: ItemResolver<T, S>): string[] => {
|
|
55
|
-
const selection = model.getSelection();
|
|
56
|
-
const ids: string[] = [];
|
|
57
|
-
const count = Number(selection.getSize());
|
|
58
|
-
for (let index = 0; index < count; index++) {
|
|
59
|
-
const position = selection.getNth(index);
|
|
60
|
-
const id = resolver.idOf(position);
|
|
61
|
-
if (id !== undefined) ids.push(id);
|
|
62
|
-
}
|
|
63
|
-
return ids;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const idsToPositions = <T, S>(ids: string[] | null | undefined, resolver: ItemResolver<T, S>): number[] => {
|
|
67
|
-
if (ids === undefined || ids === null) return [];
|
|
68
|
-
const positions: number[] = [];
|
|
69
|
-
for (const id of ids) {
|
|
70
|
-
const position = resolver.positionOfId(id);
|
|
71
|
-
if (position >= 0) positions.push(position);
|
|
72
|
-
}
|
|
73
|
-
return positions;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export const useSelectionModel = <T, S>(options: SelectionModelOptions<T, S>): Gtk.SelectionModel => {
|
|
77
|
-
const { base, selectionMode, selectedIds, onSelectionChanged, resolver } = options;
|
|
78
|
-
const mode = selectionMode ?? Gtk.SelectionMode.SINGLE;
|
|
79
|
-
|
|
80
|
-
const modelRef = useRef<WrappingSelectionModel | null>(null);
|
|
81
|
-
const modeRef = useRef<Gtk.SelectionMode | null>(null);
|
|
82
|
-
if (modelRef.current === null || modeRef.current !== mode) {
|
|
83
|
-
modelRef.current = createSelectionModel(mode, base);
|
|
84
|
-
modeRef.current = mode;
|
|
85
|
-
}
|
|
86
|
-
const model = modelRef.current;
|
|
87
|
-
|
|
88
|
-
const onChangedRef = useRef(onSelectionChanged);
|
|
89
|
-
onChangedRef.current = onSelectionChanged;
|
|
90
|
-
const resolverRef = useRef(resolver);
|
|
91
|
-
resolverRef.current = resolver;
|
|
92
|
-
const lastReportedRef = useRef<string[] | null>(null);
|
|
93
|
-
|
|
94
|
-
const report = (): void => {
|
|
95
|
-
const callback = onChangedRef.current;
|
|
96
|
-
if (!callback) return;
|
|
97
|
-
const ids = readSelectedIds(model, resolverRef.current);
|
|
98
|
-
if (lastReportedRef.current !== null && isSameArray(lastReportedRef.current, ids)) return;
|
|
99
|
-
lastReportedRef.current = ids;
|
|
100
|
-
callback(ids);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
useSignal(model, "selection-changed", report);
|
|
104
|
-
|
|
105
|
-
useLayoutEffect(() => {
|
|
106
|
-
if (model.getModel() !== base) model.setModel(base);
|
|
107
|
-
if (selectedIds !== undefined && selectedIds !== null) {
|
|
108
|
-
applySelectedPositions(model, idsToPositions(selectedIds, resolver));
|
|
109
|
-
}
|
|
110
|
-
report();
|
|
111
|
-
}, [model, base, selectedIds, resolver]);
|
|
112
|
-
|
|
113
|
-
return model;
|
|
114
|
-
};
|