@gtkx/components 2.0.0-beta.11 → 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 +4 -4
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +8 -4
- 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 +4 -3
- package/dist/grid-view.js.map +1 -1
- package/dist/internal/cells.d.ts +8 -9
- package/dist/internal/cells.d.ts.map +1 -1
- package/dist/internal/cells.js +98 -83
- 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 +61 -9
- 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/keys.d.ts.map +1 -1
- 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 +2 -1
- package/dist/internal/tree-order.d.ts.map +1 -1
- package/dist/internal/tree-order.js +3 -2
- 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/internal/use-widget-ref.d.ts.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 +3 -3
- package/dist/list-item-factory.js.map +1 -1
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +9 -4
- package/dist/list-view.js.map +1 -1
- package/dist/types.d.ts +35 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +10 -20
- package/src/column-view.tsx +8 -4
- package/src/combo-row.tsx +4 -1
- package/src/grid-view.tsx +3 -2
- package/src/internal/cells.tsx +174 -151
- 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 +112 -19
- 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 +43 -1
- package/src/internal/tree-order.ts +4 -10
- 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 +54 -24
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
2
|
import type { ReactElement } from "react";
|
|
3
3
|
import { GtkFlattenListModel } from "@gtkx/jsx/gtk";
|
|
4
|
+
import { useLatestRef } from "@gtkx/react/internal";
|
|
4
5
|
import { useLayoutEffect, useMemo, useState } from "react";
|
|
5
6
|
import type { ExpansionProps, ListItem, ListSection, SelectionProps } from "../types.js";
|
|
6
7
|
import type { Collection } from "./collection.js";
|
|
@@ -14,6 +15,7 @@ type CollectionDataOptions = {
|
|
|
14
15
|
items?: ListItem[] | undefined;
|
|
15
16
|
sections?: ListSection[] | undefined;
|
|
16
17
|
isFlat?: boolean | undefined;
|
|
18
|
+
onSectionsFilled?: (() => void) | undefined;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
type CollectionOptions = CollectionDataOptions & SelectionProps & ExpansionProps;
|
|
@@ -44,9 +46,13 @@ function useCollectionData(options: CollectionDataOptions): CollectionDataResult
|
|
|
44
46
|
return gtkModel.clear;
|
|
45
47
|
}, [gtkModel, root, model]);
|
|
46
48
|
|
|
49
|
+
const onSectionsFilled = useLatestRef(options.onSectionsFilled);
|
|
50
|
+
|
|
47
51
|
useLayoutEffect(() => {
|
|
48
|
-
gtkModel.sync(index)
|
|
49
|
-
|
|
52
|
+
gtkModel.sync(index, () => {
|
|
53
|
+
onSectionsFilled.current?.();
|
|
54
|
+
});
|
|
55
|
+
}, [gtkModel, index, root, model, onSectionsFilled]);
|
|
50
56
|
|
|
51
57
|
return {
|
|
52
58
|
collection,
|
|
@@ -10,6 +10,7 @@ import { NativeItemPortals, useItemCells } from "./internal/cells.js";
|
|
|
10
10
|
*/
|
|
11
11
|
function ListItemFactory<T extends GObject.Object>({
|
|
12
12
|
renderItem,
|
|
13
|
+
rowProps,
|
|
13
14
|
estimatedItemHeight = -1,
|
|
14
15
|
estimatedItemWidth = -1,
|
|
15
16
|
}: ListItemFactoryProps<T>): ReactNode {
|
|
@@ -19,7 +20,7 @@ function ListItemFactory<T extends GObject.Object>({
|
|
|
19
20
|
return (
|
|
20
21
|
<>
|
|
21
22
|
<GtkSignalListItemFactory {...cells.handlers} />
|
|
22
|
-
<NativeItemPortals registry={cells} render={renderItem} size={size} />
|
|
23
|
+
<NativeItemPortals registry={cells} render={renderItem} rowProps={rowProps} size={size} />
|
|
23
24
|
</>
|
|
24
25
|
);
|
|
25
26
|
}
|
package/src/list-view.tsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type * as Gtk from "@gtkx/gi/gtk";
|
|
1
2
|
import type { ReactNode } from "react";
|
|
2
3
|
import { GtkListView, GtkSignalListItemFactory } from "@gtkx/jsx/gtk";
|
|
3
4
|
import { omit } from "@gtkx/utils";
|
|
4
5
|
import type { ListViewProps } from "./types.js";
|
|
5
6
|
import { ItemPortals, useItemCells, useSectionHeader } from "./internal/cells.js";
|
|
7
|
+
import { showFirstHeader } from "./internal/first-header.js";
|
|
6
8
|
import { useCollection } from "./internal/use-collection.js";
|
|
9
|
+
import { useWidgetRef } from "./internal/use-widget-ref.js";
|
|
7
10
|
|
|
8
11
|
const LIST_VIEW_PROPS = [
|
|
9
12
|
"items",
|
|
@@ -11,6 +14,7 @@ const LIST_VIEW_PROPS = [
|
|
|
11
14
|
"isFlat",
|
|
12
15
|
"renderItem",
|
|
13
16
|
"renderHeader",
|
|
17
|
+
"rowProps",
|
|
14
18
|
"selectedIds",
|
|
15
19
|
"onSelectionChanged",
|
|
16
20
|
"selectionMode",
|
|
@@ -19,6 +23,7 @@ const LIST_VIEW_PROPS = [
|
|
|
19
23
|
"expanderDescriptions",
|
|
20
24
|
"estimatedItemHeight",
|
|
21
25
|
"estimatedItemWidth",
|
|
26
|
+
"ref",
|
|
22
27
|
] as const satisfies (keyof ListViewProps)[];
|
|
23
28
|
|
|
24
29
|
/**
|
|
@@ -26,17 +31,19 @@ const LIST_VIEW_PROPS = [
|
|
|
26
31
|
* controlled selection, controlled tree expansion, and estimated item sizing.
|
|
27
32
|
*/
|
|
28
33
|
function ListView<T = unknown, S = unknown>(props: ListViewProps<T, S>): ReactNode {
|
|
29
|
-
const { renderItem, renderHeader, expandedIds, expanderDescriptions } = props;
|
|
34
|
+
const { renderItem, renderHeader, rowProps, expandedIds, expanderDescriptions, ref } = props;
|
|
30
35
|
const { estimatedItemHeight, estimatedItemWidth } = props;
|
|
31
36
|
const rest = omit(props, LIST_VIEW_PROPS);
|
|
32
37
|
const size = { width: estimatedItemWidth ?? -1, height: estimatedItemHeight ?? -1 };
|
|
33
|
-
const
|
|
38
|
+
const [view, refCallback] = useWidgetRef<Gtk.ListView>(ref);
|
|
39
|
+
const { collection, selection } = useCollection({ ...props, onSectionsFilled: () => showFirstHeader(view) });
|
|
34
40
|
const itemCells = useItemCells(size);
|
|
35
41
|
const header = useSectionHeader(renderHeader, collection, size);
|
|
36
42
|
|
|
37
43
|
return (
|
|
38
44
|
<>
|
|
39
45
|
<GtkListView
|
|
46
|
+
ref={refCallback}
|
|
40
47
|
model={selection}
|
|
41
48
|
factory={<GtkSignalListItemFactory {...itemCells.handlers} />}
|
|
42
49
|
{...header.factoryProps}
|
|
@@ -45,6 +52,7 @@ function ListView<T = unknown, S = unknown>(props: ListViewProps<T, S>): ReactNo
|
|
|
45
52
|
<ItemPortals
|
|
46
53
|
registry={itemCells}
|
|
47
54
|
render={renderItem}
|
|
55
|
+
rowProps={rowProps}
|
|
48
56
|
collection={collection}
|
|
49
57
|
expandedIds={expandedIds}
|
|
50
58
|
expanderDescriptions={expanderDescriptions}
|
package/src/types.ts
CHANGED
|
@@ -17,7 +17,10 @@ import type { ReactNode, RefObject } from "react";
|
|
|
17
17
|
* arbitrary value. Nested items form a tree.
|
|
18
18
|
*/
|
|
19
19
|
type ListItem<T = unknown> = {
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Stable identifier that names the item in selection and expansion, so keep it unique across the collection.
|
|
22
|
+
* A row keeps its component state while its id stays among the same siblings.
|
|
23
|
+
*/
|
|
21
24
|
id: string;
|
|
22
25
|
/** Payload handed to the cell renderer as `ListItemRenderArgs.item`. */
|
|
23
26
|
value: T;
|
|
@@ -45,7 +48,10 @@ type ListSection<S = unknown, T = unknown> = {
|
|
|
45
48
|
type ListItemRenderArgs<T> = {
|
|
46
49
|
/** Value of the `ListItem` being rendered. */
|
|
47
50
|
item: T;
|
|
48
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Position of the item in the flattened item list, which excludes section headers and collapsed tree rows.
|
|
53
|
+
* A drop-down popup filtered by `enableSearch` still passes this position, not the row's place in the results.
|
|
54
|
+
*/
|
|
49
55
|
index: number;
|
|
50
56
|
/** Depth of the item within a tree, starting at zero for top-level items. */
|
|
51
57
|
depth?: number | undefined;
|
|
@@ -54,9 +60,10 @@ type ListItemRenderArgs<T> = {
|
|
|
54
60
|
};
|
|
55
61
|
|
|
56
62
|
/**
|
|
57
|
-
* Properties applied to the row that carries one item
|
|
58
|
-
*
|
|
59
|
-
* leaves the accessibility strings unset rather than
|
|
63
|
+
* Properties applied to the row that carries one item: the Gtk.ListItem of a list or grid, or the
|
|
64
|
+
* Gtk.ColumnViewRow of a table. Neither is a widget, so these are the only handles they offer; anything
|
|
65
|
+
* omitted falls back to the row's own default, which leaves the accessibility strings unset rather than
|
|
66
|
+
* setting them to an empty string.
|
|
60
67
|
*/
|
|
61
68
|
type ListRowProps = {
|
|
62
69
|
/** Name a screen reader announces for the row, through `accessible-label`. */
|
|
@@ -94,6 +101,14 @@ type ItemSizeProps = {
|
|
|
94
101
|
|
|
95
102
|
type ListItemFactoryProps<T extends GObject.Object> = ItemSizeProps & {
|
|
96
103
|
renderItem: ListItemRenderer<T>;
|
|
104
|
+
/** Resolves the props of the row carrying one model object, such as its screen-reader label. */
|
|
105
|
+
rowProps?: ListRowPropsResolver<T> | null | undefined;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** Per-row properties shared by the collection views. */
|
|
109
|
+
type RowPropsProps<T> = {
|
|
110
|
+
/** Resolves the props of the row carrying one item, such as its screen-reader label. */
|
|
111
|
+
rowProps?: ListRowPropsResolver<T> | null | undefined;
|
|
97
112
|
};
|
|
98
113
|
|
|
99
114
|
/** The flat-collection hint shared by {@link ListView} and {@link ColumnView}. */
|
|
@@ -113,7 +128,10 @@ type SelectionProps = {
|
|
|
113
128
|
* user's selection is adopted into it.
|
|
114
129
|
*/
|
|
115
130
|
selectedIds?: string[] | null | undefined;
|
|
116
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Called with one id per selected row when the user or the widget changes the selection, or when an item
|
|
133
|
+
* `selectedIds` names is not in the collection; a `selectedIds` change is not reported back.
|
|
134
|
+
*/
|
|
117
135
|
onSelectionChanged?: ((ids: string[]) => void) | null | undefined;
|
|
118
136
|
/** How much the user may select, one item at a time unless `MULTIPLE` or `NONE` is given. */
|
|
119
137
|
selectionMode?: Gtk.SelectionMode | null | undefined;
|
|
@@ -138,7 +156,10 @@ type ExpansionProps = {
|
|
|
138
156
|
* user's expansion is adopted into it.
|
|
139
157
|
*/
|
|
140
158
|
expandedIds?: string[] | null | undefined;
|
|
141
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Called with one id per expanded row, in visible order, when the user or the widget changes expansion, or
|
|
161
|
+
* when a row `expandedIds` names cannot expand; an `expandedIds` change is not reported back.
|
|
162
|
+
*/
|
|
142
163
|
onExpandedChange?: ((ids: string[]) => void) | null | undefined;
|
|
143
164
|
/**
|
|
144
165
|
* Wording announced for the expander of every row that can expand, describing what activating it does.
|
|
@@ -159,15 +180,18 @@ type SortProps = {
|
|
|
159
180
|
};
|
|
160
181
|
|
|
161
182
|
/** The data a collection view renders, either as a plain item list or grouped into sections. */
|
|
162
|
-
type SourceProps<T, S> =
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
type SourceProps<T, S> =
|
|
184
|
+
| ({
|
|
185
|
+
/** Items to render, nesting through `ListItem.children` for a tree. */
|
|
186
|
+
items?: ListItem<T>[] | undefined;
|
|
187
|
+
} & Partial<Record<"sections", undefined>> &
|
|
188
|
+
Partial<Record<"renderHeader", null | undefined>>)
|
|
189
|
+
| ({
|
|
190
|
+
/** Items grouped under section headers. */
|
|
191
|
+
sections: ListSection<S, T>[];
|
|
192
|
+
/** Renders the header shown above each section. */
|
|
193
|
+
renderHeader?: ListSectionRenderer<S> | null | undefined;
|
|
194
|
+
} & Partial<Record<"items", undefined>>);
|
|
171
195
|
|
|
172
196
|
/** One column of a {@link ColumnView}, pairing Gtk.ColumnViewColumn props with a cell renderer. */
|
|
173
197
|
type ColumnViewColumn<T = unknown> = Omit<GtkColumnViewColumnProps, "factory" | "sorter" | "id" | "title"> & {
|
|
@@ -179,6 +203,11 @@ type ColumnViewColumn<T = unknown> = Omit<GtkColumnViewColumnProps, "factory" |
|
|
|
179
203
|
renderCell: ListItemRenderer<T>;
|
|
180
204
|
/** Makes the column header clickable, reporting the choice through `onSortChanged`. */
|
|
181
205
|
isSortable?: boolean | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* Draws the tree expander and depth indentation in this column. Without a visible column marked this way,
|
|
208
|
+
* the first visible column draws them.
|
|
209
|
+
*/
|
|
210
|
+
hasExpander?: boolean | undefined;
|
|
182
211
|
/** Menu element popped up as the column header's context menu, on a right-click. */
|
|
183
212
|
headerMenu?: ReactNode;
|
|
184
213
|
};
|
|
@@ -189,11 +218,10 @@ type ColumnViewOwnProps<T, S> = SelectionProps &
|
|
|
189
218
|
SortProps &
|
|
190
219
|
SourceProps<T, S> &
|
|
191
220
|
FlatnessProps &
|
|
221
|
+
RowPropsProps<T> &
|
|
192
222
|
Omit<ItemSizeProps, "estimatedItemWidth"> & {
|
|
193
223
|
/** Columns to render, in order; each carries its own cell renderer. */
|
|
194
224
|
columns: ColumnViewColumn<T>[];
|
|
195
|
-
/** Resolves the props of the row carrying one item's cells, such as its screen-reader label. */
|
|
196
|
-
rowProps?: ListRowPropsResolver<T> | null | undefined;
|
|
197
225
|
};
|
|
198
226
|
|
|
199
227
|
/**
|
|
@@ -203,7 +231,7 @@ type ColumnViewProps<T = unknown, S = unknown> = Omit<
|
|
|
203
231
|
GtkColumnViewProps,
|
|
204
232
|
"children" | "columns" | "model" | "headerFactory" | "rowFactory" | keyof ColumnViewOwnProps<T, S>
|
|
205
233
|
> &
|
|
206
|
-
ColumnViewOwnProps<T, S>;
|
|
234
|
+
ColumnViewOwnProps<T, S>;
|
|
207
235
|
|
|
208
236
|
/** The declarative collection props {@link DropDown} and `ComboRow` add on top of their widget's own. */
|
|
209
237
|
type DropDownOwnProps<T, S> = SourceProps<T, S> & {
|
|
@@ -222,8 +250,8 @@ type DropDownWidgetProps<Widget, T, S> = Omit<
|
|
|
222
250
|
Widget,
|
|
223
251
|
"model" | "factory" | "listFactory" | "headerFactory" | keyof DropDownOwnProps<T, S>
|
|
224
252
|
> &
|
|
225
|
-
DropDownOwnProps<T, S> &
|
|
226
|
-
(SourceProps<T & Primitive, S> | Record<"renderItem", ListItemRenderer<T>>);
|
|
253
|
+
DropDownOwnProps<T, S> &
|
|
254
|
+
(SourceProps<T & Primitive, S> | Record<"renderItem", ListItemRenderer<T>>);
|
|
227
255
|
|
|
228
256
|
/**
|
|
229
257
|
* Native `Gtk.DropDown` props with declarative collections, controlled selection, and display/popup renderers.
|
|
@@ -232,7 +260,8 @@ type DropDownProps<T = unknown, S = unknown> = DropDownWidgetProps<GtkDropDownPr
|
|
|
232
260
|
|
|
233
261
|
/** The declarative collection props {@link GridView} adds on top of Gtk.GridView's own. */
|
|
234
262
|
type GridViewOwnProps<T> = ItemSizeProps &
|
|
235
|
-
SelectionProps &
|
|
263
|
+
SelectionProps &
|
|
264
|
+
RowPropsProps<T> & {
|
|
236
265
|
/** Items to render as cells; a grid is always flat, so `ListItem.children` is ignored. */
|
|
237
266
|
items?: ListItem<T>[] | undefined;
|
|
238
267
|
/** Renders the contents of one cell. */
|
|
@@ -250,7 +279,8 @@ type ListViewOwnProps<T, S> = ItemSizeProps &
|
|
|
250
279
|
SelectionProps &
|
|
251
280
|
ExpansionProps &
|
|
252
281
|
SourceProps<T, S> &
|
|
253
|
-
FlatnessProps &
|
|
282
|
+
FlatnessProps &
|
|
283
|
+
RowPropsProps<T> & {
|
|
254
284
|
/** Renders the contents of one row. */
|
|
255
285
|
renderItem: ListItemRenderer<T>;
|
|
256
286
|
};
|
|
@@ -263,7 +293,7 @@ type ListViewProps<T = unknown, S = unknown> = Omit<
|
|
|
263
293
|
GtkListViewProps,
|
|
264
294
|
"model" | "factory" | "headerFactory" | keyof ListViewOwnProps<T, S>
|
|
265
295
|
> &
|
|
266
|
-
ListViewOwnProps<T, S>;
|
|
296
|
+
ListViewOwnProps<T, S>;
|
|
267
297
|
|
|
268
298
|
/**
|
|
269
299
|
* Native `Adw.ComboRow` props with declarative collections, controlled selection, and display/popup renderers.
|