@astryxdesign/cli 0.6.3-canary.f22695a → 0.6.3

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.
Files changed (197) hide show
  1. package/README.md +1 -2
  2. package/api/build/build.type.d.mts +2 -2
  3. package/api/build/build.type.mjs +2 -2
  4. package/api/component/component.type.d.mts +6 -6
  5. package/api/component/component.type.mjs +19 -19
  6. package/api/discover/discover.type.d.mts +4 -4
  7. package/api/discover/discover.type.mjs +10 -10
  8. package/api/docs/_adapter.d.mts +24 -37
  9. package/api/docs/_adapter.mjs +83 -169
  10. package/api/docs/detail/detail.mjs +63 -14
  11. package/api/docs/detail/section/section.d.mts +1 -1
  12. package/api/docs/detail/section/section.mjs +20 -44
  13. package/api/docs/detail/section/section.test.mjs +0 -41
  14. package/api/docs/docs.d.mts +2 -7
  15. package/api/docs/docs.doc.mjs +10 -27
  16. package/api/docs/docs.mjs +9 -16
  17. package/api/docs/docs.test.mjs +0 -6
  18. package/api/docs/docs.type.d.mts +3 -40
  19. package/api/docs/docs.type.mjs +8 -36
  20. package/api/docs/integrationDocs.test.mjs +0 -106
  21. package/api/doctor/doctor.d.mts +0 -48
  22. package/api/doctor/doctor.mjs +0 -232
  23. package/api/doctor/doctor.test.mjs +0 -196
  24. package/api/hook/hook.type.d.mts +3 -3
  25. package/api/hook/hook.type.mjs +11 -11
  26. package/api/hook/list/list.d.mts +1 -1
  27. package/api/integration/add-contribution.mjs +3 -5
  28. package/api/integration/add-contribution.test.mjs +4 -4
  29. package/api/integration/integration-authoring.type.d.mts +1 -1
  30. package/api/integration/pack-check.mjs +7 -49
  31. package/api/integration/pack-check.test.mjs +0 -249
  32. package/api/search/search.d.mts +1 -1
  33. package/api/search/search.mjs +5 -5
  34. package/api/search/search.type.d.mts +2 -2
  35. package/api/search/search.type.mjs +1 -1
  36. package/api/swizzle/swizzle.type.d.mts +2 -2
  37. package/api/swizzle/swizzle.type.mjs +2 -2
  38. package/api/template/template.d.mts +1 -1
  39. package/api/template/template.type.d.mts +6 -6
  40. package/api/template/template.type.mjs +12 -12
  41. package/api/theme/build/build.mjs +6 -20
  42. package/api/theme/build/build.test.mjs +0 -127
  43. package/api/theme/palette/generate/generate.mjs +1 -1
  44. package/api/theme/palette/generate/generator.d.mts +13 -10
  45. package/api/theme/palette/generate/generator.mjs +3 -7
  46. package/api/theme/theme.type.d.mts +11 -170
  47. package/api/theme/theme.type.mjs +27 -94
  48. package/api/upgrade/_adapter.mjs +5 -71
  49. package/api/upgrade/upgrade.doc.mjs +3 -4
  50. package/api/upgrade/upgrade.type.d.mts +5 -5
  51. package/api/upgrade/upgrade.type.mjs +11 -11
  52. package/assets/codemods/integration-discovery.mjs +2 -40
  53. package/assets/codemods/integration-discovery.test.mjs +0 -58
  54. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +5 -27
  55. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +5 -20
  56. package/assets/docs/README.md +0 -9
  57. package/assets/docs/cli-integrations.doc.mjs +15 -86
  58. package/assets/docs/styling-libraries.doc.mjs +1 -1
  59. package/assets/docs/working-with-ai.doc.mjs +1 -1
  60. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +3 -19
  61. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +65 -383
  62. package/authoring/_shared/contract.ts +0 -22
  63. package/authoring/codemod/codemod.doc.mjs +1 -6
  64. package/authoring/codemod/parse.d.mts +8 -8
  65. package/authoring/codemod/parse.mjs +6 -8
  66. package/authoring/config/parse.d.mts +13 -13
  67. package/authoring/config/parse.mjs +8 -8
  68. package/authoring/config/type.ts +3 -3
  69. package/authoring/debug/parse.d.mts +5 -5
  70. package/authoring/debug/parse.mjs +3 -3
  71. package/authoring/doctypes/_schema.d.mts +23 -788
  72. package/authoring/doctypes/_schema.mjs +39 -492
  73. package/authoring/doctypes/base/type.ts +0 -40
  74. package/authoring/doctypes/command/command.doc.mjs +2 -3
  75. package/authoring/doctypes/command/parse.d.mts +2 -2
  76. package/authoring/doctypes/command/parse.mjs +1 -1
  77. package/authoring/doctypes/command/type.ts +2 -3
  78. package/authoring/doctypes/component/component.doc.mjs +3 -6
  79. package/authoring/doctypes/component/parse.d.mts +2 -2
  80. package/authoring/doctypes/component/parse.mjs +1 -1
  81. package/authoring/doctypes/component/type.ts +3 -4
  82. package/authoring/doctypes/enum/parse.d.mts +2 -2
  83. package/authoring/doctypes/enum/parse.mjs +1 -1
  84. package/authoring/doctypes/enum/type.ts +1 -3
  85. package/authoring/doctypes/function/function.doc.mjs +0 -4
  86. package/authoring/doctypes/function/parse.d.mts +2 -2
  87. package/authoring/doctypes/function/parse.mjs +1 -1
  88. package/authoring/doctypes/function/type.ts +2 -6
  89. package/authoring/doctypes/hook/hook.doc.mjs +0 -4
  90. package/authoring/doctypes/hook/parse.d.mts +2 -2
  91. package/authoring/doctypes/hook/parse.mjs +1 -1
  92. package/authoring/doctypes/hook/type.ts +2 -3
  93. package/authoring/doctypes/legacy.d.mts +6 -8
  94. package/authoring/doctypes/legacy.mjs +4 -5
  95. package/authoring/doctypes/parse.d.mts +18 -20
  96. package/authoring/doctypes/parse.mjs +10 -16
  97. package/authoring/doctypes/parse.test.mjs +3 -77
  98. package/authoring/doctypes/reference/parse.d.mts +2 -2
  99. package/authoring/doctypes/reference/parse.mjs +5 -8
  100. package/authoring/doctypes/reference/reference.doc.mjs +4 -17
  101. package/authoring/doctypes/reference/type.ts +5 -51
  102. package/authoring/doctypes/schema/parse.d.mts +2 -2
  103. package/authoring/doctypes/schema/parse.mjs +1 -1
  104. package/authoring/doctypes/schema/type.ts +2 -3
  105. package/authoring/doctypes/template/parse.d.mts +1 -92
  106. package/authoring/doctypes/template/parse.mjs +2 -36
  107. package/authoring/doctypes/template/parse.test.mjs +2 -8
  108. package/authoring/doctypes/template/template.doc.mjs +0 -4
  109. package/authoring/doctypes/template/type.ts +2 -5
  110. package/authoring/doctypes/types.ts +9 -10
  111. package/authoring/gap-report/parse.d.mts +10 -10
  112. package/authoring/gap-report/parse.mjs +6 -6
  113. package/authoring/gap-report/type.ts +1 -1
  114. package/authoring/index.d.mts +0 -1
  115. package/authoring/index.d.ts +17 -49
  116. package/authoring/index.mjs +0 -1
  117. package/authoring/integration/integration.doc.mjs +6 -13
  118. package/authoring/integration/parse.d.mts +2 -2
  119. package/authoring/integration/parse.mjs +1 -1
  120. package/authoring/integration/parse.test.mjs +1 -10
  121. package/authoring/integration/schema.d.mts +4 -6
  122. package/authoring/integration/schema.mjs +3 -9
  123. package/authoring/integration/type.ts +6 -23
  124. package/authoring/shadcn/receipt.d.mts +6 -6
  125. package/clients/cli/commands/docs.doc.mjs +3 -13
  126. package/clients/cli/commands/docs.mjs +21 -121
  127. package/clients/cli/commands/docs.test.mjs +0 -88
  128. package/clients/cli/commands/integration-authoring.test.mjs +9 -13
  129. package/clients/cli/commands/theme-palette-generate.doc.mjs +4 -8
  130. package/clients/cli/commands/upgrade.doc.mjs +2 -2
  131. package/clients/cli/formatters/index.mjs +1 -162
  132. package/clients/cli/formatters/index.test.mjs +0 -91
  133. package/clients/cli/lib/manifest.mjs +2 -7
  134. package/foundation/config/project.mjs +6 -21
  135. package/foundation/discovery/component-discovery.d.mts +1 -1
  136. package/foundation/discovery/component-discovery.mjs +1 -2
  137. package/foundation/discovery/docs-discovery.d.mts +4 -11
  138. package/foundation/discovery/docs-discovery.mjs +88 -208
  139. package/foundation/discovery/docs-discovery.test.mjs +13 -279
  140. package/foundation/discovery/template-adapter.mjs +1 -2
  141. package/foundation/integrations/autolink.mjs +5 -12
  142. package/foundation/integrations/integration-warnings.mjs +0 -6
  143. package/foundation/integrations/integrations.d.mts +2 -46
  144. package/foundation/integrations/integrations.mjs +8 -167
  145. package/foundation/integrations/integrations.test.mjs +1 -384
  146. package/foundation/integrations/validate-contributions.d.mts +0 -2
  147. package/foundation/integrations/validate-contributions.mjs +0 -10
  148. package/foundation/response/json-contract.test.mjs +17 -46
  149. package/foundation/response/response-types.doc.mjs +1 -6
  150. package/package.json +11 -9
  151. package/api/docs/compiled-topics.test.mjs +0 -78
  152. package/api/docs/index/index.d.mts +0 -18
  153. package/api/docs/index/index.mjs +0 -32
  154. package/api/docs/index/index.test.mjs +0 -62
  155. package/api/upgrade/project-context.test.mjs +0 -272
  156. package/assets/docs/authoring.doc.mjs +0 -14
  157. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +0 -14
  158. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +0 -34
  159. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +0 -14
  160. package/assets/templates/blocks/components/Timer/TimerInline.tsx +0 -14
  161. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +0 -13
  162. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +0 -47
  163. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +0 -14
  164. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +0 -31
  165. package/authoring/doctypes/base/graph-fields.doc.d.mts +0 -9
  166. package/authoring/doctypes/base/graph-fields.doc.mjs +0 -62
  167. package/authoring/doctypes/load-contract.test.mjs +0 -207
  168. package/authoring/doctypes/namespace/namespace.doc.d.mts +0 -9
  169. package/authoring/doctypes/namespace/namespace.doc.mjs +0 -132
  170. package/authoring/doctypes/namespace/parse.d.mts +0 -12
  171. package/authoring/doctypes/namespace/parse.mjs +0 -25
  172. package/authoring/doctypes/namespace/parse.test.mjs +0 -165
  173. package/authoring/doctypes/namespace/type.ts +0 -71
  174. package/authoring/identity/identity.doc.d.mts +0 -9
  175. package/authoring/identity/identity.doc.mjs +0 -61
  176. package/authoring/identity/type.ts +0 -132
  177. package/foundation/discovery/authoring-self-docs.d.mts +0 -69
  178. package/foundation/discovery/authoring-self-docs.mjs +0 -214
  179. package/foundation/discovery/authoring-self-docs.test.mjs +0 -154
  180. package/foundation/discovery/docs-output-budget.d.mts +0 -28
  181. package/foundation/discovery/docs-output-budget.mjs +0 -50
  182. package/foundation/discovery/docs-section-key.d.mts +0 -98
  183. package/foundation/discovery/docs-section-key.mjs +0 -221
  184. package/foundation/discovery/docs-section-key.test.mjs +0 -224
  185. package/foundation/doc-compiler/compile.d.mts +0 -162
  186. package/foundation/doc-compiler/compile.mjs +0 -262
  187. package/foundation/doc-compiler/doc-compiler.test.mjs +0 -687
  188. package/foundation/doc-compiler/ir.d.mts +0 -9
  189. package/foundation/doc-compiler/ir.mjs +0 -287
  190. package/foundation/doc-compiler/lenses.d.mts +0 -33
  191. package/foundation/doc-compiler/lenses.mjs +0 -127
  192. package/foundation/identity/provider-identity.d.mts +0 -90
  193. package/foundation/identity/provider-identity.mjs +0 -320
  194. package/foundation/identity/provider-identity.test.mjs +0 -254
  195. package/foundation/identity/providers.d.mts +0 -7
  196. package/foundation/identity/providers.mjs +0 -16
  197. package/foundation/integrations/provider-conflicts.test.mjs +0 -125
