@usetheo/ui 0.16.0 → 0.17.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.
@@ -0,0 +1,53 @@
1
+ import { Command as CommandPrimitive } from "cmdk";
2
+ import type { ComponentPropsWithoutRef, HTMLAttributes, ReactNode } from "react";
3
+ interface ComboboxProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
4
+ /** Selected value (controlled). */
5
+ value?: string;
6
+ onValueChange?: (value: string) => void;
7
+ /** Listbox visibility (controlled). */
8
+ open?: boolean;
9
+ defaultOpen?: boolean;
10
+ onOpenChange?: (open: boolean) => void;
11
+ /** Set false to disable cmdk's internal filter (async mode — consumer filters). */
12
+ shouldFilter?: boolean;
13
+ children: ReactNode;
14
+ }
15
+ type ComboboxInputProps = ComponentPropsWithoutRef<typeof CommandPrimitive.Input>;
16
+ interface ComboboxContentProps extends HTMLAttributes<HTMLDivElement> {
17
+ /** Async fetch in flight: shows the loading slot and hides items/empty. */
18
+ loading?: boolean;
19
+ }
20
+ type ComboboxItemProps = ComponentPropsWithoutRef<typeof CommandPrimitive.Item>;
21
+ declare const Combobox: import("react").ForwardRefExoticComponent<ComboboxProps & import("react").RefAttributes<HTMLDivElement>> & {
22
+ Input: import("react").ForwardRefExoticComponent<Omit<Omit<Pick<Pick<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof import("react").InputHTMLAttributes<HTMLInputElement>> & {
23
+ ref?: React.Ref<HTMLInputElement>;
24
+ } & {
25
+ asChild?: boolean;
26
+ }, "asChild" | "key" | keyof import("react").InputHTMLAttributes<HTMLInputElement>>, "type" | "value" | "onChange"> & {
27
+ value?: string;
28
+ onValueChange?: (search: string) => void;
29
+ } & import("react").RefAttributes<HTMLInputElement>, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
30
+ Content: import("react").ForwardRefExoticComponent<ComboboxContentProps & import("react").RefAttributes<HTMLDivElement>>;
31
+ Item: import("react").ForwardRefExoticComponent<Omit<{
32
+ children?: React.ReactNode;
33
+ } & Omit<Pick<Pick<import("react").DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
34
+ ref?: React.Ref<HTMLDivElement>;
35
+ } & {
36
+ asChild?: boolean;
37
+ }, "asChild" | "key" | keyof HTMLAttributes<HTMLDivElement>>, "disabled" | "value" | "onSelect"> & {
38
+ disabled?: boolean;
39
+ onSelect?: (value: string) => void;
40
+ value?: string;
41
+ keywords?: string[];
42
+ forceMount?: boolean;
43
+ } & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
44
+ Empty: import("react").ForwardRefExoticComponent<Omit<{
45
+ children?: React.ReactNode;
46
+ } & Pick<Pick<import("react").DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & {
47
+ ref?: React.Ref<HTMLDivElement>;
48
+ } & {
49
+ asChild?: boolean;
50
+ }, "asChild" | "key" | keyof HTMLAttributes<HTMLDivElement>> & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
51
+ };
52
+ export { Combobox };
53
+ export type { ComboboxProps, ComboboxContentProps, ComboboxInputProps, ComboboxItemProps };
@@ -0,0 +1 @@
1
+ export { Combobox, type ComboboxContentProps, type ComboboxInputProps, type ComboboxItemProps, type ComboboxProps, } from "./combobox.js";
@@ -0,0 +1 @@
1
+ export { Slider, type SliderMark, type SliderProps } from "./slider.js";
@@ -0,0 +1,24 @@
1
+ import * as SliderPrimitive from "@radix-ui/react-slider";
2
+ import type { ComponentPropsWithoutRef, ReactNode } from "react";
3
+ /**
4
+ * Slider — range input primitive over Radix Slider.
5
+ *
6
+ * Single thumb: `defaultValue={[5]}`. Range: `defaultValue={[20, 80]}` (one
7
+ * thumb per array entry). `marks` renders labelled, clickable points over the
8
+ * track (Mantine-shaped `{value, label?}`); clicking a mark sets the value in
9
+ * single mode and is a no-op in range mode (which thumb to move is ambiguous).
10
+ *
11
+ * <Slider aria-label="Top K" min={1} max={100} defaultValue={[5]}
12
+ * marks={[{ value: 1 }, { value: 50 }, { value: 100 }]} />
13
+ */
14
+ interface SliderMark {
15
+ value: number;
16
+ label?: ReactNode;
17
+ }
18
+ interface SliderProps extends ComponentPropsWithoutRef<typeof SliderPrimitive.Root> {
19
+ /** Labelled, clickable points rendered over the track. Values outside [min, max] are skipped. */
20
+ marks?: SliderMark[];
21
+ }
22
+ declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLSpanElement>>;
23
+ export { Slider };
24
+ export type { SliderMark, SliderProps };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { cn } from "./lib/cn.js";
2
2
  export { Button, buttonVariants, type ButtonProps } from "./components/primitives/button/index.js";
