@tradalab/lyra 3.10.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,9 +27,9 @@ The stylesheet pulls in Tailwind v4, so your app needs `@tailwindcss/postcss`.
27
27
  | `@tradalab/lyra/utils` | `cn` | server-safe |
28
28
  | `@tradalab/lyra/hooks` | `useMobile` | client |
29
29
  | `@tradalab/lyra/ui` | 61 shadcn primitives + `AccountMenu`, `ActionButton`, `Container`, `EmptyState`, `StatusBadge` | client |
30
- | `@tradalab/lyra/blocks` | `Form`/`FormField` + RHF glue, `Panel`, `Confirm`/`useConfirm`, `Tree`, `TzPicker`, `OptionPicker`, `McpSettings`, `LlmSettings`, `PlatePicker`, `usePlate`, `useCompact`, `PreferenceScript` | client |
31
- | `@tradalab/lyra/data-table` | `DataTable` + `usePager`, `TableFilterBar`, `TableSearch`, `TableReload`, `filterRows`, `pageWindow` | client |
32
- | `@tradalab/lyra/shell` | `AppShell`, `PageShell`, `PageHeader`, `NavItem`, `NavGroup`, `Breadcrumbs`, `useActiveRoute` | client |
30
+ | `@tradalab/lyra/blocks` | `Form`/`FormField` + RHF glue, `Panel`, `Confirm`/`useConfirm`, `Tree`, `TzPicker`, `OptionPicker`, `MobileSheet`, `ChoiceDrawer`, `McpSettings`, `LlmSettings`, `PlatePicker`, `usePlate`, `useCompact`, `PreferenceScript` | client |
31
+ | `@tradalab/lyra/data-table` | `DataTable` + `usePager`, `TableFilterBar`, `TableFilterChips`, `TableSearch`, `TableReload`, `filterRows`, `pageWindow` | client |
32
+ | `@tradalab/lyra/shell` | `AppShell`, `PageShell`, `PageHeader`, `NavItem`, `NavGroup`, `Breadcrumbs`, `BottomNav`, `useActiveRoute`, `useSearchParam`, `useTabParam`, `usePageParam`, `UrlTabs` | client |
33
33
  | `@tradalab/lyra/styles.css` | Tailwind v4 base + `radix-lyra` tokens (light/dark) | CSS |
34
34
 
35
35
  Client subpaths carry a build-injected `"use client"`; import them inside a
@@ -71,6 +71,17 @@ Two rules the components enforce rather than document:
71
71
  browser, so it answers "no results" about a row on page three. Send the query instead;
72
72
  `filterRows` is for the unpaged case, where local filtering is the truth.
73
73
 
74
+ To keep the page, the query and the open tab in the URL, `shell` holds the Next side and
75
+ `data-table` only takes state: `usePager({ ...usePageParam(), labels })`, and
76
+ `<TableSearch value={q} onChange={pager.onFilter(setQ)} />` with
77
+ `const [q, setQ] = useSearchParam("q")`. Rows per page stay out of the URL. Show what is in force
78
+ with `TableFilterChips`: a link can open a table already narrowed. Clear a chip through
79
+ `pager.onFilter` too, so the page goes back to 1 with the filter.
80
+
81
+ `DataTable` also takes `onRowClick` (the whole row, and Enter or Space) and selection
82
+ (`getRowId` + `selected` + `onSelectedChange`). The header box covers the rows on screen only;
83
+ acting on every row that matches a filter is a separate request that sends the filter.
84
+
74
85
  lyra ships **no copy and no number formatting**: `usePager` takes `labels`, including
75
86
  `range: ({from, to, total}) => string`. That keeps `next-intl` out of the library, which matters
76
87
  because `data-table` must stay loadable by a consumer that is not a Next app.
@@ -128,6 +139,26 @@ neutral default and every reader who chose a colour watches it flip. It has to b
128
139
  a raw inline script to beat that paint, which is why lyra renders it instead of
129
140
  leaving it to each app.
130
141
 
