@hanzo/ui 8.27.20 → 8.27.23

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 (38) hide show
  1. package/dist/gallery.cjs +6 -1
  2. package/dist/gallery.d.ts.map +1 -1
  3. package/dist/gallery.html +5 -3
  4. package/dist/gallery.js +6 -1
  5. package/dist/gallery.js.map +1 -1
  6. package/dist/masthead/Masthead.cjs +168 -0
  7. package/dist/masthead/Masthead.d.ts +54 -0
  8. package/dist/masthead/Masthead.d.ts.map +1 -0
  9. package/dist/masthead/Masthead.js +162 -0
  10. package/dist/masthead/Masthead.js.map +1 -0
  11. package/dist/masthead/index.cjs +31 -0
  12. package/dist/masthead/index.d.ts +10 -0
  13. package/dist/masthead/index.d.ts.map +1 -0
  14. package/dist/masthead/index.js +10 -0
  15. package/dist/masthead/index.js.map +1 -0
  16. package/dist/masthead/nav.cjs +305 -0
  17. package/dist/masthead/nav.d.ts +69 -0
  18. package/dist/masthead/nav.d.ts.map +1 -0
  19. package/dist/masthead/nav.js +301 -0
  20. package/dist/masthead/nav.js.map +1 -0
  21. package/dist/masthead.css +502 -0
  22. package/dist/models/ModelSelector.cjs +19 -4
  23. package/dist/models/ModelSelector.d.ts +10 -1
  24. package/dist/models/ModelSelector.d.ts.map +1 -1
  25. package/dist/models/ModelSelector.js +20 -5
  26. package/dist/models/ModelSelector.js.map +1 -1
  27. package/dist/models/catalog.cjs +19 -0
  28. package/dist/models/catalog.d.ts +13 -0
  29. package/dist/models/catalog.d.ts.map +1 -1
  30. package/dist/models/catalog.js +18 -0
  31. package/dist/models/catalog.js.map +1 -1
  32. package/dist/models/index.cjs +2 -1
  33. package/dist/models/index.d.ts +1 -1
  34. package/dist/models/index.d.ts.map +1 -1
  35. package/dist/models/index.js +1 -1
  36. package/dist/models/index.js.map +1 -1
  37. package/dist/styles.css +2 -0
  38. package/package.json +26 -2