3
3
  export { Badge, badgeVariants, type BadgeProps } from "./components/primitives/badge/index.js";
4
4
  export { Breadcrumb, type BreadcrumbLinkProps, } from "./components/primitives/breadcrumb/index.js";
5
+ export { Combobox, type ComboboxContentProps, type ComboboxInputProps, type ComboboxItemProps, type ComboboxProps, } from "./components/primitives/combobox/index.js";
6
+ export { Slider, type SliderMark, type SliderProps, } from "./components/primitives/slider/index.js";
5
7
  export { UpdateBanner, type UpdateBannerProps, } from "./components/primitives/update-banner/index.js";
6
8
  export { Card } from "./components/primitives/card/index.js";
7
9
  export { Input, type InputProps } from "./components/primitives/input/index.js";
package/dist/index.js CHANGED
@@ -2,9 +2,11 @@ import { clsx } from 'clsx';
2
2
  import { extendTailwindMerge } from 'tailwind-merge';
3
3
  import { Slot } from '@radix-ui/react-slot';
4
4
  import { cva } from 'class-variance-authority';
5
- import { forwardRef, createContext, useId, Children, isValidElement, cloneElement, Fragment as Fragment$1, useContext, useEffect, useState, useRef, useCallback, createElement, useMemo } from 'react';
5
+ import { forwardRef, createContext, useState, useRef, useId, useCallback, useEffect, useMemo, Children, isValidElement, cloneElement, Fragment as Fragment$1, useContext, createElement } from 'react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { ArrowUpCircle, X, AlertCircle, ChevronDown, ChevronUp, Check, Minus, Circle, ChevronRight, ChevronsUpDown, Copy, TrendingDown, TrendingUp, ArrowUpRight, Loader2, TriangleAlert, CheckCircle2, Info, ChevronsLeft, ChevronLeft, ChevronsRight, Search, Filter, GitCommit, GitBranch, Activity, Plus, Lock, EyeOff, Eye, Trash2, GitPullRequest, Server, ExternalLink, Globe, ShieldCheck, ShieldX, Clock, RotateCcw, ArrowDownLeft, MoreHorizontal } from 'lucide-react';
7
+ import { Loader2, Check, ArrowUpCircle, X, AlertCircle, ChevronDown, ChevronUp, Minus, Circle, ChevronRight, ChevronsUpDown, Copy, TrendingDown, TrendingUp, ArrowUpRight, TriangleAlert, CheckCircle2, Info, ChevronsLeft, ChevronLeft, ChevronsRight, Search, Filter, GitCommit, GitBranch, Activity, Plus, Lock, EyeOff, Eye, Trash2, GitPullRequest, Server, ExternalLink, Globe, ShieldCheck, ShieldX, Clock, RotateCcw, ArrowDownLeft, MoreHorizontal } from 'lucide-react';
8
+ import { Command, useCommandState } from 'cmdk';
9
+ import * as SliderPrimitive from '@radix-ui/react-slider';
8
10
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
11
  import * as TabsPrimitive from '@radix-ui/react-tabs';
10
12
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
@@ -17,7 +19,6 @@ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
17
19
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
18
20
  import * as SwitchPrimitive from '@radix-ui/react-switch';
19
21
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
20
- import { Command } from 'cmdk';
21
22
 
22
23
  // src/lib/cn.ts
