@godxjp/ui 33.20.0 → 33.22.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.
Files changed (116) hide show
  1. package/README.md +4 -4
  2. package/agent/START-HERE.md +7 -7
  3. package/agent/components/AppSettingPicker.json +0 -1
  4. package/agent/components/AppShell.json +11 -1
  5. package/agent/components/BlockEditor.json +6 -1
  6. package/agent/components/Button.json +1 -1
  7. package/agent/components/CardShowcase.json +44 -0
  8. package/agent/components/CatalogCard.json +83 -0
  9. package/agent/components/CatalogDetail.json +76 -0
  10. package/agent/components/CatalogDetailSection.json +52 -0
  11. package/agent/components/CatalogDetailTag.json +27 -0
  12. package/agent/components/EditorialArticle.json +53 -0
  13. package/agent/components/EditorialAuth.json +53 -0
  14. package/agent/components/EditorialAuthCard.json +52 -0
  15. package/agent/components/EditorialBanner.json +53 -0
  16. package/agent/components/EditorialBreadcrumb.json +38 -0
  17. package/agent/components/EditorialCard.json +70 -0
  18. package/agent/components/EditorialEmptyPanel.json +57 -0
  19. package/agent/components/EditorialFilterBar.json +51 -0
  20. package/agent/components/EditorialFilterField.json +39 -0
  21. package/agent/components/EditorialFilterPanel.json +46 -0
  22. package/agent/components/EditorialFooter.json +54 -0
  23. package/agent/components/EditorialFootnote.json +36 -0
  24. package/agent/components/EditorialHero.json +52 -0
  25. package/agent/components/EditorialInlineSearch.json +54 -0
  26. package/agent/components/EditorialMasthead.json +52 -0
  27. package/agent/components/EditorialMetaBar.json +37 -0
  28. package/agent/components/EditorialPageHeader.json +73 -0
  29. package/agent/components/EditorialPanel.json +48 -0
  30. package/agent/components/EditorialPillNav.json +41 -0
  31. package/agent/components/EditorialPrompt.json +54 -0
  32. package/agent/components/EditorialSearch.json +112 -0
  33. package/agent/components/EditorialSection.json +68 -0
  34. package/agent/components/EditorialSectionHead.json +62 -0
  35. package/agent/components/EditorialStats.json +32 -0
  36. package/agent/components/EditorialTextButton.json +47 -0
  37. package/agent/components/EditorialToggleGroup.json +52 -0
  38. package/agent/components/EditorialToolbar.json +45 -0
  39. package/agent/components/Eyebrow.json +39 -0
  40. package/agent/components/HoldingCard.json +69 -0
  41. package/agent/components/HoldingCardAction.json +51 -0
  42. package/agent/components/HoldingGrid.json +37 -0
  43. package/agent/components/Markdown.json +6 -0
  44. package/agent/components/NumberInput.json +5 -0
  45. package/agent/components/PriceSummary.json +32 -0
  46. package/agent/components/SettingsLayout.json +31 -0
  47. package/agent/components/SettingsPanel.json +53 -0
  48. package/agent/components/ThemePicker.json +54 -0
  49. package/agent/components/TopbarItem.json +5 -0
  50. package/agent/components-index.json +292 -98
  51. package/agent/components.json +2059 -4
  52. package/agent/index.json +7 -7
  53. package/agent/llms.txt +8 -8
  54. package/agent/tokens.json +5640 -132
  55. package/dist/components/data-display/badge.js +4 -2
  56. package/dist/components/data-display/image.js +6 -0
  57. package/dist/components/data-entry/form-field.js +2 -2
  58. package/dist/components/data-entry/number-input.d.ts +1 -0
  59. package/dist/components/data-entry/number-input.js +8 -0
  60. package/dist/components/data-entry/select.js +24 -2
  61. package/dist/components/general/button.js +14 -1
  62. package/dist/components/general/typography.d.ts +1 -1
  63. package/dist/components/layout/app-shell.d.ts +1 -1
  64. package/dist/components/layout/app-shell.js +28 -2
  65. package/dist/components/layout/centered-shell.js +4 -0
  66. package/dist/components/layout/editorial-account.d.ts +51 -0
  67. package/dist/components/layout/editorial-account.js +466 -0
  68. package/dist/components/layout/editorial-catalog.d.ts +18 -0
  69. package/dist/components/layout/editorial-catalog.js +164 -0
  70. package/dist/components/layout/editorial.d.ts +56 -0
  71. package/dist/components/layout/editorial.js +867 -0
  72. package/dist/components/layout/index.d.ts +6 -0
  73. package/dist/components/layout/index.js +98 -0
  74. package/dist/components/layout/mobile-shell.d.ts +2 -0
  75. package/dist/components/layout/mobile-shell.js +18 -11
  76. package/dist/components/layout/responsive-grid.js +9 -1
  77. package/dist/components/layout/topbar-item.d.ts +1 -0
  78. package/dist/components/layout/topbar-item.js +2 -0
  79. package/dist/contracts/measurement.json +1 -1
  80. package/dist/lab/legal-document-shell.js +61 -51
  81. package/dist/lib/toast-clearance.js +1 -1
  82. package/dist/props/components/data-display.prop.d.ts +2 -0
  83. package/dist/props/components/data-entry.prop.d.ts +9 -0
  84. package/dist/props/components/editorial-account.prop.d.ts +249 -0
  85. package/dist/props/components/editorial-account.prop.js +0 -0
  86. package/dist/props/components/general.prop.d.ts +6 -2
  87. package/dist/props/components/layout.prop.d.ts +602 -2
  88. package/dist/props/registry.d.ts +1124 -0
  89. package/dist/props/registry.js +792 -0
  90. package/dist/styles/badge-layout.css +2 -0
  91. package/dist/styles/control.css +60 -13
  92. package/dist/styles/core.css +1 -0
  93. package/dist/styles/data-display-layout.css +9 -3
  94. package/dist/styles/editorial-account-layout.css +1130 -0
  95. package/dist/styles/focus-ring.css +33 -10
  96. package/dist/styles/form-layout.css +8 -1
  97. package/dist/styles/index.css +1 -0
  98. package/dist/styles/layers.json +248 -1
  99. package/dist/styles/layout.css +2031 -0
  100. package/dist/styles/logo-layout.css +27 -0
  101. package/dist/styles/shell-layout.css +101 -3
  102. package/dist/styles/table-layout.css +25 -13
  103. package/dist/styles/text-layout.css +6 -0
  104. package/dist/styles.css +1 -1
  105. package/dist/tokens/base.css +2 -0
  106. package/dist/tokens/components/badge.css +3 -0
  107. package/dist/tokens/components/control.css +9 -0
  108. package/dist/tokens/components/editorial-account.css +393 -0
  109. package/dist/tokens/components/editorial.css +721 -0
  110. package/dist/tokens/components/form.css +4 -0
  111. package/dist/tokens/components/logo.css +2 -0
  112. package/dist/tokens/components/shell.css +23 -0
  113. package/dist/tokens/components/table.css +1 -1
  114. package/docs/TOKENS.md +26 -0
  115. package/package.json +2 -2
  116. package/scripts/ui-audit.mjs +3 -2
