@stll/ui 0.33.0 → 0.34.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.
@@ -13,8 +13,8 @@ import { VariantProps } from "class-variance-authority";
13
13
  */
14
14
  declare const buttonAccessibleDisabledClass = "cursor-not-allowed opacity-64";
15
15
  declare const buttonVariants: (props?: ({
16
- size?: "sm" | "default" | "lg" | "row" | "icon" | "chip" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "xl" | "xs" | null | undefined;
17
- variant?: "link" | "default" | "muted" | "destructive" | "destructive-outline" | "destructive-ghost" | "ghost" | "outline" | "secondary" | null | undefined;
16
+ size?: "default" | "chip" | "icon" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "row" | "sm" | "xl" | "xs" | null | undefined;
17
+ variant?: "link" | "default" | "destructive" | "destructive-outline" | "destructive-ghost" | "ghost" | "muted" | "outline" | "secondary" | null | undefined;
18
18
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
19
19
  type ButtonProps = {
20
20
  variant?: VariantProps<typeof buttonVariants>["variant"];
@@ -1,12 +1,14 @@
1
- import * as React$1 from "react";
2
1
  //#region src/components/file-input.d.ts
3
- type FileInputProps = Omit<React$1.ComponentProps<"input">, "type" | "value" | "onChange" | "multiple" | "className"> & {
4
- className?: string;
2
+ type FileInputProps = {
3
+ accept?: string | undefined;
4
+ "aria-labelledby"?: string | undefined;
5
+ className?: string | undefined;
6
+ disabled?: boolean | undefined;
5
7
  file: File | null;
6
- onFileChange: (file: File | null) => void;
8
+ onFileChange: (file: File) => void;
7
9
  chooseLabel: string;
8
10
  emptyLabel: string;
9
11
  };
10
- declare const FileInput: ({ className, disabled, file, onFileChange, chooseLabel, emptyLabel, "aria-labelledby": labelledBy, ...props }: FileInputProps) => React$1.JSX.Element;
12
+ declare const FileInput: ({ accept, "aria-labelledby": labelledBy, className, disabled, file, onFileChange, chooseLabel, emptyLabel }: FileInputProps) => import("react").JSX.Element;
11
13
  //#endregion
12
14
  export { FileInput, type FileInputProps };
@@ -1,49 +1,33 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/utils.js";
3
3
  import { Button } from "./button.js";
4
+ import { openFilePicker } from "../lib/file-picker.js";
4
5
  import { UploadIcon } from "lucide-react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { useId, useRef } from "react";
7
+ import { useId } from "react";
7
8
  //#region src/components/file-input.tsx
8
- const FileInput = ({ className, disabled, file, onFileChange, chooseLabel, emptyLabel, "aria-labelledby": labelledBy, ...props }) => {
9
- const inputRef = useRef(null);
9
+ const FileInput = ({ accept, "aria-labelledby": labelledBy, className, disabled, file, onFileChange, chooseLabel, emptyLabel }) => {
10
10
  const triggerId = useId();
11
11
  return /* @__PURE__ */ jsxs("span", {
12
12
  className: cn("flex min-w-0 items-center gap-3", className),
13
13
  "data-slot": "file-input",
14
- children: [
15
- /* @__PURE__ */ jsx("input", {
16
- "aria-hidden": "true",
17
- className: "sr-only",
18
- disabled,
19
- ref: inputRef,
20
- tabIndex: -1,
21
- ...props,
22
- multiple: false,
23
- onChange: (event) => {
24
- const next = event.currentTarget.files?.item(0) ?? null;
25
- event.currentTarget.value = "";
26
- onFileChange(next);
27
- },
28
- type: "file",
29
- value: void 0
14
+ children: [/* @__PURE__ */ jsxs(Button, {
15
+ "aria-labelledby": labelledBy ? `${labelledBy} ${triggerId}` : void 0,
16
+ "data-slot": "file-input-trigger",
17
+ disabled,
18
+ id: triggerId,
19
+ onClick: () => openFilePicker({
20
+ accept,
21
+ onPick: ([first]) => onFileChange(first)
30
22
  }),
31
- /* @__PURE__ */ jsxs(Button, {
32
- "aria-labelledby": labelledBy ? `${labelledBy} ${triggerId}` : void 0,
33
- "data-slot": "file-input-trigger",
34
- disabled,
35
- id: triggerId,
36
- onClick: () => inputRef.current?.click(),
37
- type: "button",
38
- variant: "outline",
39
- children: [/* @__PURE__ */ jsx(UploadIcon, { "aria-hidden": "true" }), chooseLabel]
40
- }),
41
- /* @__PURE__ */ jsx("span", {
42
- className: "text-muted-foreground min-w-0 truncate text-sm",
43
- "data-slot": "file-input-name",
44
- children: file ? /* @__PURE__ */ jsx("bdi", { children: file.name }) : emptyLabel
45
- })
46
- ]
23
+ type: "button",
24
+ variant: "outline",
25
+ children: [/* @__PURE__ */ jsx(UploadIcon, { "aria-hidden": "true" }), chooseLabel]
26
+ }), /* @__PURE__ */ jsx("span", {
27
+ className: "text-muted-foreground min-w-0 truncate text-sm",
28
+ "data-slot": "file-input-name",
29
+ children: file ? /* @__PURE__ */ jsx("bdi", { children: file.name }) : emptyLabel
30
+ })]
47
31
  });
48
32
  };
49
33
  //#endregion
@@ -267,7 +267,7 @@ const OutlineRail = ({ items, scrollContainerRef, resolvePct, onJump, activeId,
267
267
  const highlighted = isActive || isHovered;
268
268
  const indent = 8 + Math.min(node.item.level, maxLevel) * 12;
269
269
  return /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsxs("div", {
270
- className: cn("flex items-center rounded-md pe-2.5 transition-colors", !hasChildren && highlighted && "bg-accent"),
270
+ className: cn("flex items-center rounded-md pe-2.5", !hasChildren && highlighted && "bg-accent"),
271
271
  ...isActive ? { [ACTIVE_ROW_ATTRIBUTE]: "" } : {},
272
272
  onMouseEnter: () => setHoveredId(node.item.id),
273
273
  onMouseLeave: () => setHoveredId(null),
@@ -367,7 +367,7 @@ const OutlineRail = ({ items, scrollContainerRef, resolvePct, onJump, activeId,
367
367
  return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx("button", {
368
368
  "aria-current": isActive ? "true" : void 0,
369
369
  "aria-label": item.label,
370
- className: cn("absolute end-0 rounded-full transition-[width,height,opacity,background-color] duration-150", isHovered || isActive ? "opacity-100" : "opacity-45 hover:opacity-90"),
370
+ className: cn("absolute end-0 rounded-full transition-[width,height,opacity] duration-150", isHovered || isActive ? "opacity-100" : "opacity-45 hover:opacity-90"),
371
371
  onClick: () => jumpTo(item.id),
372
372
  onMouseEnter: () => setHoveredId(item.id),
373
373
  onMouseLeave: () => setHoveredId(null),
@@ -9,6 +9,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  * the same across the app. */
10
10
  const SegmentedIconToggle = ({ value, options, onChange, size = "compact" }) => /* @__PURE__ */ jsx("div", {
11
11
  className: cn("border-border/70 bg-muted/30 inline-flex shrink-0 items-center overflow-hidden rounded-md border p-0.5", size === "touch" ? "h-7 [@media(any-pointer:coarse)]:h-12" : "h-7"),
12
+ "data-slot": "segmented-icon-toggle",
12
13
  children: options.map((option) => {
13
14
  const Icon = option.icon;
14
15
  const isActive = value === option.value;
@@ -17,6 +18,7 @@ const SegmentedIconToggle = ({ value, options, onChange, size = "compact" }) =>
17
18
  "aria-label": option.label,
18
19
  "aria-pressed": isActive,
19
20
  className: cn("text-muted-foreground h-6 min-h-0 w-7 rounded-[4px] p-0", size === "touch" && "[@media(any-pointer:coarse)]:h-11 [@media(any-pointer:coarse)]:min-h-11 [@media(any-pointer:coarse)]:w-11", isActive && "bg-muted text-foreground ring-border/80 hover:bg-muted hover:text-foreground shadow-xs ring-1"),
21
+ "data-control-value": option.value,
20
22
  onClick: () => onChange(option.value),
21
23
  size: "icon-xs",
22
24
  type: "button",
@@ -30,7 +30,7 @@ declare function useSidebar(): SidebarContextProps;
30
30
  * left for the content column. Mobile reports 0: there the sidebar is an
31
31
  * overlay sheet and occupies no layout width.
32
32
  */
33
- declare function useSidebarInlineSize(): 0 | 256 | 48;
33
+ declare function useSidebarInlineSize(): 0 | 48 | 256;
34
34
  declare const SidebarProvider: ({ defaultOpen, forceCollapsed, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }: React.ComponentProps<"div"> & {
35
35
  defaultOpen?: boolean;
36
36
  forceCollapsed?: boolean;
@@ -83,7 +83,7 @@ declare const SidebarMenu: ({ className, ...props }: React.ComponentProps<"ul">)
83
83
  declare const SidebarMenuItem: ({ className, ...props }: React.ComponentProps<"li">) => import("react").JSX.Element;
84
84
  declare const sidebarMenuButtonVariants: (props?: ({
85
85
  variant?: "default" | "outline" | null | undefined;
86
- size?: "sm" | "default" | "lg" | "rail" | null | undefined;
86
+ size?: "default" | "lg" | "sm" | "rail" | null | undefined;
87
87
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
88
88
  declare const SidebarMenuButton: ({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<"button"> & {
89
89
  asChild?: boolean;
@@ -174,7 +174,7 @@ const SidebarRail = ({ className, label = DEFAULT_TOGGLE_LABEL, "aria-label": ar
174
174
  return /* @__PURE__ */ jsx("button", {
175
175
  "aria-label": ariaLabel ?? label,
176
176
  type: "button",
177
- className: cn("hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 transition-[transform,background-color] ease-linear group-data-[side=left]:-end-4 group-data-[side=right]:start-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex", "ltr:-translate-x-1/2 rtl:translate-x-1/2", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "hover:group-data-[collapsible=offcanvas]:bg-sidebar", "group-data-[collapsible=offcanvas]:ltr:translate-x-0 group-data-[collapsible=offcanvas]:rtl:translate-x-0", "group-data-[collapsible=offcanvas]:group-data-[side=left]:after:end-full group-data-[collapsible=offcanvas]:group-data-[side=right]:after:start-full", "[[data-side=left][data-collapsible=offcanvas]_&]:-end-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-start-2", className),
177
+ className: cn("hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 transition-transform ease-linear group-data-[side=left]:-end-4 group-data-[side=right]:start-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex", "ltr:-translate-x-1/2 rtl:translate-x-1/2", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "hover:group-data-[collapsible=offcanvas]:bg-sidebar", "group-data-[collapsible=offcanvas]:ltr:translate-x-0 group-data-[collapsible=offcanvas]:rtl:translate-x-0", "group-data-[collapsible=offcanvas]:group-data-[side=left]:after:end-full group-data-[collapsible=offcanvas]:group-data-[side=right]:after:start-full", "[[data-side=left][data-collapsible=offcanvas]_&]:-end-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-start-2", className),
178
178
  "data-sidebar": "rail",
179
179
  "data-slot": "sidebar-rail",
180
180
  onClick: toggleSidebar,
@@ -257,7 +257,7 @@ const SidebarMenuItem = ({ className, ...props }) => /* @__PURE__ */ jsx("li", {
257
257
  "data-slot": "sidebar-menu-item",
258
258
  ...props
259
259
  });
260
- const sidebarMenuButtonVariants = cva("peer/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-[active=true]:bg-accent data-[active=true]:text-sidebar-accent-foreground data-[active=true]:hover:bg-sidebar-accent data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-sm outline-hidden transition-[width,height,padding,border-radius] group-has-data-[sidebar=menu-action]/menu-item:pe-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>span:last-child]:transition-opacity [&>span:last-child]:duration-200 group-data-[collapsible=icon]:[&>span:last-child]:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0", {
260
+ const sidebarMenuButtonVariants = cva("peer/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-[active=true]:bg-accent data-[active=true]:text-sidebar-accent-foreground data-[active=true]:hover:bg-sidebar-accent data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-sm outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pe-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>span:last-child]:transition-opacity [&>span:last-child]:duration-200 group-data-[collapsible=icon]:[&>span:last-child]:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0", {
261
261
  variants: {
262
262
  variant: {
263
263
  default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
@@ -33,7 +33,7 @@ const TabsList = ({ variant = "default", className, children, ref, ...props }) =
33
33
  });
34
34
  };
35
35
  const TabsTab = ({ className, ...props }) => /* @__PURE__ */ jsx(Tabs$1.Tab, {
36
- className: cn("hover:text-foreground focus-visible:ring-ring data-active:text-foreground relative flex h-9 shrink-0 grow cursor-pointer items-center justify-center gap-1.5 rounded-md border border-transparent px-[calc(--spacing(2.5)-1px)] text-base font-medium whitespace-nowrap transition-[color,background-color,box-shadow] outline-none focus-visible:ring-2 focus-visible:ring-inset data-disabled:pointer-events-none data-disabled:opacity-64 data-[orientation=vertical]:w-full data-[orientation=vertical]:justify-start sm:h-8 sm:text-sm [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4", className),
36
+ className: cn("hover:text-foreground focus-visible:ring-ring data-active:text-foreground relative flex h-9 shrink-0 grow cursor-pointer items-center justify-center gap-1.5 rounded-md border border-transparent px-[calc(--spacing(2.5)-1px)] text-base font-medium whitespace-nowrap outline-none focus-visible:ring-2 focus-visible:ring-inset data-disabled:pointer-events-none data-disabled:opacity-64 data-[orientation=vertical]:w-full data-[orientation=vertical]:justify-start sm:h-8 sm:text-sm [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4", className),
37
37
  "data-slot": "tabs-tab",
38
38
  ...props
39
39
  });
@@ -79,6 +79,8 @@ const InspectorFacetBar = ({ facet, facets, labels, disabledFacets, pulseSeq, ac
79
79
  }
80
80
  return /* @__PURE__ */ jsxs("div", {
81
81
  className: cn("bg-background/85 supports-[backdrop-filter]:bg-background/65 sticky top-0 z-10 flex shrink-0 items-center gap-0.5 overflow-hidden border-b px-1.5 backdrop-blur", TOOLBAR_ROW_HEIGHT),
82
+ "data-active-facet": facet,
83
+ "data-slot": "inspector-facet-bar",
82
84
  ref: containerRef,
83
85
  children: [
84
86
  visibleFacets.map((value) => /* @__PURE__ */ jsx(FacetChip, {
@@ -86,11 +88,13 @@ const InspectorFacetBar = ({ facet, facets, labels, disabledFacets, pulseSeq, ac
86
88
  disabled: disabledFacets?.has(value) ?? false,
87
89
  isActive: value === facet,
88
90
  label: labels[value],
89
- onSelect: () => onChange(value)
91
+ onSelect: () => onChange(value),
92
+ value
90
93
  }, value)),
91
94
  overflowing && /* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsx(MenuTrigger, {
92
95
  "aria-label": overflowMenuLabel,
93
96
  className: "ms-auto",
97
+ "data-slot": "inspector-facet-overflow-trigger",
94
98
  render: /* @__PURE__ */ jsx(Button, {
95
99
  size: "icon-sm",
96
100
  type: "button",
@@ -101,6 +105,7 @@ const InspectorFacetBar = ({ facet, facets, labels, disabledFacets, pulseSeq, ac
101
105
  align: "end",
102
106
  side: "bottom",
103
107
  children: overflowFacets.map((value) => /* @__PURE__ */ jsx(MenuItem, {
108
+ "data-facet-overflow-value": value,
104
109
  disabled: disabledFacets?.has(value) ?? false,
105
110
  onClick: () => onChange(value),
106
111
  children: labels[value]
@@ -112,6 +117,8 @@ const InspectorFacetBar = ({ facet, facets, labels, disabledFacets, pulseSeq, ac
112
117
  ref: measureRef,
113
118
  children: [facets.map((value) => /* @__PURE__ */ jsx("span", {
114
119
  className: cn(CHIP_CLASS, INACTIVE_CHIP_CLASS),
120
+ "data-facet-option": value,
121
+ "data-facet-option-disabled": disabledFacets?.has(value) ? "" : void 0,
115
122
  children: labels[value]
116
123
  }, value)), /* @__PURE__ */ jsx("span", { className: "size-8 shrink-0 rounded-lg border sm:size-7" })]
117
124
  })
@@ -152,10 +159,11 @@ const flashFacetChip = (el) => {
152
159
  };
153
160
  const CHIP_CLASS = "shrink-0 rounded-md px-1.5 py-1 text-xs font-medium whitespace-nowrap transition-colors";
154
161
  const INACTIVE_CHIP_CLASS = "text-muted-foreground hover:bg-muted hover:text-foreground";
155
- const FacetChip = ({ label, isActive, disabled, activeBadge, onSelect }) => /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
162
+ const FacetChip = ({ label, value, isActive, disabled, activeBadge, onSelect }) => /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
156
163
  render: /* @__PURE__ */ jsx("button", {
157
164
  className: cn(CHIP_CLASS, isActive ? "bg-foreground text-background" : INACTIVE_CHIP_CLASS, disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"),
158
165
  "data-facet-chip-active": isActive ? "" : void 0,
166
+ "data-facet-value": value,
159
167
  disabled,
160
168
  onClick: onSelect,
161
169
  type: "button"
@@ -5,6 +5,6 @@ declare const CONTROL_SIZE: Readonly<{
5
5
  readonly lg: "lg";
6
6
  }>;
7
7
  type ControlSize = (typeof CONTROL_SIZE)[keyof typeof CONTROL_SIZE];
8
- declare const CONTROL_SIZES: readonly ("sm" | "default" | "lg")[];
8
+ declare const CONTROL_SIZES: readonly ("default" | "lg" | "sm")[];
9
9
  //#endregion
10
10
  export { CONTROL_SIZE, CONTROL_SIZES, type ControlSize };
@@ -0,0 +1,20 @@
1
+ //#region src/lib/file-picker.d.ts
2
+ type PickedFiles = [File, ...File[]];
3
+ type OpenFilePickerOptions = {
4
+ accept?: string | undefined;
5
+ multiple?: boolean | undefined;
6
+ onPick: (files: PickedFiles) => void;
7
+ };
8
+ /**
9
+ * Opens the browser's file chooser without an `<input type="file">` in the
10
+ * component tree, so no surface carries a hidden input, a ref, or the
11
+ * value-reset that lets the same file be picked twice.
12
+ *
13
+ * Call it synchronously inside a user gesture (a click or keydown handler):
14
+ * browsers open the chooser only under transient activation, so an `await`
15
+ * before the call silently does nothing. Dismissing the chooser calls nothing;
16
+ * `onPick` runs only with at least one file.
17
+ */
18
+ declare const openFilePicker: ({ accept, multiple, onPick }: OpenFilePickerOptions) => void;
19
+ //#endregion
20
+ export { type OpenFilePickerOptions, openFilePicker };
@@ -0,0 +1,29 @@
1
+ //#region src/lib/file-picker.ts
2
+ /**
3
+ * Opens the browser's file chooser without an `<input type="file">` in the
4
+ * component tree, so no surface carries a hidden input, a ref, or the
5
+ * value-reset that lets the same file be picked twice.
6
+ *
7
+ * Call it synchronously inside a user gesture (a click or keydown handler):
8
+ * browsers open the chooser only under transient activation, so an `await`
9
+ * before the call silently does nothing. Dismissing the chooser calls nothing;
10
+ * `onPick` runs only with at least one file.
11
+ */
12
+ const openFilePicker = ({ accept, multiple = false, onPick }) => {
13
+ const input = document.createElement("input");
14
+ input.type = "file";
15
+ input.multiple = multiple;
16
+ if (accept !== void 0) input.accept = accept;
17
+ input.hidden = true;
18
+ const settle = () => {
19
+ input.remove();
20
+ const [first, ...rest] = Array.from(input.files ?? []);
21
+ if (first !== void 0) onPick([first, ...rest]);
22
+ };
23
+ input.addEventListener("change", settle, { once: true });
24
+ input.addEventListener("cancel", settle, { once: true });
25
+ document.body.append(input);
26
+ input.click();
27
+ };
28
+ //#endregion
29
+ export { openFilePicker };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/ui",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Stella's design system: bidi-aware React primitives built on Base UI, the dockable inspector pane, and the Tailwind v4 theme they are styled with.",
5
5
  "keywords": [
6
6
  "base-ui",
@@ -578,6 +578,10 @@
578
578
  "types": "./dist/hooks/use-viewport-width.d.ts",
579
579
  "import": "./dist/hooks/use-viewport-width.js"
580
580
  },
581
+ "./file-picker": {
582
+ "types": "./dist/lib/file-picker.d.ts",
583
+ "import": "./dist/lib/file-picker.js"
584
+ },
581
585
  "./lib/overlay-layer": {
582
586
  "types": "./dist/lib/overlay-layer.d.ts",
583
587
  "import": "./dist/lib/overlay-layer.js"
@@ -614,7 +618,7 @@
614
618
  "clsx": "^2.1.1",
615
619
  "input-otp": "^1.5.0",
616
620
  "lucide-react": "1.41.0",
617
- "tailwind-merge": "^3.6.0",
621
+ "tailwind-merge": "^3.7.0",
618
622
  "temporal-polyfill": "1.0.4"
619
623
  },
620
624
  "devDependencies": {