23
24
  var twMerge = extendTailwindMerge({
@@ -286,6 +287,334 @@ var Breadcrumb = Object.assign(Root, {
286
287
  Separator,
287
288
  Ellipsis
288
289
  });
290
+ var inputVariants = cva(
291
+ [
292
+ "flex w-full rounded-md border border-input bg-card",
293
+ "text-foreground placeholder:text-muted-foreground",
294
+ "transition-[box-shadow,border-color] duration-base ease-out-soft",
295
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
296
+ "focus-visible:border-primary",
297
+ "disabled:cursor-not-allowed disabled:opacity-50",
298
+ "file:border-0 file:bg-transparent file:font-medium file:text-body-sm"
299
+ ],
300
+ {
301
+ variants: {
302
+ size: {
303
+ sm: "h-8 px-2.5 py-1 text-body-sm",
304
+ // md: density-tunable via CSS var. Comfortable (default) = 36px.
305
+ md: "h-[var(--theo-control-h,2.25rem)] px-[var(--theo-control-px,0.875rem)] py-1.5 text-body-sm",
306
+ lg: "h-11 px-4 py-2.5 text-body-md"
307
+ }
308
+ },
309
+ defaultVariants: { size: "md" }
310
+ }
311
+ );
312
+ var Input = forwardRef(
313
+ ({ className, type = "text", size, ...props }, ref) => /* @__PURE__ */ jsx(
314
+ "input",
315
+ {
316
+ "data-slot": "input",
317
+ "data-size": size,
318
+ ref,
319
+ type,
320
+ className: cn(inputVariants({ size }), className),
321
+ ...props
322
+ }
323
+ )
324
+ );
325
+ Input.displayName = "Input";
326
+ var ComboboxContext = createContext(null);
327
+ function composeRefs(local, forwarded) {
328
+ return (node) => {
329
+ local.current = node;
330
+ if (typeof forwarded === "function") forwarded(node);
331
+ else if (forwarded) forwarded.current = node;
332
+ };
333
+ }
334
+ function useComboboxContext(sub2) {
335
+ const ctx = useContext(ComboboxContext);
336
+ if (!ctx) throw new Error(`<Combobox.${sub2}> must be used inside <Combobox>`);
337
+ return ctx;
338
+ }
339
+ var Root2 = forwardRef(
340
+ ({
341
+ className,
342
+ children,
343
+ value,
344
+ onValueChange,
345
+ open: openProp,
346
+ defaultOpen = false,
347
+ onOpenChange,
348
+ shouldFilter = true,
349
+ "aria-label": ariaLabel,
350
+ ...props
351
+ }, ref) => {
352
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
353
+ const open = openProp ?? uncontrolledOpen;
354
+ const rootRef = useRef(null);
355
+ const listId = useId();
356
+ const setOpen = useCallback(
357
+ (next) => {
358
+ setUncontrolledOpen(next);
359
+ onOpenChange?.(next);
360
+ },
361
+ [onOpenChange]
362
+ );
363
+ const select = useCallback(
364
+ (next) => {
365
+ onValueChange?.(next);
366
+ setOpen(false);
367
+ },
368
+ [onValueChange, setOpen]
369
+ );
370
+ useEffect(() => {
371
+ if (!open) return;
372
+ const onMouseDown = (event) => {
373
+ if (rootRef.current && !rootRef.current.contains(event.target)) {
374
+ setOpen(false);
375
+ }
376
+ };
377
+ document.addEventListener("mousedown", onMouseDown);
378
+ return () => document.removeEventListener("mousedown", onMouseDown);
379
+ }, [open, setOpen]);
380
+ return /* @__PURE__ */ jsx(ComboboxContext.Provider, { value: { open, setOpen, value, select, listId }, children: /* @__PURE__ */ jsx(
381
+ "div",
382
+ {
383
+ "data-slot": "combobox",
384
+ ref: composeRefs(rootRef, ref),
385
+ className: cn("relative w-full", className),
386
+ ...props,
387
+ children: /* @__PURE__ */ jsx(Command, { label: ariaLabel, shouldFilter, children })
388
+ }
389
+ ) });
390
+ }
391
+ );
392
+ Root2.displayName = "Combobox";
393
+ var Input2 = forwardRef(
394
+ ({ className, onFocus, onKeyDown, onValueChange, ...props }, ref) => {
395
+ const { open, setOpen, listId } = useComboboxContext("Input");
396
+ const innerRef = useRef(null);
397
+ useEffect(() => {
398
+ const el = innerRef.current;
399
+ if (!el) return;
400
+ el.setAttribute("aria-expanded", String(open));
401
+ if (open) el.setAttribute("aria-controls", listId);
402
+ else el.removeAttribute("aria-controls");
403
+ });
404
+ return /* @__PURE__ */ jsx(
405
+ Command.Input,
406
+ {
407
+ "data-slot": "combobox-input",
408
+ ref: composeRefs(innerRef, ref),
409
+ className: cn(inputVariants({ size: "md" }), className),
410
+ onFocus: (event) => {
411
+ setOpen(true);
412
+ onFocus?.(event);
413
+ },
414
+ onKeyDown: (event) => {
415
+ if (event.key === "Escape") setOpen(false);
416
+ onKeyDown?.(event);
417
+ },
418
+ onValueChange: (search) => {
419
+ if (!open) setOpen(true);
420
+ onValueChange?.(search);
421
+ },
422
+ ...props
423
+ }
424
+ );
425
+ }
426
+ );
427
+ Input2.displayName = "Combobox.Input";
428
+ var Content = forwardRef(
429
+ ({ className, children, loading, ...props }, ref) => {
430
+ const { open, listId } = useComboboxContext("Content");
431
+ const resultCount = useCommandState((state) => state.filtered.count);
432
+ const listRef = useRef(null);
433
+ useEffect(() => {
434
+ const el = listRef.current;
435
+ if (!el) return;
436
+ el.setAttribute("id", listId);
437
+ if (resultCount === 0) {
438
+ el.setAttribute("role", "presentation");
439
+ el.removeAttribute("aria-label");
440
+ } else {
441
+ el.setAttribute("role", "listbox");
442
+ if (!el.getAttribute("aria-label")) el.setAttribute("aria-label", "Suggestions");
443
+ }
444
+ });
445
+ if (!open) return null;
446
+ return /* @__PURE__ */ jsx(
447
+ "div",
448
+ {
449
+ "data-slot": "combobox-content",
450
+ ref,
451
+ className: cn(
452
+ "absolute top-full z-50 mt-1 w-full rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-md",
453
+ className
454
+ ),
455
+ ...props,
456
+ children: loading ? /* @__PURE__ */ jsxs(
457
+ "div",
458
+ {
459
+ "data-slot": "combobox-loading",
460
+ id: listId,
461
+ "aria-busy": "true",
462
+ className: "flex items-center justify-center gap-2 px-3 py-6 text-body-sm text-muted-foreground",
463
+ children: [
464
+ /* @__PURE__ */ jsx(Loader2, { "aria-hidden": true, className: "size-4 animate-spin" }),
465
+ "Loading\u2026"
466
+ ]
467
+ }
468
+ ) : /* @__PURE__ */ jsx(Command.List, { ref: listRef, className: "max-h-64 overflow-y-auto", children })
469
+ }
470
+ );
471
+ }
472
+ );
473
+ Content.displayName = "Combobox.Content";
474
+ var Item2 = forwardRef(
475
+ ({ className, children, value, onSelect, ...props }, ref) => {
476
+ const ctx = useComboboxContext("Item");
477
+ const selected = value !== void 0 && ctx.value === value;
478
+ return /* @__PURE__ */ jsxs(
479
+ Command.Item,
480
+ {
481
+ "data-slot": "combobox-item",
482
+ "data-selected-value": selected ? "true" : void 0,
483
+ ref,
484
+ value,
485
+ onSelect: (selectedValue) => {
486
+ ctx.select(selectedValue);
487
+ onSelect?.(selectedValue);
488
+ },
489
+ className: cn(
490
+ "flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-body-sm",
491
+ "data-[selected=true]:bg-accent/10 data-[selected=true]:text-foreground",
492
+ className
493
+ ),
494
+ ...props,
495
+ children: [
496
+ children,
497
+ /* @__PURE__ */ jsx(
498
+ Check,
499
+ {
500
+ "aria-hidden": true,
501
+ className: cn("ml-auto size-4", selected ? "opacity-100" : "opacity-0")
502
+ }
503
+ )
504
+ ]
505
+ }
506
+ );
507
+ }
508
+ );
509
+ Item2.displayName = "Combobox.Item";
510
+ var Empty = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
511
+ Command.Empty,
512
+ {
513
+ "data-slot": "combobox-empty",
514
+ ref,
515
+ className: cn("px-3 py-6 text-center text-body-sm text-muted-foreground", className),
516
+ ...props
517
+ }
518
+ ));
519
+ Empty.displayName = "Combobox.Empty";
520
+ var Combobox = Object.assign(Root2, { Input: Input2, Content, Item: Item2, Empty });
521
+ var Slider = forwardRef(
522
+ ({
523
+ className,
524
+ defaultValue,
525
+ value,
526
+ min = 0,
527
+ max = 100,
528
+ marks,
529
+ disabled,
530
+ onValueChange,
531
+ "aria-label": ariaLabel,
532
+ "aria-labelledby": ariaLabelledby,
533
+ ...props
534
+ }, ref) => {
535
+ const clamp = (entries) => entries?.map((entry) => Math.min(Math.max(entry, min), max));
536
+ const [internalValue, setInternalValue] = useState(clamp(defaultValue));
537
+ const clampedValue = clamp(value) ?? internalValue;
538
+ const thumbCount = useMemo(() => {
539
+ if (Array.isArray(value)) return value.length;
540
+ if (Array.isArray(defaultValue)) return defaultValue.length;
541
+ return 1;
542
+ }, [value, defaultValue]);
543
+ const span = max - min || 1;
544
+ const visibleMarks = (marks ?? []).filter((mark) => mark.value >= min && mark.value <= max);
545
+ const isRange = thumbCount > 1;
546
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "slider", className: cn("relative w-full", visibleMarks.length > 0 && "pb-5"), children: [
547
+ /* @__PURE__ */ jsxs(
548
+ SliderPrimitive.Root,
549
+ {
550
+ ref,
551
+ "data-slot": "slider-root",
552
+ value: clampedValue,
553
+ min,
554
+ max,
555
+ disabled,
556
+ onValueChange: (next) => {
557
+ if (value === void 0) setInternalValue(next);
558
+ onValueChange?.(next);
559
+ },
560
+ className: cn(
561
+ "relative flex w-full touch-none select-none items-center",
562
+ "data-[disabled]:opacity-50",
563
+ "data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
564
+ className
565
+ ),
566
+ ...props,
567
+ children: [
568
+ /* @__PURE__ */ jsx(
569
+ SliderPrimitive.Track,
570
+ {
571
+ "data-slot": "slider-track",
572
+ className: "relative grow overflow-hidden rounded-full bg-muted data-[orientation=horizontal]:h-1.5 data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-1.5",
573
+ children: /* @__PURE__ */ jsx(
574
+ SliderPrimitive.Range,
575
+ {
576
+ "data-slot": "slider-range",
577
+ className: "absolute bg-primary data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
578
+ }
579
+ )
580
+ }
581
+ ),
582
+ Array.from({ length: thumbCount }, (_, index) => /* @__PURE__ */ jsx(
583
+ SliderPrimitive.Thumb,
584
+ {
585
+ "aria-label": isRange && ariaLabel ? `${ariaLabel} (${index + 1} of ${thumbCount})` : ariaLabel,
586
+ "aria-labelledby": ariaLabelledby,
587
+ "data-slot": "slider-thumb",
588
+ className: "block size-4 shrink-0 rounded-full border border-primary bg-background shadow-sm transition-[box-shadow] hover:ring-4 hover:ring-ring/50 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50"
589
+ },
590
+ index
591
+ ))
592
+ ]
593
+ }
594
+ ),
595
+ visibleMarks.map((mark) => /* @__PURE__ */ jsx(
596
+ "button",
597
+ {
598
+ type: "button",
599
+ "data-slot": "slider-mark",
600
+ disabled,
601
+ tabIndex: -1,
602
+ "aria-hidden": "true",
603
+ style: { left: `${(mark.value - min) / span * 100}%` },
604
+ className: "-translate-x-1/2 absolute top-4 cursor-pointer text-body-sm text-muted-foreground disabled:cursor-default",
605
+ onClick: () => {
606
+ if (disabled || isRange) return;
607
+ if (value === void 0) setInternalValue([mark.value]);
608
+ onValueChange?.([mark.value]);
609
+ },
610
+ children: mark.label ?? mark.value
611
+ },
612
+ mark.value
613
+ ))
614
+ ] });
615
+ }
616
+ );
617
+ Slider.displayName = "Slider";
289
618
  var UpdateBanner = forwardRef(
290
619
  ({
291
620
  currentVersion,
@@ -361,7 +690,7 @@ var UpdateBanner = forwardRef(
361
690
  UpdateBanner.displayName = "UpdateBanner";
362
691
  var CardContext = createContext({ size: "md" });
363
692
  var useCardSize = () => useContext(CardContext).size;
364
- var Root2 = forwardRef(
693
+ var Root4 = forwardRef(
365
694
  ({ className, size = "md", ...props }, ref) => /* @__PURE__ */ jsx(CardContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(
366
695
  "div",
367
696
  {
@@ -376,7 +705,7 @@ var Root2 = forwardRef(
376
705
  }
377
706
  ) })
378
707
  );
379
- Root2.displayName = "Card";
708
+ Root4.displayName = "Card";
380
709
  var headerPadBySize = {
381
710
  sm: "gap-1 p-3 pb-1.5",
382
711
  md: "gap-1.5 p-5 pb-2.5",
@@ -478,49 +807,13 @@ var Footer = forwardRef(
478
807
  }
479
808
  );
480
809
  Footer.displayName = "Card.Footer";
481
- var Card = /* @__PURE__ */ Object.assign(Root2, {
810
+ var Card = /* @__PURE__ */ Object.assign(Root4, {
482
811
  Header,
483
812
  Title,
484
813
  Description,
485
814
  Body,
486
815
  Footer
487
816
  });
488
- var inputVariants = cva(
489
- [
490
- "flex w-full rounded-md border border-input bg-card",
491
- "text-foreground placeholder:text-muted-foreground",
492
- "transition-[box-shadow,border-color] duration-base ease-out-soft",
493
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
494
- "focus-visible:border-primary",
495
- "disabled:cursor-not-allowed disabled:opacity-50",
496
- "file:border-0 file:bg-transparent file:font-medium file:text-body-sm"
497
- ],
498
- {
499
- variants: {
500
- size: {
501
- sm: "h-8 px-2.5 py-1 text-body-sm",
502
- // md: density-tunable via CSS var. Comfortable (default) = 36px.
503
- md: "h-[var(--theo-control-h,2.25rem)] px-[var(--theo-control-px,0.875rem)] py-1.5 text-body-sm",
504
- lg: "h-11 px-4 py-2.5 text-body-md"
505
- }
506
- },
507
- defaultVariants: { size: "md" }
508
- }
509
- );
510
- var Input = forwardRef(
511
- ({ className, type = "text", size, ...props }, ref) => /* @__PURE__ */ jsx(
512
- "input",
513
- {
514
- "data-slot": "input",
515
- "data-size": size,
516
- ref,
517
- type,
518
- className: cn(inputVariants({ size }), className),
519
- ...props
520
- }
521
- )
522
- );
523
- Input.displayName = "Input";
524
817
  var Overlay2 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
525
818
  DialogPrimitive.Overlay,
526
819
  {
@@ -536,7 +829,7 @@ var Overlay2 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
536
829
  }
537
830
  ));
538
831
  Overlay2.displayName = "Dialog.Overlay";
539
- var Content2 = forwardRef(
832
+ var Content3 = forwardRef(
540
833
  ({ className, children, hideCloseButton, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
541
834
  /* @__PURE__ */ jsx(Overlay2, {}),
542
835
  /* @__PURE__ */ jsxs(
@@ -575,7 +868,7 @@ var Content2 = forwardRef(
575
868
  )
576
869
  ] })
577
870
  );
578
- Content2.displayName = "Dialog.Content";
871
+ Content3.displayName = "Dialog.Content";
579
872
  var Header2 = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-1.5 p-6 pb-3 text-left", className), ...props });
580
873
  Header2.displayName = "Dialog.Header";
581
874
  var Body2 = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("px-6 pb-6 text-body-md text-muted-foreground", className), ...props });
@@ -613,7 +906,7 @@ Description3.displayName = "Dialog.Description";
613
906
  var Dialog = /* @__PURE__ */ Object.assign(DialogPrimitive.Root, {
614
907
  Trigger: DialogPrimitive.Trigger,
615
908
  Close: DialogPrimitive.Close,
616
- Content: Content2,
909
+ Content: Content3,
617
910
  Overlay: Overlay2,
618
911
  Header: Header2,
619
912
  Body: Body2,
@@ -655,7 +948,7 @@ var Trigger3 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
655
948
  }
656
949
  ));
657
950
  Trigger3.displayName = "Tabs.Trigger";
658
- var Content4 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
951
+ var Content5 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
659
952
  TabsPrimitive.Content,
660
953
  {
661
954
  "data-slot": "tabs-content",
@@ -667,16 +960,16 @@ var Content4 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
667
960
  ...props
668
961
  }
669
962
  ));
670
- Content4.displayName = "Tabs.Content";
963
+ Content5.displayName = "Tabs.Content";
671
964
  var Tabs = /* @__PURE__ */ Object.assign(TabsPrimitive.Root, {
672
965
  List: List3,
673
966
  Trigger: Trigger3,
674
- Content: Content4
967
+ Content: Content5
675
968
  });
676
969
  var Provider2 = TooltipPrimitive.Provider;
677
- var Root6 = TooltipPrimitive.Root;
970
+ var Root8 = TooltipPrimitive.Root;
678
971
  var Trigger5 = TooltipPrimitive.Trigger;
679
- var Content6 = forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
972
+ var Content7 = forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
680
973
  TooltipPrimitive.Content,
681
974
  {
682
975
  "data-slot": "tooltip-content",
@@ -694,7 +987,7 @@ var Content6 = forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @
694
987
  ...props
695
988
  }
696
989
  ) }));