@@ -2,402 +2,84 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import {useMemo, useState} from 'react';
6
- import * as stylex from '@stylexjs/stylex';
7
- import {
8
- borderVars,
9
- colorVars,
10
- radiusVars,
11
- } from '@astryxdesign/core/theme/tokens.stylex';
5
+ import {useState} from 'react';
12
6
  import {Toolbar} from '@astryxdesign/core/Toolbar';
13
7
  import {Selector} from '@astryxdesign/core/Selector';
14
8
  import {TextInput} from '@astryxdesign/core/TextInput';
15
- import {OverflowList} from '@astryxdesign/core/OverflowList';
16
- import {Popover} from '@astryxdesign/core/Popover';
17
- import {Button} from '@astryxdesign/core/Button';
18
- import {Icon} from '@astryxdesign/core/Icon';
19
- import {Link} from '@astryxdesign/core/Link';
20
- import {Text, Heading} from '@astryxdesign/core/Text';
21
- import {CheckboxList, CheckboxListItem} from '@astryxdesign/core/CheckboxList';
22
- import {Stack, StackItem, HStack, VStack} from '@astryxdesign/core/Layout';
23
- import {Section} from '@astryxdesign/core/Section';
24
- import {Table, pixel, proportional} from '@astryxdesign/core/Table';
25
- import type {TableColumn} from '@astryxdesign/core/Table';
26
- import {EmptyState} from '@astryxdesign/core/EmptyState';
27
- import {Columns3Cog, Search} from 'lucide-react';
28
-
29
- interface Job extends Record<string, unknown> {
30
- id: string;
31
- job: string;
32
- customer: string;
33
- status: string;
34
- priority: string;
35
- }
36
-
37
- const JOBS: Job[] = [
38
- {
39
- id: 'SJ-2136',
40
- job: 'VAV zones not cooling',
41
- customer: 'Northgate Dental',
42
- status: 'In progress',
43
- priority: 'High',
44
- },
45
- {
46
- id: 'SJ-2135',
47
- job: 'Exhaust fan noise',
48
- customer: 'Riverside Club',
49
- status: 'On hold',
50
- priority: 'Normal',
51
- },
52
- {
53
- id: 'SJ-2134',
54
- job: 'Humidifier board fault',
55
- customer: 'Summit Medical',
56
- status: 'Overdue',
57
- priority: 'High',
58
- },
59
- {
60
- id: 'SJ-2133',
61
- job: 'Economizer stuck shut',
62
- customer: 'Northgate Dental',
63
- status: 'Scheduled',
64
- priority: 'Normal',
65
- },
66
- {
67
- id: 'SJ-2101',
68
- job: 'Contactor replacement',
69
- customer: 'Harborview Hotel',
70
- status: 'Completed',
71
- priority: 'Low',
72
- },
73
- ];
74
-
75
- // One entry per filterable field. The closed trigger reads as the bare field
76
- // name unset, and renderValue expands a set one to the whole clause, so each
77
- // Selector doubles as its own filter chip.
78
- const FIELDS = [
79
- {
80
- key: 'status',
81
- label: 'Status',
82
- options: ['Scheduled', 'In progress', 'On hold', 'Overdue', 'Completed'],
83
- },
84
- {key: 'priority', label: 'Priority', options: ['High', 'Normal', 'Low']},
85
- {
86
- key: 'customer',
87
- label: 'Customer',
88
- options: [
89
- 'Northgate Dental',
90
- 'Riverside Club',
91
- 'Summit Medical',
92
- 'Harborview Hotel',
93
- ],
94
- },
95
- ];
96
-
97
- const COLUMNS: TableColumn<Job>[] = [
98
- {key: 'job', header: 'Job', width: proportional(2)},
99
- {key: 'customer', header: 'Customer', width: proportional(2)},
100
- {key: 'status', header: 'Status', width: pixel(110)},
101
- {key: 'priority', header: 'Priority', width: pixel(90)},
102
- ];
103
-
104
- /**
105
- * Width held back inside the clause slot for the readout that sits in it.
106
- *
107
- * The readout lives in the slot the overflow list measures, so without this
108
- * the list would count its width as room for another clause and push it off
109
- * the end. The slot pays for it as padding — the one part of the box the
110
- * measurement already subtracts — and the readout takes it back with a
111
- * matching negative margin, so it draws over the reserve and still lands
112
- * against the last clause rather than at the row's far edge.
113
- */
114
- const READOUT_RESERVE = 116;
115
-
116
- const styles = stylex.create({
117
- toolbarRow: {
118
- // Grow so the row spans the toolbar: the clause slot inside it can only
119
- // measure the width it is actually given.
120
- flexGrow: 1,
121
- minWidth: 0,
122
- },
123
- // Containment, not just a min-width reset: the reset lets flex squeeze this
124
- // slot, but the toolbar's own slot still floors at the width this one
125
- // reports it needs — the clauses at full length. Containment makes that
126
- // report independent of the clauses, so the row settles inside the toolbar
127
- // and the list finally reads a width that narrows. The popover it opens is
128
- // portalled, so nothing the reader needs is inside the clip.
129
- clauseSlot: {
130
- display: 'flex',
131
- alignItems: 'center',
132
- minWidth: 0,
133
- overflow: 'hidden',
134
- containerType: 'inline-size',
135
- // The held-back width, as padding (see READOUT_RESERVE).
136
- paddingInlineEnd: READOUT_RESERVE,
137
- },
138
- // Fixed: the field is the row's anchor, so it keeps one width in every
139
- // state. It still gives before the readout does, but only once the clauses
140
- // have folded away and there is nothing else left to take.
141
- searchSlot: {
142
- flexShrink: 1,
143
- minWidth: 120,
144
- width: 120,
145
- },
146
- // The fill a control switches to once it carries a value, so a set clause is
147
- // legible as engaged at a glance rather than only by reading it. This is the
148
- // token ToggleButton paints for its own pressed state, so a set selector and
149
- // a pressed control land on the same value over the same backdrop instead of
150
- // two neighbouring shades of engaged.
151
- filterFill: {
152
- backgroundColor: colorVars['--color-overlay-pressed'],
153
- },
154
- // A ghost Button has no chrome at all, so the border is what puts the count
155
- // in the same family as the unset selectors it stands in for. Left unfilled
156
- // deliberately: the fill means "this control carries a value", and the count
157
- // carries none of its own — it stands in for clauses that may or may not be
158
- // set.
159
- overflowChip: {
160
- borderWidth: borderVars['--border-width'],
161
- borderStyle: 'solid',
162
- borderColor: colorVars['--color-border-emphasized'],
163
- borderRadius: radiusVars['--radius-element'],
164
- backgroundColor: colorVars['--color-background-surface'],
165
- },
166
- // Shrink-wrapped to the clauses actually on the row. As a flex item the
167
- // list's basis is its unfolded content, which is wider than the slot, so it
168
- // would otherwise settle at the slot's full width and strand the readout at
169
- // the far edge with a gap where the folded clauses used to be. The list
170
- // measures the slot, not itself, so sizing it to its visible children costs
171
- // the fold nothing.
172
- clauseList: {
173
- flexGrow: 0,
174
- flexShrink: 0,
175
- width: 'max-content',
176
- maxWidth: '100%',
177
- },
178
- // Takes back the width the slot held back for it, so the readout draws over
179
- // the reserve and lands against the last clause. The gap to that clause is a
180
- // margin rather than the row's `gap`, because a gap would fall on the
181
- // measured side of the reserve and cost the clauses those pixels.
182
- readout: {
183
- flexShrink: 0,
184
- whiteSpace: 'nowrap',
185
- marginInlineStart: 8,
186
- marginInlineEnd: -READOUT_RESERVE,
187
- },
188
- viewPanel: {
189
- width: 320,
190
- },
191
- });
9
+ import {MoreMenu} from '@astryxdesign/core/MoreMenu';
10
+ import {Stack} from '@astryxdesign/core/Layout';
11
+ import {Table} from '@astryxdesign/core/Table';
12
+ import {MagnifyingGlassIcon} from '@heroicons/react/24/outline';
192
13
 