142
+ ## Phones
143
+
144
+ `3.12.0` moved in what the scorix Android apps had each written by hand. The kit
145
+ is sized for a pointer, so a phone app opts in to finger-sized controls on its
146
+ root, and takes the phone's own chrome from the kit:
147
+
148
+ ```tsx
149
+ <html data-touch="true"> // 40px controls, 14px text
150
+
151
+ import { BottomNav } from "@tradalab/lyra/shell"
152
+ <BottomNav items={[{ id: "codes", label: t("codes"), icon: <KeyRound /> }]} activeId={tab} onSelect={setTab} />
153
+
154
+ import { ChoiceDrawer, MobileSheet } from "@tradalab/lyra/blocks"
155
+ <MobileSheet open title="Add account" onOpenChange={open => !open && close()}>…</MobileSheet>
156
+ <ChoiceDrawer trigger={row} title="Theme" options={themes} value={theme} onValueChange={setTheme} />
157
+ ```
158
+
159
+ `BottomNav` routes nothing and adds no safe-area padding: the id comes back to
160
+ the app, and the app's root pads the edges.
161
+
131
162
  ## Develop
132
163
 
133
164
  ```bash
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import * as class_variance_authority_types from 'class-variance-authority/types';
3
3
  import { VariantProps } from 'class-variance-authority';
4
- import { Separator as Separator$1, Tooltip as Tooltip$1 } from 'radix-ui';
4
+ import { Separator as Separator$1, Tooltip as Tooltip$1, Tabs as Tabs$1 } from 'radix-ui';
5
5
 
6
6
  declare const buttonVariants: (props?: ({
7
7
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
@@ -93,6 +93,14 @@ declare function SidebarMenuSubButton({ asChild, size, isActive, className, ...p
93
93
  isActive?: boolean;
94
94
  }): React.JSX.Element;
95
95
 
96
+ declare function Tabs({ className, orientation, ...props }: React.ComponentProps<typeof Tabs$1.Root>): React.JSX.Element;
97
+ declare const tabsListVariants: (props?: ({
98
+ variant?: "line" | "default" | null | undefined;
99
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
100
+ declare function TabsList({ className, variant, ...props }: React.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
101
+ declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof Tabs$1.Trigger>): React.JSX.Element;
102
+ declare function TabsContent({ className, ...props }: React.ComponentProps<typeof Tabs$1.Content>): React.JSX.Element;
103
+
96
104
  type AccountMenuUser = {
97
105
  name?: string | null;
98
106
  email?: string | null;
@@ -134,4 +142,4 @@ declare function AccountMenu({ user, labels, onSignOut, onSwitchAccount, onSignI
134
142
  /** Two-letter avatar fallback from a name or email. Shared with shell NavUser. */
135
143
  declare function initialsOf(value?: string | null): string;
136
144
 
137
- export { type AccountMenuUser as A, Breadcrumb as B, SidebarMenuSkeleton as C, SidebarMenuSub as D, SidebarMenuSubButton as E, SidebarMenuSubItem as F, SidebarRail as G, SidebarSeparator as H, Input as I, SidebarTrigger as J, TooltipContent as K, TooltipProvider as L, TooltipTrigger as M, buttonVariants as N, defaultAccountMenuLabels as O, initialsOf as P, useSidebar as Q, SidebarProvider as S, Tooltip as T, SidebarInset as a, Sidebar as b, type AccountMenuLabels as c, Button as d, Separator as e, AccountMenu as f, type AccountMenuProps as g, BreadcrumbEllipsis as h, BreadcrumbItem as i, BreadcrumbLink as j, BreadcrumbList as k, BreadcrumbPage as l, BreadcrumbSeparator as m, SidebarContent as n, SidebarFooter as o, SidebarGroup as p, SidebarGroupAction as q, SidebarGroupContent as r, SidebarGroupLabel as s, SidebarHeader as t, SidebarInput as u, SidebarMenu as v, SidebarMenuAction as w, SidebarMenuBadge as x, SidebarMenuButton as y, SidebarMenuItem as z };
145
+ export { type AccountMenuUser as A, Breadcrumb as B, SidebarMenuSkeleton as C, SidebarMenuSub as D, SidebarMenuSubButton as E, SidebarMenuSubItem as F, SidebarRail as G, SidebarSeparator as H, Input as I, SidebarTrigger as J, TabsContent as K, TabsList as L, TabsTrigger as M, Tooltip as N, TooltipContent as O, TooltipProvider as P, TooltipTrigger as Q, buttonVariants as R, SidebarProvider as S, Tabs as T, defaultAccountMenuLabels as U, initialsOf as V, tabsListVariants as W, useSidebar as X, SidebarInset as a, Sidebar as b, type AccountMenuLabels as c, Button as d, Separator as e, AccountMenu as f, type AccountMenuProps as g, BreadcrumbEllipsis as h, BreadcrumbItem as i, BreadcrumbLink as j, BreadcrumbList as k, BreadcrumbPage as l, BreadcrumbSeparator as m, SidebarContent as n, SidebarFooter as o, SidebarGroup as p, SidebarGroupAction as q, SidebarGroupContent as r, SidebarGroupLabel as s, SidebarHeader as t, SidebarInput as u, SidebarMenu as v, SidebarMenuAction as w, SidebarMenuBadge as x, SidebarMenuButton as y, SidebarMenuItem as z };
@@ -1,7 +1,7 @@
1
1
  import * as react_hook_form from 'react-hook-form';
2
2
  import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
3
- import * as React from 'react';
4
- import { ReactNode, HTMLAttributes } from 'react';
3
+ import * as React$1 from 'react';
4
+ import { ReactNode, HTMLAttributes, ReactElement } from 'react';
5
5
  import { Slot, Label } from 'radix-ui';
6
6
  import { LucideIcon } from 'lucide-react';
7
7
  export { B as BEARING_PLATES, a as BearingPlate, P as PLATES, b as Plate, d as derivePlate, i as isPlate } from '../plate-BJ19iaVV.js';
@@ -9,8 +9,8 @@ export { u as useCompact, a as usePlate } from '../use-compact-BvI4sJf9.js';
9
9
  export { P as PlatePicker, a as PlatePickerProps } from '../plate-picker-CXxUGyNz.js';
10
10
  export { P as PreferenceScript } from '../preference-script-Dm-LEoYX.js';
11
11
 
12
- declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, }: react_hook_form.FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
13
- declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>) => React.JSX.Element;
12
+ declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, }: react_hook_form.FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React$1.JSX.Element;
13
+ declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>) => React$1.JSX.Element;
14
14
  declare const useFormField: () => {
15
15
  invalid: boolean;
16
16
  isDirty: boolean;
@@ -23,11 +23,11 @@ declare const useFormField: () => {
23
23
  formDescriptionId: string;
24
24
  formMessageId: string;
25
25
  };
26
- declare function FormItem({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
27
- declare function FormLabel({ className, ...props }: React.ComponentProps<typeof Label.Root>): React.JSX.Element;
28
- declare function FormControl({ ...props }: React.ComponentProps<typeof Slot.Root>): React.JSX.Element;
29
- declare function FormDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
30
- declare function FormMessage({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element | null;
26
+ declare function FormItem({ className, ...props }: React$1.ComponentProps<"div">): React$1.JSX.Element;
27
+ declare function FormLabel({ className, ...props }: React$1.ComponentProps<typeof Label.Root>): React$1.JSX.Element;
28
+ declare function FormControl({ ...props }: React$1.ComponentProps<typeof Slot.Root>): React$1.JSX.Element;
29
+ declare function FormDescription({ className, ...props }: React$1.ComponentProps<"p">): React$1.JSX.Element;
30
+ declare function FormMessage({ className, ...props }: React$1.ComponentProps<"p">): React$1.JSX.Element | null;
31
31
 
32
32
  type PanelItemType = {
33
33
  key: string;
@@ -48,7 +48,7 @@ type PanelItemType = {
48
48
  */
49
49
  declare function Panel({ items }: {
50
50
  items: PanelItemType[];
51
- }): React.JSX.Element | null;
51
+ }): React$1.JSX.Element | null;
52
52
  interface PanelItemProps {
53
53
  children: ReactNode;
54
54
  active?: boolean;
@@ -64,7 +64,7 @@ interface PanelCardProps {
64
64
  action?: ReactNode;
65
65
  children?: ReactNode;
66
66
  }
67
- declare function PanelCard({ title, description, hint, action, children }: PanelCardProps): React.JSX.Element;
67
+ declare function PanelCard({ title, description, hint, action, children }: PanelCardProps): React$1.JSX.Element;
68
68
 
69
69
  type ConfirmOptions = {
70
70
  title: string;
@@ -79,13 +79,13 @@ type Props = {
79
79
  onConfirm: () => void;
80
80
  onCancel: () => void;
81
81
  };
82
- declare function ConfirmDialog({ options, onConfirm, onCancel }: Props): React.JSX.Element;
82
+ declare function ConfirmDialog({ options, onConfirm, onCancel }: Props): React$1.JSX.Element;
83
83
 
84
84
  type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
85
- declare const ConfirmContext: React.Context<ConfirmFn | null>;
85
+ declare const ConfirmContext: React$1.Context<ConfirmFn | null>;
86
86
  declare function ConfirmProvider({ children }: {
87
87
  children: ReactNode;
88
- }): React.JSX.Element;
88
+ }): React$1.JSX.Element;
89
89
 
90
90
  declare const useConfirm: () => ConfirmFn;
91
91
 
@@ -104,9 +104,9 @@ type TreeProviderProps = {
104
104
  animateExpand?: boolean;
105
105
  className?: string;
106
106
  };
107
- declare const TreeProvider: ({ children, defaultExpandedIds, showLines, showIcons, selectable, multiSelect, selectedIds, onSelectionChange, indent, animateExpand, className, expandedIds, onExpandedChange, }: TreeProviderProps) => React.JSX.Element;
107
+ declare const TreeProvider: ({ children, defaultExpandedIds, showLines, showIcons, selectable, multiSelect, selectedIds, onSelectionChange, indent, animateExpand, className, expandedIds, onExpandedChange, }: TreeProviderProps) => React$1.JSX.Element;
108
108
  type TreeViewProps = HTMLAttributes<HTMLDivElement>;
109
- declare const TreeView: ({ className, children, ...props }: TreeViewProps) => React.JSX.Element;
109
+ declare const TreeView: ({ className, children, ...props }: TreeViewProps) => React$1.JSX.Element;
110
110
  type TreeNodeProps = HTMLAttributes<HTMLDivElement> & {
111
111
  nodeId?: string;
112
112
  level?: number;
@@ -114,27 +114,27 @@ type TreeNodeProps = HTMLAttributes<HTMLDivElement> & {
114
114
  parentPath?: boolean[];
115
115
  children?: ReactNode;
116
116
  };
117
- declare const TreeNode: ({ nodeId: providedNodeId, level, isLast, parentPath, children, className, onClick: _onClick, ...props }: TreeNodeProps) => React.JSX.Element;
117
+ declare const TreeNode: ({ nodeId: providedNodeId, level, isLast, parentPath, children, className, onClick: _onClick, ...props }: TreeNodeProps) => React$1.JSX.Element;
118
118
  type TreeNodeTriggerProps = HTMLAttributes<HTMLDivElement> & {
119
119
  expandOnClick?: boolean;
120
120
  };
121
- declare const TreeNodeTrigger: ({ children, className, onClick, expandOnClick, ...props }: TreeNodeTriggerProps) => React.JSX.Element;
122
- declare const TreeLines: () => React.JSX.Element | null;
121
+ declare const TreeNodeTrigger: ({ children, className, onClick, expandOnClick, ...props }: TreeNodeTriggerProps) => React$1.JSX.Element;
122
+ declare const TreeLines: () => React$1.JSX.Element | null;
123
123
  type TreeNodeContentProps = HTMLAttributes<HTMLDivElement> & {
124
124
  hasChildren?: boolean;
125
125
  };
126
- declare const TreeNodeContent: ({ children, hasChildren, className, ...props }: TreeNodeContentProps) => React.JSX.Element | null;
126
+ declare const TreeNodeContent: ({ children, hasChildren, className, ...props }: TreeNodeContentProps) => React$1.JSX.Element | null;
127
127
  type TreeExpanderProps = HTMLAttributes<HTMLDivElement> & {
128
128
  hasChildren?: boolean;
129
129
  };
130
- declare const TreeExpander: ({ hasChildren, className, onClick, ...props }: TreeExpanderProps) => React.JSX.Element;
130
+ declare const TreeExpander: ({ hasChildren, className, onClick, ...props }: TreeExpanderProps) => React$1.JSX.Element;
131
131
  type TreeIconProps = HTMLAttributes<HTMLDivElement> & {
132
132
  icon?: ReactNode;
133
133
  hasChildren?: boolean;
134
134
  };
135
- declare const TreeIcon: ({ icon, hasChildren, className, ...props }: TreeIconProps) => React.JSX.Element | null;
135
+ declare const TreeIcon: ({ icon, hasChildren, className, ...props }: TreeIconProps) => React$1.JSX.Element | null;
136
136
  type TreeLabelProps = HTMLAttributes<HTMLSpanElement>;
137
- declare const TreeLabel: ({ className, ...props }: TreeLabelProps) => React.JSX.Element;
137
+ declare const TreeLabel: ({ className, ...props }: TreeLabelProps) => React$1.JSX.Element;
138
138
 
139
139
  interface TzPickerLabels {
140
140
  /** Shown when the value is empty and `allowInherit`. Default: "Inherit". */
@@ -158,7 +158,7 @@ interface TzPickerProps {
158
158
  id?: string;
159
159
  className?: string;
160
160
  }
161
- declare function TzPicker({ value, onChange, allowInherit, labels, disabled, id, className, }: TzPickerProps): React.JSX.Element;
161
+ declare function TzPicker({ value, onChange, allowInherit, labels, disabled, id, className, }: TzPickerProps): React$1.JSX.Element;
162
162
 
163
163
  /**
164
164
  * Pick one id from a known set.
@@ -202,7 +202,62 @@ declare function OptionPicker({ value, onChange, options, labels, disabled, id,
202
202
  disabled?: boolean;
203
203
  id?: string;
204
204
  className?: string;
205
- }): React.JSX.Element;
205
+ }): React$1.JSX.Element;
206
+
207
+ interface AvatarTileProps {
208
+ src?: string;
209
+ alt?: string;
210
+ /** Shown while the image loads, or instead of it: initials, an icon. */
211
+ fallback: React.ReactNode;
212
+ className?: string;
213
+ }
214
+ /**
215
+ * The frame, its `after:` border, the image and the fallback each round on their own, so a
216
+ * `rounded-none` on the frame alone still shows a round photo inside a square.
217
+ */
218
+ declare function AvatarTile({ src, alt, fallback, className }: AvatarTileProps): React$1.JSX.Element;
219
+
220
+ interface MobileSheetProps {
221
+ title: ReactNode;
222
+ description?: ReactNode;
223
+ /** Opens the sheet when tapped. Omit it and drive `open` instead. */
224
+ trigger?: ReactElement;
225
+ open?: boolean;
226
+ onOpenChange?: (open: boolean) => void;
227
+ /** Goes on the scrolling body, not the drawer. */
228
+ className?: string;
229
+ children: ReactNode;
230
+ }
231
+ /**
232
+ * A bottom drawer the finger swipes down, for a phone. The three scorix Android apps each wrapped
233
+ * `Drawer` the same way, because the primitive is sized for a pointer (12px body) and stops growing at
234
+ * 80% of the screen without letting what is below that point scroll into view.
235
+ *
236
+ * The body keeps 16px of side padding; content that should run edge to edge (a list of rows) takes
237
+ * it back with `-mx-4`, as `ChoiceDrawer` does.
238
+ */
239
+ declare function MobileSheet({ title, description, trigger, open, onOpenChange, className, children }: MobileSheetProps): React$1.JSX.Element;
240
+
241
+ interface ChoiceOption<T extends string = string> {
242
+ value: T;
243
+ label: ReactNode;
244
+ }
245
+ interface ChoiceDrawerProps<T extends string = string> extends Omit<MobileSheetProps, "children" | "className"> {
246
+ options: readonly ChoiceOption<T>[];
247
+ value: T | undefined;
248
+ onValueChange: (value: T) => void;
249
+ }
250
+ /**
251
+ * Pick one of a few options from a bottom sheet: theme, language, a sound. lunarcalendar and pomodoro
252
+ * had five copies of it.
253
+ *
254
+ * Each row is a `<label>` around its radio, so the whole row takes the tap. The copies made the row a
255
+ * `div` with its own click handler and stopped the radio's click from bubbling, which worked but left
256
+ * the row text unnamed for a screen reader.
257
+ *
258
+ * The sheet stays open after a pick: the choice applies at once and is visible behind it.
259
+ */
260
+ declare function ChoiceDrawer<T extends string = string>({ options, value, onValueChange, ...sheet }: ChoiceDrawerProps<T>): React$1.JSX.Element;
206
261
 
207
262
  /**
208
263
  * The settings screen for a scorix app's MCP tools: the user's switch, one switch per tool,
@@ -290,7 +345,7 @@ declare function McpSettings({ api, serverName, copy, labels, locale, className,
290
345
  labels?: McpSettingsLabels;
291
346
  locale?: string;
292
347
  className?: string;
293
- }): React.JSX.Element;
348
+ }): React$1.JSX.Element;
294
349
 
295
350
  /**
296
351
  * The settings screen for a scorix app's language models: which provider and model each of the
@@ -390,7 +445,7 @@ interface LlmSettingsApi {
390
445
  * this block means silently dropping such a warning, which is what kept loom on its own 687-line
391
446
  * copy of this screen.
392
447
  */
393
- slotNote?(slot: string): React.ReactNode;
448
+ slotNote?(slot: string): React$1.ReactNode;
394
449
  }
395
450
  interface LlmSettingsLabels {
396
451
  slots?: string;
@@ -430,6 +485,6 @@ declare function LlmSettings({ api, labels, className, }: {
430
485
  api: LlmSettingsApi;
431
486
  labels?: LlmSettingsLabels;
432
487
  className?: string;
433
- }): React.JSX.Element;
488
+ }): React$1.JSX.Element;
434
489
 
435
- export { ConfirmContext, ConfirmDialog, type ConfirmFn, type ConfirmOptions, ConfirmProvider, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, type LlmCapability, type LlmDriver, type LlmField, type LlmFound, type LlmModel, type LlmProvider, type LlmProviderInput, type LlmPullProgress, LlmSettings, type LlmSettingsApi, type LlmSettingsLabels, type LlmSlot, type LlmState, type McpCall, type McpClient, McpSettings, type McpSettingsApi, type McpSettingsLabels, type McpStatus, type McpTool, OptionPicker, type OptionPickerLabels, Panel, PanelCard, type PanelCardProps, type PanelItemProps, type PickOption, TreeExpander, type TreeExpanderProps, TreeIcon, type TreeIconProps, TreeLabel, type TreeLabelProps, TreeLines, TreeNode, TreeNodeContent, type TreeNodeContentProps, type TreeNodeProps, TreeNodeTrigger, type TreeNodeTriggerProps, TreeProvider, type TreeProviderProps, TreeView, type TreeViewProps, TzPicker, type TzPickerLabels, type TzPickerProps, useConfirm, useFormField };
490
+ export { AvatarTile, type AvatarTileProps, ChoiceDrawer, type ChoiceDrawerProps, type ChoiceOption, ConfirmContext, ConfirmDialog, type ConfirmFn, type ConfirmOptions, ConfirmProvider, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, type LlmCapability, type LlmDriver, type LlmField, type LlmFound, type LlmModel, type LlmProvider, type LlmProviderInput, type LlmPullProgress, LlmSettings, type LlmSettingsApi, type LlmSettingsLabels, type LlmSlot, type LlmState, type McpCall, type McpClient, McpSettings, type McpSettingsApi, type McpSettingsLabels, type McpStatus, type McpTool, MobileSheet, type MobileSheetProps, OptionPicker, type OptionPickerLabels, Panel, PanelCard, type PanelCardProps, type PanelItemProps, type PickOption, TreeExpander, type TreeExpanderProps, TreeIcon, type TreeIconProps, TreeLabel, type TreeLabelProps, TreeLines, TreeNode, TreeNodeContent, type TreeNodeContentProps, type TreeNodeProps, TreeNodeTrigger, type TreeNodeTriggerProps, TreeProvider, type TreeProviderProps, TreeView, type TreeViewProps, TzPicker, type TzPickerLabels, type TzPickerProps, useConfirm, useFormField };
@@ -1,14 +1,14 @@
1
1
  "use client";
2
- import { Label, Combobox, ComboboxInput, ComboboxContent, ComboboxEmpty, ComboboxList, ComboboxItem, Spinner, Alert, AlertDescription, FieldGroup, FieldSet, FieldLegend, FieldDescription, Field, FieldContent, FieldLabel, Badge, FieldSeparator, Progress } from '../chunk-S5O4AGES.js';
3
- export { PreferenceScript } from '../chunk-S5O4AGES.js';
4
- import { NativeSelect, NativeSelectOption } from '../chunk-AM6UJ666.js';
2
+ import { Label, Combobox, ComboboxInput, ComboboxContent, ComboboxEmpty, ComboboxList, ComboboxItem, Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, Spinner, Alert, AlertDescription, FieldGroup, FieldSet, FieldLegend, FieldDescription, Field, FieldContent, FieldLabel, Badge, FieldSeparator, Progress } from '../chunk-4ILJ3M7K.js';
3
+ export { PreferenceScript } from '../chunk-4ILJ3M7K.js';
4
+ import { NativeSelect, NativeSelectOption } from '../chunk-U4HIZXI6.js';
5
5
  export { useCompact, usePlate } from '../chunk-AIULLZYM.js';
6
- import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Switch } from '../chunk-CLNMWZPV.js';
7
- export { PlatePicker } from '../chunk-CLNMWZPV.js';
6
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, RadioGroup, RadioGroupItem, Switch } from '../chunk-SQELPQZU.js';
7
+ export { PlatePicker } from '../chunk-SQELPQZU.js';
8
8
  export { BEARING_PLATES, PLATES, derivePlate, isPlate } from '../chunk-D7DMRCDY.js';
9
9
  import '../chunk-VEWKPOMS.js';
10
10
  import { Dialog, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from '../chunk-L4LQCVOF.js';
11
- import '../chunk-VXW3K5O5.js';
11
+ import { Avatar, AvatarImage, AvatarFallback } from '../chunk-VXW3K5O5.js';
12
12
  import { Button, Input } from '../chunk-VGOGWZCF.js';
13
13
  import { cn } from '../chunk-XH55BHUU.js';
14
14
  import * as React5 from 'react';
@@ -574,6 +574,30 @@ function OptionPicker({
574
574
  }
575
575
  );
576
576
  }
577
+ function AvatarTile({ src, alt, fallback, className }) {
578
+ return /* @__PURE__ */ jsxs(Avatar, { className: cn("rounded-none after:rounded-none", className), children: [
579
+ src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt: alt ?? "", className: "rounded-none" }) : null,
580
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-none text-xs", children: fallback })
581
+ ] });
582
+ }
583
+ function MobileSheet({ title, description, trigger, open, onOpenChange, className, children }) {
584
+ return /* @__PURE__ */ jsxs(Drawer, { open, onOpenChange, children: [
585
+ trigger && /* @__PURE__ */ jsx(DrawerTrigger, { asChild: true, children: trigger }),
586
+ /* @__PURE__ */ jsxs(DrawerContent, { children: [
587
+ /* @__PURE__ */ jsxs(DrawerHeader, { children: [
588
+ /* @__PURE__ */ jsx(DrawerTitle, { className: "text-base", children: title }),
589
+ description && /* @__PURE__ */ jsx(DrawerDescription, { className: "text-sm", children: description })
590
+ ] }),
591
+ /* @__PURE__ */ jsx("div", { className: cn("min-h-0 overflow-y-auto px-4 pb-[calc(1.5rem+env(safe-area-inset-bottom))] text-sm", className), children })
592
+ ] })
593
+ ] });
594
+ }
595
+ function ChoiceDrawer({ options, value, onValueChange, ...sheet }) {
596
+ return /* @__PURE__ */ jsx(MobileSheet, { ...sheet, children: /* @__PURE__ */ jsx(RadioGroup, { value: value ?? "", onValueChange: (v) => onValueChange(v), className: "-mx-4 gap-0 divide-y divide-border", children: options.map((option) => /* @__PURE__ */ jsxs("label", { className: "flex min-h-12 cursor-pointer items-center justify-between gap-4 px-4 py-3 active:bg-muted", children: [
597
+ /* @__PURE__ */ jsx("span", { children: option.label }),
598
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: option.value })
599
+ ] }, option.value)) }) });
600
+ }
577
601
  var FALLBACK2 = {
578
602
  enable: "Allow MCP clients",
579
603
  enableHint: "Let an AI agent such as Claude Desktop or Cursor use the tools this app offers.",
@@ -1289,6 +1313,6 @@ function LlmSettings({
1289
1313
  );
1290
1314
  }
1291
1315
 
1292
- export { ConfirmContext, ConfirmDialog, ConfirmProvider, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, LlmSettings, McpSettings, OptionPicker, Panel, PanelCard, TreeExpander, TreeIcon, TreeLabel, TreeLines, TreeNode, TreeNodeContent, TreeNodeTrigger, TreeProvider, TreeView, TzPicker, useConfirm, useFormField };
1316
+ export { AvatarTile, ChoiceDrawer, ConfirmContext, ConfirmDialog, ConfirmProvider, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, LlmSettings, McpSettings, MobileSheet, OptionPicker, Panel, PanelCard, TreeExpander, TreeIcon, TreeLabel, TreeLines, TreeNode, TreeNodeContent, TreeNodeTrigger, TreeProvider, TreeView, TzPicker, useConfirm, useFormField };
1293
1317
  //# sourceMappingURL=index.js.map
1294
1318
  //# sourceMappingURL=index.js.map