@gtkx/components 0.21.0 → 1.0.0-rc.1
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/LICENSE +373 -0
- package/README.md +173 -0
- package/dist/cell.d.ts +30 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +45 -0
- package/dist/cell.js.map +1 -0
- package/dist/column-view-column.d.ts +24 -14
- package/dist/column-view-column.d.ts.map +1 -1
- package/dist/column-view-column.js +19 -40
- package/dist/column-view-column.js.map +1 -1
- package/dist/column-view.d.ts +25 -11
- package/dist/column-view.d.ts.map +1 -1
- package/dist/column-view.js +53 -83
- package/dist/column-view.js.map +1 -1
- package/dist/constraint-layout-apply.d.ts +50 -1
- package/dist/constraint-layout-apply.d.ts.map +1 -1
- package/dist/constraint-layout-apply.js.map +1 -1
- package/dist/constraint-layout.d.ts +8 -1
- package/dist/constraint-layout.d.ts.map +1 -1
- package/dist/constraint-layout.js +12 -9
- package/dist/constraint-layout.js.map +1 -1
- package/dist/drop-down.d.ts +26 -36
- package/dist/drop-down.d.ts.map +1 -1
- package/dist/drop-down.js +47 -87
- package/dist/drop-down.js.map +1 -1
- package/dist/fixed.d.ts +26 -0
- package/dist/fixed.d.ts.map +1 -0
- package/dist/fixed.js +40 -0
- package/dist/fixed.js.map +1 -0
- package/dist/grid-view.d.ts +13 -10
- package/dist/grid-view.d.ts.map +1 -1
- package/dist/grid-view.js +30 -16
- package/dist/grid-view.js.map +1 -1
- package/dist/grid.d.ts +27 -0
- package/dist/grid.d.ts.map +1 -0
- package/dist/grid.js +48 -0
- package/dist/grid.js.map +1 -0
- package/dist/hooks/use-cell-containers.d.ts +18 -0
- package/dist/hooks/use-cell-containers.d.ts.map +1 -0
- package/dist/hooks/{use-realized-slots.js → use-cell-containers.js} +18 -17
- package/dist/hooks/use-cell-containers.js.map +1 -0
- package/dist/hooks/use-collection-model.d.ts +26 -0
- package/dist/hooks/use-collection-model.d.ts.map +1 -0
- package/dist/hooks/use-collection-model.js +35 -0
- package/dist/hooks/use-collection-model.js.map +1 -0
- package/dist/hooks/use-collection-widget.d.ts +28 -0
- package/dist/hooks/use-collection-widget.d.ts.map +1 -0
- package/dist/hooks/use-collection-widget.js +21 -0
- package/dist/hooks/use-collection-widget.js.map +1 -0
- package/dist/hooks/use-drop-down-selection.d.ts +7 -6
- package/dist/hooks/use-drop-down-selection.d.ts.map +1 -1
- package/dist/hooks/use-drop-down-selection.js +6 -6
- package/dist/hooks/use-drop-down-selection.js.map +1 -1
- package/dist/hooks/use-expansion-model.d.ts +12 -0
- package/dist/hooks/use-expansion-model.d.ts.map +1 -0
- package/dist/hooks/use-expansion-model.js +71 -0
- package/dist/hooks/use-expansion-model.js.map +1 -0
- package/dist/hooks/use-header-menu.d.ts.map +1 -1
- package/dist/hooks/use-header-menu.js +12 -24
- package/dist/hooks/use-header-menu.js.map +1 -1
- package/dist/hooks/use-installed-model.d.ts +4 -0
- package/dist/hooks/use-installed-model.d.ts.map +1 -0
- package/dist/hooks/use-installed-model.js +15 -0
- package/dist/hooks/use-installed-model.js.map +1 -0
- package/dist/hooks/use-list-model.d.ts +14 -15
- package/dist/hooks/use-list-model.d.ts.map +1 -1
- package/dist/hooks/use-list-model.js +61 -34
- package/dist/hooks/use-list-model.js.map +1 -1
- package/dist/hooks/use-placed-child.d.ts +18 -0
- package/dist/hooks/use-placed-child.d.ts.map +1 -0
- package/dist/hooks/use-placed-child.js +47 -0
- package/dist/hooks/use-placed-child.js.map +1 -0
- package/dist/hooks/use-selection-model.d.ts +4 -3
- package/dist/hooks/use-selection-model.d.ts.map +1 -1
- package/dist/hooks/use-selection-model.js +8 -16
- package/dist/hooks/use-selection-model.js.map +1 -1
- package/dist/hooks/use-sort-handler.d.ts +10 -5
- package/dist/hooks/use-sort-handler.d.ts.map +1 -1
- package/dist/hooks/use-sort-handler.js +2 -2
- package/dist/hooks/use-sort-handler.js.map +1 -1
- package/dist/index.d.ts +11 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -13
- package/dist/index.js.map +1 -1
- package/dist/list-view.d.ts +17 -9
- package/dist/list-view.d.ts.map +1 -1
- package/dist/list-view.js +49 -24
- package/dist/list-view.js.map +1 -1
- package/dist/menu-items.d.ts.map +1 -1
- package/dist/menu-items.js.map +1 -1
- package/dist/menu.d.ts +6 -10
- package/dist/menu.d.ts.map +1 -1
- package/dist/menu.js +7 -9
- package/dist/menu.js.map +1 -1
- package/dist/overlay.d.ts +24 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +49 -0
- package/dist/overlay.js.map +1 -0
- package/dist/size-group.d.ts +20 -0
- package/dist/size-group.d.ts.map +1 -0
- package/dist/size-group.js +57 -0
- package/dist/size-group.js.map +1 -0
- package/dist/types.d.ts +43 -173
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/{realized-slot-store.d.ts → cell-container-store.d.ts} +7 -9
- package/dist/utils/cell-container-store.d.ts.map +1 -0
- package/dist/utils/{realized-slot-store.js → cell-container-store.js} +9 -14
- package/dist/utils/cell-container-store.js.map +1 -0
- package/dist/utils/item-models.d.ts +10 -0
- package/dist/utils/item-models.d.ts.map +1 -0
- package/dist/utils/{position-only-model.js → item-models.js} +13 -14
- package/dist/utils/item-models.js.map +1 -0
- package/dist/utils/item-resolver.d.ts +14 -17
- package/dist/utils/item-resolver.d.ts.map +1 -1
- package/dist/utils/item-resolver.js +34 -43
- package/dist/utils/item-resolver.js.map +1 -1
- package/dist/utils/list-item-flatten.d.ts +16 -24
- package/dist/utils/list-item-flatten.d.ts.map +1 -1
- package/dist/utils/list-item-flatten.js +16 -36
- package/dist/utils/list-item-flatten.js.map +1 -1
- package/package.json +52 -53
- package/src/cell.tsx +144 -0
- package/src/column-view-column.tsx +57 -48
- package/src/column-view.tsx +130 -146
- package/src/constraint-layout-apply.ts +53 -1
- package/src/constraint-layout.tsx +18 -13
- package/src/drop-down.tsx +129 -196
- package/src/fixed.tsx +86 -0
- package/src/grid-view.tsx +52 -44
- package/src/grid.tsx +88 -0
- package/src/hooks/{use-realized-slots.ts → use-cell-containers.ts} +30 -30
- package/src/hooks/use-collection-model.ts +60 -0
- package/src/hooks/use-collection-widget.ts +47 -0
- package/src/hooks/use-drop-down-selection.ts +12 -13
- package/src/hooks/use-expansion-model.ts +82 -0
- package/src/hooks/use-header-menu.ts +24 -23
- package/src/hooks/use-installed-model.ts +20 -0
- package/src/hooks/use-list-model.ts +103 -87
- package/src/hooks/use-placed-child.ts +79 -0
- package/src/hooks/use-selection-model.ts +11 -18
- package/src/hooks/use-sort-handler.ts +13 -8
- package/src/index.ts +25 -27
- package/src/list-view.tsx +120 -57
- package/src/menu.tsx +12 -14
- package/src/overlay.tsx +88 -0
- package/src/size-group.tsx +96 -0
- package/src/types.ts +55 -206
- package/src/utils/{realized-slot-store.ts → cell-container-store.ts} +13 -25
- package/src/utils/{position-only-model.ts → item-models.ts} +26 -28
- package/src/utils/item-resolver.ts +54 -59
- package/src/utils/list-item-flatten.ts +33 -56
- package/dist/collection-view.d.ts +0 -30
- package/dist/collection-view.d.ts.map +0 -1
- package/dist/collection-view.js +0 -52
- package/dist/collection-view.js.map +0 -1
- package/dist/contexts/column-view-context.d.ts +0 -17
- package/dist/contexts/column-view-context.d.ts.map +0 -1
- package/dist/contexts/column-view-context.js +0 -10
- package/dist/contexts/column-view-context.js.map +0 -1
- package/dist/hooks/use-model-installation.d.ts +0 -9
- package/dist/hooks/use-model-installation.d.ts.map +0 -1
- package/dist/hooks/use-model-installation.js +0 -20
- package/dist/hooks/use-model-installation.js.map +0 -1
- package/dist/hooks/use-realized-slots.d.ts +0 -20
- package/dist/hooks/use-realized-slots.d.ts.map +0 -1
- package/dist/hooks/use-realized-slots.js.map +0 -1
- package/dist/list-portal-host.d.ts +0 -11
- package/dist/list-portal-host.d.ts.map +0 -1
- package/dist/list-portal-host.js +0 -8
- package/dist/list-portal-host.js.map +0 -1
- package/dist/list-slot.d.ts +0 -14
- package/dist/list-slot.d.ts.map +0 -1
- package/dist/list-slot.js +0 -29
- package/dist/list-slot.js.map +0 -1
- package/dist/utils/position-only-model.d.ts +0 -10
- package/dist/utils/position-only-model.d.ts.map +0 -1
- package/dist/utils/position-only-model.js.map +0 -1
- package/dist/utils/realized-slot-store.d.ts.map +0 -1
- package/dist/utils/realized-slot-store.js.map +0 -1
- package/src/collection-view.tsx +0 -125
- package/src/contexts/column-view-context.ts +0 -28
- package/src/hooks/use-model-installation.ts +0 -25
- package/src/list-portal-host.tsx +0 -27
- package/src/list-slot.tsx +0 -56
package/src/types.ts
CHANGED
|
@@ -1,227 +1,76 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/gi/gio";
|
|
2
|
-
import type * as GObject from "@gtkx/gi/gobject";
|
|
3
1
|
import type * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import type {
|
|
2
|
+
import type { ComponentPropsWithRef, ElementType } from "react";
|
|
3
|
+
|
|
4
|
+
/** Props of a container's Child component: the widget to render, its own props, and any placement props. */
|
|
5
|
+
export type ChildProps<C extends ElementType, Placement = unknown> = Placement & {
|
|
6
|
+
component: C;
|
|
7
|
+
} & Omit<ComponentPropsWithRef<C>, keyof Placement>;
|
|
8
|
+
|
|
9
|
+
/** Props of a component whose backing widget defaults to one type but can be swapped through `component`. */
|
|
10
|
+
export type WidgetProps<C extends ElementType, Own = unknown, ExtraOmit extends string = never> = Own & {
|
|
11
|
+
component?: C;
|
|
12
|
+
} & Omit<ComponentPropsWithRef<C>, ExtraOmit | keyof Own>;
|
|
5
13
|
|
|
6
14
|
/**
|
|
7
|
-
* A
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* A non-section item carries an arbitrary value of type `T` and may declare
|
|
11
|
-
* tree `children`. A section item carries a value of type `S` and groups a list
|
|
12
|
-
* of child items underneath a header.
|
|
15
|
+
* A single item in a collection model, identified by a stable id and holding an
|
|
16
|
+
* arbitrary value. Nested items form a tree.
|
|
13
17
|
*/
|
|
14
|
-
export type
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
export type ItemNode<T = unknown> = {
|
|
19
|
+
/** Stable identifier used to track the item across updates and selection. */
|
|
20
|
+
id: string;
|
|
21
|
+
value: T;
|
|
22
|
+
children?: ItemNode<T>[] | undefined;
|
|
23
|
+
/** Hides the tree expander arrow even when the item has children. */
|
|
24
|
+
hideExpander?: boolean | undefined;
|
|
25
|
+
/** Adds indentation matching the item's depth in the tree. */
|
|
26
|
+
indentForDepth?: boolean | undefined;
|
|
27
|
+
/** Reserves indentation space for an expander icon. */
|
|
28
|
+
indentForIcon?: boolean | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** A group of items rendered under a shared section header. */
|
|
32
|
+
export type SectionNode<S = unknown, T = unknown> = {
|
|
33
|
+
/** Stable identifier used to track the section across updates. */
|
|
34
|
+
id: string;
|
|
35
|
+
value: S;
|
|
36
|
+
/** Items belonging to this section. */
|
|
37
|
+
data: ItemNode<T>[];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Props passed to a renderItem callback when rendering one cell. */
|
|
41
|
+
export type RenderItemProps<T> = {
|
|
42
|
+
item: T;
|
|
43
|
+
index: number;
|
|
44
|
+
/** Depth of the item within a tree, starting at zero for top-level items. */
|
|
45
|
+
depth?: number | undefined;
|
|
46
|
+
/** Whether the item is currently expanded in a tree view. */
|
|
47
|
+
isExpanded?: boolean | undefined;
|
|
48
|
+
};
|
|
30
49
|
|
|
31
|
-
type
|
|
50
|
+
export type CollectionItemSizeProps = {
|
|
32
51
|
estimatedItemHeight?: number | undefined;
|
|
33
52
|
estimatedItemWidth?: number | undefined;
|
|
34
53
|
};
|
|
35
54
|
|
|
36
|
-
type
|
|
37
|
-
|
|
55
|
+
export type ControlledSelectionProps = {
|
|
56
|
+
selectedIds?: string[] | null | undefined;
|
|
38
57
|
onSelectionChanged?: ((ids: string[]) => void) | null | undefined;
|
|
39
58
|
selectionMode?: Gtk.SelectionMode | null | undefined;
|
|
40
59
|
};
|
|
41
60
|
|
|
42
|
-
type
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* Props for the {@link ListView} component, replacing the raw `GtkListView`
|
|
46
|
-
* factory/model surface with a declarative `items`/`renderItem` API, optional
|
|
47
|
-
* controlled selection, section headers, and tree autoexpansion. Supplying an
|
|
48
|
-
* external `model` switches to the uncontrolled form.
|
|
49
|
-
*/
|
|
50
|
-
export type ListViewProps<T = unknown, S = unknown> = ListViewSharedProps &
|
|
51
|
-
(
|
|
52
|
-
| (ListViewControlledSelectionProps & {
|
|
53
|
-
items?: ListItem<T, S>[] | undefined;
|
|
54
|
-
renderItem: (item: T, row?: Gtk.TreeListRow | null) => ReactNode;
|
|
55
|
-
autoexpand?: boolean | undefined;
|
|
56
|
-
renderHeader?: ((item: S) => ReactNode) | null | undefined;
|
|
57
|
-
model?: never;
|
|
58
|
-
})
|
|
59
|
-
| {
|
|
60
|
-
model: Gio.ListModel;
|
|
61
|
-
renderItem: (item: UncontrolledItemType<T>) => ReactNode;
|
|
62
|
-
items?: never;
|
|
63
|
-
autoexpand?: never;
|
|
64
|
-
renderHeader?: never;
|
|
65
|
-
selected?: never;
|
|
66
|
-
onSelectionChanged?: never;
|
|
67
|
-
selectionMode?: never;
|
|
68
|
-
}
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Props for the {@link GridView} component, replacing the raw `GtkGridView`
|
|
73
|
-
* factory/model surface with a declarative `items`/`renderItem` API and
|
|
74
|
-
* optional controlled selection. Supplying an external `model` switches to the
|
|
75
|
-
* uncontrolled form.
|
|
76
|
-
*/
|
|
77
|
-
export type GridViewProps<T = unknown> = ListViewSharedProps &
|
|
78
|
-
(
|
|
79
|
-
| (ListViewControlledSelectionProps & {
|
|
80
|
-
items?: ListItem<T>[] | undefined;
|
|
81
|
-
renderItem: (item: T) => ReactNode;
|
|
82
|
-
model?: never;
|
|
83
|
-
})
|
|
84
|
-
| {
|
|
85
|
-
model: Gio.ListModel;
|
|
86
|
-
renderItem: (item: UncontrolledItemType<T>) => ReactNode;
|
|
87
|
-
items?: never;
|
|
88
|
-
selected?: never;
|
|
89
|
-
onSelectionChanged?: never;
|
|
90
|
-
selectionMode?: never;
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
type ColumnViewSortProps = {
|
|
95
|
-
sortColumn?: string | null | undefined;
|
|
96
|
-
sortOrder?: Gtk.SortType | null | undefined;
|
|
97
|
-
onSortChanged?: ((column: string | null, order: Gtk.SortType) => void) | null | undefined;
|
|
98
|
-
estimatedRowHeight?: number | null | undefined;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Props for the {@link ColumnView} component, replacing the raw `GtkColumnView`
|
|
103
|
-
* surface with a declarative `items` model, optional controlled selection,
|
|
104
|
-
* controlled sorting, and section headers. Columns are declared as
|
|
105
|
-
* {@link ColumnViewColumn} children. Supplying an external `model` switches to
|
|
106
|
-
* the uncontrolled form.
|
|
107
|
-
*/
|
|
108
|
-
export type ColumnViewProps<T = unknown, S = unknown> = ColumnViewSortProps &
|
|
109
|
-
(
|
|
110
|
-
| (ListViewControlledSelectionProps & {
|
|
111
|
-
items?: ListItem<T, S>[] | undefined;
|
|
112
|
-
renderHeader?: ((item: S) => ReactNode) | null | undefined;
|
|
113
|
-
model?: never;
|
|
114
|
-
})
|
|
115
|
-
| {
|
|
116
|
-
model: Gio.ListModel;
|
|
117
|
-
items?: never;
|
|
118
|
-
renderHeader?: never;
|
|
119
|
-
selected?: never;
|
|
120
|
-
onSelectionChanged?: never;
|
|
121
|
-
selectionMode?: never;
|
|
122
|
-
}
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Props for a single {@link ColumnViewColumn} of a {@link ColumnView},
|
|
127
|
-
* replacing the raw `GtkColumnViewColumn` factory/sorter surface with a
|
|
128
|
-
* declarative `renderCell` callback and an optional header context menu.
|
|
129
|
-
*/
|
|
130
|
-
export type ColumnViewColumnProps<T = unknown> = {
|
|
131
|
-
title: string;
|
|
132
|
-
expand?: boolean | undefined;
|
|
133
|
-
resizable?: boolean | undefined;
|
|
134
|
-
fixedWidth?: number | undefined;
|
|
135
|
-
id: string;
|
|
136
|
-
sortable?: boolean | undefined;
|
|
137
|
-
visible?: boolean | undefined;
|
|
138
|
-
renderCell: (item: T) => ReactNode;
|
|
139
|
-
headerMenu?: ReactNode;
|
|
61
|
+
export type ControlledExpansionProps = {
|
|
62
|
+
expandedIds?: string[] | null | undefined;
|
|
63
|
+
onExpandedChange?: ((ids: string[]) => void) | null | undefined;
|
|
140
64
|
};
|
|
141
65
|
|
|
142
|
-
/**
|
|
143
|
-
* Props shared by the {@link DropDown} and {@link ComboRow} components,
|
|
144
|
-
* replacing the raw factory/model surface with declarative `items`, controlled
|
|
145
|
-
* `selectedId`, and per-slot renderers for the selected face, the popup list,
|
|
146
|
-
* and section headers. Supplying an external `model` switches to the
|
|
147
|
-
* uncontrolled form.
|
|
148
|
-
*/
|
|
149
|
-
export type DropDownProps<T = unknown, S = unknown> =
|
|
150
|
-
| {
|
|
151
|
-
items?: ListItem<T, S>[] | undefined;
|
|
152
|
-
selectedId?: string | null | undefined;
|
|
153
|
-
onSelectionChanged?: ((id: string) => void) | null | undefined;
|
|
154
|
-
renderItem?: ((item: T) => ReactNode) | null | undefined;
|
|
155
|
-
renderListItem?: ((item: T) => ReactNode) | null | undefined;
|
|
156
|
-
renderHeader?: ((item: S) => ReactNode) | null | undefined;
|
|
157
|
-
model?: never;
|
|
158
|
-
}
|
|
159
|
-
| {
|
|
160
|
-
model: Gio.ListModel;
|
|
161
|
-
renderItem?: ((item: UncontrolledItemType<T>) => ReactNode) | null | undefined;
|
|
162
|
-
renderListItem?: ((item: UncontrolledItemType<T>) => ReactNode) | null | undefined;
|
|
163
|
-
items?: never;
|
|
164
|
-
selectedId?: never;
|
|
165
|
-
onSelectionChanged?: never;
|
|
166
|
-
renderHeader?: never;
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* A single declarative entry in a {@link Menu} model. An entry is a plain item
|
|
171
|
-
* (`label` plus `action`), a `submenu`, or a `section` of nested entries.
|
|
172
|
-
*/
|
|
66
|
+
/** Declarative description of a single menu item, optionally nesting a submenu or section. */
|
|
173
67
|
export type MenuEntry = {
|
|
68
|
+
/** Text shown for the item. */
|
|
174
69
|
label?: string | undefined;
|
|
70
|
+
/** Action name activated when the item is chosen, for example "app.quit". */
|
|
175
71
|
action?: string | undefined;
|
|
72
|
+
/** Nested entries shown as a submenu opened from this item. */
|
|
176
73
|
submenu?: MenuEntry[] | undefined;
|
|
74
|
+
/** Nested entries grouped as a visually separated section. */
|
|
177
75
|
section?: MenuEntry[] | undefined;
|
|
178
76
|
};
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The declarative menu-model surface added by the {@link Menu} component on top
|
|
182
|
-
* of the raw `GMenu` element.
|
|
183
|
-
*/
|
|
184
|
-
export type MenuItemsProps = {
|
|
185
|
-
items?: MenuEntry[] | null | undefined;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Props for a `<ConstraintLayout.Constraint>` declaring a single relation
|
|
190
|
-
* between a target attribute and a source attribute within a
|
|
191
|
-
* {@link ConstraintLayout}.
|
|
192
|
-
*/
|
|
193
|
-
export type ConstraintProps = {
|
|
194
|
-
target?: string;
|
|
195
|
-
targetAttribute: Gtk.ConstraintAttribute;
|
|
196
|
-
relation?: Gtk.ConstraintRelation;
|
|
197
|
-
source?: string;
|
|
198
|
-
sourceAttribute?: Gtk.ConstraintAttribute;
|
|
199
|
-
multiplier?: number;
|
|
200
|
-
constant?: number;
|
|
201
|
-
strength?: number;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Props for a `<ConstraintLayout.Guide>` declaring an invisible layout guide
|
|
206
|
-
* that other constraints can reference by `id` within a {@link ConstraintLayout}.
|
|
207
|
-
*/
|
|
208
|
-
export type ConstraintGuideProps = {
|
|
209
|
-
id: string;
|
|
210
|
-
minWidth?: number;
|
|
211
|
-
minHeight?: number;
|
|
212
|
-
natWidth?: number;
|
|
213
|
-
natHeight?: number;
|
|
214
|
-
maxWidth?: number;
|
|
215
|
-
maxHeight?: number;
|
|
216
|
-
strength?: Gtk.ConstraintStrength;
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Props for a `<ConstraintLayout.Vfl>` declaring constraints through the GTK
|
|
221
|
-
* Visual Format Language within a {@link ConstraintLayout}.
|
|
222
|
-
*/
|
|
223
|
-
export type ConstraintVflProps = {
|
|
224
|
-
lines: string[];
|
|
225
|
-
hspacing?: number;
|
|
226
|
-
vspacing?: number;
|
|
227
|
-
};
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
2
|
import type * as Gtk from "@gtkx/gi/gtk";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
container: GObject.Object;
|
|
4
|
+
export type CellEntry = {
|
|
6
5
|
position: number;
|
|
7
6
|
treeRow: Gtk.TreeListRow | null;
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
};
|
|
10
8
|
|
|
11
9
|
let nextKey = 0;
|
|
12
10
|
|
|
13
|
-
export class
|
|
14
|
-
private entries = new Map<GObject.Object,
|
|
11
|
+
export class CellContainerStore {
|
|
12
|
+
private entries = new Map<GObject.Object, CellEntry>();
|
|
15
13
|
|
|
16
|
-
private published = new Map<GObject.Object,
|
|
14
|
+
private published = new Map<GObject.Object, CellEntry>();
|
|
17
15
|
|
|
18
16
|
private setListeners = new Set<() => void>();
|
|
19
17
|
|
|
@@ -32,7 +30,7 @@ export class RealizedSlotStore {
|
|
|
32
30
|
};
|
|
33
31
|
};
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
getContainersSnapshot = (): GObject.Object[] => this.snapshot;
|
|
36
34
|
|
|
37
35
|
subscribePosition = (container: GObject.Object, onChange: () => void): (() => void) => {
|
|
38
36
|
let listeners = this.positionListeners.get(container);
|
|
@@ -49,10 +47,10 @@ export class RealizedSlotStore {
|
|
|
49
47
|
};
|
|
50
48
|
};
|
|
51
49
|
|
|
52
|
-
getPosition = (container: GObject.Object):
|
|
50
|
+
getPosition = (container: GObject.Object): CellEntry => {
|
|
53
51
|
let entry = this.published.get(container);
|
|
54
52
|
if (entry === undefined) {
|
|
55
|
-
entry = {
|
|
53
|
+
entry = { position: -1, treeRow: null };
|
|
56
54
|
this.published.set(container, entry);
|
|
57
55
|
}
|
|
58
56
|
return entry;
|
|
@@ -61,35 +59,25 @@ export class RealizedSlotStore {
|
|
|
61
59
|
keyFor = (container: GObject.Object): string => {
|
|
62
60
|
const existing = this.keys.get(container);
|
|
63
61
|
if (existing !== undefined) return existing;
|
|
64
|
-
const key = `
|
|
62
|
+
const key = `cell-${nextKey++}`;
|
|
65
63
|
this.keys.set(container, key);
|
|
66
64
|
return key;
|
|
67
65
|
};
|
|
68
66
|
|
|
69
67
|
addContainer = (container: GObject.Object): void => {
|
|
70
68
|
if (this.entries.has(container)) return;
|
|
71
|
-
this.entries.set(container, {
|
|
69
|
+
this.entries.set(container, { position: -1, treeRow: null });
|
|
72
70
|
this.notifySet();
|
|
73
71
|
};
|
|
74
72
|
|
|
75
|
-
bind = (
|
|
76
|
-
container
|
|
77
|
-
position: number,
|
|
78
|
-
treeRow: Gtk.TreeListRow | null,
|
|
79
|
-
item: GObject.Object | null,
|
|
80
|
-
): void => {
|
|
81
|
-
if (!this.entries.has(container)) {
|
|
82
|
-
this.entries.set(container, { container, position, treeRow, item });
|
|
83
|
-
this.notifySet();
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
this.entries.set(container, { container, position, treeRow, item });
|
|
73
|
+
bind = (container: GObject.Object, position: number, treeRow: Gtk.TreeListRow | null): void => {
|
|
74
|
+
this.entries.set(container, { position, treeRow });
|
|
87
75
|
this.notifyPosition(container);
|
|
88
76
|
};
|
|
89
77
|
|
|
90
78
|
unbind = (container: GObject.Object): void => {
|
|
91
79
|
if (!this.entries.has(container)) return;
|
|
92
|
-
this.entries.set(container, {
|
|
80
|
+
this.entries.set(container, { position: -1, treeRow: null });
|
|
93
81
|
this.notifyPosition(container);
|
|
94
82
|
};
|
|
95
83
|
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import * as Gio from "@gtkx/gi/gio";
|
|
2
2
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
3
3
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ItemNode, SectionNode } from "../types.js";
|
|
5
5
|
import type { RowValue } from "./item-resolver.js";
|
|
6
|
-
import { treeItemMetadata } from "./list-item-flatten.js";
|
|
6
|
+
import { countDescendants, treeItemMetadata } from "./list-item-flatten.js";
|
|
7
7
|
|
|
8
8
|
const emptyStrings = (count: number): string[] => new Array<string>(Math.max(0, count)).fill("");
|
|
9
9
|
|
|
10
|
-
export const retagRows = <T
|
|
11
|
-
items:
|
|
12
|
-
rowValues: WeakMap<GObject.Object, RowValue<T
|
|
10
|
+
export const retagRows = <T>(
|
|
11
|
+
items: ItemNode<T>[],
|
|
12
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
13
13
|
placeholdersById: Map<string, GObject.Object>,
|
|
14
14
|
): void => {
|
|
15
|
-
const walk = (list:
|
|
15
|
+
const walk = (list: ItemNode<T>[]): void => {
|
|
16
16
|
for (const item of list) {
|
|
17
17
|
const placeholder = placeholdersById.get(item.id);
|
|
18
18
|
if (placeholder !== undefined) {
|
|
19
19
|
rowValues.set(placeholder, {
|
|
20
20
|
id: item.id,
|
|
21
21
|
value: item.value,
|
|
22
|
-
isHeader: item.section === true,
|
|
23
22
|
metadata: treeItemMetadata(item),
|
|
24
23
|
});
|
|
25
24
|
}
|
|
@@ -42,9 +41,9 @@ export const resizeFlatModel = (model: Gtk.StringList, count: number): void => {
|
|
|
42
41
|
model.splice(target, current - target, null);
|
|
43
42
|
};
|
|
44
43
|
|
|
45
|
-
const createTaggedRow = <T
|
|
46
|
-
row: RowValue<T
|
|
47
|
-
rowValues: WeakMap<GObject.Object, RowValue<T
|
|
44
|
+
const createTaggedRow = <T>(
|
|
45
|
+
row: RowValue<T>,
|
|
46
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
48
47
|
placeholdersById?: Map<string, GObject.Object>,
|
|
49
48
|
): GObject.Object => {
|
|
50
49
|
const placeholder = Gtk.StringObject.new("");
|
|
@@ -53,16 +52,16 @@ const createTaggedRow = <T, S>(
|
|
|
53
52
|
return placeholder;
|
|
54
53
|
};
|
|
55
54
|
|
|
56
|
-
const childModelOf = <T
|
|
57
|
-
children:
|
|
58
|
-
rowValues: WeakMap<GObject.Object, RowValue<T
|
|
55
|
+
const childModelOf = <T>(
|
|
56
|
+
children: ItemNode<T>[],
|
|
57
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
59
58
|
placeholdersById: Map<string, GObject.Object>,
|
|
60
59
|
): Gio.ListStore => {
|
|
61
|
-
const store = Gio.ListStore.new(Gtk.StringObject.prototype.
|
|
60
|
+
const store = Gio.ListStore.new(Gtk.StringObject.prototype.__type__);
|
|
62
61
|
for (const child of children) {
|
|
63
62
|
store.append(
|
|
64
63
|
createTaggedRow(
|
|
65
|
-
{ id: child.id, value: child.value,
|
|
64
|
+
{ id: child.id, value: child.value, metadata: treeItemMetadata(child) },
|
|
66
65
|
rowValues,
|
|
67
66
|
placeholdersById,
|
|
68
67
|
),
|
|
@@ -71,17 +70,16 @@ const childModelOf = <T, S>(
|
|
|
71
70
|
return store;
|
|
72
71
|
};
|
|
73
72
|
|
|
74
|
-
export const createTreeModel = <T
|
|
75
|
-
items:
|
|
76
|
-
|
|
77
|
-
rowValues: WeakMap<GObject.Object, RowValue<T, S>>,
|
|
73
|
+
export const createTreeModel = <T>(
|
|
74
|
+
items: ItemNode<T>[],
|
|
75
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
78
76
|
placeholdersById: Map<string, GObject.Object>,
|
|
79
77
|
): Gtk.TreeListModel => {
|
|
80
|
-
const childrenByRow = new WeakMap<GObject.Object,
|
|
81
|
-
const root = Gio.ListStore.new(Gtk.StringObject.prototype.
|
|
78
|
+
const childrenByRow = new WeakMap<GObject.Object, ItemNode<T>[]>();
|
|
79
|
+
const root = Gio.ListStore.new(Gtk.StringObject.prototype.__type__);
|
|
82
80
|
for (const item of items) {
|
|
83
81
|
const placeholder = createTaggedRow(
|
|
84
|
-
{ id: item.id, value: item.value,
|
|
82
|
+
{ id: item.id, value: item.value, metadata: treeItemMetadata(item) },
|
|
85
83
|
rowValues,
|
|
86
84
|
placeholdersById,
|
|
87
85
|
);
|
|
@@ -103,13 +101,13 @@ export const createTreeModel = <T, S>(
|
|
|
103
101
|
}
|
|
104
102
|
return store;
|
|
105
103
|
};
|
|
106
|
-
return Gtk.TreeListModel.new(root, false,
|
|
104
|
+
return Gtk.TreeListModel.new(root, false, false, createFunc);
|
|
107
105
|
};
|
|
108
106
|
|
|
109
|
-
export const createSectionModel = <
|
|
110
|
-
const
|
|
111
|
-
for (const section of
|
|
112
|
-
|
|
107
|
+
export const createSectionModel = <S, T>(sections: SectionNode<S, T>[]): Gtk.FlattenListModel => {
|
|
108
|
+
const store = Gio.ListStore.new(Gtk.StringList.prototype.__type__);
|
|
109
|
+
for (const section of sections) {
|
|
110
|
+
store.append(Gtk.StringList.new(emptyStrings(countDescendants(section.data))));
|
|
113
111
|
}
|
|
114
|
-
return Gtk.FlattenListModel.new(
|
|
112
|
+
return Gtk.FlattenListModel.new(store);
|
|
115
113
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type * as Gio from "@gtkx/gi/gio";
|
|
2
1
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
3
2
|
import type * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import type {
|
|
5
|
-
import { flattenListItems, type TreeItemMetadata } from "./list-item-flatten.js";
|
|
3
|
+
import type { ItemNode, SectionNode } from "../types.js";
|
|
4
|
+
import { countDescendants, flattenListItems, type TreeItemMetadata } from "./list-item-flatten.js";
|
|
6
5
|
|
|
7
6
|
const NO_TREE_METADATA: TreeItemMetadata = { hideExpander: false, indentForDepth: true, indentForIcon: true };
|
|
8
7
|
|
|
@@ -16,44 +15,48 @@ const treeRowItem = (treeRow: Gtk.TreeListRow): GObject.Object | null => {
|
|
|
16
15
|
return item;
|
|
17
16
|
};
|
|
18
17
|
|
|
19
|
-
export
|
|
18
|
+
export type Resolved<T = unknown, S = unknown> = {
|
|
20
19
|
value: T | S | undefined;
|
|
21
20
|
present: boolean;
|
|
22
21
|
isHeader: boolean;
|
|
23
|
-
treeRow: Gtk.TreeListRow | null;
|
|
24
22
|
metadata: TreeItemMetadata;
|
|
25
|
-
}
|
|
23
|
+
};
|
|
26
24
|
|
|
27
|
-
export
|
|
28
|
-
resolve(position: number, treeRow: Gtk.TreeListRow | null
|
|
29
|
-
|
|
25
|
+
export type ItemResolver<T = unknown, S = unknown> = {
|
|
26
|
+
resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S>;
|
|
27
|
+
positionOfId(id: string): number;
|
|
30
28
|
idOf(position: number): string | undefined;
|
|
31
|
-
|
|
32
|
-
}
|
|
29
|
+
};
|
|
33
30
|
|
|
34
|
-
export
|
|
31
|
+
export type RowValue<T = unknown> = {
|
|
35
32
|
id: string;
|
|
36
|
-
value: T
|
|
37
|
-
isHeader: boolean;
|
|
33
|
+
value: T;
|
|
38
34
|
metadata: TreeItemMetadata;
|
|
39
|
-
}
|
|
35
|
+
};
|
|
40
36
|
|
|
41
|
-
export const
|
|
42
|
-
|
|
37
|
+
export const rowIdOf = <T>(
|
|
38
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
39
|
+
row: Gtk.TreeListRow,
|
|
40
|
+
): string | undefined => {
|
|
41
|
+
const item = row.getItem();
|
|
42
|
+
return item === null ? undefined : rowValues.get(item)?.id;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const createItemResolver = <T, S>(
|
|
46
|
+
items: ItemNode<T>[] | undefined,
|
|
43
47
|
flattenTreeChildren: boolean,
|
|
44
|
-
rowValues: WeakMap<GObject.Object, RowValue<T
|
|
48
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
45
49
|
): ItemResolver<T, S> => {
|
|
46
50
|
const flattened = flattenListItems(items, flattenTreeChildren);
|
|
47
51
|
return {
|
|
48
|
-
|
|
49
|
-
positionOf(id: string): number {
|
|
52
|
+
positionOfId(id: string): number {
|
|
50
53
|
const position = flattened.idToPosition.get(id);
|
|
51
54
|
return position === undefined ? -1 : position;
|
|
52
55
|
},
|
|
53
56
|
idOf(position: number): string | undefined {
|
|
54
57
|
return flattened.positionToId.get(position);
|
|
55
58
|
},
|
|
56
|
-
resolve(position: number, treeRow: Gtk.TreeListRow | null
|
|
59
|
+
resolve(position: number, treeRow: Gtk.TreeListRow | null): Resolved<T, S> {
|
|
57
60
|
if (treeRow !== null && !flattenTreeChildren) {
|
|
58
61
|
const rowItem = treeRowItem(treeRow);
|
|
59
62
|
if (rowItem !== null) {
|
|
@@ -62,8 +65,7 @@ export const createControlledResolver = <T, S>(
|
|
|
62
65
|
return {
|
|
63
66
|
value: tagged.value,
|
|
64
67
|
present: true,
|
|
65
|
-
isHeader:
|
|
66
|
-
treeRow,
|
|
68
|
+
isHeader: false,
|
|
67
69
|
metadata: tagged.metadata,
|
|
68
70
|
};
|
|
69
71
|
}
|
|
@@ -75,69 +77,62 @@ export const createControlledResolver = <T, S>(
|
|
|
75
77
|
value: undefined,
|
|
76
78
|
present: false,
|
|
77
79
|
isHeader: false,
|
|
78
|
-
treeRow,
|
|
79
80
|
metadata: NO_TREE_METADATA,
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
83
|
return {
|
|
83
84
|
value: record.value,
|
|
84
85
|
present: true,
|
|
85
|
-
isHeader: record.isHeader,
|
|
86
|
-
treeRow,
|
|
87
|
-
metadata: record.metadata,
|
|
88
|
-
};
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const createModelResolver = <T, S>(model: Gio.ListModel): ItemResolver<T, S> => {
|
|
94
|
-
return {
|
|
95
|
-
get count(): number {
|
|
96
|
-
return model.getNItems();
|
|
97
|
-
},
|
|
98
|
-
positionOf(id: string): number {
|
|
99
|
-
const numeric = Number(id);
|
|
100
|
-
return Number.isInteger(numeric) ? numeric : -1;
|
|
101
|
-
},
|
|
102
|
-
idOf(position: number): string {
|
|
103
|
-
return String(position);
|
|
104
|
-
},
|
|
105
|
-
resolve(position: number, treeRow: Gtk.TreeListRow | null, boundItem: GObject.Object | null): Resolved<T, S> {
|
|
106
|
-
const item = boundItem ?? model.getItem(position);
|
|
107
|
-
return {
|
|
108
|
-
value: (item ?? undefined) as T | undefined,
|
|
109
|
-
present: item !== null,
|
|
110
86
|
isHeader: false,
|
|
111
|
-
|
|
112
|
-
metadata: NO_TREE_METADATA,
|
|
87
|
+
metadata: record.metadata,
|
|
113
88
|
};
|
|
114
89
|
},
|
|
115
90
|
};
|
|
116
91
|
};
|
|
117
92
|
|
|
118
|
-
export const createSectionHeaderResolver = <T, S>(
|
|
93
|
+
export const createSectionHeaderResolver = <T, S>(sections: SectionNode<S, T>[] | undefined): ItemResolver<T, S> => {
|
|
119
94
|
const valueByStart = new Map<number, S>();
|
|
120
95
|
let start = 0;
|
|
121
|
-
for (const section of
|
|
122
|
-
if (section.section !== true) continue;
|
|
96
|
+
for (const section of sections ?? []) {
|
|
123
97
|
valueByStart.set(start, section.value);
|
|
124
|
-
start += section.
|
|
98
|
+
start += countDescendants(section.data);
|
|
125
99
|
}
|
|
126
100
|
return {
|
|
127
|
-
|
|
128
|
-
positionOf: () => -1,
|
|
101
|
+
positionOfId: () => -1,
|
|
129
102
|
idOf: () => undefined,
|
|
130
103
|
resolve(position: number): Resolved<T, S> {
|
|
131
104
|
if (!valueByStart.has(position)) {
|
|
132
|
-
return { value: undefined, present: false, isHeader: true,
|
|
105
|
+
return { value: undefined, present: false, isHeader: true, metadata: NO_TREE_METADATA };
|
|
133
106
|
}
|
|
134
107
|
return {
|
|
135
108
|
value: valueByStart.get(position),
|
|
136
109
|
present: true,
|
|
137
110
|
isHeader: true,
|
|
138
|
-
treeRow: null,
|
|
139
111
|
metadata: NO_TREE_METADATA,
|
|
140
112
|
};
|
|
141
113
|
},
|
|
142
114
|
};
|
|
143
115
|
};
|
|
116
|
+
|
|
117
|
+
export const createTreeResolver = <T, S>(
|
|
118
|
+
items: ItemNode<T>[] | undefined,
|
|
119
|
+
rowValues: WeakMap<GObject.Object, RowValue<T>>,
|
|
120
|
+
model: Gtk.TreeListModel,
|
|
121
|
+
): ItemResolver<T, S> => {
|
|
122
|
+
const base = createItemResolver<T, S>(items, false, rowValues);
|
|
123
|
+
return {
|
|
124
|
+
resolve: base.resolve,
|
|
125
|
+
idOf: (position: number): string | undefined => {
|
|
126
|
+
const row = model.getRow(position);
|
|
127
|
+
return row === null ? undefined : rowIdOf(rowValues, row);
|
|
128
|
+
},
|
|
129
|
+
positionOfId: (id: string): number => {
|
|
130
|
+
const count = model.getNItems();
|
|
131
|
+
for (let position = 0; position < count; position++) {
|
|
132
|
+
const row = model.getRow(position);
|
|
133
|
+
if (row !== null && rowIdOf(rowValues, row) === id) return position;
|
|
134
|
+
}
|
|
135
|
+
return -1;
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
};
|