@@ -0,0 +1,502 @@
1
+ /* hanzo.ai's header (Masthead, @hanzo/ui/masthead): the bar, a menu's plane,
2
+ Log in ▾, and the phone sheet. Imported once by every site that wears it.
3
+
4
+ The bar reads the theme's tokens (@hanzo/design via @hanzo/ui/theme.css), so
5
+ light and dark need no second copy of any of it. The three below are the
6
+ chrome's own; a site that states them at :root wins, since these sit at zero
7
+ specificity. */
8
+ :where(:root) {
9
+ /* The header's height. */
10
+ --header: 60px;
11
+ /* One inset for the chrome and the page under it, the shell's GUTTER. */
12
+ --page-gutter: clamp(20px, 4vw, 72px);
13
+ /* The ground every chrome menu stands on: @hanzo/design's dropdown panel,
14
+ opaque, a shade above --background in either theme. */
15
+ --chrome-panel: var(--popover);
16
+ }
17
+ /* The bar's ink on a light page. The shell writes its inks as
18
+ `var(--white-92, …)` with white only as the fallback, so stating these names
19
+ on the bar turns every inline use black at once. Scoped to the bar: the names
20
+ mean a hue, and a page's own glows and hover fills stay white.
21
+
22
+ --white-45 is pushed to .56 rather than mirrored: black on white reads fainter
23
+ than white on black at the same alpha, and .56 is 4.5:1 on both the bar and
24
+ the panel. The panel under these inks is --chrome-panel, which flips with the
25
+ theme at `.light` wherever a menu is mounted. */
26
+ .light .hz-masthead {
27
+ --white-92: rgb(0 0 0 / 0.92);
28
+ --white-60: rgb(0 0 0 / 0.6);
29
+ --white-45: rgb(0 0 0 / 0.56);
30
+ --white-10: rgb(0 0 0 / 0.1);
31
+ }
32
+
33
+ /* ==========================================================================
34
+ THE BAR AND THE SHEET
35
+
36
+ One nav tree, two drawings: the bar and the phone sheet. The bar's geometry
37
+ is @hanzogui/shell's — a 60px row, 34px pills, 13px labels, a 16px mark
38
+ before each, a 12px chevron after — so it reads as the same chrome the rest
39
+ of the estate wears. Every ink and ground is a theme token.
40
+
41
+ THREE GROUNDS for the bar. Clear over the top of a page; glass once the page
42
+ moves under it; and the plane's own opaque ground while a menu or the sheet
43
+ hangs from it, so bar and plane are one surface. The open bar carries no
44
+ backdrop filter on purpose: a filtered element is a backdrop root, and the
45
+ veil inside it would then blur the bar instead of the page.
46
+ ========================================================================== */
47
+
48
+ .hz-masthead {
49
+ --wash: color-mix(in srgb, var(--foreground) 6%, transparent);
50
+ --hairline: color-mix(in srgb, var(--foreground) 10%, transparent);
51
+ position: sticky;
52
+ top: 0;
53
+ z-index: var(--z-header);
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 12px;
57
+ box-sizing: content-box;
58
+ height: var(--header);
59
+ padding: env(safe-area-inset-top) var(--page-gutter) 0;
60
+ font-family: var(--font-sans);
61
+ /* The type the chrome is set in: @hanzo/gui's body, 16px on a 20px line. A
62
+ fixed line, so every row keeps its height whatever the host's body type. */
63
+ font-size: 16px;
64
+ line-height: 20px;
65
+ color: var(--foreground);
66
+ transition: background-color 160ms ease;
67
+ }
68
+
69
+ .hz-masthead[data-grounded] {
70
+ background: color-mix(in srgb, var(--background) 72%, transparent);
71
+ backdrop-filter: blur(20px) saturate(1.8);
72
+ -webkit-backdrop-filter: blur(20px) saturate(1.8);
73
+ }
74
+
75
+ .hz-masthead:has([aria-expanded='true']) {
76
+ background: var(--chrome-panel);
77
+ backdrop-filter: none;
78
+ -webkit-backdrop-filter: none;
79
+ }
80
+
81
+ .hz-masthead a,
82
+ .hz-masthead button {
83
+ font-family: inherit;
84
+ text-decoration: none;
85
+ }
86
+
87
+ /* ------------------------------------------------------------------ pills */
88
+
89
+ .hz-masthead .hz-trigger,
90
+ .hz-masthead .hz-find,
91
+ .hz-masthead .hz-brand {
92
+ display: inline-flex;
93
+ align-items: center;
94
+ flex-shrink: 0;
95
+ box-sizing: border-box;
96
+ height: 34px;
97
+ border: 0;
98
+ border-radius: 999px;
99
+ background: transparent;
100
+ color: var(--muted-foreground);
101
+ cursor: pointer;
102
+ transition: color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
103
+ }
104
+
105
+ .hz-masthead .hz-trigger {
106
+ gap: 6px;
107
+ padding: 0 12px;
108
+ font-size: var(--text-sm);
109
+ font-weight: var(--weight-medium);
110
+ white-space: nowrap;
111
+ }
112
+
113
+ .hz-masthead .hz-trigger:hover,
114
+ .hz-masthead .hz-trigger[aria-expanded='true'],
115
+ .hz-masthead .hz-find:hover,
116
+ .hz-masthead .hz-brand:hover,
117
+ .hz-masthead .hz-brand:has([aria-expanded='true']) {
118
+ color: var(--foreground);
119
+ background: var(--wash);
120
+ box-shadow: inset 0 0 0 1px var(--hairline);
121
+ }
122
+
123
+ :is(.hz-masthead, .hz-sheet) .hz-mark {
124
+ display: inline-flex;
125
+ opacity: 0.9;
126
+ }
127
+
128
+ :is(.hz-masthead, .hz-sheet) .hz-chevron {
129
+ flex-shrink: 0;
130
+ transition: transform 150ms ease;
131
+ }
132
+
133
+ [aria-expanded='true'] > .hz-chevron,
134
+ details[open] > summary > .hz-chevron {
135
+ transform: rotate(180deg);
136
+ }
137
+
138
+ /* The name of the place is never dim, and the chevron beside it is its own stop:
139
+ the name goes home, the chevron opens the company. */
140
+ .hz-masthead .hz-brand {
141
+ margin-left: -4px;
142
+ color: var(--foreground);
143
+ }
144
+
145
+ .hz-masthead .hz-brand .hz-wordmark {
146
+ display: inline-flex;
147
+ align-items: center;
148
+ height: 100%;
149
+ padding-left: 12px;
150
+ color: inherit;
151
+ }
152
+
153
+ .hz-masthead .hz-brand .hz-company {
154
+ display: inline-grid;
155
+ place-items: center;
156
+ width: 30px;
157
+ height: 100%;
158
+ padding: 0 6px 0 0;
159
+ border: 0;
160
+ border-radius: 0 999px 999px 0;
161
+ background: transparent;
162
+ color: inherit;
163
+ cursor: pointer;
164
+ }
165
+
166
+ .hz-masthead .hz-nav {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 2px;
170
+ }
171
+
172
+ .hz-masthead .hz-find {
173
+ justify-content: center;
174
+ width: 34px;
175
+ }
176
+
177
+ .hz-masthead .hz-end {
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 8px;
181
+ margin-left: auto;
182
+ }
183
+
184
+ .hz-masthead .hz-menu {
185
+ position: relative;
186
+ display: inline-flex;
187
+ }
188
+
189
+ /* The one filled control in the bar. */
190
+ :is(.hz-masthead, .hz-sheet) .hz-try {
191
+ display: inline-flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ gap: 2px;
195
+ box-sizing: border-box;
196
+ height: 34px;
197
+ padding: 0 14px;
198
+ border-radius: 999px;
199
+ background: var(--foreground);
200
+ color: var(--background);
201
+ font-size: var(--text-sm);
202
+ font-weight: var(--weight-semibold);
203
+ white-space: nowrap;
204
+ text-decoration: none;
205
+ transition: opacity 120ms ease;
206
+ }
207
+
208
+ :is(.hz-masthead, .hz-sheet) .hz-try:hover {
209
+ opacity: 0.88;
210
+ }
211
+
212
+ :is(.hz-masthead, .hz-sheet) .hz-out {
213
+ display: inline-block;
214
+ margin-left: 0.28em;
215
+ vertical-align: middle;
216
+ opacity: 0.7;
217
+ }
218
+
219
+ .hz-masthead .hz-toggle {
220
+ display: none;
221
+ place-items: center;
222
+ width: 44px;
223
+ height: 44px;
224
+ margin-right: -10px;
225
+ border: 0;
226
+ background: transparent;
227
+ color: var(--foreground);
228
+ cursor: pointer;
229
+ }
230
+
231
+ /* ------------------------------------------------------------------ plane */
232
+
233
+ /* A menu's panel spans the window under the bar and lays its columns out from
234
+ the wordmark's column. */
235
+ .hz-masthead .hz-plane {
236
+ position: fixed;
237
+ top: calc(var(--header) + env(safe-area-inset-top));
238
+ left: 0;
239
+ right: 0;
240
+ z-index: calc(var(--z-base) + 1);
241
+ max-height: calc(100dvh - var(--header));
242
+ overflow-y: auto;
243
+ background: var(--chrome-panel);
244
+ box-shadow: 0 24px 60px -16px color-mix(in srgb, var(--pure-black) 75%, transparent);
245
+ animation: hz-plane-in 160ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
246
+ }
247
+
248
+ @keyframes hz-plane-in {
249
+ from { opacity: 0; transform: translateY(-4px); }
250
+ to { opacity: 1; transform: none; }
251
+ }
252
+
253
+ .hz-masthead .hz-veil {
254
+ position: fixed;
255
+ top: calc(var(--header) + env(safe-area-inset-top));
256
+ left: 0;
257
+ right: 0;
258
+ bottom: 0;
259
+ z-index: var(--z-base);
260
+ background: color-mix(in srgb, var(--pure-black) 40%, transparent);
261
+ backdrop-filter: blur(24px) saturate(1.2);
262
+ -webkit-backdrop-filter: blur(24px) saturate(1.2);
263
+ }
264
+
265
+ .hz-masthead .hz-columns {
266
+ display: grid;
267
+ grid-auto-flow: column;
268
+ grid-auto-columns: max-content;
269
+ justify-content: start;
270
+ gap: clamp(24px, 3vw, 64px);
271
+ padding: 36px calc(var(--page-gutter) + 8px) 48px;
272
+ }
273
+
274
+ :is(.hz-masthead, .hz-sheet) .hz-column {
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 2px;
278
+ min-width: 0;
279
+ transition: opacity 160ms ease;
280
+ }
281
+
282
+ /* The column under the pointer is the one being read; the others step back. */
283
+ .hz-masthead .hz-columns:has(> .hz-column:hover) > .hz-column:not(:hover) {
284
+ opacity: 0.45;
285
+ }
286
+
287
+ :is(.hz-masthead, .hz-sheet) .hz-column-title {
288
+ margin: 0 0 10px;
289
+ font-size: var(--text-sm);
290
+ font-weight: var(--weight-semibold);
291
+ color: var(--foreground);
292
+ text-decoration: none;
293
+ }
294
+
295
+ /* `justify-content` is stated on every row: this sheet centres any link whose
296
+ one element child is an svg, and ↗ is exactly that. A row is as wide as its
297
+ words, so a keyboard ring hugs the words it names rather than the column. */
298
+ :is(.hz-masthead, .hz-sheet) .hz-column a {
299
+ display: block;
300
+ width: fit-content;
301
+ justify-content: flex-start;
302
+ margin: 0 -8px;
303
+ padding: 5px 8px;
304
+ border-radius: 8px;
305
+ font-size: var(--text-sm);
306
+ font-weight: var(--weight-medium);
307
+ color: var(--muted-foreground);
308
+ white-space: nowrap;
309
+ text-decoration: none;
310
+ transition: color 120ms ease;
311
+ }
312
+
313
+ :is(.hz-masthead, .hz-sheet) .hz-column a:hover,
314
+ :is(.hz-masthead, .hz-sheet) .hz-column a:focus-visible {
315
+ color: var(--foreground);
316
+ }
317
+
318
+ /* The destinations someone arrives wanting, in display type. */
319
+ .hz-masthead .hz-column[data-lead] a {
320
+ padding: 2px 8px;
321
+ font-size: var(--text-3xl);
322
+ font-weight: var(--weight-normal);
323
+ line-height: 1.28;
324
+ letter-spacing: -0.01em;
325
+ color: var(--foreground);
326
+ }
327
+
328
+ /* ------------------------------------------------------------------ log in */
329
+
330
+ .hz-masthead .hz-card {
331
+ position: absolute;
332
+ top: calc(100% + 8px);
333
+ right: 0;
334
+ display: grid;
335
+ gap: 2px;
336
+ min-width: 240px;
337
+ padding: 6px;
338
+ border: 1px solid var(--border);
339
+ border-radius: 12px;
340
+ background: var(--chrome-panel);
341
+ box-shadow: 0 24px 60px -16px color-mix(in srgb, var(--pure-black) 75%, transparent);
342
+ animation: hz-plane-in 160ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
343
+ }
344
+
345
+ .hz-masthead .hz-card a {
346
+ display: grid;
347
+ gap: 2px;
348
+ padding: 8px 10px;
349
+ border-radius: 8px;
350
+ color: var(--foreground);
351
+ font-size: var(--text-sm);
352
+ font-weight: var(--weight-semibold);
353
+ }
354
+
355
+ .hz-masthead .hz-card a:hover,
356
+ .hz-masthead .hz-card a:focus-visible {
357
+ background: color-mix(in srgb, var(--foreground) 6%, transparent);
358
+ }
359
+
360
+ .hz-masthead .hz-card small {
361
+ font-size: var(--text-xs);
362
+ font-weight: var(--weight-normal);
363
+ color: var(--muted-foreground);
364
+ }
365
+
366
+ /* ------------------------------------------------------------------ phone */
367
+
368
+ .hz-sheet {
369
+ position: fixed;
370
+ top: calc(var(--header) + env(safe-area-inset-top));
371
+ left: 0;
372
+ right: 0;
373
+ bottom: 0;
374
+ z-index: var(--z-overlay);
375
+ overflow-y: auto;
376
+ overscroll-behavior: contain;
377
+ padding: 4px var(--page-gutter) calc(24px + env(safe-area-inset-bottom));
378
+ background: var(--chrome-panel);
379
+ font-family: var(--font-sans);
380
+ font-size: 16px;
381
+ line-height: 20px;
382
+ animation: hz-plane-in 160ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
383
+ }
384
+
385
+ .hz-sheet details {
386
+ border-bottom: 1px solid var(--border);
387
+ }
388
+
389
+ .hz-sheet summary {
390
+ display: flex;
391
+ align-items: center;
392
+ gap: 10px;
393
+ min-height: 56px;
394
+ list-style: none;
395
+ font-size: var(--text-xl);
396
+ font-weight: var(--weight-medium);
397
+ color: var(--foreground);
398
+ cursor: pointer;
399
+ }
400
+
401
+ .hz-sheet summary::-webkit-details-marker {
402
+ display: none;
403
+ }
404
+
405
+ .hz-sheet summary .hz-chevron {
406
+ margin-left: auto;
407
+ }
408
+
409
+ .hz-sheet .hz-column {
410
+ padding: 0 0 16px;
411
+ }
412
+
413
+ .hz-sheet .hz-column-title {
414
+ margin: 4px 0 2px;
415
+ font-size: var(--text-xs);
416
+ color: var(--text-tertiary);
417
+ }
418
+
419
+ .hz-sheet .hz-column a,
420
+ .hz-sheet .hz-column[data-lead] a {
421
+ display: flex;
422
+ width: auto;
423
+ align-items: center;
424
+ justify-content: flex-start;
425
+ min-height: 44px;
426
+ margin: 0;
427
+ padding: 0;
428
+ font-size: var(--text-lg);
429
+ font-weight: var(--weight-normal);
430
+ letter-spacing: 0;
431
+ line-height: 1.2;
432
+ white-space: normal;
433
+ }
434
+
435
+ .hz-sheet .hz-column[data-lead] a {
436
+ font-size: var(--text-xl);
437
+ }
438
+
439
+ .hz-sheet .hz-doors {
440
+ display: grid;
441
+ gap: 4px;
442
+ padding-top: 20px;
443
+ }
444
+
445
+ .hz-sheet .hz-door {
446
+ display: flex;
447
+ align-items: center;
448
+ justify-content: flex-start;
449
+ min-height: 44px;
450
+ font-size: var(--text-lg);
451
+ color: var(--foreground);
452
+ text-decoration: none;
453
+ }
454
+
455
+ .hz-sheet .hz-try {
456
+ height: 48px;
457
+ margin-top: 12px;
458
+ font-size: var(--text-base);
459
+ }
460
+
461
+ /* One compact bar on a phone and a tablet: the name, search, and the menu. */
462
+ @media (max-width: 1023px) {
463
+ .hz-masthead .hz-nav,
464
+ .hz-masthead .hz-login,
465
+ .hz-masthead .hz-end > .hz-try,
466
+ .hz-masthead .hz-brand .hz-company {
467
+ display: none;
468
+ }
469
+
470
+ .hz-masthead .hz-brand .hz-wordmark {
471
+ padding-right: 12px;
472
+ }
473
+
474
+ .hz-masthead .hz-find {
475
+ width: 44px;
476
+ height: 44px;
477
+ margin-left: auto;
478
+ }
479
+
480
+ .hz-masthead .hz-end {
481
+ margin-left: 0;
482
+ }
483
+
484
+ .hz-masthead .hz-toggle {
485
+ display: inline-grid;
486
+ }
487
+ }
488
+
489
+ /* Between a tablet and a wide laptop the row keeps its labels and drops its marks. */
490
+ @media (min-width: 1024px) and (max-width: 1199px) {
491
+ .hz-masthead .hz-nav .hz-mark {
492
+ display: none;
493
+ }
494
+ }
495
+
496
+ @media (prefers-reduced-motion: reduce) {
497
+ .hz-masthead .hz-plane,
498
+ .hz-masthead .hz-card,
499
+ .hz-sheet {
500
+ animation: none;
501
+ }
502
+ }
@@ -30,13 +30,25 @@ function fmtContext(ctx) {
30
30
  * family headers, premium markers, context suffixes, keyboard navigation, and
31
31
  * type-to-filter search for large catalogs.
32
32
  *
33
+ * A model with `access` is listed and never chosen: its row is disabled, says
34
+ * why, and links to where a person asks for access. The link sits inside a
35
+ * list item rather than an option, so it is a control of its own and not one
36
+ * nested in another; it keeps Enter to itself, which the list would otherwise
37
+ * take as a pick.
38
+ *
33
39
  * Styling is gui style props and tokens throughout — no class strings. The panel
34
40
  * matches the trigger's MEASURED width (`onLayout`, which gui implements on web
35
41
  * too), never a Radix `--radix-popover-trigger-width` custom property: nothing
