@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
package/src/drop-down.tsx
CHANGED
|
@@ -1,192 +1,205 @@
|
|
|
1
|
-
import type * as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
widget
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (value === undefined || value === null) return null;
|
|
26
|
-
return <GtkLabel>{String(value)}</GtkLabel>;
|
|
1
|
+
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
+
import type { ElementType, ReactNode, Ref, RefObject } from "react";
|
|
3
|
+
import { GtkDropDown, GtkLabel, GtkSignalListItemFactory } from "@gtkx/jsx/gtk";
|
|
4
|
+
import { useSignal } from "@gtkx/react";
|
|
5
|
+
import { omit } from "@gtkx/utils";
|
|
6
|
+
import { useEffectEvent, useLayoutEffect, useRef } from "react";
|
|
7
|
+
import type { Collection } from "./internal/collection.js";
|
|
8
|
+
import type { DropDownProps, ItemRenderer, RenderItemArgs } from "./types.js";
|
|
9
|
+
import { HeaderPortals, ItemPortals, useHeaderCells, useItemCells } from "./internal/cells.js";
|
|
10
|
+
import { useCollectionData } from "./internal/use-collection.js";
|
|
11
|
+
import { useWidgetRef } from "./internal/use-widget-ref.js";
|
|
12
|
+
|
|
13
|
+
type SelectableWidget = GObject.Object & { getSelected: () => number; selected: number };
|
|
14
|
+
|
|
15
|
+
type DropDownRuntimeProps = DropDownProps & {
|
|
16
|
+
component?: ElementType | undefined;
|
|
17
|
+
ref?: Ref<SelectableWidget | null> | undefined;
|
|
18
|
+
} & Record<string, unknown>;
|
|
19
|
+
|
|
20
|
+
type SelectionOptions = {
|
|
21
|
+
widget: SelectableWidget | null;
|
|
22
|
+
collection: Collection;
|
|
23
|
+
applying: RefObject<boolean>;
|
|
24
|
+
props: DropDownRuntimeProps;
|
|
27
25
|
};
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
type KnownSelection = {
|
|
28
|
+
known: { current: string | null };
|
|
29
|
+
onSelectionChanged: ((id: string) => void) | null | undefined;
|
|
32
30
|
};
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
type DropDownComponent = <T = unknown, S = unknown, C extends ElementType = typeof GtkDropDown>(
|
|
33
|
+
props: DropDownProps<T, S, C>,
|
|
34
|
+
) => ReactNode;
|
|
35
|
+
|
|
36
|
+
const DROP_DOWN_PROPS: string[] = [
|
|
37
|
+
"component",
|
|
38
|
+
"items",
|
|
39
|
+
"sections",
|
|
40
|
+
"selectedId",
|
|
41
|
+
"onSelectionChanged",
|
|
42
|
+
"renderItem",
|
|
43
|
+
"renderListItem",
|
|
44
|
+
"renderHeader",
|
|
45
|
+
"ref",
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Renders a drop-down backed by a collection model, with customizable renderers for the
|
|
50
|
+
* collapsed display, popup rows, and popup section headers, and controlled selection.
|
|
51
|
+
* The backing widget defaults to GtkDropDown and is swappable through `component`.
|
|
52
|
+
*/
|
|
53
|
+
const DropDown: DropDownComponent = DropDownImpl as DropDownComponent;
|
|
54
|
+
|
|
55
|
+
const describeValue = (value: unknown): string => {
|
|
56
|
+
if (typeof value === "string") {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
return JSON.stringify(value);
|
|
62
|
+
} catch {
|
|
63
|
+
return String(value);
|
|
64
|
+
}
|
|
40
65
|
};
|
|
41
66
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
const defaultItemContent = (value: unknown): ReactNode =>
|
|
68
|
+
value == null ? null : <GtkLabel>{describeValue(value)}</GtkLabel>;
|
|
69
|
+
|
|
70
|
+
const defaultRenderItem = ({ item }: RenderItemArgs<unknown>): ReactNode => defaultItemContent(item);
|
|
71
|
+
|
|
72
|
+
const faceRenderer = (props: DropDownRuntimeProps): ItemRenderer<never> =>
|
|
73
|
+
props.renderItem ?? defaultRenderItem;
|
|
74
|
+
|
|
75
|
+
const listRenderer = (props: DropDownRuntimeProps): ItemRenderer<never> =>
|
|
76
|
+
props.renderListItem ?? props.renderItem ?? defaultRenderItem;
|
|
77
|
+
|
|
78
|
+
const resolvePosition = (
|
|
79
|
+
widget: SelectableWidget,
|
|
80
|
+
collection: Collection,
|
|
81
|
+
selectedId: string | null | undefined,
|
|
82
|
+
): number => {
|
|
83
|
+
const requested = selectedId == null ? -1 : collection.positionFor(selectedId);
|
|
84
|
+
|
|
85
|
+
return requested >= 0 ? requested : widget.getSelected();
|
|
60
86
|
};
|
|
61
87
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
selectedId: string | null | undefined;
|
|
77
|
-
onSelectionChanged: ((id: string) => void) | null | undefined;
|
|
78
|
-
renderHeader: ((info: { section: S }) => ReactNode) | null | undefined;
|
|
79
|
-
}
|
|
88
|
+
const updateKnownSelection = (
|
|
89
|
+
tracker: KnownSelection,
|
|
90
|
+
effectiveId: string,
|
|
91
|
+
selectedId: string | null | undefined,
|
|
92
|
+
): void => {
|
|
93
|
+
const { known, onSelectionChanged } = tracker;
|
|
94
|
+
const expectedId = selectedId ?? known.current;
|
|
95
|
+
const isNew = effectiveId !== known.current;
|
|
96
|
+
known.current = effectiveId;
|
|
97
|
+
|
|
98
|
+
if (expectedId !== null && effectiveId !== expectedId && isNew) {
|
|
99
|
+
onSelectionChanged?.(effectiveId);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
80
102
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
listStore: CellContainerStore;
|
|
88
|
-
headerStore: CellContainerStore;
|
|
89
|
-
useHeader: boolean;
|
|
90
|
-
}
|
|
103
|
+
const reportKnownSelection = (tracker: KnownSelection, id: string | null): void => {
|
|
104
|
+
const { known, onSelectionChanged } = tracker;
|
|
105
|
+
|
|
106
|
+
if (id === null || id === known.current) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
91
109
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const captureWidget = useCallback((value: Gtk.DropDown | null) => {
|
|
96
|
-
widgetRef.current = value;
|
|
97
|
-
setWidget(value);
|
|
98
|
-
}, []);
|
|
99
|
-
const setRef = useMergeRefs<Gtk.DropDown>(props.ref, captureWidget);
|
|
110
|
+
known.current = id;
|
|
111
|
+
onSelectionChanged?.(id);
|
|
112
|
+
};
|
|
100
113
|
|
|
101
|
-
|
|
114
|
+
const reportSelectedNotify = (
|
|
115
|
+
options: SelectionOptions,
|
|
116
|
+
tracker: KnownSelection,
|
|
117
|
+
applying: RefObject<boolean>,
|
|
118
|
+
): void => {
|
|
119
|
+
const { widget, collection } = options;
|
|
102
120
|
|
|
103
|
-
|
|
121
|
+
if (widget === null || applying.current) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
104
124
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
125
|
+
reportKnownSelection(tracker, collection.idAt(widget.getSelected()));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const applySelectedPosition = (widget: SelectableWidget, position: number, applying: RefObject<boolean>): void => {
|
|
129
|
+
applying.current = true;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
widget.selected = position;
|
|
133
|
+
} finally {
|
|
134
|
+
applying.current = false;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const useDropDownSelection = (options: SelectionOptions): void => {
|
|
139
|
+
const { widget, collection, applying } = options;
|
|
140
|
+
const { selectedId } = options.props;
|
|
141
|
+
const known = useRef<string | null>(null);
|
|
111
142
|
|
|
112
|
-
|
|
143
|
+
const syncKnownSelection = useEffectEvent((position: number): void => {
|
|
144
|
+
const effectiveId = collection.idAt(position);
|
|
113
145
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
146
|
+
if (effectiveId === null) {
|
|
147
|
+
known.current = null;
|
|
148
|
+
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const { onSelectionChanged } = options.props;
|
|
153
|
+
updateKnownSelection({ known, onSelectionChanged }, effectiveId, selectedId);
|
|
119
154
|
});
|
|
120
155
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const selectionPosition =
|
|
126
|
-
controlledPosition >= 0 ? controlledPosition : selectedPosition < 0 ? 0 : selectedPosition;
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
setRef,
|
|
130
|
-
resolver: listModel.resolver,
|
|
131
|
-
selectionResolver: createSelectionResolver(listModel.resolver, selectionPosition),
|
|
132
|
-
headerResolver: listModel.headerResolver,
|
|
133
|
-
selectionStore,
|
|
134
|
-
listStore,
|
|
135
|
-
headerStore,
|
|
136
|
-
useHeader,
|
|
137
|
-
};
|
|
138
|
-
};
|
|
156
|
+
useLayoutEffect(() => {
|
|
157
|
+
if (widget === null) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
139
160
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
): ReactNode => {
|
|
148
|
-
const {
|
|
149
|
-
component,
|
|
150
|
-
ref,
|
|
151
|
-
items,
|
|
152
|
-
sections,
|
|
153
|
-
renderItem,
|
|
154
|
-
renderListItem,
|
|
155
|
-
renderHeader,
|
|
156
|
-
selectedId,
|
|
157
|
-
onSelectionChanged,
|
|
158
|
-
...intrinsicProps
|
|
159
|
-
} = props;
|
|
160
|
-
const Component: ElementType = component ?? GtkDropDown;
|
|
161
|
-
|
|
162
|
-
const wiring = useDropDownWiring<T, S>({
|
|
163
|
-
ref,
|
|
164
|
-
items,
|
|
165
|
-
sections,
|
|
166
|
-
selectedId,
|
|
167
|
-
onSelectionChanged,
|
|
168
|
-
renderHeader,
|
|
161
|
+
const position = resolvePosition(widget, collection, selectedId);
|
|
162
|
+
applySelectedPosition(widget, position, applying);
|
|
163
|
+
syncKnownSelection(position);
|
|
164
|
+
}, [widget, collection, selectedId, applying]);
|
|
165
|
+
|
|
166
|
+
useSignal(widget, "notify::selected", (): void => {
|
|
167
|
+
reportSelectedNotify(options, { known, onSelectionChanged: options.props.onSelectionChanged }, applying);
|
|
169
168
|
});
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
function DropDownImpl(props: DropDownRuntimeProps): ReactNode {
|
|
172
|
+
const { component, items, sections, renderListItem, renderHeader, ref } = props;
|
|
173
|
+
const rest = omit(props, DROP_DOWN_PROPS);
|
|
174
|
+
const [widget, refCallback] = useWidgetRef<SelectableWidget>(ref);
|
|
175
|
+
const applying = useRef(false);
|
|
176
|
+
const collection = useCollectionData({ items, sections, applying });
|
|
177
|
+
const faceCells = useItemCells({ width: -1, height: -1 });
|
|
178
|
+
const listCells = useItemCells({ width: -1, height: -1 });
|
|
179
|
+
const headerCells = useHeaderCells({ width: -1, height: -1 });
|
|
180
|
+
useDropDownSelection({ widget, collection, applying, props });
|
|
181
|
+
const Component = component ?? GtkDropDown;
|
|
182
|
+
const hasHeader = typeof renderHeader === "function";
|
|
170
183
|
|
|
171
184
|
return (
|
|
172
185
|
<>
|
|
173
|
-
<Component
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
render={toListRenderer<T, S>(renderListItem, renderItem)}
|
|
183
|
-
/>
|
|
184
|
-
<HeaderRenderHost
|
|
185
|
-
useHeader={wiring.useHeader}
|
|
186
|
-
store={wiring.headerStore}
|
|
187
|
-
resolver={wiring.headerResolver}
|
|
188
|
-
renderHeader={renderHeader}
|
|
186
|
+
<Component
|
|
187
|
+
ref={refCallback}
|
|
188
|
+
model={collection.model}
|
|
189
|
+
factory={<GtkSignalListItemFactory {...faceCells.handlers} />}
|
|
190
|
+
{...(renderListItem != null && {
|
|
191
|
+
listFactory: <GtkSignalListItemFactory {...listCells.handlers} />,
|
|
192
|
+
})}
|
|
193
|
+
{...(hasHeader && { headerFactory: <GtkSignalListItemFactory {...headerCells.handlers} /> })}
|
|
194
|
+
{...rest}
|
|
189
195
|
/>
|
|
196
|
+
<ItemPortals store={faceCells} render={faceRenderer(props)} collection={collection} />
|
|
197
|
+
{renderListItem != null && (
|
|
198
|
+
<ItemPortals store={listCells} render={listRenderer(props)} collection={collection} />
|
|
199
|
+
)}
|
|
200
|
+
{hasHeader && <HeaderPortals store={headerCells} render={renderHeader} collection={collection} />}
|
|
190
201
|
</>
|
|
191
202
|
);
|
|
192
|
-
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export { DropDown };
|
package/src/grid-view.tsx
CHANGED
|
@@ -1,81 +1,37 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { GtkGridView,
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Props for {@link GridView}. Combines the underlying Gtk.GridView props with
|
|
21
|
-
* declarative collection props: items, a per-cell renderItem, controlled selection,
|
|
22
|
-
* and estimated item sizing.
|
|
23
|
-
*/
|
|
24
|
-
export type GridViewProps<T = unknown> = Omit<
|
|
25
|
-
GtkGridViewProps,
|
|
26
|
-
"model" | "factory" | keyof GridViewDeclarativeProps<T>
|
|
27
|
-
> &
|
|
28
|
-
GridViewDeclarativeProps<T>;
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { GtkGridView, GtkSignalListItemFactory } from "@gtkx/jsx/gtk";
|
|
3
|
+
import { omit } from "@gtkx/utils";
|
|
4
|
+
import type { GridViewProps } from "./types.js";
|
|
5
|
+
import { ItemPortals, useItemCells } from "./internal/cells.js";
|
|
6
|
+
import { useCollection } from "./internal/use-collection.js";
|
|
7
|
+
|
|
8
|
+
const GRID_VIEW_PROPS = [
|
|
9
|
+
"items",
|
|
10
|
+
"renderItem",
|
|
11
|
+
"selectedIds",
|
|
12
|
+
"onSelectionChanged",
|
|
13
|
+
"selectionMode",
|
|
14
|
+
"estimatedItemHeight",
|
|
15
|
+
"estimatedItemWidth",
|
|
16
|
+
] as const satisfies (keyof GridViewProps)[];
|
|
29
17
|
|
|
30
18
|
/**
|
|
31
|
-
* Renders a Gtk.GridView
|
|
32
|
-
*
|
|
19
|
+
* Renders a Gtk.GridView of uniform cells from declarative items, with per-cell
|
|
20
|
+
* rendering, controlled selection, and estimated item sizing.
|
|
33
21
|
*/
|
|
34
|
-
|
|
35
|
-
const {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
selectionMode,
|
|
41
|
-
onSelectionChanged,
|
|
42
|
-
estimatedItemHeight,
|
|
43
|
-
estimatedItemWidth,
|
|
44
|
-
...intrinsicProps
|
|
45
|
-
} = props as GridViewDeclarativeProps<T> & {
|
|
46
|
-
ref?: Ref<Gtk.GridView | null>;
|
|
47
|
-
estimatedItemHeight?: number;
|
|
48
|
-
estimatedItemWidth?: number;
|
|
49
|
-
[key: string]: unknown;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const cellRenderer: CellRenderer<T, unknown> = itemRenderer<T, unknown>(renderItem);
|
|
53
|
-
|
|
54
|
-
const widgetRef = useRef<Gtk.GridView | null>(null);
|
|
55
|
-
const setRef = useMergeRefs<Gtk.GridView>(ref, widgetRef);
|
|
56
|
-
|
|
57
|
-
const collection = useCollectionModel<T, unknown>({
|
|
58
|
-
items,
|
|
59
|
-
sections: undefined,
|
|
60
|
-
selectionMode,
|
|
61
|
-
selectedIds,
|
|
62
|
-
onSelectionChanged,
|
|
63
|
-
renderHeader: undefined,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const itemStore = useCellContainers<Gtk.GridView>({
|
|
67
|
-
object: widgetRef,
|
|
68
|
-
installer: factoryInstaller,
|
|
69
|
-
estimatedHeight: estimatedItemHeight,
|
|
70
|
-
estimatedWidth: estimatedItemWidth,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
useInstalledModel(widgetRef, collection.installedModel, (widget, value) => widget.setModel(value));
|
|
22
|
+
function GridView<T = unknown>(props: GridViewProps<T>): ReactNode {
|
|
23
|
+
const { renderItem, estimatedItemHeight, estimatedItemWidth } = props;
|
|
24
|
+
const rest = omit(props, GRID_VIEW_PROPS);
|
|
25
|
+
const size = { width: estimatedItemWidth ?? -1, height: estimatedItemHeight ?? -1 };
|
|
26
|
+
const { collection, selection } = useCollection({ ...props, flat: true });
|
|
27
|
+
const itemCells = useItemCells(size);
|
|
74
28
|
|
|
75
29
|
return (
|
|
76
30
|
<>
|
|
77
|
-
<GtkGridView {
|
|
78
|
-
<
|
|
31
|
+
<GtkGridView model={selection} factory={<GtkSignalListItemFactory {...itemCells.handlers} />} {...rest} />
|
|
32
|
+
<ItemPortals store={itemCells} render={renderItem} collection={collection} />
|
|
79
33
|
</>
|
|
80
34
|
);
|
|
81
|
-
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { GridView };
|
package/src/index.ts
CHANGED
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type ColumnViewProps,
|
|
7
|
-
type ColumnViewSortProps,
|
|
8
|
-
} from "./column-view.js";
|
|
9
|
-
export { ConstraintLayout, type ConstraintLayoutProps } from "./constraint-layout.js";
|
|
10
|
-
export type { ConstraintGuideProps, ConstraintProps, ConstraintVflProps } from "./constraint-layout-apply.js";
|
|
11
|
-
export { DropDown, type DropDownDeclarativeProps, type DropDownItemRenderer, type DropDownProps } from "./drop-down.js";
|
|
12
|
-
export { Fixed, type FixedChildProps, type FixedPlacementProps, type FixedProps } from "./fixed.js";
|
|
13
|
-
export { Grid, type GridChildProps, type GridPlacement, type GridProps } from "./grid.js";
|
|
14
|
-
export { GridView, type GridViewDeclarativeProps, type GridViewProps } from "./grid-view.js";
|
|
15
|
-
export { ListView, type ListViewDeclarativeProps, type ListViewProps } from "./list-view.js";
|
|
16
|
-
export { Menu, type MenuItemsProps, type MenuProps } from "./menu.js";
|
|
17
|
-
export { Overlay, type OverlayChildProps, type OverlayPlacementProps, type OverlayProps } from "./overlay.js";
|
|
18
|
-
export { SizeGroup, type SizeGroupChildProps, type SizeGroupProps } from "./size-group.js";
|
|
1
|
+
export { ColumnView } from "./column-view.js";
|
|
2
|
+
export { DropDown } from "./drop-down.js";
|
|
3
|
+
export { GridView } from "./grid-view.js";
|
|
4
|
+
export { ListView } from "./list-view.js";
|
|
5
|
+
export { SizeGroup } from "./size-group.js";
|
|
19
6
|
export type {
|
|
20
7
|
ChildProps,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
Column,
|
|
9
|
+
ColumnViewProps,
|
|
10
|
+
DropDownProps,
|
|
11
|
+
GridViewProps,
|
|
12
|
+
HeaderRenderer,
|
|
13
|
+
Item,
|
|
14
|
+
ItemRenderer,
|
|
15
|
+
ListViewProps,
|
|
16
|
+
RenderHeaderArgs,
|
|
17
|
+
RenderItemArgs,
|
|
18
|
+
Section,
|
|
19
|
+
SizeGroupChildProps,
|
|
20
|
+
SizeGroupProps,
|
|
28
21
|
WidgetProps,
|
|
29
22
|
} from "./types.js";
|