193
14
  export default function ToolbarTableFilter() {
194
15
  const [search, setSearch] = useState('');
195
- const [clauses, setClauses] = useState<Record<string, string | null>>({});
196
- const [columnKeys, setColumnKeys] = useState(COLUMNS.map(c => c.key));
197
-
198
- const hasFilters =
199
- search !== '' || Object.values(clauses).some(value => value != null);
200
-
201
- const clearAll = () => {
202
- setSearch('');
203
- setClauses({});
204
- };
205
-
206
- // Search and every clause narrow one pass, so the table answers the whole
207
- // bar rather than whichever control moved last.
208
- const results = useMemo(() => {
209
- const query = search.trim().toLowerCase();
210
- return JOBS.filter(
211
- row =>
212
- (query === '' ||
213
- `${row.job} ${row.customer}`.toLowerCase().includes(query)) &&
214
- FIELDS.every(
215
- field =>
216
- clauses[field.key] == null || row[field.key] === clauses[field.key],
217
- ),
218
- );
219
- }, [search, clauses]);
220
-
221
- // One flat array rather than inline JSX: OverflowList hands its renderer the
222
- // indices of the clauses it had to hide, so the row and the folded panel have
223
- // to read from the same list for those indices to mean anything.
224
- const clauseControls = FIELDS.map(field => (
225
- <Selector
226
- key={field.key}
227
- label={`${field.label} filter`}
228
- isLabelHidden
229
- placeholder={field.label}
230
- size="sm"
231
- hasClear
232
- options={field.options}
233
- value={clauses[field.key] ?? null}
234
- xstyle={clauses[field.key] != null ? styles.filterFill : undefined}
235
- onChange={value => setClauses(prev => ({...prev, [field.key]: value}))}
236
- renderValue={option =>
237
- `${field.label} is ${option.label ?? option.value}`
238
- }
239
- />
240
- ));
241
-
242
- const viewOptions = (
243
- <VStack gap={3} xstyle={styles.viewPanel}>
244
- <Heading level={3}>Columns</Heading>
245
- <CheckboxList
246
- label="Displayed columns"
247
- isLabelHidden
248
- density="compact"
249
- value={columnKeys}
250
- onChange={setColumnKeys}>
251
- {COLUMNS.map(column => (
252
- <CheckboxListItem
253
- key={column.key}
254
- value={column.key}
255
- label={String(column.header)}
256
- />
257
- ))}
258
- </CheckboxList>
259
- </VStack>
260
- );
16
+ const [status, setStatus] = useState<string | null>(null);
17
+ const [priority, setPriority] = useState<string | null>(null);
261
18
 
262
19
  return (
263
- // Section, not a bare stack: the toolbar row and the table's first column
264
- // have to start on the same line, and the container publishes the padding
265
- // both read — the toolbar pads to it, and the table bleeds edge to edge
266
- // and compensates its outer cells back to it. Transparent and borderless,
267
- // because whatever hosts this block already paints its own frame.
268
- <Section variant="transparent" padding={2} width="100%" height="100%">
20
+ <Stack direction="vertical" style={{width: '100%'}}>
269
21
  <Toolbar
270
- label="Job filters"
22
+ label="Table filters"
271
23
  size="sm"
272
24
  dividers={['bottom']}
273
25
  startContent={
274
- // One full-width row rather than the toolbar's own two slots: the
275
- // overflow list has to measure the width it actually has, and a slot
276
- // sized by its own contents would feed the list its own output —
277
- // fold a clause, the slot narrows, the list folds again.
278
- <HStack
279
- gap={2}
280
- vAlign="center"
281
- wrap="nowrap"
282
- xstyle={styles.toolbarRow}>
283
- {/* Search leads the row as the broadest filter, and sits outside
284
- the overflow list so it is never the clause that folds — a
285
- hidden search box reads as a missing feature, not a folded
286
- one. */}
287
- <StackItem xstyle={styles.searchSlot}>
288
- <TextInput
289
- label="Search jobs"
290
- isLabelHidden
291
- placeholder="Search"
292
- size="sm"
293
- width="100%"
294
- value={search}
295
- onChange={setSearch}
296
- startIcon={Search}
297
- hasClear
298
- />
299
- </StackItem>
300
- {/* The slot, not the list, carries the sizing: as the row's only
301
- grower it settles at whatever the search box and the trailing
302
- controls leave, and the list reads that. */}
303
- <StackItem size="fill" xstyle={styles.clauseSlot}>
304
- <OverflowList
305
- behavior="observeParent"
306
- gap={2}
307
- xstyle={styles.clauseList}
308
- // No floor on how many stay out: at this width a set clause
309
- // reads as a whole sentence ("Status is Overdue"), and pinning
310
- // one to the row would push the readout off the end. The count
311
- // is what stays, and it opens onto every clause.
312
- minVisibleItems={0}
313
- overflowRenderer={overflowItems => (
314
- <Popover
315
- placement="below"
316
- alignment="start"
317
- width={240}
318
- label={`${overflowItems.length} more filters`}
319
- content={
320
- <VStack gap={2}>
321
- {overflowItems.map(({child, index}) => (
322
- <Stack key={index} direction="vertical">
323
- {child}
324
- </Stack>
325
- ))}
326
- </VStack>
327
- }>
328
- <Button
329
- label={`+${overflowItems.length}`}
330
- tooltip={`${overflowItems.length} more filters`}
331
- variant="ghost"
332
- size="sm"
333
- xstyle={styles.overflowChip}
334
- />
335
- </Popover>
336
- )}>
337
- {clauseControls}
338
- </OverflowList>
339
-
340
- {/* Inside the slot rather than beside it: a sibling would sit
341
- after the slot, and the slot spans the row's leftover, so the
342
- readout would land at the trailing edge however few clauses
343
- were showing. In here it follows the clauses, and the reserve
344
- is what stops the list from spending the width it needs. */}
345
- <HStack
346
- gap={2}
347
- vAlign="center"
348
- wrap="nowrap"
349
- xstyle={styles.readout}>
350
- <Text type="supporting" color="secondary">
351
- {results.length} of {JOBS.length}
352
- </Text>
353
- {hasFilters && (
354
- <>
355
- <Text type="supporting" color="secondary">
356
- •
357
- </Text>
358
- {/* Href-less, so Link renders a button: this resets the
359
- filters, it does not navigate. */}
360
- <Link type="supporting" onClick={clearAll}>
361
- Clear all
362
- </Link>
363
- </>
364
- )}
365
- </HStack>
366
- </StackItem>
367
- {/* View options closes the row: it acts on the table, not on the
368
- filter set, so it stands apart from the clauses. */}
369
- <Popover
370
- placement="below"
371
- alignment="end"
372
- label="View options"
373
- content={viewOptions}>
374
- <Button
375
- label="View options"
376
- tooltip="View options"
377
- isIconOnly
378
- variant="ghost"
379
- size="sm"
380
- icon={<Icon icon={Columns3Cog} size="sm" color="secondary" />}
381
- />
382
- </Popover>
383
- </HStack>
26
+ <>
27
+ <TextInput
28
+ label="Search"
29
+ isLabelHidden
30
+ placeholder="Search..."
31
+ value={search}
32
+ onChange={setSearch}
33
+ startIcon={MagnifyingGlassIcon}
34
+ />
35
+ <Selector
36
+ label="Status"
37
+ isLabelHidden
38
+ placeholder="Status"
39
+ hasClear
40
+ value={status}
41
+ onChange={setStatus}
42
+ options={['Open', 'In progress', 'Done']}
43
+ />
44
+ <Selector
45
+ label="Priority"
46
+ isLabelHidden
47
+ placeholder="Priority"
48
+ hasClear
49
+ value={priority}
50
+ onChange={setPriority}
51
+ options={['High', 'Medium', 'Low']}
52
+ />
53
+ </>
54
+ }
55
+ endContent={
56
+ <MoreMenu
57
+ items={[
58
+ {label: 'Compact view'},
59
+ {label: 'Comfortable view'},
60
+ {label: 'Export CSV'},
61
+ ]}
62
+ />
384
63
  }
385
64
  />
386
- {results.length === 0 ? (
387
- <EmptyState
388
- isCompact
389
- title="No jobs match these filters"
390
- actions={<Button label="Clear all" size="sm" onClick={clearAll} />}
391
- />
392
- ) : (
393
- <Table
394
- idKey="id"
395
- density="compact"
396
- textOverflow="truncate"
397
- columns={COLUMNS.filter(column => columnKeys.includes(column.key))}
398
- data={results}
399
- />
400
- )}
401
- </Section>
65
+ <Table
66
+ idKey="id"
67
+ columns={[
68
+ {key: 'task', header: 'Task'},
69
+ {key: 'status', header: 'Status'},
70
+ {key: 'priority', header: 'Priority'},
71
+ ]}
72
+ data={[
73
+ {id: '1', task: 'Fix login bug', status: 'Open', priority: 'High'},
74
+ {
75
+ id: '2',
76
+ task: 'Update docs',
77
+ status: 'In progress',
78
+ priority: 'Medium',
79
+ },
80
+ {id: '3', task: 'Add unit tests', status: 'Open', priority: 'Low'},
81
+ ]}
82
+ />
83
+ </Stack>
402
84
  );
403
85
  }