36
42
  * defines that variable now that Radix is gone.
37
43
  */
38
- function ModelSelector({ models, value, onChange, disabled = false, size = 'md', placeholder = 'Select model', chatOnly = true, className, }) {
39
- const [open, setOpen] = (0, react_1.useState)(false);
44
+ function ModelSelector({ models, value, onChange, disabled = false, size = 'md', placeholder = 'Select model', chatOnly = true, className, open: openProp, onOpenChange, }) {
45
+ const [own, setOwn] = (0, react_1.useState)(false);
46
+ const open = openProp ?? own;
47
+ const setOpen = (next) => {
48
+ if (openProp === undefined)
49
+ setOwn(next);
50
+ onOpenChange?.(next);
51
+ };
40
52
  const [triggerW, setTriggerW] = (0, react_1.useState)(0);
41
53
  const visible = (0, react_1.useMemo)(() => (chatOnly ? (0, catalog_1.filterChatModels)(models) : models), [models, chatOnly]);
42
54
  const groups = (0, react_1.useMemo)(() => (0, catalog_1.groupModelsByFamily)(visible), [visible]);
@@ -50,10 +62,13 @@ function ModelSelector({ models, value, onChange, disabled = false, size = 'md',
50
62
  return ((0, jsx_runtime_1.jsxs)(gui_2.Popover, { open: open, onOpenChange: setOpen, children: [(0, jsx_runtime_1.jsx)(gui_1.XStack, { onLayout: (e) => setTriggerW(e.nativeEvent.layout.width), children: (0, jsx_runtime_1.jsx)(gui_2.PopoverTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)(gui_2.Button, { variant: "outline", size: isSm ? 'sm' : 'default', role: "combobox", "aria-expanded": open, disabled: disabled, justify: "flex-start", ...(0, sx_1.sx)(className), children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { numberOfLines: 1, size: isSm ? '$1' : '$2', color: "$color12", children: selectedLabel }), selectedFamily && ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { numberOfLines: 1, size: isSm ? '$1' : '$2', color: "$color11", children: selectedFamily })), (0, jsx_runtime_1.jsx)(lucide_icons_2_1.ChevronsUpDown, { size: isSm ? 12 : 14, ml: "auto", shrink: 0, opacity: 0.5 })] }) }) }), (0, jsx_runtime_1.jsx)(gui_2.PopoverContent, { align: "start", p: 0, width: Math.max(triggerW, MIN_W), children: (0, jsx_runtime_1.jsxs)(gui_2.Command, { children: [showSearch && (0, jsx_runtime_1.jsx)(gui_2.CommandInput, { placeholder: "Search models\u2026" }), (0, jsx_runtime_1.jsxs)(gui_2.CommandList, { maxH: MAX_H, children: [(0, jsx_runtime_1.jsx)(gui_2.CommandEmpty, { children: "No models found." }), groups.map((group) => ((0, jsx_runtime_1.jsx)(gui_2.CommandGroup, { heading: group.family, children: group.models.map((m) => {
51
63
  const label = m.label ?? m.id;
52
64
  const ctx = fmtContext(m.context_window);
53
- return ((0, jsx_runtime_1.jsxs)(gui_2.CommandItem, { value: `${group.family} ${label} ${m.id}`, onSelect: () => {
65
+ const locked = m.access === 'research';
66
+ return ((0, jsx_runtime_1.jsxs)(gui_2.CommandItem, { value: `${group.family} ${label} ${m.id}`, disabled: locked, "aria-disabled": locked || undefined, onSelect: () => {
54
67
  onChange(m.id);
55
68
  setOpen(false);
56
- }, children: [(0, jsx_runtime_1.jsx)(lucide_icons_2_1.Check, { size: 14, shrink: 0, opacity: m.id === value ? 1 : 0 }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { numberOfLines: 1, size: "$2", children: label }), m.premium && ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$2", color: "$color11", "aria-label": "Premium", children: "\u2726" })), ctx && ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ml: "auto", shrink: 0, pl: "$2", children: (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$color11", fontVariant: ['tabular-nums'], children: ctx }) }))] }, m.id));
69
+ }, children: [(0, jsx_runtime_1.jsx)(lucide_icons_2_1.Check, { size: 14, shrink: 0, opacity: m.id === value ? 1 : 0 }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { numberOfLines: 1, size: "$2", children: label }), m.premium && ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$2", color: "$color11", "aria-label": "Premium", children: "\u2726" })), locked ? ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ml: "auto", shrink: 0, pl: "$2", gap: "$2", items: "center", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$color11", children: "Research preview" }), m.request && ((0, jsx_runtime_1.jsx)(gui_2.Anchor, { href: m.request, target: "_blank", rel: "noopener noreferrer", size: "$1", color: "$color12", textDecorationLine: "underline",
70
+ // The row takes no pointer while disabled; its link does.
71
+ pointerEvents: "auto", onKeyDown: (e) => e.stopPropagation(), children: "Request access" }))] })) : ctx && ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ml: "auto", shrink: 0, pl: "$2", children: (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$color11", fontVariant: ['tabular-nums'], children: ctx }) }))] }, m.id));
57
72
  }) }, group.family)))] })] }) })] }));