@@ -0,0 +1,466 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Check, Search } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ const headingTag = (level) => level === 3 ? "h3" : "h2";
7
+ function EditorialToggleGroup({
8
+ items,
9
+ value,
10
+ onValueChange,
11
+ variant = "text",
12
+ className,
13
+ ...rest
14
+ }) {
15
+ return /* @__PURE__ */ jsx(
16
+ "div",
17
+ {
18
+ role: "group",
19
+ "aria-label": rest["aria-label"],
20
+ "data-slot": "editorial-toggle-group",
21
+ "data-variant": variant,
22
+ className: cn("ui-editorial-toggle-group", className),
23
+ children: items.map((item) => /* @__PURE__ */ jsxs(
24
+ "button",
25
+ {
26
+ type: "button",
27
+ "aria-pressed": item.value === value,
28
+ "aria-label": variant === "icon" ? item.label : void 0,
29
+ title: variant === "icon" ? item.label : void 0,
30
+ className: "ui-editorial-toggle-group-option ui-focus-ring",
31
+ onClick: () => onValueChange(item.value),
32
+ children: [
33
+ item.icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-editorial-toggle-group-icon", children: item.icon }),
34
+ variant === "text" && item.label
35
+ ]
36
+ },
37
+ item.value
38
+ ))
39
+ }
40
+ );
41
+ }
42
+ function EditorialMetaBar({ icon, start, end, className }) {
43
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "editorial-meta-bar", className: cn("ui-editorial-meta-bar", className), children: [
44
+ /* @__PURE__ */ jsxs("span", { className: "ui-editorial-meta-bar-start", children: [
45
+ icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-editorial-meta-bar-icon", children: icon }),
46
+ start
47
+ ] }),
48
+ end != null && /* @__PURE__ */ jsx("span", { className: "ui-editorial-meta-bar-end", children: end })
49
+ ] });
50
+ }
51
+ function EditorialEmptyPanel({
52
+ variant = "guest",
53
+ eyebrow,
54
+ title,
55
+ level,
56
+ description,
57
+ actions,
58
+ icon,
59
+ className
60
+ }) {
61
+ const Heading = headingTag(level);
62
+ return /* @__PURE__ */ jsxs(
63
+ "div",
64
+ {
65
+ "data-slot": "editorial-empty-panel",
66
+ "data-variant": variant,
67
+ className: cn("ui-editorial-empty-panel", className),
68
+ children: [
69
+ variant === "guest" ? /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "ui-editorial-empty-panel-art", children: [
70
+ /* @__PURE__ */ jsx("span", {}),
71
+ /* @__PURE__ */ jsx("span", {}),
72
+ /* @__PURE__ */ jsx("span", {})
73
+ ] }) : icon != null && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "ui-editorial-empty-panel-icon", children: icon }),
74
+ eyebrow,
75
+ /* @__PURE__ */ jsx(Heading, { className: "ui-editorial-empty-panel-title", children: title }),
76
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-empty-panel-description", children: description }),
77
+ actions != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-empty-panel-actions", children: actions })
78
+ ]
79
+ }
80
+ );
81
+ }
82
+ function EditorialStats({ items, className, ...rest }) {
83
+ return /* @__PURE__ */ jsx(
84
+ "ul",
85
+ {
86
+ "aria-label": rest["aria-label"],
87
+ "data-slot": "editorial-stats",
88
+ className: cn("ui-editorial-stats", className),
89
+ children: items.map((item, index) => /* @__PURE__ */ jsxs("li", { className: "ui-editorial-stats-item", children: [
90
+ /* @__PURE__ */ jsx("span", { className: "ui-editorial-stats-label", children: item.label }),
91
+ /* @__PURE__ */ jsxs("strong", { className: "ui-editorial-stats-value", children: [
92
+ item.value,
93
+ item.unit != null && /* @__PURE__ */ jsx("small", { className: "ui-editorial-stats-unit", children: item.unit })
94
+ ] }),
95
+ item.note != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-stats-note", children: item.note })
96
+ ] }, index))
97
+ }
98
+ );
99
+ }
100
+ function EditorialToolbar({
101
+ summary,
102
+ start,
103
+ end,
104
+ divider = false,
105
+ className
106
+ }) {
107
+ const hasSummary = summary != null && (summary.count != null || summary.note != null);
108
+ return /* @__PURE__ */ jsxs(
109
+ "div",
110
+ {
111
+ "data-slot": "editorial-toolbar",
112
+ "data-summary": hasSummary ? "" : void 0,
113
+ "data-divider": divider ? "" : void 0,
114
+ className: cn("ui-editorial-toolbar", className),
115
+ children: [
116
+ hasSummary && /* @__PURE__ */ jsxs("div", { className: "ui-editorial-toolbar-summary", children: [
117
+ summary.count != null && /* @__PURE__ */ jsx("p", { "aria-live": "polite", className: "ui-editorial-toolbar-count", children: summary.count }),
118
+ summary.note != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-toolbar-note", children: summary.note })
119
+ ] }),
120
+ start != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-toolbar-start", children: start }),
121
+ end != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-toolbar-end", children: end })
122
+ ]
123
+ }
124
+ );
125
+ }
126
+ function HoldingGrid({ view = "grid", children, className, ...rest }) {
127
+ return /* @__PURE__ */ jsx(
128
+ "ul",
129
+ {
130
+ "aria-label": rest["aria-label"],
131
+ "data-slot": "holding-grid",
132
+ "data-view": view,
133
+ className: cn("ui-holding-grid", className),
134
+ children: React.Children.map(
135
+ children,
136
+ (child) => child == null || child === false ? null : /* @__PURE__ */ jsx("li", { className: "ui-holding-grid-item", children: child })
137
+ )
138
+ }
139
+ );
140
+ }
141
+ function HoldingCard({
142
+ media,
143
+ overline,
144
+ title,
145
+ level,
146
+ meta,
147
+ tags,
148
+ purchase,
149
+ date,
150
+ actions,
151
+ className
152
+ }) {
153
+ const Heading = headingTag(level);
154
+ const mediaBox = React.isValidElement(media) ? React.cloneElement(media, {
155
+ className: cn("ui-holding-card-media", media.props.className)
156
+ }) : /* @__PURE__ */ jsx("div", { className: "ui-holding-card-media", children: media });
157
+ return /* @__PURE__ */ jsxs("article", { "data-slot": "holding-card", className: cn("ui-holding-card", className), children: [
158
+ mediaBox,
159
+ /* @__PURE__ */ jsxs("div", { className: "ui-holding-card-body", children: [
160
+ overline != null && /* @__PURE__ */ jsx("p", { className: "ui-holding-card-overline", children: overline }),
161
+ /* @__PURE__ */ jsx(Heading, { className: "ui-holding-card-title", children: title }),
162
+ meta != null && /* @__PURE__ */ jsx("p", { className: "ui-holding-card-meta", children: meta }),
163
+ tags != null && tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "ui-holding-card-tags", children: tags.map((tag, index) => /* @__PURE__ */ jsx("span", { className: "ui-holding-card-tag", children: tag }, index)) }),
164
+ purchase != null && /* @__PURE__ */ jsxs("div", { className: "ui-holding-card-purchase", children: [
165
+ /* @__PURE__ */ jsx("span", { className: "ui-holding-card-purchase-label", children: purchase.label }),
166
+ /* @__PURE__ */ jsx("strong", { className: "ui-holding-card-purchase-value", children: purchase.value })
167
+ ] }),
168
+ date != null && /* @__PURE__ */ jsx("p", { className: "ui-holding-card-date", children: date }),
169
+ actions != null && /* @__PURE__ */ jsx("div", { className: "ui-holding-card-actions", children: actions })
170
+ ] })
171
+ ] });
172
+ }
173
+ function HoldingCardAction({
174
+ icon,
175
+ children,
176
+ asChild,
177
+ onClick,
178
+ disabled,
179
+ className,
180
+ ...rest
181
+ }) {
182
+ const glyph = icon != null ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-holding-card-action-icon", children: icon }) : null;
183
+ if (asChild && React.isValidElement(children)) {
184
+ const child = children;
185
+ return React.cloneElement(
186
+ child,
187
+ {
188
+ "aria-label": rest["aria-label"],
189
+ className: cn("ui-holding-card-action ui-focus-ring", className, child.props.className)
190
+ },
191
+ /* @__PURE__ */ jsxs(Fragment, { children: [
192
+ glyph,
193
+ child.props.children
194
+ ] })
195
+ );
196
+ }
197
+ return /* @__PURE__ */ jsxs(
198
+ "button",
199
+ {
200
+ type: "button",
201
+ "aria-label": rest["aria-label"],
202
+ disabled,
203
+ onClick,
204
+ className: cn("ui-holding-card-action ui-focus-ring", className),
205
+ children: [
206
+ glyph,
207
+ children
208
+ ]
209
+ }
210
+ );
211
+ }
212
+ function SettingsLayout({ aside, children, className }) {
213
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "settings-layout", className: cn("ui-settings-layout", className), children: [
214
+ aside != null && /* @__PURE__ */ jsx("aside", { className: "ui-settings-layout-aside", children: aside }),
215
+ /* @__PURE__ */ jsx("div", { className: "ui-settings-layout-panels", children })
216
+ ] });
217
+ }
218
+ function SettingsPanel({
219
+ number,
220
+ title,
221
+ level,
222
+ description,
223
+ children,
224
+ titleId,
225
+ className
226
+ }) {
227
+ const Heading = headingTag(level);
228
+ return /* @__PURE__ */ jsxs(
229
+ "section",
230
+ {
231
+ "aria-labelledby": titleId,
232
+ "data-slot": "settings-panel",
233
+ className: cn("ui-settings-panel", className),
234
+ children: [
235
+ /* @__PURE__ */ jsxs("div", { className: "ui-settings-panel-head", children: [
236
+ number != null && /* @__PURE__ */ jsx("span", { className: "ui-settings-panel-number", children: number }),
237
+ /* @__PURE__ */ jsxs("div", { children: [
238
+ /* @__PURE__ */ jsx(Heading, { id: titleId, className: "ui-settings-panel-title", children: title }),
239
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-settings-panel-description", children: description })
240
+ ] })
241
+ ] }),
242
+ children
243
+ ]
244
+ }
245
+ );
246
+ }
247
+ function ThemePicker({
248
+ legend,
249
+ options,
250
+ value,
251
+ defaultValue,
252
+ onValueChange,
253
+ name,
254
+ className
255
+ }) {
256
+ const reactId = React.useId();
257
+ const groupName = name ?? `theme-picker-${reactId}`;
258
+ const [inner, setInner] = React.useState(defaultValue);
259
+ const current = value !== void 0 ? value : inner;
260
+ return /* @__PURE__ */ jsxs("fieldset", { "data-slot": "theme-picker", className: cn("ui-theme-picker", className), children: [
261
+ /* @__PURE__ */ jsx("legend", { className: "sr-only", children: legend }),
262
+ options.map((option) => /* @__PURE__ */ jsxs("label", { className: "ui-theme-picker-option", children: [
263
+ /* @__PURE__ */ jsx(
264
+ "input",
265
+ {
266
+ type: "radio",
267
+ name: groupName,
268
+ value: option.value,
269
+ checked: current === option.value,
270
+ onChange: () => {
271
+ if (value === void 0) setInner(option.value);
272
+ onValueChange?.(option.value);
273
+ },
274
+ className: "ui-theme-picker-input"
275
+ }
276
+ ),
277
+ /* @__PURE__ */ jsxs("span", { "aria-hidden": true, "data-preview": option.preview, className: "ui-theme-picker-preview", children: [
278
+ /* @__PURE__ */ jsx("i", {}),
279
+ /* @__PURE__ */ jsx("i", {}),
280
+ /* @__PURE__ */ jsx("i", {})
281
+ ] }),
282
+ /* @__PURE__ */ jsxs("span", { className: "ui-theme-picker-label", children: [
283
+ option.icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-theme-picker-icon", children: option.icon }),
284
+ option.label
285
+ ] })
286
+ ] }, option.value))
287
+ ] });
288
+ }
289
+ function EditorialAuth({
290
+ eyebrow,
291
+ title,
292
+ description,
293
+ art,
294
+ benefits,
295
+ children,
296
+ className
297
+ }) {
298
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "editorial-auth", className: cn("ui-editorial-auth", className), children: [
299
+ /* @__PURE__ */ jsxs("div", { className: "ui-editorial-auth-story", children: [
300
+ eyebrow,
301
+ /* @__PURE__ */ jsx("h1", { className: "ui-editorial-auth-title", children: title }),
302
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-auth-description", children: description }),
303
+ /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "ui-editorial-auth-art", children: [
304
+ /* @__PURE__ */ jsx("div", {}),
305
+ /* @__PURE__ */ jsx("div", { children: art })
306
+ ] }),
307
+ benefits != null && benefits.length > 0 && /* @__PURE__ */ jsx("ul", { className: "ui-editorial-auth-benefits", children: benefits.map((benefit, index) => /* @__PURE__ */ jsxs("li", { children: [
308
+ /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "ui-editorial-auth-benefit-icon" }),
309
+ benefit
310
+ ] }, index)) })
311
+ ] }),
312
+ children
313
+ ] });
314
+ }
315
+ function EditorialAuthCard({
316
+ badge,
317
+ title,
318
+ level,
319
+ description,
320
+ children,
321
+ footer,
322
+ className
323
+ }) {
324
+ const Heading = headingTag(level);
325
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "editorial-auth-card", className: cn("ui-editorial-auth-card", className), children: [
326
+ badge != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-auth-card-badge", children: badge }),
327
+ /* @__PURE__ */ jsx(Heading, { className: "ui-editorial-auth-card-title", children: title }),
328
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-auth-card-description", children: description }),
329
+ /* @__PURE__ */ jsx("div", { className: "ui-editorial-auth-card-body", children }),
330
+ footer != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-auth-card-footer", children: footer })
331
+ ] });
332
+ }
333
+ function EditorialTextButton({
334
+ children,
335
+ icon,
336
+ asChild,
337
+ onClick,
338
+ disabled,
339
+ className
340
+ }) {
341
+ const glyph = icon != null ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-editorial-text-button-icon", children: icon }) : null;
342
+ if (asChild && React.isValidElement(children)) {
343
+ const child = children;
344
+ return React.cloneElement(
345
+ child,
346
+ { className: cn("ui-editorial-text-button ui-focus-ring", className, child.props.className) },
347
+ /* @__PURE__ */ jsxs(Fragment, { children: [
348
+ child.props.children,
349
+ glyph
350
+ ] })
351
+ );
352
+ }
353
+ return /* @__PURE__ */ jsxs(
354
+ "button",
355
+ {
356
+ type: "button",
357
+ disabled,
358
+ onClick,
359
+ className: cn("ui-editorial-text-button ui-focus-ring", className),
360
+ children: [
361
+ children,
362
+ glyph
363
+ ]
364
+ }
365
+ );
366
+ }
367
+ function EditorialSearchInline({
368
+ label,
369
+ id,
370
+ placeholder,
371
+ defaultValue,
372
+ onSearch,
373
+ debounce = 300,
374
+ count,
375
+ className
376
+ }) {
377
+ const reactId = React.useId();
378
+ const inputId = id ?? `editorial-inline-search-${reactId}`;
379
+ const timer = React.useRef(void 0);
380
+ const last = React.useRef((defaultValue ?? "").trim());
381
+ const report = React.useCallback(
382
+ (value) => {
383
+ const query = value.trim();
384
+ if (query === last.current) return;
385
+ last.current = query;
386
+ onSearch?.(query);
387
+ },
388
+ [onSearch]
389
+ );
390
+ React.useEffect(() => () => clearTimeout(timer.current), []);
391
+ return /* @__PURE__ */ jsxs(
392
+ "div",
393
+ {
394
+ role: "search",
395
+ "aria-label": label,
396
+ "data-slot": "editorial-search",
397
+ "data-variant": "inline",
398
+ className: cn("ui-editorial-search-inline", className),
399
+ children: [
400
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "ui-editorial-search-inline-label", children: label }),
401
+ /* @__PURE__ */ jsxs("div", { className: "ui-editorial-search-inline-field", children: [
402
+ /* @__PURE__ */ jsx(Search, { "aria-hidden": true, className: "ui-editorial-search-inline-icon" }),
403
+ /* @__PURE__ */ jsx(
404
+ "input",
405
+ {
406
+ id: inputId,
407
+ type: "search",
408
+ placeholder,
409
+ defaultValue,
410
+ autoComplete: "off",
411
+ className: "ui-editorial-search-inline-input ui-focus-ring",
412
+ onChange: (event) => {
413
+ const value = event.currentTarget.value;
414
+ clearTimeout(timer.current);
415
+ timer.current = setTimeout(() => report(value), debounce);
416
+ },
417
+ onKeyDown: (event) => {
418
+ if (event.key !== "Enter") return;
419
+ clearTimeout(timer.current);
420
+ report(event.currentTarget.value);
421
+ }
422
+ }
423
+ )
424
+ ] }),
425
+ count != null && /* @__PURE__ */ jsx("span", { role: "status", "aria-live": "polite", className: "ui-editorial-search-inline-count", children: count })
426
+ ]
427
+ }
428
+ );
429
+ }
430
+ function EditorialFootnote({
431
+ children,
432
+ action,
433
+ align = "start",
434
+ className
435
+ }) {
436
+ return /* @__PURE__ */ jsxs(
437
+ "div",
438
+ {
439
+ "data-slot": "editorial-footnote",
440
+ "data-align": align === "start" ? void 0 : align,
441
+ className: cn("ui-editorial-footnote", className),
442
+ children: [
443
+ children != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-footnote-body", children }),
444
+ action != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-footnote-action", children: action })
445
+ ]
446
+ }
447
+ );
448
+ }
449
+ export {
450
+ EditorialAuth,
451
+ EditorialAuthCard,
452
+ EditorialEmptyPanel,
453
+ EditorialFootnote,
454
+ EditorialMetaBar,
455
+ EditorialSearchInline,
456
+ EditorialStats,
457
+ EditorialTextButton,
458
+ EditorialToggleGroup,
459
+ EditorialToolbar,
460
+ HoldingCard,
461
+ HoldingCardAction,
462
+ HoldingGrid,
463
+ SettingsLayout,
464
+ SettingsPanel,
465
+ ThemePicker
466
+ };
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import type { CatalogDetailProp, CatalogDetailSectionProp, CatalogDetailTagProp, EditorialFilterFieldProp, EditorialFilterPanelProp, EditorialPromptProp, PriceSummaryProp } from "../../props/components/layout.prop.js";
3
+ export type { CatalogDetailProp, CatalogDetailProp as CatalogDetailProps, CatalogDetailSectionProp, CatalogDetailSectionProp as CatalogDetailSectionProps, CatalogDetailTagProp, EditorialPromptProp, EditorialPromptProp as EditorialPromptProps, PriceSummaryProp, PriceSummaryProp as PriceSummaryProps, } from "../../props/components/layout.prop.js";
4
+ export type { EditorialFilterFieldProp, EditorialFilterFieldProp as EditorialFilterFieldProps, EditorialFilterPanelProp, EditorialFilterPanelProp as EditorialFilterPanelProps, } from "../../props/components/layout.prop.js";
5
+ /** A catalog's filter panel: labelled fields that wrap, bottom aligned, and a trailing action. */
6
+ export declare function EditorialFilterPanel({ variant, children, action, className, ...rest }: EditorialFilterPanelProp): React.JSX.Element;
7
+ /** One field of an `EditorialFilterPanel`: a visible label over one control. */
8
+ export declare function EditorialFilterField({ label, htmlFor, children, className, }: EditorialFilterFieldProp): React.JSX.Element;
9
+ /** The head of a catalog item's page: framed picture beside kicker, h1, tags, summary, facts. */
10
+ export declare function CatalogDetail({ variant, media, favorite, mediaCaption, overline, title, meta, summary, actions, facts, className, }: CatalogDetailProp): React.JSX.Element;
11
+ /** One outlined tag in a `CatalogDetail` meta row. */
12
+ export declare function CatalogDetailTag({ children, className }: CatalogDetailTagProp): React.JSX.Element;
13
+ /** One band of an item page under its head: hairline, h2, muted paragraph, then the rest. */
14
+ export declare function CatalogDetailSection({ variant, title, description, children, id, titleId, className, }: CatalogDetailSectionProp): React.JSX.Element;
15
+ /** A joined strip of headline figures, with an optional wider context cell. */
16
+ export declare function PriceSummary({ items, context, className }: PriceSummaryProp): React.JSX.Element;
17
+ /** A polite inline invitation: round glyph, heading, paragraph, note, one action. */
18
+ export declare function EditorialPrompt({ icon, title, description, note, action, level, className, }: EditorialPromptProp): React.JSX.Element;
@@ -0,0 +1,164 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Bookmark } from "lucide-react";
3
+ import { cn } from "../../lib/utils.js";
4
+ function EditorialFilterPanel({
5
+ variant = "panel",
6
+ children,
7
+ action,
8
+ className,
9
+ ...rest
10
+ }) {
11
+ return /* @__PURE__ */ jsxs(
12
+ "div",
13
+ {
14
+ role: "group",
15
+ "aria-label": rest["aria-label"],
16
+ "data-slot": "editorial-filter-panel",
17
+ "data-variant": variant === "bare" ? "bare" : void 0,
18
+ className: cn("ui-editorial-filter-panel", className),
19
+ children: [
20
+ children,
21
+ action != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-filter-panel-action", children: action })
22
+ ]
23
+ }
24
+ );
25
+ }
26
+ function EditorialFilterField({
27
+ label,
28
+ htmlFor,
29
+ children,
30
+ className
31
+ }) {
32
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "editorial-filter-field", className: cn("ui-editorial-filter-field", className), children: [
33
+ /* @__PURE__ */ jsx("label", { htmlFor, className: "ui-editorial-filter-field-label", children: label }),
34
+ children
35
+ ] });
36
+ }
37
+ function CatalogDetail({
38
+ variant = "card",
39
+ media,
40
+ favorite,
41
+ mediaCaption,
42
+ overline,
43
+ title,
44
+ meta,
45
+ summary,
46
+ actions,
47
+ facts,
48
+ className
49
+ }) {
50
+ return /* @__PURE__ */ jsxs(
51
+ "div",
52
+ {
53
+ "data-slot": "catalog-detail",
54
+ "data-variant": variant,
55
+ className: cn("ui-catalog-detail", className),
56
+ children: [
57
+ /* @__PURE__ */ jsxs("div", { className: "ui-catalog-detail-visual", children: [
58
+ /* @__PURE__ */ jsxs("div", { className: "ui-catalog-detail-art", children: [
59
+ favorite && /* @__PURE__ */ jsx(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ "aria-pressed": favorite.pressed,
64
+ "aria-label": favorite.label,
65
+ disabled: favorite.disabled,
66
+ className: "ui-catalog-card-favorite ui-focus-ring",
67
+ onClick: () => favorite.onPressedChange(!favorite.pressed),
68
+ children: /* @__PURE__ */ jsx(Bookmark, { "aria-hidden": true, className: "ui-catalog-card-favorite-icon" })
69
+ }
70
+ ),
71
+ media
72
+ ] }),
73
+ mediaCaption != null && /* @__PURE__ */ jsx("p", { className: "ui-catalog-detail-caption", children: mediaCaption })
74
+ ] }),
75
+ /* @__PURE__ */ jsxs("div", { className: "ui-catalog-detail-main", children: [
76
+ overline,
77
+ /* @__PURE__ */ jsx("h1", { className: "ui-catalog-detail-title", children: title }),
78
+ meta != null && /* @__PURE__ */ jsx("div", { className: "ui-catalog-detail-meta", children: meta }),
79
+ summary && /* @__PURE__ */ jsxs("div", { className: "ui-catalog-detail-summary", children: [
80
+ summary.label != null && /* @__PURE__ */ jsx("p", { className: "ui-catalog-detail-summary-label", children: summary.label }),
81
+ /* @__PURE__ */ jsx("p", { className: "ui-catalog-detail-summary-price", children: summary.price }),
82
+ summary.note != null && /* @__PURE__ */ jsx("p", { className: "ui-catalog-detail-summary-note", children: summary.note })
83
+ ] }),
84
+ actions != null && /* @__PURE__ */ jsx("div", { className: "ui-catalog-detail-actions", children: actions }),
85
+ facts && facts.length > 0 && /* @__PURE__ */ jsx("dl", { className: "ui-catalog-detail-facts", children: facts.map((fact) => /* @__PURE__ */ jsxs("div", { className: "ui-catalog-detail-fact", children: [
86
+ /* @__PURE__ */ jsx("dt", { children: fact.label }),
87
+ /* @__PURE__ */ jsx("dd", { children: fact.value })
88
+ ] }, fact.key)) })
89
+ ] })
90
+ ]
91
+ }
92
+ );
93
+ }
94
+ function CatalogDetailTag({ children, className }) {
95
+ return /* @__PURE__ */ jsx("span", { className: cn("ui-catalog-detail-tag", className), children });
96
+ }
97
+ function CatalogDetailSection({
98
+ variant = "band",
99
+ title,
100
+ description,
101
+ children,
102
+ id,
103
+ titleId,
104
+ className
105
+ }) {
106
+ return /* @__PURE__ */ jsxs(
107
+ "section",
108
+ {
109
+ id,
110
+ "aria-labelledby": title != null ? titleId : void 0,
111
+ "data-slot": "catalog-detail-section",
112
+ "data-variant": variant === "module" ? "module" : void 0,
113
+ className: cn("ui-catalog-detail-section", className),
114
+ children: [
115
+ title != null && /* @__PURE__ */ jsx("h2", { id: titleId, className: "ui-catalog-detail-section-title", children: title }),
116
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-catalog-detail-section-description", children: description }),
117
+ children
118
+ ]
119
+ }
120
+ );
121
+ }
122
+ function PriceSummary({ items, context, className }) {
123
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "price-summary", className: cn("ui-price-summary", className), children: [
124
+ items.map((item) => /* @__PURE__ */ jsxs("div", { className: "ui-price-summary-cell", children: [
125
+ /* @__PURE__ */ jsx("span", { className: "ui-price-summary-label", children: item.label }),
126
+ /* @__PURE__ */ jsx("strong", { className: "ui-price-summary-value", children: item.value }),
127
+ item.caption != null && /* @__PURE__ */ jsx("small", { className: "ui-price-summary-caption", children: item.caption })
128
+ ] }, item.key)),
129
+ context && /* @__PURE__ */ jsxs("div", { className: "ui-price-summary-cell", "data-context": "", children: [
130
+ /* @__PURE__ */ jsx("span", { className: "ui-price-summary-label", children: context.label }),
131
+ /* @__PURE__ */ jsx("b", { className: "ui-price-summary-context", children: context.value }),
132
+ context.caption != null && /* @__PURE__ */ jsx("small", { className: "ui-price-summary-caption", children: context.caption })
133
+ ] })
134
+ ] });
135
+ }
136
+ function EditorialPrompt({
137
+ icon,
138
+ title,
139
+ description,
140
+ note,
141
+ action,
142
+ level = 3,
143
+ className
144
+ }) {
145
+ const Heading = level === 2 ? "h2" : level === 4 ? "h4" : "h3";
146
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "editorial-prompt", className: cn("ui-editorial-prompt", className), children: [
147
+ icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ui-editorial-prompt-icon", children: icon }),
148
+ /* @__PURE__ */ jsxs("div", { className: "ui-editorial-prompt-copy", children: [
149
+ /* @__PURE__ */ jsx(Heading, { className: "ui-editorial-prompt-title", children: title }),
150
+ description != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-prompt-description", children: description }),
151
+ note != null && /* @__PURE__ */ jsx("p", { className: "ui-editorial-prompt-note", children: note })
152
+ ] }),
153
+ action != null && /* @__PURE__ */ jsx("div", { className: "ui-editorial-prompt-action", children: action })
154
+ ] });
155
+ }
156
+ export {
157
+ CatalogDetail,
158
+ CatalogDetailSection,
159
+ CatalogDetailTag,
160
+ EditorialFilterField,
161
+ EditorialFilterPanel,
162
+ EditorialPrompt,
163
+ PriceSummary
164
+ };