@@ -28,27 +28,5 @@ export type MutuallyAssignable<A, B> = [A] extends [B]
28
28
  : false
29
29
  : false;
30
30
 
31
- /**
32
- * `T` without string or number index signatures, at every depth. A
33
- * `.passthrough()` schema infers one and a hand-written interface never has
34
- * one, so a lock drops them before comparing named fields. Recursive fields
35
- * that a schema casts to their public type compare equal by construction.
36
- */
37
- export type NamedFields<T> = T extends readonly (infer U)[]
38
- ? NamedFields<U>[]
39
- : T extends (...args: never[]) => unknown
40
- ? T
41
- : T extends object
42
- ? {
43
- [
44
- K in keyof T as string extends K
45
- ? never
46
- : number extends K
47
- ? never
48
- : K
49
- ]: NamedFields<T[K]>;
50
- }
51
- : T;
52
-
53
31
  /** Compiles only when `T` is exactly `true`; otherwise a type error. */
54
32
  export type Expect<T extends true> = T;
@@ -63,13 +63,11 @@ export const doc = {
63
63
  name: 'file.path',
64
64
  type: 'string',
65
65
  description: 'Absolute path to the file being transformed.',
66
- required: true,
67
66
  },
68
67
  {
69
68
  name: 'file.source',
70
69
  type: 'string',
71
70
  description: 'The current source contents of the file.',
72
- required: true,
73
71
  },
