@gtkx/cli 0.11.0 → 0.11.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/package.json +7 -3
- package/templates/claude/EXAMPLES.md.ejs +372 -234
- package/templates/claude/SKILL.md.ejs +29 -319
- package/templates/claude/WIDGETS.md.ejs +213 -332
|
@@ -1,43 +1,48 @@
|
|
|
1
1
|
# GTKX Widget Reference
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Common Props (All Widgets)
|
|
4
|
+
|
|
5
|
+
| Prop | Type | Description |
|
|
6
|
+
|------|------|-------------|
|
|
7
|
+
| `hexpand` / `vexpand` | boolean | Expand to fill available space |
|
|
8
|
+
| `halign` / `valign` | `Gtk.Align.START \| CENTER \| END \| FILL` | Alignment |
|
|
9
|
+
| `marginStart/End/Top/Bottom` | number | Margins in pixels |
|
|
10
|
+
| `sensitive` | boolean | Enabled/disabled state |
|
|
11
|
+
| `visible` | boolean | Visibility |
|
|
12
|
+
| `cssClasses` | string[] | CSS classes for styling |
|
|
13
|
+
| `widthRequest` / `heightRequest` | number | Minimum size |
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Containers
|
|
4
18
|
|
|
5
19
|
### GtkBox
|
|
6
|
-
Linear layout
|
|
20
|
+
Linear layout (horizontal or vertical).
|
|
7
21
|
|
|
8
22
|
```tsx
|
|
9
|
-
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12}>
|
|
10
|
-
|
|
11
|
-
Child 2
|
|
23
|
+
<GtkBox orientation={Gtk.Orientation.VERTICAL} spacing={12} homogeneous={false}>
|
|
24
|
+
{children}
|
|
12
25
|
</GtkBox>
|
|
13
26
|
```
|
|
14
27
|
|
|
15
|
-
Props:
|
|
16
|
-
- `orientation`: `Gtk.Orientation.HORIZONTAL` | `Gtk.Orientation.VERTICAL`
|
|
17
|
-
- `spacing`: number (pixels between children)
|
|
18
|
-
- `homogeneous`: boolean (equal child sizes)
|
|
19
|
-
|
|
20
28
|
### GtkGrid
|
|
21
|
-
2D grid
|
|
29
|
+
2D grid with explicit positioning using `GridChild`.
|
|
22
30
|
|
|
23
31
|
```tsx
|
|
24
|
-
<GtkGrid rowSpacing={
|
|
25
|
-
<GridChild column={0} row={0}
|
|
26
|
-
<GridChild column={1} row={0}
|
|
32
|
+
<GtkGrid rowSpacing={8} columnSpacing={12}>
|
|
33
|
+
<GridChild column={0} row={0}><GtkLabel label="Name:" /></GridChild>
|
|
34
|
+
<GridChild column={1} row={0}><GtkEntry hexpand /></GridChild>
|
|
35
|
+
<GridChild column={0} row={1} columnSpan={2}><GtkButton label="Submit" /></GridChild>
|
|
27
36
|
</GtkGrid>
|
|
28
37
|
```
|
|
29
38
|
|
|
30
|
-
GridChild props
|
|
31
|
-
- `column`: number (0-indexed)
|
|
32
|
-
- `row`: number (0-indexed)
|
|
33
|
-
- `columnSpan`: number (default 1)
|
|
34
|
-
- `rowSpan`: number (default 1)
|
|
39
|
+
**GridChild props:** `column`, `row`, `columnSpan`, `rowSpan`
|
|
35
40
|
|
|
36
41
|
### GtkStack
|
|
37
|
-
|
|
42
|
+
Page container, shows one child at a time.
|
|
38
43
|
|
|
39
44
|
```tsx
|
|
40
|
-
<GtkStack visibleChildName="page1">
|
|
45
|
+
<GtkStack visibleChildName="page1" transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT}>
|
|
41
46
|
<StackPage name="page1" title="First" iconName="document-new">
|
|
42
47
|
<Content1 />
|
|
43
48
|
</StackPage>
|
|
@@ -47,33 +52,19 @@ Shows one child at a time, switchable by name.
|
|
|
47
52
|
</GtkStack>
|
|
48
53
|
```
|
|
49
54
|
|
|
50
|
-
StackPage props (
|
|
51
|
-
- `name`: string (required, unique identifier)
|
|
52
|
-
- `title`: string (display title)
|
|
53
|
-
- `iconName`: string (icon name)
|
|
54
|
-
- `needsAttention`: boolean (show attention indicator)
|
|
55
|
-
- `visible`: boolean (visibility in switchers)
|
|
56
|
-
- `useUnderline`: boolean (mnemonic underlines in title)
|
|
57
|
-
- `badgeNumber`: number (badge on indicator, AdwViewStack only)
|
|
55
|
+
**StackPage props:** `name` (required), `title`, `iconName`, `needsAttention`, `badgeNumber` (AdwViewStack only)
|
|
58
56
|
|
|
59
57
|
### GtkNotebook
|
|
60
58
|
Tabbed container with visible tabs.
|
|
61
59
|
|
|
62
60
|
```tsx
|
|
63
61
|
<GtkNotebook>
|
|
64
|
-
<Notebook.Page label="Tab 1">
|
|
65
|
-
|
|
66
|
-
</Notebook.Page>
|
|
67
|
-
<Notebook.Page label="Tab 2">
|
|
68
|
-
<Content2 />
|
|
69
|
-
</Notebook.Page>
|
|
62
|
+
<Notebook.Page label="Tab 1"><Content1 /></Notebook.Page>
|
|
63
|
+
<Notebook.Page label="Tab 2"><Content2 /></Notebook.Page>
|
|
70
64
|
</GtkNotebook>
|
|
71
65
|
```
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
- `label`: string (tab label, optional when using Notebook.PageTab)
|
|
75
|
-
|
|
76
|
-
Custom tab widgets with Notebook.PageTab:
|
|
67
|
+
Custom tab widget:
|
|
77
68
|
```tsx
|
|
78
69
|
<Notebook.Page>
|
|
79
70
|
<Notebook.PageTab>
|
|
@@ -87,67 +78,62 @@ Custom tab widgets with Notebook.PageTab:
|
|
|
87
78
|
```
|
|
88
79
|
|
|
89
80
|
### GtkPaned
|
|
90
|
-
Resizable split
|
|
81
|
+
Resizable split with draggable divider. **Requires Slot components.**
|
|
91
82
|
|
|
92
83
|
```tsx
|
|
93
|
-
<GtkPaned
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
shrinkStartChild={false}
|
|
97
|
-
shrinkEndChild={false}
|
|
98
|
-
>
|
|
99
|
-
<Slot for={GtkPaned} id="startChild">
|
|
100
|
-
<SidePanel />
|
|
101
|
-
</Slot>
|
|
102
|
-
<Slot for={GtkPaned} id="endChild">
|
|
103
|
-
<MainContent />
|
|
104
|
-
</Slot>
|
|
84
|
+
<GtkPaned orientation={Gtk.Orientation.HORIZONTAL} position={280} shrinkStartChild={false}>
|
|
85
|
+
<Slot for={GtkPaned} id="startChild"><Sidebar /></Slot>
|
|
86
|
+
<Slot for={GtkPaned} id="endChild"><MainContent /></Slot>
|
|
105
87
|
</GtkPaned>
|
|
106
88
|
```
|
|
107
89
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
### GtkOverlay
|
|
91
|
+
Stack widgets on top of each other. First child is base layer, additional children need `OverlayChild` wrapper.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<GtkOverlay>
|
|
95
|
+
<GtkButton label="Notifications" />
|
|
96
|
+
<OverlayChild>
|
|
97
|
+
<GtkLabel label="3" cssClasses={["badge"]} halign={Gtk.Align.END} valign={Gtk.Align.START} />
|
|
98
|
+
</OverlayChild>
|
|
99
|
+
</GtkOverlay>
|
|
100
|
+
```
|
|
113
101
|
|
|
114
|
-
|
|
102
|
+
### GtkScrolledWindow
|
|
103
|
+
Scrollable container.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<GtkScrolledWindow vexpand hscrollbarPolicy={Gtk.PolicyType.NEVER}>
|
|
107
|
+
<Content />
|
|
108
|
+
</GtkScrolledWindow>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Virtual Lists
|
|
114
|
+
|
|
115
|
+
All virtual list widgets use `ListItem` children and a `renderItem` function.
|
|
115
116
|
|
|
116
117
|
### ListView
|
|
117
|
-
High-performance scrollable list with
|
|
118
|
+
High-performance scrollable list with selection.
|
|
118
119
|
|
|
119
120
|
```tsx
|
|
120
121
|
<ListView<Item>
|
|
121
122
|
vexpand
|
|
122
|
-
selected={[selectedId]}
|
|
123
|
+
selected={selectedId ? [selectedId] : []}
|
|
123
124
|
selectionMode={Gtk.SelectionMode.SINGLE}
|
|
124
125
|
onSelectionChanged={(ids) => setSelectedId(ids[0])}
|
|
125
|
-
renderItem={(item) =>
|
|
126
|
-
<GtkLabel label={item?.text ?? ""} />
|
|
127
|
-
)}
|
|
126
|
+
renderItem={(item) => <GtkLabel label={item?.name ?? ""} />}
|
|
128
127
|
>
|
|
129
|
-
{items.map(item =>
|
|
130
|
-
<ListItem key={item.id} id={item.id} value={item} />
|
|
131
|
-
))}
|
|
128
|
+
{items.map(item => <ListItem key={item.id} id={item.id} value={item} />)}
|
|
132
129
|
</ListView>
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
Props:
|
|
136
|
-
- `renderItem`: `(item: T | null) => ReactElement` (required)
|
|
137
|
-
- `selected`: string[] (array of selected item IDs)
|
|
138
|
-
- `selectionMode`: `Gtk.SelectionMode.SINGLE` | `MULTIPLE` | `NONE`
|
|
139
|
-
- `onSelectionChanged`: `(ids: string[]) => void`
|
|
140
|
-
|
|
141
|
-
ListItem props:
|
|
142
|
-
- `id`: string (required, unique identifier for selection)
|
|
143
|
-
- `value`: T (the data item)
|
|
144
|
-
|
|
145
132
|
### GridView
|
|
146
|
-
Grid-based virtual scrolling.
|
|
133
|
+
Grid-based virtual scrolling.
|
|
147
134
|
|
|
148
135
|
```tsx
|
|
149
136
|
<GridView<Item>
|
|
150
|
-
vexpand
|
|
151
137
|
minColumns={2}
|
|
152
138
|
maxColumns={4}
|
|
153
139
|
renderItem={(item) => (
|
|
@@ -157,9 +143,7 @@ Grid-based virtual scrolling. Same API as ListView but renders items in a grid.
|
|
|
157
143
|
</GtkBox>
|
|
158
144
|
)}
|
|
159
145
|
>
|
|
160
|
-
{items.map(item =>
|
|
161
|
-
<ListItem key={item.id} id={item.id} value={item} />
|
|
162
|
-
))}
|
|
146
|
+
{items.map(item => <ListItem key={item.id} id={item.id} value={item} />)}
|
|
163
147
|
</GridView>
|
|
164
148
|
```
|
|
165
149
|
|
|
@@ -167,363 +151,260 @@ Grid-based virtual scrolling. Same API as ListView but renders items in a grid.
|
|
|
167
151
|
Table with sortable columns.
|
|
168
152
|
|
|
169
153
|
```tsx
|
|
170
|
-
<GtkColumnView
|
|
171
|
-
sortColumn="name"
|
|
172
|
-
sortOrder={Gtk.SortType.ASCENDING}
|
|
173
|
-
onSortChange={(column, order) => handleSort(column, order)}
|
|
174
|
-
>
|
|
154
|
+
<GtkColumnView sortColumn="name" sortOrder={Gtk.SortType.ASCENDING} onSortChange={handleSort}>
|
|
175
155
|
<ColumnViewColumn<Item>
|
|
176
156
|
title="Name"
|
|
177
157
|
id="name"
|
|
178
158
|
expand
|
|
179
159
|
resizable
|
|
180
160
|
sortable
|
|
181
|
-
renderCell={(item) =>
|
|
182
|
-
|
|
183
|
-
|
|
161
|
+
renderCell={(item) => <GtkLabel label={item?.name ?? ""} />}
|
|
162
|
+
/>
|
|
163
|
+
<ColumnViewColumn<Item>
|
|
164
|
+
title="Size"
|
|
165
|
+
id="size"
|
|
166
|
+
fixedWidth={100}
|
|
167
|
+
renderCell={(item) => <GtkLabel label={item?.size ?? ""} />}
|
|
184
168
|
/>
|
|
185
|
-
{items.map(item =>
|
|
186
|
-
<ListItem key={item.id} id={item.id} value={item} />
|
|
187
|
-
))}
|
|
169
|
+
{items.map(item => <ListItem key={item.id} id={item.id} value={item} />)}
|
|
188
170
|
</GtkColumnView>
|
|
189
171
|
```
|
|
190
172
|
|
|
191
|
-
ColumnViewColumn props:
|
|
192
|
-
- `title`: string (column header)
|
|
193
|
-
- `id`: string (used for sorting)
|
|
194
|
-
- `expand`: boolean (fill available space)
|
|
195
|
-
- `resizable`: boolean (user can resize)
|
|
196
|
-
- `sortable`: boolean (clicking header triggers sort)
|
|
197
|
-
- `fixedWidth`: number (fixed width in pixels)
|
|
198
|
-
- `renderCell`: `(item: T | null) => ReactElement`
|
|
199
|
-
|
|
200
173
|
### GtkDropDown
|
|
201
|
-
|
|
174
|
+
Selection dropdown.
|
|
202
175
|
|
|
203
176
|
```tsx
|
|
204
177
|
<GtkDropDown selectedId={selectedId} onSelectionChanged={setSelectedId}>
|
|
205
|
-
{options.map(opt =>
|
|
206
|
-
<SimpleListItem key={opt.id} id={opt.id} value={opt.label} />
|
|
207
|
-
))}
|
|
178
|
+
{options.map(opt => <SimpleListItem key={opt.id} id={opt.id} value={opt.label} />)}
|
|
208
179
|
</GtkDropDown>
|
|
209
180
|
```
|
|
210
181
|
|
|
211
|
-
|
|
212
|
-
- `selectedId`: string (controlled selected item ID)
|
|
213
|
-
- `onSelectionChanged`: `(id: string) => void`
|
|
182
|
+
---
|
|
214
183
|
|
|
215
|
-
|
|
216
|
-
- `id`: string (unique identifier)
|
|
217
|
-
- `value`: string (display text)
|
|
184
|
+
## Inputs
|
|
218
185
|
|
|
219
|
-
###
|
|
220
|
-
|
|
186
|
+
### GtkEntry
|
|
187
|
+
Single-line text input. **Requires two-way binding.**
|
|
221
188
|
|
|
222
189
|
```tsx
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<GtkLabel
|
|
226
|
-
label="3"
|
|
227
|
-
cssClasses={["badge"]}
|
|
228
|
-
halign={Gtk.Align.END}
|
|
229
|
-
valign={Gtk.Align.START}
|
|
230
|
-
marginEnd={4}
|
|
231
|
-
marginTop={4}
|
|
232
|
-
/>
|
|
233
|
-
</GtkOverlay>
|
|
190
|
+
const [text, setText] = useState("");
|
|
191
|
+
<GtkEntry text={text} onChanged={(e) => setText(e.getText())} placeholderText="Enter text..." />
|
|
234
192
|
```
|
|
235
193
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
## Header Widgets
|
|
239
|
-
|
|
240
|
-
### GtkHeaderBar
|
|
241
|
-
Title bar with packed widgets at start and end.
|
|
194
|
+
### GtkToggleButton
|
|
195
|
+
Toggle button. Auto-prevents signal feedback loops.
|
|
242
196
|
|
|
243
197
|
```tsx
|
|
244
|
-
<
|
|
245
|
-
<Pack.Start>
|
|
246
|
-
<GtkButton iconName="go-previous-symbolic" />
|
|
247
|
-
</Pack.Start>
|
|
248
|
-
<Slot for={GtkHeaderBar} id="titleWidget">
|
|
249
|
-
<GtkLabel label="My App" cssClasses={["title"]} />
|
|
250
|
-
</Slot>
|
|
251
|
-
<Pack.End>
|
|
252
|
-
<GtkMenuButton iconName="open-menu-symbolic" />
|
|
253
|
-
</Pack.End>
|
|
254
|
-
</GtkHeaderBar>
|
|
198
|
+
<GtkToggleButton active={isActive} onToggled={() => setIsActive(!isActive)} label="Toggle" />
|
|
255
199
|
```
|
|
256
200
|
|
|
257
|
-
###
|
|
258
|
-
|
|
201
|
+
### GtkCheckButton
|
|
202
|
+
Checkbox.
|
|
259
203
|
|
|
260
204
|
```tsx
|
|
261
|
-
<
|
|
262
|
-
<Pack.Start>
|
|
263
|
-
<GtkButton label="Cancel" />
|
|
264
|
-
</Pack.Start>
|
|
265
|
-
<Pack.End>
|
|
266
|
-
<GtkButton label="Save" cssClasses={["suggested-action"]} />
|
|
267
|
-
</Pack.End>
|
|
268
|
-
</GtkActionBar>
|
|
205
|
+
<GtkCheckButton active={checked} onToggled={() => setChecked(!checked)} label="Option" />
|
|
269
206
|
```
|
|
270
207
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
### GtkEntry
|
|
274
|
-
Single-line text input. Requires two-way binding for controlled behavior.
|
|
208
|
+
### GtkSwitch
|
|
209
|
+
On/off switch.
|
|
275
210
|
|
|
276
211
|
```tsx
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
<GtkEntry
|
|
280
|
-
text={text}
|
|
281
|
-
onChanged={(entry) => setText(entry.getText())}
|
|
282
|
-
placeholderText="Enter text..."
|
|
283
|
-
/>
|
|
212
|
+
<GtkSwitch active={enabled} onStateSet={() => { setEnabled(!enabled); return true; }} />
|
|
284
213
|
```
|
|
285
214
|
|
|
286
|
-
###
|
|
287
|
-
|
|
215
|
+
### GtkSpinButton
|
|
216
|
+
Numeric input with increment/decrement.
|
|
288
217
|
|
|
289
218
|
```tsx
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
<GtkToggleButton
|
|
293
|
-
active={active}
|
|
294
|
-
onToggled={() => setActive(!active)}
|
|
295
|
-
label="Toggle me"
|
|
296
|
-
/>
|
|
219
|
+
<GtkSpinButton value={count} onValueChanged={(sb) => setCount(sb.getValue())} />
|
|
297
220
|
```
|
|
298
221
|
|
|
299
|
-
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Display
|
|
300
225
|
|
|
301
226
|
### GtkLabel
|
|
302
227
|
```tsx
|
|
303
|
-
<GtkLabel label="
|
|
228
|
+
<GtkLabel label="Text" halign={Gtk.Align.START} wrap useMarkup />
|
|
304
229
|
```
|
|
305
230
|
|
|
306
231
|
### GtkButton
|
|
307
232
|
```tsx
|
|
308
|
-
<GtkButton label="Click
|
|
233
|
+
<GtkButton label="Click" onClicked={handleClick} iconName="document-new-symbolic" />
|
|
309
234
|
```
|
|
310
235
|
|
|
311
|
-
###
|
|
236
|
+
### GtkImage
|
|
312
237
|
```tsx
|
|
313
|
-
<
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
238
|
+
<GtkImage iconName="folder-symbolic" pixelSize={48} />
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Header & Action Bars
|
|
244
|
+
|
|
245
|
+
### GtkHeaderBar
|
|
246
|
+
Title bar with packed widgets. Use `Pack.Start`, `Pack.End`, and `Slot` for titleWidget.
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
<GtkHeaderBar>
|
|
250
|
+
<Pack.Start><GtkButton iconName="go-previous-symbolic" /></Pack.Start>
|
|
251
|
+
<Slot for={GtkHeaderBar} id="titleWidget">
|
|
252
|
+
<GtkLabel label="Title" cssClasses={["title"]} />
|
|
318
253
|
</Slot>
|
|
319
|
-
|
|
254
|
+
<Pack.End><GtkMenuButton iconName="open-menu-symbolic" /></Pack.End>
|
|
255
|
+
</GtkHeaderBar>
|
|
320
256
|
```
|
|
321
257
|
|
|
322
|
-
|
|
258
|
+
### GtkActionBar
|
|
259
|
+
Bottom action bar.
|
|
323
260
|
|
|
324
|
-
### GtkPopoverMenu
|
|
325
261
|
```tsx
|
|
326
|
-
<
|
|
327
|
-
<
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<Menu.Section>
|
|
331
|
-
<Menu.Submenu label="File">
|
|
332
|
-
<Menu.Item id="open" label="Open" onActivate={handleOpen} />
|
|
333
|
-
<Menu.Item id="save" label="Save" onActivate={handleSave} />
|
|
334
|
-
</Menu.Submenu>
|
|
335
|
-
</Menu.Section>
|
|
336
|
-
<Menu.Section>
|
|
337
|
-
<Menu.Item id="quit" label="Quit" onActivate={quit} accels="<Control>q" />
|
|
338
|
-
</Menu.Section>
|
|
339
|
-
</GtkPopoverMenu>
|
|
262
|
+
<GtkActionBar>
|
|
263
|
+
<Pack.Start><GtkButton label="Cancel" /></Pack.Start>
|
|
264
|
+
<Pack.End><GtkButton label="Save" cssClasses={["suggested-action"]} /></Pack.End>
|
|
265
|
+
</GtkActionBar>
|
|
340
266
|
```
|
|
341
267
|
|
|
342
|
-
|
|
343
|
-
Props:
|
|
344
|
-
- `id`: string (required, unique identifier)
|
|
345
|
-
- `label`: string
|
|
346
|
-
- `onActivate`: `() => void`
|
|
347
|
-
- `accels`: string | string[] (e.g., "<Control>n")
|
|
268
|
+
---
|
|
348
269
|
|
|
349
|
-
|
|
350
|
-
Groups menu items with optional label.
|
|
270
|
+
## Menus
|
|
351
271
|
|
|
352
|
-
###
|
|
353
|
-
|
|
272
|
+
### GtkPopoverMenu with GtkMenuButton
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
<GtkMenuButton iconName="open-menu-symbolic">
|
|
276
|
+
<Slot for={GtkMenuButton} id="popover">
|
|
277
|
+
<GtkPopoverMenu>
|
|
278
|
+
<Menu.Section>
|
|
279
|
+
<Menu.Item id="new" label="New" onActivate={handleNew} accels="<Control>n" />
|
|
280
|
+
<Menu.Item id="open" label="Open" onActivate={handleOpen} />
|
|
281
|
+
</Menu.Section>
|
|
282
|
+
<Menu.Section>
|
|
283
|
+
<Menu.Submenu label="Export">
|
|
284
|
+
<Menu.Item id="pdf" label="PDF" onActivate={exportPdf} />
|
|
285
|
+
<Menu.Item id="csv" label="CSV" onActivate={exportCsv} />
|
|
286
|
+
</Menu.Submenu>
|
|
287
|
+
</Menu.Section>
|
|
288
|
+
<Menu.Section>
|
|
289
|
+
<Menu.Item id="quit" label="Quit" onActivate={quit} accels="<Control>q" />
|
|
290
|
+
</Menu.Section>
|
|
291
|
+
</GtkPopoverMenu>
|
|
292
|
+
</Slot>
|
|
293
|
+
</GtkMenuButton>
|
|
294
|
+
```
|
|
354
295
|
|
|
355
|
-
|
|
296
|
+
**Menu.Item props:** `id` (required), `label`, `onActivate`, `accels` (e.g., `"<Control>n"`)
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Windows
|
|
356
301
|
|
|
357
302
|
### GtkApplicationWindow
|
|
303
|
+
|
|
358
304
|
```tsx
|
|
359
305
|
<GtkApplicationWindow
|
|
360
|
-
title="
|
|
306
|
+
title="App"
|
|
361
307
|
defaultWidth={800}
|
|
362
308
|
defaultHeight={600}
|
|
363
|
-
showMenubar
|
|
364
309
|
onCloseRequest={quit}
|
|
365
310
|
>
|
|
366
|
-
<
|
|
311
|
+
<Content />
|
|
367
312
|
</GtkApplicationWindow>
|
|
368
313
|
```
|
|
369
314
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
Import from `@gtkx/ffi/adw` for enums and `@gtkx/react` for components.
|
|
373
|
-
|
|
374
|
-
### AdwApplicationWindow
|
|
375
|
-
Modern application window.
|
|
376
|
-
|
|
315
|
+
Custom titlebar:
|
|
377
316
|
```tsx
|
|
378
|
-
<
|
|
379
|
-
<
|
|
380
|
-
|
|
317
|
+
<GtkApplicationWindow ...>
|
|
318
|
+
<Slot for={GtkWindow} id="titlebar">
|
|
319
|
+
<GtkHeaderBar />
|
|
320
|
+
</Slot>
|
|
321
|
+
<Content />
|
|
322
|
+
</GtkApplicationWindow>
|
|
381
323
|
```
|
|
382
324
|
|
|
383
|
-
|
|
384
|
-
Layout container for apps with top/bottom toolbars.
|
|
325
|
+
---
|
|
385
326
|
|
|
386
|
-
|
|
387
|
-
<AdwToolbarView>
|
|
388
|
-
<Toolbar.Top>
|
|
389
|
-
<AdwHeaderBar />
|
|
390
|
-
</Toolbar.Top>
|
|
391
|
-
<MainContent />
|
|
392
|
-
<Toolbar.Bottom>
|
|
393
|
-
<GtkActionBar />
|
|
394
|
-
</Toolbar.Bottom>
|
|
395
|
-
</AdwToolbarView>
|
|
396
|
-
```
|
|
327
|
+
## Adwaita (Libadwaita)
|
|
397
328
|
|
|
398
|
-
|
|
399
|
-
|
|
329
|
+
Import: `import * as Adw from "@gtkx/ffi/adw";`
|
|
330
|
+
|
|
331
|
+
### AdwApplicationWindow + AdwToolbarView
|
|
332
|
+
Modern app structure.
|
|
400
333
|
|
|
401
334
|
```tsx
|
|
402
|
-
<
|
|
403
|
-
<
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
335
|
+
<AdwApplicationWindow title="App" defaultWidth={800} defaultHeight={600} onCloseRequest={quit}>
|
|
336
|
+
<AdwToolbarView>
|
|
337
|
+
<Toolbar.Top>
|
|
338
|
+
<AdwHeaderBar>
|
|
339
|
+
<Slot for={AdwHeaderBar} id="titleWidget">
|
|
340
|
+
<AdwWindowTitle title="App" subtitle="Description" />
|
|
341
|
+
</Slot>
|
|
342
|
+
</AdwHeaderBar>
|
|
343
|
+
</Toolbar.Top>
|
|
344
|
+
<MainContent />
|
|
345
|
+
<Toolbar.Bottom>
|
|
346
|
+
<GtkActionBar />
|
|
347
|
+
</Toolbar.Bottom>
|
|
348
|
+
</AdwToolbarView>
|
|
349
|
+
</AdwApplicationWindow>
|
|
408
350
|
```
|
|
409
351
|
|
|
410
352
|
### AdwStatusPage
|
|
411
|
-
Welcome, error, or empty state
|
|
353
|
+
Welcome, error, or empty state.
|
|
412
354
|
|
|
413
355
|
```tsx
|
|
414
|
-
<AdwStatusPage
|
|
415
|
-
|
|
416
|
-
title="Welcome"
|
|
417
|
-
description="Description text"
|
|
418
|
-
vexpand
|
|
419
|
-
>
|
|
420
|
-
<GtkButton label="Get Started" cssClasses={["suggested-action", "pill"]} />
|
|
356
|
+
<AdwStatusPage iconName="applications-system-symbolic" title="Welcome" description="Get started" vexpand>
|
|
357
|
+
<GtkButton label="Start" cssClasses={["suggested-action", "pill"]} halign={Gtk.Align.CENTER} />
|
|
421
358
|
</AdwStatusPage>
|
|
422
359
|
```
|
|
423
360
|
|
|
424
361
|
### AdwBanner
|
|
425
|
-
Dismissable notification
|
|
362
|
+
Dismissable notification.
|
|
426
363
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
- `revealed`: boolean
|
|
431
|
-
- `onButtonClicked`: `() => void`
|
|
364
|
+
```tsx
|
|
365
|
+
<AdwBanner title="Update available" buttonLabel="Dismiss" revealed={show} onButtonClicked={() => setShow(false)} />
|
|
366
|
+
```
|
|
432
367
|
|
|
433
368
|
### AdwPreferencesPage / AdwPreferencesGroup
|
|
434
|
-
Settings UI
|
|
369
|
+
Settings UI.
|
|
435
370
|
|
|
436
371
|
```tsx
|
|
437
372
|
<AdwPreferencesPage title="Settings">
|
|
438
|
-
<AdwPreferencesGroup title="
|
|
439
|
-
<
|
|
440
|
-
<
|
|
373
|
+
<AdwPreferencesGroup title="Appearance" description="Customize look">
|
|
374
|
+
<AdwSwitchRow title="Dark Mode" active={dark} onActivated={() => setDark(!dark)} />
|
|
375
|
+
<AdwActionRow title="Theme" subtitle="Select color">
|
|
376
|
+
<Slot for={AdwActionRow} id="activatableWidget">
|
|
377
|
+
<GtkImage iconName="go-next-symbolic" valign={Gtk.Align.CENTER} />
|
|
378
|
+
</Slot>
|
|
379
|
+
</AdwActionRow>
|
|
441
380
|
</AdwPreferencesGroup>
|
|
442
381
|
</AdwPreferencesPage>
|
|
443
382
|
```
|
|
444
383
|
|
|
445
|
-
### AdwActionRow
|
|
446
|
-
List row with title, subtitle, and optional widgets.
|
|
447
|
-
|
|
448
|
-
```tsx
|
|
449
|
-
<AdwActionRow title="Setting" subtitle="Description">
|
|
450
|
-
<Slot for={AdwActionRow} id="activatableWidget">
|
|
451
|
-
<GtkImage iconName="go-next-symbolic" />
|
|
452
|
-
</Slot>
|
|
453
|
-
</AdwActionRow>
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
### AdwSwitchRow
|
|
457
|
-
Toggle switch in a list row.
|
|
458
|
-
|
|
459
|
-
Props:
|
|
460
|
-
- `title`: string
|
|
461
|
-
- `subtitle`: string
|
|
462
|
-
- `active`: boolean
|
|
463
|
-
- `onActivate`: `() => void`
|
|
464
|
-
|
|
465
384
|
### AdwExpanderRow
|
|
466
|
-
Expandable row
|
|
385
|
+
Expandable settings row.
|
|
467
386
|
|
|
468
387
|
```tsx
|
|
469
|
-
<AdwExpanderRow title="Advanced" subtitle="More options"
|
|
470
|
-
<
|
|
471
|
-
<AdwSwitchRow title="
|
|
388
|
+
<AdwExpanderRow title="Advanced" subtitle="More options">
|
|
389
|
+
<AdwSwitchRow title="Option 1" active />
|
|
390
|
+
<AdwSwitchRow title="Option 2" active={false} />
|
|
472
391
|
</AdwExpanderRow>
|
|
473
392
|
```
|
|
474
393
|
|
|
475
394
|
### AdwEntryRow / AdwPasswordEntryRow
|
|
476
|
-
|
|
395
|
+
Input in list row.
|
|
477
396
|
|
|
478
397
|
```tsx
|
|
479
|
-
<AdwEntryRow title="Username" text={
|
|
398
|
+
<AdwEntryRow title="Username" text={username} onChanged={(e) => setUsername(e.getText())} />
|
|
480
399
|
<AdwPasswordEntryRow title="Password" />
|
|
481
400
|
```
|
|
482
401
|
|
|
483
|
-
###
|
|
484
|
-
Button styled as a list row.
|
|
485
|
-
|
|
486
|
-
```tsx
|
|
487
|
-
<AdwButtonRow title="Add Item" startIconName="list-add-symbolic" />
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### AdwClamp
|
|
491
|
-
Limits content width for readability.
|
|
492
|
-
|
|
493
|
-
```tsx
|
|
494
|
-
<AdwClamp maximumSize={600}>
|
|
495
|
-
<GtkBox>...</GtkBox>
|
|
496
|
-
</AdwClamp>
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
### AdwAvatar
|
|
500
|
-
User avatar with initials fallback.
|
|
501
|
-
|
|
502
|
-
Props:
|
|
503
|
-
- `size`: number (32, 48, 64, 80, etc.)
|
|
504
|
-
- `text`: string (for initials)
|
|
505
|
-
- `showInitials`: boolean
|
|
506
|
-
|
|
507
|
-
### AdwSpinner
|
|
508
|
-
Loading spinner.
|
|
509
|
-
|
|
510
|
-
```tsx
|
|
511
|
-
<AdwSpinner widthRequest={32} heightRequest={32} />
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
### AdwWindowTitle
|
|
515
|
-
Title and subtitle for header bars.
|
|
516
|
-
|
|
517
|
-
```tsx
|
|
518
|
-
<AdwWindowTitle title="App Name" subtitle="Page description" />
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
## Common Props
|
|
402
|
+
### Other Adwaita Widgets
|
|
522
403
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
404
|
+
| Widget | Description |
|
|
405
|
+
|--------|-------------|
|
|
406
|
+
| `AdwClamp` | Limits content width (`maximumSize={600}`) |
|
|
407
|
+
| `AdwAvatar` | User avatar (`size={48} text="Name" showInitials`) |
|
|
408
|
+
| `AdwSpinner` | Loading indicator |
|
|
409
|
+
| `AdwWindowTitle` | Title + subtitle for header bars |
|
|
410
|
+
| `AdwButtonRow` | Button styled as list row |
|