58
73
  }
59
74
  exports.default = ModelSelector;
@@ -9,6 +9,9 @@ export interface ModelSelectorProps {
9
9
  /** Default true: filter to chat-capable models (exclude embedding/image/etc.). */
10
10
  chatOnly?: boolean;
11
11
  className?: string;
12
+ /** Open state, when the host owns it. */
13
+ open?: boolean;
14
+ onOpenChange?: (open: boolean) => void;
12
15
  }
13
16
  /**
14
17
  * ModelSelector — the one unified model picker for every Hanzo app.
@@ -17,11 +20,17 @@ export interface ModelSelectorProps {
17
20
  * family headers, premium markers, context suffixes, keyboard navigation, and
18
21
  * type-to-filter search for large catalogs.
19
22
  *
23
+ * A model with `access` is listed and never chosen: its row is disabled, says
24
+ * why, and links to where a person asks for access. The link sits inside a
25
+ * list item rather than an option, so it is a control of its own and not one
26
+ * nested in another; it keeps Enter to itself, which the list would otherwise
27
+ * take as a pick.
28
+ *
20
29
  * Styling is gui style props and tokens throughout — no class strings. The panel
21
30
  * matches the trigger's MEASURED width (`onLayout`, which gui implements on web
22
31
  * too), never a Radix `--radix-popover-trigger-width` custom property: nothing
23
32
  * defines that variable now that Radix is gone.
24
33
  */