74
72
  ],
75
73
  },
@@ -83,21 +81,18 @@ export const doc = {
83
81
  type: 'unknown',
84
82
  description:
85
83
  'A jscodeshift instance configured with a parser for the file.',
86
- required: true,
87
84
  },
88
85
  {
89
86
  name: 'api.stats',
90
87
  type: '(...args: unknown[]) => void',
91
88
  description:
92
89
  'Report a statistic (no-op-friendly; provided for jscodeshift parity).',
93
- required: true,
94
90
  },
95
91
  {
96
92
  name: 'api.report',
97
93
  type: '(...args: unknown[]) => void',
98
94
  description:
99
95
  'Report progress (no-op-friendly; provided for jscodeshift parity).',
100
- required: true,
101
96
  },
102
97
  ],
103
98
  },
@@ -105,7 +100,7 @@ export const doc = {
105
100
  },
106
101
  {
107
102
  name: 'type',
108
- type: "'code' | 'config'",
103
+ type: "'code'",
109
104
  description:
110
105
  "Discriminant for the file-transforming variant. Use 'config' for a " +
111
106
  'codemod that rewrites astryx.config.* instead (see notes).',
@@ -5,8 +5,8 @@
5
5
  * Compile-time drift-lock: sealed envelope must infer exactly the public
6
6
  * stamped-codemod union.
7
7
  *
8
- * @typedef {import('../_shared/contract.js').Expect<
9
- * import('../_shared/contract.js').Equal<
8
+ * @typedef {import('../_shared/contract').Expect<
9
+ * import('../_shared/contract').Equal<
10
10
  * z.infer<typeof codemodEnvelopeSchema>,
11
11
  * AstryxCodemod | AstryxConfigCodemod
12
12
  * >
@@ -24,10 +24,10 @@ export function parseCodemod(input: unknown, label?: string): AstryxCodemod | As
24
24
  * Compile-time drift-lock: sealed envelope must infer exactly the public
25
25
  * stamped-codemod union.
26
26
  */
27
- export type _CodemodDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof codemodEnvelopeSchema>, AstryxCodemod | AstryxConfigCodemod>>;
28
- export type AstryxCodemod = import("./type.js").AstryxCodemod;
29
- export type AstryxConfigCodemod = import("./type.js").AstryxConfigCodemod;
30
- export type AstryxCodemodTransform = import("./type.js").AstryxCodemodTransform;
27
+ export type _CodemodDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").Equal<z.infer<typeof codemodEnvelopeSchema>, AstryxCodemod | AstryxConfigCodemod>>;
28
+ export type AstryxCodemod = import("./type").AstryxCodemod;
29
+ export type AstryxConfigCodemod = import("./type").AstryxConfigCodemod;
30
+ export type AstryxCodemodTransform = import("./type").AstryxCodemodTransform;
31
31
  import { z } from 'zod';
32
32
  /**
33
33
  * The load-boundary contract: a stamped codemod default export, discriminated
@@ -38,13 +38,13 @@ declare const codemodEnvelopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
38
38
  description: z.ZodOptional<z.ZodString>;
39
39
  isOptional: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
40
40
  fileExtensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
- transform: z.ZodType<import("./type.js").AstryxCodemodTransform, any, z.core.$ZodTypeInternals<import("./type.js").AstryxCodemodTransform, any>>;
41
+ transform: z.ZodType<import("./type").AstryxCodemodTransform, any, z.core.$ZodTypeInternals<import("./type").AstryxCodemodTransform, any>>;
42
42
  type: z.ZodLiteral<"code">;
43
43
  }, z.core.$strict>, z.ZodObject<{
44
44
  title: z.ZodString;
45
45
  description: z.ZodOptional<z.ZodString>;
46
46
  isOptional: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
47
- transform: z.ZodType<import("./type.js").AstryxCodemodTransform, any, z.core.$ZodTypeInternals<import("./type.js").AstryxCodemodTransform, any>>;
47
+ transform: z.ZodType<import("./type").AstryxCodemodTransform, any, z.core.$ZodTypeInternals<import("./type").AstryxCodemodTransform, any>>;
48
48
  type: z.ZodLiteral<"config">;
49
49
  }, z.core.$strict>], "type">;
50
50
  export {};
@@ -10,14 +10,12 @@
10
10
  import {z} from 'zod';
11
11
  import {formatZodError} from '../_shared/errors.mjs';
12
12
 
13
- /** @typedef {import('./type.js').AstryxCodemod} AstryxCodemod */
14
- /** @typedef {import('./type.js').AstryxConfigCodemod} AstryxConfigCodemod */
15
- /** @typedef {import('./type.js').AstryxCodemodTransform} AstryxCodemodTransform */
13
+ /** @typedef {import('./type').AstryxCodemod} AstryxCodemod */
14
+ /** @typedef {import('./type').AstryxConfigCodemod} AstryxConfigCodemod */
15
+ /** @typedef {import('./type').AstryxCodemodTransform} AstryxCodemodTransform */
16
16
 
17
17
  const transform = /** @type {z.ZodType<AstryxCodemodTransform>} */ (
18
- z.custom(value => typeof value === 'function', {
19
- message: 'Expected a function',
20
- })
18
+ z.custom(value => typeof value === 'function', {message: 'Expected a function'})
21
19
  );
22
20
 
23
21
  const codeCodemodSchema = z
@@ -54,8 +52,8 @@ const codemodEnvelopeSchema = z.discriminatedUnion('type', [
54
52
  * Compile-time drift-lock: sealed envelope must infer exactly the public
55
53
  * stamped-codemod union.
56
54
  *
57
- * @typedef {import('../_shared/contract.js').Expect<
58
- * import('../_shared/contract.js').Equal<
55
+ * @typedef {import('../_shared/contract').Expect<
56
+ * import('../_shared/contract').Equal<
59
57
  * z.infer<typeof codemodEnvelopeSchema>,
60
58
  * AstryxCodemod | AstryxConfigCodemod
61
59
  * >
@@ -6,8 +6,8 @@
6
6
  * {@link AstryxConfig} type. If they drift, `Equal` becomes `false` and
7
7
  * `Expect<false>` fails the `tsconfig.authoring-contract.json` typecheck.
8
8
  *
9
- * @typedef {import('../_shared/contract.js').Expect<
10
- * import('../_shared/contract.js').MutuallyAssignable<z.infer<typeof configSchema>, AstryxConfig>
9
+ * @typedef {import('../_shared/contract').Expect<
10
+ * import('../_shared/contract').MutuallyAssignable<z.infer<typeof configSchema>, AstryxConfig>
11
11
  * >} _ConfigDriftLock
12
12
  */
13
13
  /**
@@ -23,13 +23,13 @@ export function parseConfig(input: unknown, label?: string): AstryxConfig;
23
23
  * {@link AstryxConfig} type. If they drift, `Equal` becomes `false` and
24
24
  * `Expect<false>` fails the `tsconfig.authoring-contract.json` typecheck.
25
25
  */
26
- export type _ConfigDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").MutuallyAssignable<z.infer<typeof configSchema>, AstryxConfig>>;
27
- export type AstryxConfig = import("./type.js").AstryxConfig;
28
- export type PostCodemodHook = import("./type.js").PostCodemodHook;
29
- export type XleComponent = import("./type.js").XleComponent;
30
- export type DebugConfig = import("./type.js").DebugConfig;
31
- export type DebugEventHandler = import("../debug/type.js").DebugEventHandler;
32
- export type GapReportHandler = import("../gap-report/type.js").GapReportHandler;
26
+ export type _ConfigDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").MutuallyAssignable<z.infer<typeof configSchema>, AstryxConfig>>;
27
+ export type AstryxConfig = import("./type").AstryxConfig;
28
+ export type PostCodemodHook = import("./type").PostCodemodHook;
29
+ export type XleComponent = import("./type").XleComponent;
30
+ export type DebugConfig = import("./type").DebugConfig;
31
+ export type DebugEventHandler = import("../debug/type").DebugEventHandler;
32
+ export type GapReportHandler = import("../gap-report/type").GapReportHandler;
33
33
  import { z } from 'zod';
34
34
  declare const configSchema: z.ZodObject<{
35
35
  integrations: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -40,14 +40,14 @@ declare const configSchema: z.ZodObject<{
40
40
  buildCommand: z.ZodType<(ctx: {
41
41
  packageDir: string;
42
42
  files: string[];
43
- }) => import("./type.js").PostCodemodCommand | null | undefined | Promise<import("./type.js").PostCodemodCommand | null | undefined>, any, z.core.$ZodTypeInternals<(ctx: {
43
+ }) => import("./type").PostCodemodCommand | null | undefined | Promise<import("./type").PostCodemodCommand | null | undefined>, any, z.core.$ZodTypeInternals<(ctx: {
44
44
  packageDir: string;
45
45
  files: string[];
46
- }) => import("./type.js").PostCodemodCommand | null | undefined | Promise<import("./type.js").PostCodemodCommand | null | undefined>, any>>;
46
+ }) => import("./type").PostCodemodCommand | null | undefined | Promise<import("./type").PostCodemodCommand | null | undefined>, any>>;
47
47
  }, z.core.$strict>>>;
48
48
  }, z.core.$strict>>;
49
- debug: z.ZodOptional<z.ZodType<import("../debug/type.js").DebugEventHandler, any, z.core.$ZodTypeInternals<import("../debug/type.js").DebugEventHandler, any>>>;
50
- gapReport: z.ZodOptional<z.ZodType<import("../gap-report/type.js").GapReportHandler, any, z.core.$ZodTypeInternals<import("../gap-report/type.js").GapReportHandler, any>>>;
49
+ debug: z.ZodOptional<z.ZodType<import("../debug/type").DebugEventHandler, any, z.core.$ZodTypeInternals<import("../debug/type").DebugEventHandler, any>>>;
50
+ gapReport: z.ZodOptional<z.ZodType<import("../gap-report/type").GapReportHandler, any, z.core.$ZodTypeInternals<import("../gap-report/type").GapReportHandler, any>>>;
51
51
  experimental: z.ZodOptional<z.ZodObject<{
52
52
  xle: z.ZodOptional<z.ZodObject<{
53
53
  components: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{