697
- Content6.displayName = "Tooltip.Content";
990
+ Content7.displayName = "Tooltip.Content";
698
991
  var Tooltip = ({
699
992
  label,
700
993
  side = "top",
@@ -702,15 +995,15 @@ var Tooltip = ({
702
995
  delayDuration = 200,
703
996
  children,
704
997
  ...rootProps
705
- }) => /* @__PURE__ */ jsx(Provider2, { delayDuration, children: /* @__PURE__ */ jsxs(Root6, { ...rootProps, children: [
998
+ }) => /* @__PURE__ */ jsx(Provider2, { delayDuration, children: /* @__PURE__ */ jsxs(Root8, { ...rootProps, children: [
706
999
  /* @__PURE__ */ jsx(Trigger5, { asChild: true, children }),
707
- /* @__PURE__ */ jsx(Content6, { side, align, children: label })
1000
+ /* @__PURE__ */ jsx(Content7, { side, align, children: label })
708
1001
  ] }) });
709
1002
  var TooltipWithStatics = Tooltip;
710
1003
  TooltipWithStatics.Provider = Provider2;
711
- TooltipWithStatics.Root = Root6;
1004
+ TooltipWithStatics.Root = Root8;
712
1005
  TooltipWithStatics.Trigger = Trigger5;
713
- TooltipWithStatics.Content = Content6;
1006
+ TooltipWithStatics.Content = Content7;
714
1007
  var ScrollAreaRoot = forwardRef(
715
1008
  ({ className, children, orientation = "vertical", size = "thin", type = "hover", ...props }, ref) => /* @__PURE__ */ jsxs(
716
1009
  ScrollAreaPrimitive.Root,
@@ -1560,7 +1853,7 @@ var Textarea = forwardRef(
1560
1853
  )
1561
1854
  );
1562
1855
  Textarea.displayName = "Textarea";
1563
- var Root16 = forwardRef(
1856
+ var Root18 = forwardRef(
1564
1857
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1565
1858
  "aside",
1566
1859
  {
@@ -1574,7 +1867,7 @@ var Root16 = forwardRef(
1574
1867
  }
1575
1868
  )
1576
1869
  );
1577
- Root16.displayName = "Sidebar";
1870
+ Root18.displayName = "Sidebar";
1578
1871
  var Header3 = forwardRef(
1579
1872
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1580
1873
  "div",
@@ -1603,7 +1896,7 @@ var Section = forwardRef(
1603
1896
  )
1604
1897
  );
1605
1898
  Section.displayName = "Sidebar.Section";
1606
- var Item4 = forwardRef(
1899
+ var Item5 = forwardRef(
1607
1900
  ({ className, icon: Icon2, active, count, as = "button", href, children, ...props }, ref) => {
1608
1901
  const classes = cn(
1609
1902
  "group flex w-full items-center gap-3 rounded-lg px-2 py-2",
@@ -1663,7 +1956,7 @@ var Item4 = forwardRef(
1663
1956
  );
1664
1957
  }
1665
1958
  );
1666
- Item4.displayName = "Sidebar.Item";
1959
+ Item5.displayName = "Sidebar.Item";
1667
1960
  var Footer3 = forwardRef(
1668
1961
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1669
1962
  "div",
@@ -1676,13 +1969,13 @@ var Footer3 = forwardRef(
1676
1969
  )
1677
1970
  );
1678
1971
  Footer3.displayName = "Sidebar.Footer";
1679
- var Sidebar = /* @__PURE__ */ Object.assign(Root16, {
1972
+ var Sidebar = /* @__PURE__ */ Object.assign(Root18, {
1680
1973
  Header: Header3,
1681
1974
  Section,
1682
- Item: Item4,
1975
+ Item: Item5,
1683
1976
  Footer: Footer3
1684
1977
  });
1685
- var Root17 = forwardRef(
1978
+ var Root19 = forwardRef(
1686
1979
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1687
1980
  "header",
1688
1981
  {
@@ -1696,7 +1989,7 @@ var Root17 = forwardRef(
1696
1989
  }
1697
1990
  )
1698
1991
  );
1699
- Root17.displayName = "TopNav";
1992
+ Root19.displayName = "TopNav";
1700
1993
  var Left = forwardRef(
1701
1994
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1702
1995
  "div",
@@ -1831,7 +2124,7 @@ var ModeSwitcher = forwardRef(
1831
2124
  }
1832
2125
  );
1833
2126
  ModeSwitcher.displayName = "TopNav.ModeSwitcher";
1834
- var TopNav = /* @__PURE__ */ Object.assign(Root17, {
2127
+ var TopNav = /* @__PURE__ */ Object.assign(Root19, {
1835
2128
  Left,
1836
2129
  Center,
1837
2130
  Right,
@@ -1871,7 +2164,7 @@ var sheetVariants = cva(
1871
2164
  defaultVariants: { side: "right" }
1872
2165
  }
1873
2166
  );
1874
- var Content9 = forwardRef(
2167
+ var Content10 = forwardRef(
1875
2168
  ({ className, children, hideCloseButton, side = "right", ...props }, ref) => /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
1876
2169
  /* @__PURE__ */ jsx(Overlay4, {}),
1877
2170
  /* @__PURE__ */ jsxs(
@@ -1903,7 +2196,7 @@ var Content9 = forwardRef(
1903
2196
  )
1904
2197
  ] })
1905
2198
  );
1906
- Content9.displayName = "Sheet.Content";
2199
+ Content10.displayName = "Sheet.Content";
1907
2200
  var Header4 = ({ className, ...props }) => /* @__PURE__ */ jsx(
1908
2201
  "div",
1909
2202
  {
@@ -1948,7 +2241,7 @@ Description6.displayName = "Sheet.Description";
1948
2241
  var Sheet = DialogPrimitive.Root;
1949
2242
  Sheet.Trigger = DialogPrimitive.Trigger;
1950
2243
  Sheet.Close = DialogPrimitive.Close;
1951
- Sheet.Content = Content9;
2244
+ Sheet.Content = Content10;
1952
2245
  Sheet.Overlay = Overlay4;
1953
2246
  Sheet.Header = Header4;
1954
2247
  Sheet.Body = Body3;
@@ -2127,7 +2420,7 @@ var alignClass = {
2127
2420
  center: "text-center",
2128
2421
  right: "text-right"
2129
2422
  };
2130
- var Root19 = forwardRef(
2423
+ var Root21 = forwardRef(
2131
2424
  ({ className, density = "default", children, ...props }, ref) => /* @__PURE__ */ jsx(TableDensityContext.Provider, { value: density, children: /* @__PURE__ */ jsx(
2132
2425
  "table",
2133
2426
  {
@@ -2139,7 +2432,7 @@ var Root19 = forwardRef(
2139
2432
  }
2140
2433
  ) })
2141
2434
  );
2142
- Root19.displayName = "Table";
2435
+ Root21.displayName = "Table";
2143
2436
  var Header5 = forwardRef(
2144
2437
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2145
2438
  "thead",
@@ -2259,7 +2552,7 @@ var HeaderCell = forwardRef(
2259
2552
  }
2260
2553
  );
2261
2554
  HeaderCell.displayName = "Table.HeaderCell";
2262
- var Table = Object.assign(Root19, { Header: Header5, Body: Body4, Row, Cell, HeaderCell });
2555
+ var Table = Object.assign(Root21, { Header: Header5, Body: Body4, Row, Cell, HeaderCell });
2263
2556
 
2264
2557
  // src/lib/env.ts
2265
2558
  function readNodeEnv() {
@@ -2636,7 +2929,7 @@ var StatTile = forwardRef(
2636
2929
  }
2637
2930
  );
2638
2931
  StatTile.displayName = "StatTile";
2639
- var Root20 = forwardRef(
2932
+ var Root22 = forwardRef(
2640
2933
  ({ className, title = "Danger Zone", children, ...props }, ref) => /* @__PURE__ */ jsxs(
2641
2934
  "section",
2642
2935
  {
@@ -2652,7 +2945,7 @@ var Root20 = forwardRef(
2652
2945
  }
2653
2946
  )
2654
2947
  );
2655
- Root20.displayName = "DangerZone";
2948
+ Root22.displayName = "DangerZone";
2656
2949
  var Action2 = forwardRef(
2657
2950
  ({ className, title, description, action, ...props }, ref) => /* @__PURE__ */ jsxs(
2658
2951
  "div",
@@ -2675,7 +2968,7 @@ var Action2 = forwardRef(
2675
2968
  )
2676
2969
  );
2677
2970
  Action2.displayName = "DangerZone.Action";
2678
- var DangerZone = Object.assign(Root20, { Action: Action2 });
2971
+ var DangerZone = Object.assign(Root22, { Action: Action2 });
2679
2972
  var ConfirmDialog = forwardRef(
2680
2973
  ({
2681
2974
  open,
@@ -3187,7 +3480,7 @@ var Portal6 = DropdownMenuPrimitive.Portal;
3187
3480
  var Group3 = DropdownMenuPrimitive.Group;
3188
3481
  var Sub2 = DropdownMenuPrimitive.Sub;
3189
3482
  var RadioGroup3 = DropdownMenuPrimitive.RadioGroup;
3190
- var Content11 = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
3483
+ var Content12 = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
3191
3484
  DropdownMenuPrimitive.Content,
3192
3485
  {
3193
3486
  "data-slot": "dropdown-menu-content",
@@ -3203,8 +3496,8 @@ var Content11 = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /*
3203
3496
  ...props
3204
3497
  }
3205
3498
  ) }));
3206
- Content11.displayName = "DropdownMenu.Content";
3207
- var Item6 = forwardRef(
3499
+ Content12.displayName = "DropdownMenu.Content";
3500
+ var Item7 = forwardRef(
3208
3501
  ({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
3209
3502
  DropdownMenuPrimitive.Item,
3210
3503
  {
@@ -3223,7 +3516,7 @@ var Item6 = forwardRef(
3223
3516
  }
3224
3517
  )
3225
3518
  );
3226
- Item6.displayName = "DropdownMenu.Item";
3519
+ Item7.displayName = "DropdownMenu.Item";
3227
3520
  var CheckboxItem2 = forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
3228
3521
  DropdownMenuPrimitive.CheckboxItem,
3229
3522
  {
@@ -3338,8 +3631,8 @@ SubContent2.displayName = "DropdownMenu.SubContent";
3338
3631
  var DropdownMenu = Object.assign(DropdownMenuPrimitive.Root, {
3339
3632
  Trigger: Trigger9,
3340
3633
  Portal: Portal6,
3341
- Content: Content11,
3342
- Item: Item6,
3634
+ Content: Content12,
3635
+ Item: Item7,
3343
3636
  CheckboxItem: CheckboxItem2,
3344
3637
  RadioItem: RadioItem2,
3345
3638
  Label: Label4,
@@ -4788,4 +5081,4 @@ function CommandPalette({
4788
5081
  ] }) });
4789
5082
  }
4790
5083
 
4791
- export { AccountMenu, ActionBar, Alert, Avatar, BadgeWithDot as Badge, Breadcrumb, Button, Card, Checkbox, CodeBlock, CommandPalette, ConfirmDialog, CopyButton, DangerZone, DataTable, DeploymentRow, Dialog, DomainConfig, DropdownMenu, EmptyState, EnvVarEditor, FormField, Input, Label, LoginSplit, MetricCard, MetricsPanel, PageShell, Pagination, PinInput, PlanBadge, PreviewEnvCard, Progress, ProjectCard, RadioGroup, RollbackUI, ScrollArea, Select, Sheet, Sidebar, Skeleton, SocialAuthRow, StatTile, StatusDot, StatusIndicator, Switch, Table, Tabs, TaskHeader, Textarea, Timestamp, Toast, Toaster, TooltipWithStatics as Tooltip, TopNav, UpdateBanner, avatarVariants, badgeVariants, buttonVariants, cn, computePageRange, isNearBottom, sheetVariants, useStickToBottom, useToast };
5084
+ export { AccountMenu, ActionBar, Alert, Avatar, BadgeWithDot as Badge, Breadcrumb, Button, Card, Checkbox, CodeBlock, Combobox, CommandPalette, ConfirmDialog, CopyButton, DangerZone, DataTable, DeploymentRow, Dialog, DomainConfig, DropdownMenu, EmptyState, EnvVarEditor, FormField, Input, Label, LoginSplit, MetricCard, MetricsPanel, PageShell, Pagination, PinInput, PlanBadge, PreviewEnvCard, Progress, ProjectCard, RadioGroup, RollbackUI, ScrollArea, Select, Sheet, Sidebar, Skeleton, Slider, SocialAuthRow, StatTile, StatusDot, StatusIndicator, Switch, Table, Tabs, TaskHeader, Textarea, Timestamp, Toast, Toaster, TooltipWithStatics as Tooltip, TopNav, UpdateBanner, avatarVariants, badgeVariants, buttonVariants, cn, computePageRange, isNearBottom, sheetVariants, useStickToBottom, useToast };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usetheo/ui",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Violet Forge design system — generic React components + primitives (the non-AI foundation of @theokit/ui).",
@@ -34,6 +34,7 @@
34
34
  "@radix-ui/react-radio-group": "^1.3.8",
35
35
  "@radix-ui/react-scroll-area": "^1.2.10",
36
36
  "@radix-ui/react-select": "^2.2.6",
37
+ "@radix-ui/react-slider": "^1.4.3",
37
38
  "@radix-ui/react-slot": "^1.1.2",
38
39
  "@radix-ui/react-switch": "^1.2.6",
39
40
  "@radix-ui/react-tabs": "^1.1.3",