25
- export declare function ModelSelector({ models, value, onChange, disabled, size, placeholder, chatOnly, className, }: ModelSelectorProps): import("react").JSX.Element;
34
+ export declare function ModelSelector({ models, value, onChange, disabled, size, placeholder, chatOnly, className, open: openProp, onOpenChange, }: ModelSelectorProps): import("react").JSX.Element;
26
35
  export default ModelSelector;
27
36
  //# sourceMappingURL=ModelSelector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/models/ModelSelector.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAmD,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAenG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,IAAW,EACX,WAA4B,EAC5B,QAAe,EACf,SAAS,GACV,EAAE,kBAAkB,+BA0FpB;eAEc,aAAa"}
1
+ {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/models/ModelSelector.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAmD,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAenG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,IAAW,EACX,WAA4B,EAC5B,QAAe,EACf,SAAS,EACT,IAAI,EAAE,QAAQ,EACd,YAAY,GACb,EAAE,kBAAkB,+BAuHpB;eAEc,aAAa"}
@@ -4,7 +4,7 @@ import { useMemo, useState } from 'react';
4
4
  import { sx } from '../sx.js';
5
5
  import { Check, ChevronsUpDown } from '@hanzogui/lucide-icons-2';
6
6
  import { SizableText, XStack } from '@hanzo/gui';
7
- import { Button, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, } from '../backends/gui/index.js';
7
+ import { Anchor, Button, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, } from '../backends/gui/index.js';
8
8
  import { familyOf, filterChatModels, groupModelsByFamily } from './catalog.js';
9
9
  /** Show the search input once a catalog gets this large. */
10
10
  const SEARCH_THRESHOLD = 12;
@@ -27,13 +27,25 @@ function fmtContext(ctx) {
27
27
  * family headers, premium markers, context suffixes, keyboard navigation, and
28
28
  * type-to-filter search for large catalogs.
29
29
  *
30
+ * A model with `access` is listed and never chosen: its row is disabled, says
31
+ * why, and links to where a person asks for access. The link sits inside a
32
+ * list item rather than an option, so it is a control of its own and not one
33
+ * nested in another; it keeps Enter to itself, which the list would otherwise
34
+ * take as a pick.
35
+ *
30
36
  * Styling is gui style props and tokens throughout — no class strings. The panel
31
37
  * matches the trigger's MEASURED width (`onLayout`, which gui implements on web
32
38
  * too), never a Radix `--radix-popover-trigger-width` custom property: nothing
33
39
  * defines that variable now that Radix is gone.
34
40
  */
35
- export function ModelSelector({ models, value, onChange, disabled = false, size = 'md', placeholder = 'Select model', chatOnly = true, className, }) {
36
- const [open, setOpen] = useState(false);
41
+ export function ModelSelector({ models, value, onChange, disabled = false, size = 'md', placeholder = 'Select model', chatOnly = true, className, open: openProp, onOpenChange, }) {
42
+ const [own, setOwn] = useState(false);
43
+ const open = openProp ?? own;
44
+ const setOpen = (next) => {
45
+ if (openProp === undefined)
46
+ setOwn(next);
47
+ onOpenChange?.(next);
48
+ };
37
49
  const [triggerW, setTriggerW] = useState(0);
38
50
  const visible = useMemo(() => (chatOnly ? filterChatModels(models) : models), [models, chatOnly]);
39
51
  const groups = useMemo(() => groupModelsByFamily(visible), [visible]);
@@ -47,10 +59,13 @@ export function ModelSelector({ models, value, onChange, disabled = false, size
47
59
  return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(XStack, { onLayout: (e) => setTriggerW(e.nativeEvent.layout.width), children: _jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: isSm ? 'sm' : 'default', role: "combobox", "aria-expanded": open, disabled: disabled, justify: "flex-start", ...sx(className), children: [_jsx(SizableText, { numberOfLines: 1, size: isSm ? '$1' : '$2', color: "$color12", children: selectedLabel }), selectedFamily && (_jsx(SizableText, { numberOfLines: 1, size: isSm ? '$1' : '$2', color: "$color11", children: selectedFamily })), _jsx(ChevronsUpDown, { size: isSm ? 12 : 14, ml: "auto", shrink: 0, opacity: 0.5 })] }) }) }), _jsx(PopoverContent, { align: "start", p: 0, width: Math.max(triggerW, MIN_W), children: _jsxs(Command, { children: [showSearch && _jsx(CommandInput, { placeholder: "Search models\u2026" }), _jsxs(CommandList, { maxH: MAX_H, children: [_jsx(CommandEmpty, { children: "No models found." }), groups.map((group) => (_jsx(CommandGroup, { heading: group.family, children: group.models.map((m) => {
48
60
  const label = m.label ?? m.id;
49
61
  const ctx = fmtContext(m.context_window);
50
- return (_jsxs(CommandItem, { value: `${group.family} ${label} ${m.id}`, onSelect: () => {
62
+ const locked = m.access === 'research';
63
+ return (_jsxs(CommandItem, { value: `${group.family} ${label} ${m.id}`, disabled: locked, "aria-disabled": locked || undefined, onSelect: () => {
51
64
  onChange(m.id);
52
65
  setOpen(false);
53
- }, children: [_jsx(Check, { size: 14, shrink: 0, opacity: m.id === value ? 1 : 0 }), _jsx(SizableText, { numberOfLines: 1, size: "$2", children: label }), m.premium && (_jsx(SizableText, { size: "$2", color: "$color11", "aria-label": "Premium", children: "\u2726" })), ctx && (_jsx(XStack, { ml: "auto", shrink: 0, pl: "$2", children: _jsx(SizableText, { size: "$1", color: "$color11", fontVariant: ['tabular-nums'], children: ctx }) }))] }, m.id));
66
+ }, children: [_jsx(Check, { size: 14, shrink: 0, opacity: m.id === value ? 1 : 0 }), _jsx(SizableText, { numberOfLines: 1, size: "$2", children: label }), m.premium && (_jsx(SizableText, { size: "$2", color: "$color11", "aria-label": "Premium", children: "\u2726" })), locked ? (_jsxs(XStack, { ml: "auto", shrink: 0, pl: "$2", gap: "$2", items: "center", children: [_jsx(SizableText, { size: "$1", color: "$color11", children: "Research preview" }), m.request && (_jsx(Anchor, { href: m.request, target: "_blank", rel: "noopener noreferrer", size: "$1", color: "$color12", textDecorationLine: "underline",
67
+ // The row takes no pointer while disabled; its link does.
68
+ pointerEvents: "auto", onKeyDown: (e) => e.stopPropagation(), children: "Request access" }))] })) : ctx && (_jsx(XStack, { ml: "auto", shrink: 0, pl: "$2", children: _jsx(SizableText, { size: "$1", color: "$color11", fontVariant: ['tabular-nums'], children: ctx }) }))] }, m.id));
54
69
  }) }, group.family)))] })] }) })] }));
55
70
  }
56
71
  export default ModelSelector;
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.js","sourceRoot":"","sources":["../../src/models/ModelSelector.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ModelSelector.js","sourceRoot":"","sources":["../../src/models/ModelSelector.tsx"],"names":[],"mappings":"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"}