@claralight-design/react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.d.ts +12 -0
  2. package/dist/index.js +12 -0
  3. package/dist/lib/anchored.d.ts +152 -0
  4. package/dist/lib/anchored.js +821 -0
  5. package/dist/lib/anchored.js.map +1 -0
  6. package/dist/lib/morph.js +484 -0
  7. package/dist/lib/morph.js.map +1 -0
  8. package/dist/lib/squircle.d.ts +95 -0
  9. package/dist/lib/squircle.js +220 -0
  10. package/dist/lib/squircle.js.map +1 -0
  11. package/dist/lib/utils.d.ts +30 -0
  12. package/dist/lib/utils.js +76 -0
  13. package/dist/lib/utils.js.map +1 -0
  14. package/dist/ui/button.d.ts +40 -0
  15. package/dist/ui/button.js +104 -0
  16. package/dist/ui/button.js.map +1 -0
  17. package/dist/ui/card.d.ts +54 -0
  18. package/dist/ui/card.js +82 -0
  19. package/dist/ui/card.js.map +1 -0
  20. package/dist/ui/dialog.d.ts +82 -0
  21. package/dist/ui/dialog.js +129 -0
  22. package/dist/ui/dialog.js.map +1 -0
  23. package/dist/ui/input.d.ts +34 -0
  24. package/dist/ui/input.js +60 -0
  25. package/dist/ui/input.js.map +1 -0
  26. package/dist/ui/popover.d.ts +67 -0
  27. package/dist/ui/popover.js +93 -0
  28. package/dist/ui/popover.js.map +1 -0
  29. package/dist/ui/scroll-area.d.ts +110 -0
  30. package/dist/ui/scroll-area.js +125 -0
  31. package/dist/ui/scroll-area.js.map +1 -0
  32. package/dist/ui/select.d.ts +113 -0
  33. package/dist/ui/select.js +213 -0
  34. package/dist/ui/select.js.map +1 -0
  35. package/dist/ui/tooltip.d.ts +108 -0
  36. package/dist/ui/tooltip.js +142 -0
  37. package/dist/ui/tooltip.js.map +1 -0
  38. package/package.json +72 -0
  39. package/styles/anchored.css +115 -0
  40. package/styles/base.css +309 -0
  41. package/styles/fonts/README.md +63 -0
  42. package/styles/index.css +28 -0
  43. package/styles/scroll-area.css +299 -0
  44. package/styles/theme.css +540 -0
  45. package/styles/tooltip.css +156 -0
@@ -0,0 +1,67 @@
1
+ import { AnchoredSide } from "../lib/anchored.js";
2
+ import { ComponentProps, ReactNode } from "react";
3
+ import { Popover } from "@base-ui/react/popover";
4
+ //#region src/ui/popover.d.ts
5
+ declare const Popover$1: typeof Popover.Root;
6
+ /** Re-exported unstyled, for building something other than the default content. */
7
+ export declare const PopoverPortal: typeof Popover.Portal;
8
+ export declare const PopoverPositioner: typeof Popover.Positioner;
9
+ export declare const PopoverPopup: typeof Popover.Popup;
10
+ export declare const PopoverArrow: typeof Popover.Arrow;
11
+ export declare const PopoverBackdrop: typeof Popover.Backdrop;
12
+ export type PopoverTriggerProps = Omit<ComponentProps<typeof Popover.Trigger>, "className"> & {
13
+ className?: string;
14
+ };
15
+ export declare function PopoverTrigger({ className, ...props }: PopoverTriggerProps): import("react").JSX.Element;
16
+ export type PopoverContentProps = Omit<ComponentProps<typeof Popover.Popup>, "className"> & {
17
+ /** Applied to the clipped element: the frost, padding and text. */
18
+ className?: string;
19
+ /** Applied to the wrapper, which is what is positioned and animated. */
20
+ wrapperClassName?: string;
21
+ /** Preferred side of the trigger. Base UI flips when there is not enough room. */
22
+ side?: AnchoredSide;
23
+ align?: ComponentProps<typeof Popover.Positioner>["align"];
24
+ /** Gap between the trigger and the surface, in px. Measured from the arrow's tip. */
25
+ sideOffset?: number;
26
+ /** Space kept clear of the viewport edge, in px. */
27
+ collisionPadding?: number;
28
+ /** Whether the surface points at its trigger. */
29
+ arrow?: boolean;
30
+ children?: ReactNode;
31
+ };
32
+ /**
33
+ * Portal, positioner and the pointing frosted surface, in the composition
34
+ * everyone actually wants.
35
+ *
36
+ * `top` is the default side because that is ClaraLight's, not Base UI's — a
37
+ * popover belongs above the control that opened it, so the control stays
38
+ * visible under the reader's hand on touch.
39
+ *
40
+ * The arrow is part of the surface rather than an element beside it, so the
41
+ * `Arrow` rendered here paints nothing: Floating UI solves and clamps its
42
+ * position, and `AnchoredSurface` reads that back to splice the tail into the
43
+ * surface's own path. See `src/lib/anchored.tsx`.
44
+ *
45
+ * The entrance grows the surface out of its own tail rather than from Base UI's
46
+ * `--transform-origin`, which is the anchor's edge and therefore sits in the
47
+ * gap *outside* the surface. `AnchoredSurface` sets the origin from the tail it
48
+ * measured, and carries `.cl-anchored-root`, whose scale starts at zero instead
49
+ * of at a dialog's 95% nudge. `sticky` keeps the surface on screen once its
50
+ * trigger has been scrolled out of view, instead of letting it leave with it.
51
+ */
52
+ export declare function PopoverContent({ className, wrapperClassName, side, align, sideOffset, collisionPadding, arrow, children, ...props }: PopoverContentProps): import("react").JSX.Element;
53
+ export type PopoverTitleProps = Omit<ComponentProps<typeof Popover.Title>, "className"> & {
54
+ className?: string;
55
+ };
56
+ export declare function PopoverTitle({ className, ...props }: PopoverTitleProps): import("react").JSX.Element;
57
+ export type PopoverDescriptionProps = Omit<ComponentProps<typeof Popover.Description>, "className"> & {
58
+ className?: string;
59
+ };
60
+ export declare function PopoverDescription({ className, ...props }: PopoverDescriptionProps): import("react").JSX.Element;
61
+ export type PopoverCloseProps = Omit<ComponentProps<typeof Popover.Close>, "className"> & {
62
+ className?: string;
63
+ };
64
+ export declare function PopoverClose({ className, ...props }: PopoverCloseProps): import("react").JSX.Element;
65
+ //#endregion
66
+ export { Popover$1 as Popover };
67
+ //# sourceMappingURL=popover.d.ts.map
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { AnchoredSurface, themedNumber, useThemedNumber } from "../lib/anchored.js";
4
+ import { useRef } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Popover } from "@base-ui/react/popover";
7
+ //#region src/ui/popover.tsx
8
+ const Popover$1 = Popover.Root;
9
+ /** Re-exported unstyled, for building something other than the default content. */
10
+ const PopoverPortal = Popover.Portal;
11
+ const PopoverPositioner = Popover.Positioner;
12
+ const PopoverPopup = Popover.Popup;
13
+ const PopoverArrow = Popover.Arrow;
14
+ const PopoverBackdrop = Popover.Backdrop;
15
+ function PopoverTrigger({ className, ...props }) {
16
+ return /* @__PURE__ */ jsx(Popover.Trigger, {
17
+ className,
18
+ ...props
19
+ });
20
+ }
21
+ /**
22
+ * Portal, positioner and the pointing frosted surface, in the composition
23
+ * everyone actually wants.
24
+ *
25
+ * `top` is the default side because that is ClaraLight's, not Base UI's — a
26
+ * popover belongs above the control that opened it, so the control stays
27
+ * visible under the reader's hand on touch.
28
+ *
29
+ * The arrow is part of the surface rather than an element beside it, so the
30
+ * `Arrow` rendered here paints nothing: Floating UI solves and clamps its
31
+ * position, and `AnchoredSurface` reads that back to splice the tail into the
32
+ * surface's own path. See `src/lib/anchored.tsx`.
33
+ *
34
+ * The entrance grows the surface out of its own tail rather than from Base UI's
35
+ * `--transform-origin`, which is the anchor's edge and therefore sits in the
36
+ * gap *outside* the surface. `AnchoredSurface` sets the origin from the tail it
37
+ * measured, and carries `.cl-anchored-root`, whose scale starts at zero instead
38
+ * of at a dialog's 95% nudge. `sticky` keeps the surface on screen once its
39
+ * trigger has been scrolled out of view, instead of letting it leave with it.
40
+ */
41
+ function PopoverContent({ className, wrapperClassName, side = "top", align = "center", sideOffset, collisionPadding, arrow = true, children, ...props }) {
42
+ const positionerRef = useRef(null);
43
+ const margin = useThemedNumber(positionerRef, "--cl-anchor-margin");
44
+ return /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
45
+ ref: positionerRef,
46
+ side,
47
+ align,
48
+ sideOffset: sideOffset ?? (() => themedNumber(positionerRef.current, "--cl-anchor-gap") ?? 0),
49
+ collisionPadding: collisionPadding ?? margin,
50
+ sticky: true,
51
+ className: "z-50 outline-none",
52
+ children: /* @__PURE__ */ jsx(AnchoredSurface, {
53
+ asChild: true,
54
+ radius: "panel",
55
+ side,
56
+ arrow,
57
+ wrapperClassName: cn("w-fit", wrapperClassName),
58
+ children: /* @__PURE__ */ jsxs(Popover.Popup, {
59
+ "data-cl-slot": "popover-content",
60
+ className: cn("cl-exit-sentinel cl-frost shadow-none font-sans text-foreground", "[--cl-anchored-padding-x:var(--cl-popover-padding)]", "[--cl-anchored-padding-y:var(--cl-popover-padding)]", className),
61
+ ...props,
62
+ children: [children, arrow ? /* @__PURE__ */ jsx(Popover.Arrow, {
63
+ "data-cl-anchor-probe": "",
64
+ className: "cl-anchor-probe"
65
+ }) : null]
66
+ })
67
+ })
68
+ }) });
69
+ }
70
+ function PopoverTitle({ className, ...props }) {
71
+ return /* @__PURE__ */ jsx(Popover.Title, {
72
+ "data-cl-slot": "popover-title",
73
+ className: cn("text-callout text-foreground", className),
74
+ ...props
75
+ });
76
+ }
77
+ function PopoverDescription({ className, ...props }) {
78
+ return /* @__PURE__ */ jsx(Popover.Description, {
79
+ "data-cl-slot": "popover-description",
80
+ className: cn("text-caption text-foreground-tertiary", className),
81
+ ...props
82
+ });
83
+ }
84
+ function PopoverClose({ className, ...props }) {
85
+ return /* @__PURE__ */ jsx(Popover.Close, {
86
+ className,
87
+ ...props
88
+ });
89
+ }
90
+ //#endregion
91
+ export { Popover$1 as Popover, PopoverArrow, PopoverBackdrop, PopoverClose, PopoverContent, PopoverDescription, PopoverPopup, PopoverPortal, PopoverPositioner, PopoverTitle, PopoverTrigger };
92
+
93
+ //# sourceMappingURL=popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.js","names":["Popover","BasePopover"],"sources":["../../src/ui/popover.tsx"],"sourcesContent":["\"use client\";\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport { type ComponentProps, type ReactNode, useRef } from \"react\";\nimport { type AnchoredSide, AnchoredSurface, themedNumber, useThemedNumber } from \"@/lib/anchored\";\nimport { cn } from \"@/lib/utils\";\n\nexport const Popover: typeof BasePopover.Root = BasePopover.Root;\n\n/** Re-exported unstyled, for building something other than the default content. */\nexport const PopoverPortal: typeof BasePopover.Portal = BasePopover.Portal;\nexport const PopoverPositioner: typeof BasePopover.Positioner = BasePopover.Positioner;\nexport const PopoverPopup: typeof BasePopover.Popup = BasePopover.Popup;\nexport const PopoverArrow: typeof BasePopover.Arrow = BasePopover.Arrow;\nexport const PopoverBackdrop: typeof BasePopover.Backdrop = BasePopover.Backdrop;\n\nexport type PopoverTriggerProps = Omit<ComponentProps<typeof BasePopover.Trigger>, \"className\"> & {\n className?: string;\n};\n\nexport function PopoverTrigger({ className, ...props }: PopoverTriggerProps) {\n return <BasePopover.Trigger className={className} {...props} />;\n}\n\nexport type PopoverContentProps = Omit<ComponentProps<typeof BasePopover.Popup>, \"className\"> & {\n /** Applied to the clipped element: the frost, padding and text. */\n className?: string;\n /** Applied to the wrapper, which is what is positioned and animated. */\n wrapperClassName?: string;\n /** Preferred side of the trigger. Base UI flips when there is not enough room. */\n side?: AnchoredSide;\n align?: ComponentProps<typeof BasePopover.Positioner>[\"align\"];\n /** Gap between the trigger and the surface, in px. Measured from the arrow's tip. */\n sideOffset?: number;\n /** Space kept clear of the viewport edge, in px. */\n collisionPadding?: number;\n /** Whether the surface points at its trigger. */\n arrow?: boolean;\n children?: ReactNode;\n};\n\n/**\n * Portal, positioner and the pointing frosted surface, in the composition\n * everyone actually wants.\n *\n * `top` is the default side because that is ClaraLight's, not Base UI's — a\n * popover belongs above the control that opened it, so the control stays\n * visible under the reader's hand on touch.\n *\n * The arrow is part of the surface rather than an element beside it, so the\n * `Arrow` rendered here paints nothing: Floating UI solves and clamps its\n * position, and `AnchoredSurface` reads that back to splice the tail into the\n * surface's own path. See `src/lib/anchored.tsx`.\n *\n * The entrance grows the surface out of its own tail rather than from Base UI's\n * `--transform-origin`, which is the anchor's edge and therefore sits in the\n * gap *outside* the surface. `AnchoredSurface` sets the origin from the tail it\n * measured, and carries `.cl-anchored-root`, whose scale starts at zero instead\n * of at a dialog's 95% nudge. `sticky` keeps the surface on screen once its\n * trigger has been scrolled out of view, instead of letting it leave with it.\n */\nexport function PopoverContent({\n className,\n wrapperClassName,\n side = \"top\",\n align = \"center\",\n sideOffset,\n collisionPadding,\n arrow = true,\n children,\n ...props\n}: PopoverContentProps) {\n const positionerRef = useRef<HTMLDivElement>(null);\n const margin = useThemedNumber(positionerRef, \"--cl-anchor-margin\");\n\n return (\n <BasePopover.Portal>\n <BasePopover.Positioner\n ref={positionerRef}\n side={side}\n align={align}\n sideOffset={\n sideOffset ?? (() => themedNumber(positionerRef.current, \"--cl-anchor-gap\") ?? 0)\n }\n collisionPadding={collisionPadding ?? margin}\n sticky\n className=\"z-50 outline-none\"\n >\n <AnchoredSurface\n asChild\n radius=\"panel\"\n side={side}\n arrow={arrow}\n wrapperClassName={cn(\"w-fit\", wrapperClassName)}\n >\n <BasePopover.Popup\n data-cl-slot=\"popover-content\"\n className={cn(\n \"cl-exit-sentinel cl-frost shadow-none font-sans text-foreground\",\n \"[--cl-anchored-padding-x:var(--cl-popover-padding)]\",\n \"[--cl-anchored-padding-y:var(--cl-popover-padding)]\",\n className,\n )}\n {...props}\n >\n {children}\n {arrow ? (\n <BasePopover.Arrow data-cl-anchor-probe=\"\" className=\"cl-anchor-probe\" />\n ) : null}\n </BasePopover.Popup>\n </AnchoredSurface>\n </BasePopover.Positioner>\n </BasePopover.Portal>\n );\n}\n\nexport type PopoverTitleProps = Omit<ComponentProps<typeof BasePopover.Title>, \"className\"> & {\n className?: string;\n};\n\nexport function PopoverTitle({ className, ...props }: PopoverTitleProps) {\n return (\n <BasePopover.Title\n data-cl-slot=\"popover-title\"\n className={cn(\"text-callout text-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport type PopoverDescriptionProps = Omit<\n ComponentProps<typeof BasePopover.Description>,\n \"className\"\n> & { className?: string };\n\nexport function PopoverDescription({ className, ...props }: PopoverDescriptionProps) {\n return (\n <BasePopover.Description\n data-cl-slot=\"popover-description\"\n className={cn(\"text-caption text-foreground-tertiary\", className)}\n {...props}\n />\n );\n}\n\nexport type PopoverCloseProps = Omit<ComponentProps<typeof BasePopover.Close>, \"className\"> & {\n className?: string;\n};\n\nexport function PopoverClose({ className, ...props }: PopoverCloseProps) {\n return <BasePopover.Close className={className} {...props} />;\n}\n"],"mappings":";;;;;;;AAOA,MAAaA,YAAmCC,QAAY;;AAG5D,MAAa,gBAA2CA,QAAY;AACpE,MAAa,oBAAmDA,QAAY;AAC5E,MAAa,eAAyCA,QAAY;AAClE,MAAa,eAAyCA,QAAY;AAClE,MAAa,kBAA+CA,QAAY;AAMxE,SAAgB,eAAe,EAAE,WAAW,GAAG,SAA8B;CAC3E,OAAO,oBAACA,QAAY,SAAb;EAAgC;EAAW,GAAI;CAAQ,CAAA;AAChE;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,eAAe,EAC7B,WACA,kBACA,OAAO,OACP,QAAQ,UACR,YACA,kBACA,QAAQ,MACR,UACA,GAAG,SACmB;CACtB,MAAM,gBAAgB,OAAuB,IAAI;CACjD,MAAM,SAAS,gBAAgB,eAAe,oBAAoB;CAElE,OACE,oBAACA,QAAY,QAAb,EAAA,UACE,oBAACA,QAAY,YAAb;EACE,KAAK;EACC;EACC;EACP,YACE,qBAAqB,aAAa,cAAc,SAAS,iBAAiB,KAAK;EAEjF,kBAAkB,oBAAoB;EACtC,QAAA;EACA,WAAU;EAEV,UAAA,oBAAC,iBAAD;GACE,SAAA;GACA,QAAO;GACD;GACC;GACP,kBAAkB,GAAG,SAAS,gBAAgB;GAE9C,UAAA,qBAACA,QAAY,OAAb;IACE,gBAAa;IACb,WAAW,GACT,mEACA,uDACA,uDACA,SACF;IACA,GAAI;IARN,UAAA,CAUG,UACA,QACC,oBAACA,QAAY,OAAb;KAAmB,wBAAqB;KAAG,WAAU;IAAmB,CAAA,IACtE,IACa;;EACJ,CAAA;CACK,CAAA,EACN,CAAA;AAExB;AAMA,SAAgB,aAAa,EAAE,WAAW,GAAG,SAA4B;CACvE,OACE,oBAACA,QAAY,OAAb;EACE,gBAAa;EACb,WAAW,GAAG,gCAAgC,SAAS;EACvD,GAAI;CACL,CAAA;AAEL;AAOA,SAAgB,mBAAmB,EAAE,WAAW,GAAG,SAAkC;CACnF,OACE,oBAACA,QAAY,aAAb;EACE,gBAAa;EACb,WAAW,GAAG,yCAAyC,SAAS;EAChE,GAAI;CACL,CAAA;AAEL;AAMA,SAAgB,aAAa,EAAE,WAAW,GAAG,SAA4B;CACvE,OAAO,oBAACA,QAAY,OAAb;EAA8B;EAAW,GAAI;CAAQ,CAAA;AAC9D"}
@@ -0,0 +1,110 @@
1
+ import { RadiusToken } from "../lib/squircle.js";
2
+ import { ComponentProps, ReactNode, Ref } from "react";
3
+ import { ScrollArea } from "@base-ui/react/scroll-area";
4
+ //#region src/ui/scroll-area.d.ts
5
+ /** Axes the content can move in. */
6
+ export type ScrollAreaOrientation = "vertical" | "horizontal" | "both";
7
+ /** Visibility policy for one scrollbar. */
8
+ export type ScrollbarVisibility = "auto" | "always" | "hidden";
9
+ /**
10
+ * How a side announces that there is more content behind it.
11
+ *
12
+ * `blur` is the full treatment: the content fades out *and* smears into the
13
+ * edge. **It needs an opaque fill** — `bg-panel` or `bg-background`, not
14
+ * `bg-control`, `bg-track` or `cl-frost`. The smooth-corner clip makes the
15
+ * surface its own backdrop root, so the blur can only see the surface's own
16
+ * fill and the scrolled content; over a translucent fill there is barely any
17
+ * colour there to blur and the engine lifts it into a white halo instead. See
18
+ * `scroll-area.css` for the measurements and why nothing else can be done
19
+ * about it.
20
+ *
21
+ * `mask` keeps only the fade. It has none of that coupling — it is a
22
+ * compositor-only effect that works over any fill — and it is the right choice
23
+ * for a translucent surface, or for a scroll area already inside something
24
+ * expensive. `none` leaves the edges hard.
25
+ */
26
+ export type ScrollAreaEdge = "blur" | "mask" | "none";
27
+ /** Re-exported unstyled, for building something other than the default area. */
28
+ export declare const ScrollAreaRoot: typeof ScrollArea.Root;
29
+ export declare const ScrollAreaViewport: typeof ScrollArea.Viewport;
30
+ export declare const ScrollAreaContent: typeof ScrollArea.Content;
31
+ export declare const ScrollAreaScrollbar: typeof ScrollArea.Scrollbar;
32
+ export declare const ScrollAreaThumb: typeof ScrollArea.Thumb;
33
+ export declare const ScrollAreaCorner: typeof ScrollArea.Corner;
34
+ export interface ScrollAreaProps extends Omit<ComponentProps<typeof ScrollArea.Root>, "className" | "children"> {
35
+ /**
36
+ * Applied to the clipped element: fill, border, and **the area's size**.
37
+ *
38
+ * The size has to be here and it has to be definite. The viewport fills the
39
+ * surface absolutely, so a surface left to size itself to its content has no
40
+ * height at all — `className="h-64"`, not a bare `<ScrollArea>`.
41
+ */
42
+ className?: string;
43
+ /**
44
+ * Applied to the layout wrapper, which is the element the caller's grid or
45
+ * flex lays out. Placement goes here — `col-span-2`, `flex-1` — and when the
46
+ * placement is what decides the height, pair it with `className="h-full"` so
47
+ * the surface inside still resolves to something definite.
48
+ */
49
+ wrapperClassName?: string;
50
+ /** Applied to the scrolling element itself. */
51
+ viewportClassName?: string;
52
+ /**
53
+ * Applied to the box that moves. This is where padding belongs: put it on
54
+ * the surface instead and it stays pinned over the scrolling content, with
55
+ * the edge effects fading a gap rather than the content.
56
+ */
57
+ contentClassName?: string;
58
+ /**
59
+ * Axes the content can move in.
60
+ *
61
+ * `both` matches the Flutter widget and leaves the content unconstrained on
62
+ * each enabled axis, which is why the content box is `max-content` wide
63
+ * whenever the inline axis can scroll: a horizontally scrollable child has to
64
+ * be allowed to exceed the viewport before it has anything to scroll. Lock
65
+ * the axis with `vertical` and the box is pinned to the viewport instead, so
66
+ * the content wraps rather than running off an edge it cannot scroll to.
67
+ */
68
+ orientation?: ScrollAreaOrientation;
69
+ /** How the sides announce content behind them. */
70
+ edge?: ScrollAreaEdge;
71
+ /** One policy for both bars, or one per axis. */
72
+ scrollbars?: ScrollbarVisibility | {
73
+ x?: ScrollbarVisibility;
74
+ y?: ScrollbarVisibility;
75
+ };
76
+ /** Which `--radius-*` token shapes the corners. */
77
+ radius?: RadiusToken;
78
+ /** Figma's `xi`; see `Squircle`. */
79
+ smoothing?: number;
80
+ /**
81
+ * The scrolling element. This is the web's scroll controller — `scrollTo`,
82
+ * `scrollTop` and `scrollIntoView` on a child all work through it — so there
83
+ * is no separate controller object and no per-axis pairing to keep distinct.
84
+ */
85
+ viewportRef?: Ref<HTMLDivElement>;
86
+ children?: ReactNode;
87
+ }
88
+ /**
89
+ * A ClaraLight viewport: content that scrolls, sides that dissolve into the
90
+ * frame as more of it comes into range, and scrollbars that surface while you
91
+ * are using them.
92
+ *
93
+ * Almost nothing here runs in React. Base UI reports the four overflow edges
94
+ * both as booleans and as live pixel distances, and `scroll-area.css` drives
95
+ * the mask straight off the distances — so the fade tracks the scroll position
96
+ * exactly, with no animation, no timer and no re-render between the wheel and
97
+ * the pixels. Scrolling only re-renders when an edge is genuinely crossed.
98
+ *
99
+ * Everything dimensional is a CSS variable rather than a prop, which is how the
100
+ * per-side control the design asks for costs no API surface:
101
+ *
102
+ * <ScrollArea className="[--cl-scroll-edge-block-end:0px]" />
103
+ *
104
+ * turns the bottom edge off, and scoping `--cl-scroll-blur` to one `[data-edge]`
105
+ * gives that side its own sigma.
106
+ */
107
+ declare function ScrollArea$1({ className, wrapperClassName, viewportClassName, contentClassName, orientation, edge, scrollbars, radius, smoothing, viewportRef, children, ...props }: ScrollAreaProps): import("react").JSX.Element;
108
+ //#endregion
109
+ export { ScrollArea$1 as ScrollArea };
110
+ //# sourceMappingURL=scroll-area.d.ts.map
@@ -0,0 +1,125 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Squircle } from "../lib/squircle.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { ScrollArea } from "@base-ui/react/scroll-area";
6
+ //#region src/ui/scroll-area.tsx
7
+ /** Re-exported unstyled, for building something other than the default area. */
8
+ const ScrollAreaRoot = ScrollArea.Root;
9
+ const ScrollAreaViewport = ScrollArea.Viewport;
10
+ const ScrollAreaContent = ScrollArea.Content;
11
+ const ScrollAreaScrollbar = ScrollArea.Scrollbar;
12
+ const ScrollAreaThumb = ScrollArea.Thumb;
13
+ const ScrollAreaCorner = ScrollArea.Corner;
14
+ const EDGES = {
15
+ vertical: ["block-start", "block-end"],
16
+ horizontal: ["inline-start", "inline-end"]
17
+ };
18
+ /**
19
+ * Three layers per edge, because a single `backdrop-filter` has one sigma for
20
+ * its whole box and the effect needs sigma to fall off across the band. The
21
+ * masks and the sigma ramp live in `scroll-area.css`; the count is here because
22
+ * it is the one part the CSS cannot express on its own.
23
+ */
24
+ function ScrollEdge({ edge }) {
25
+ return /* @__PURE__ */ jsxs("div", {
26
+ "data-cl-slot": "scroll-area-edge",
27
+ "data-edge": edge,
28
+ className: "cl-scroll-edge",
29
+ "aria-hidden": true,
30
+ children: [
31
+ /* @__PURE__ */ jsx("div", { className: "cl-scroll-edge-layer" }),
32
+ /* @__PURE__ */ jsx("div", { className: "cl-scroll-edge-layer" }),
33
+ /* @__PURE__ */ jsx("div", { className: "cl-scroll-edge-layer" })
34
+ ]
35
+ });
36
+ }
37
+ function resolveScrollbars(value) {
38
+ if (value === void 0) return {
39
+ x: "auto",
40
+ y: "auto"
41
+ };
42
+ if (typeof value === "string") return {
43
+ x: value,
44
+ y: value
45
+ };
46
+ return {
47
+ x: value.x ?? "auto",
48
+ y: value.y ?? "auto"
49
+ };
50
+ }
51
+ /**
52
+ * A ClaraLight viewport: content that scrolls, sides that dissolve into the
53
+ * frame as more of it comes into range, and scrollbars that surface while you
54
+ * are using them.
55
+ *
56
+ * Almost nothing here runs in React. Base UI reports the four overflow edges
57
+ * both as booleans and as live pixel distances, and `scroll-area.css` drives
58
+ * the mask straight off the distances — so the fade tracks the scroll position
59
+ * exactly, with no animation, no timer and no re-render between the wheel and
60
+ * the pixels. Scrolling only re-renders when an edge is genuinely crossed.
61
+ *
62
+ * Everything dimensional is a CSS variable rather than a prop, which is how the
63
+ * per-side control the design asks for costs no API surface:
64
+ *
65
+ * <ScrollArea className="[--cl-scroll-edge-block-end:0px]" />
66
+ *
67
+ * turns the bottom edge off, and scoping `--cl-scroll-blur` to one `[data-edge]`
68
+ * gives that side its own sigma.
69
+ */
70
+ function ScrollArea$1({ className, wrapperClassName, viewportClassName, contentClassName, orientation = "both", edge = "blur", scrollbars, radius = "medium", smoothing, viewportRef, children, ...props }) {
71
+ const visibility = resolveScrollbars(scrollbars);
72
+ const vertical = orientation !== "horizontal";
73
+ const horizontal = orientation !== "vertical";
74
+ const activeEdges = edge === "blur" ? [...vertical ? EDGES.vertical : [], ...horizontal ? EDGES.horizontal : []] : [];
75
+ return /* @__PURE__ */ jsx(Squircle, {
76
+ asChild: true,
77
+ radius,
78
+ smoothing,
79
+ wrapperClassName,
80
+ children: /* @__PURE__ */ jsxs(ScrollArea.Root, {
81
+ "data-cl-slot": "scroll-area",
82
+ className: cn("cl-scroll-area", className),
83
+ ...props,
84
+ children: [
85
+ /* @__PURE__ */ jsx(ScrollArea.Viewport, {
86
+ ref: viewportRef,
87
+ "data-cl-slot": "scroll-area-viewport",
88
+ className: cn("size-full overscroll-contain", edge !== "none" && "cl-scroll-viewport", viewportClassName),
89
+ style: vertical && horizontal ? void 0 : vertical ? { overflowX: "hidden" } : { overflowY: "hidden" },
90
+ children: /* @__PURE__ */ jsx(ScrollArea.Content, {
91
+ "data-cl-slot": "scroll-area-content",
92
+ className: contentClassName,
93
+ style: { minWidth: horizontal ? "max-content" : 0 },
94
+ children
95
+ })
96
+ }),
97
+ activeEdges.map((side) => /* @__PURE__ */ jsx(ScrollEdge, { edge: side }, side)),
98
+ vertical && visibility.y !== "hidden" && /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
99
+ orientation: "vertical",
100
+ "data-cl-slot": "scroll-area-scrollbar",
101
+ "data-cl-visibility": visibility.y,
102
+ className: "cl-scrollbar",
103
+ children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {
104
+ "data-cl-slot": "scroll-area-thumb",
105
+ className: "cl-scroll-thumb"
106
+ })
107
+ }),
108
+ horizontal && visibility.x !== "hidden" && /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
109
+ orientation: "horizontal",
110
+ "data-cl-slot": "scroll-area-scrollbar",
111
+ "data-cl-visibility": visibility.x,
112
+ className: "cl-scrollbar",
113
+ children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {
114
+ "data-cl-slot": "scroll-area-thumb",
115
+ className: "cl-scroll-thumb"
116
+ })
117
+ })
118
+ ]
119
+ })
120
+ });
121
+ }
122
+ //#endregion
123
+ export { ScrollArea$1 as ScrollArea, ScrollAreaContent, ScrollAreaCorner, ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport };
124
+
125
+ //# sourceMappingURL=scroll-area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-area.js","names":["BaseScrollArea","ScrollArea"],"sources":["../../src/ui/scroll-area.tsx"],"sourcesContent":["\"use client\";\n\nimport { ScrollArea as BaseScrollArea } from \"@base-ui/react/scroll-area\";\nimport type { ComponentProps, ReactNode, Ref } from \"react\";\nimport { type RadiusToken, Squircle } from \"@/lib/squircle\";\nimport { cn } from \"@/lib/utils\";\n\n/** Axes the content can move in. */\nexport type ScrollAreaOrientation = \"vertical\" | \"horizontal\" | \"both\";\n\n/** Visibility policy for one scrollbar. */\nexport type ScrollbarVisibility = \"auto\" | \"always\" | \"hidden\";\n\n/**\n * How a side announces that there is more content behind it.\n *\n * `blur` is the full treatment: the content fades out *and* smears into the\n * edge. **It needs an opaque fill** — `bg-panel` or `bg-background`, not\n * `bg-control`, `bg-track` or `cl-frost`. The smooth-corner clip makes the\n * surface its own backdrop root, so the blur can only see the surface's own\n * fill and the scrolled content; over a translucent fill there is barely any\n * colour there to blur and the engine lifts it into a white halo instead. See\n * `scroll-area.css` for the measurements and why nothing else can be done\n * about it.\n *\n * `mask` keeps only the fade. It has none of that coupling — it is a\n * compositor-only effect that works over any fill — and it is the right choice\n * for a translucent surface, or for a scroll area already inside something\n * expensive. `none` leaves the edges hard.\n */\nexport type ScrollAreaEdge = \"blur\" | \"mask\" | \"none\";\n\n/** Re-exported unstyled, for building something other than the default area. */\nexport const ScrollAreaRoot: typeof BaseScrollArea.Root = BaseScrollArea.Root;\nexport const ScrollAreaViewport: typeof BaseScrollArea.Viewport = BaseScrollArea.Viewport;\nexport const ScrollAreaContent: typeof BaseScrollArea.Content = BaseScrollArea.Content;\nexport const ScrollAreaScrollbar: typeof BaseScrollArea.Scrollbar = BaseScrollArea.Scrollbar;\nexport const ScrollAreaThumb: typeof BaseScrollArea.Thumb = BaseScrollArea.Thumb;\nexport const ScrollAreaCorner: typeof BaseScrollArea.Corner = BaseScrollArea.Corner;\n\nconst EDGES = {\n vertical: [\"block-start\", \"block-end\"],\n horizontal: [\"inline-start\", \"inline-end\"],\n} as const;\n\n/**\n * Three layers per edge, because a single `backdrop-filter` has one sigma for\n * its whole box and the effect needs sigma to fall off across the band. The\n * masks and the sigma ramp live in `scroll-area.css`; the count is here because\n * it is the one part the CSS cannot express on its own.\n */\nfunction ScrollEdge({ edge }: { edge: (typeof EDGES)[keyof typeof EDGES][number] }) {\n return (\n <div data-cl-slot=\"scroll-area-edge\" data-edge={edge} className=\"cl-scroll-edge\" aria-hidden>\n <div className=\"cl-scroll-edge-layer\" />\n <div className=\"cl-scroll-edge-layer\" />\n <div className=\"cl-scroll-edge-layer\" />\n </div>\n );\n}\n\nexport interface ScrollAreaProps\n extends Omit<ComponentProps<typeof BaseScrollArea.Root>, \"className\" | \"children\"> {\n /**\n * Applied to the clipped element: fill, border, and **the area's size**.\n *\n * The size has to be here and it has to be definite. The viewport fills the\n * surface absolutely, so a surface left to size itself to its content has no\n * height at all — `className=\"h-64\"`, not a bare `<ScrollArea>`.\n */\n className?: string;\n /**\n * Applied to the layout wrapper, which is the element the caller's grid or\n * flex lays out. Placement goes here — `col-span-2`, `flex-1` — and when the\n * placement is what decides the height, pair it with `className=\"h-full\"` so\n * the surface inside still resolves to something definite.\n */\n wrapperClassName?: string;\n /** Applied to the scrolling element itself. */\n viewportClassName?: string;\n /**\n * Applied to the box that moves. This is where padding belongs: put it on\n * the surface instead and it stays pinned over the scrolling content, with\n * the edge effects fading a gap rather than the content.\n */\n contentClassName?: string;\n /**\n * Axes the content can move in.\n *\n * `both` matches the Flutter widget and leaves the content unconstrained on\n * each enabled axis, which is why the content box is `max-content` wide\n * whenever the inline axis can scroll: a horizontally scrollable child has to\n * be allowed to exceed the viewport before it has anything to scroll. Lock\n * the axis with `vertical` and the box is pinned to the viewport instead, so\n * the content wraps rather than running off an edge it cannot scroll to.\n */\n orientation?: ScrollAreaOrientation;\n /** How the sides announce content behind them. */\n edge?: ScrollAreaEdge;\n /** One policy for both bars, or one per axis. */\n scrollbars?: ScrollbarVisibility | { x?: ScrollbarVisibility; y?: ScrollbarVisibility };\n /** Which `--radius-*` token shapes the corners. */\n radius?: RadiusToken;\n /** Figma's `xi`; see `Squircle`. */\n smoothing?: number;\n /**\n * The scrolling element. This is the web's scroll controller — `scrollTo`,\n * `scrollTop` and `scrollIntoView` on a child all work through it — so there\n * is no separate controller object and no per-axis pairing to keep distinct.\n */\n viewportRef?: Ref<HTMLDivElement>;\n children?: ReactNode;\n}\n\nfunction resolveScrollbars(value: ScrollAreaProps[\"scrollbars\"]) {\n if (value === undefined) return { x: \"auto\", y: \"auto\" } as const;\n if (typeof value === \"string\") return { x: value, y: value };\n return { x: value.x ?? \"auto\", y: value.y ?? \"auto\" };\n}\n\n/**\n * A ClaraLight viewport: content that scrolls, sides that dissolve into the\n * frame as more of it comes into range, and scrollbars that surface while you\n * are using them.\n *\n * Almost nothing here runs in React. Base UI reports the four overflow edges\n * both as booleans and as live pixel distances, and `scroll-area.css` drives\n * the mask straight off the distances — so the fade tracks the scroll position\n * exactly, with no animation, no timer and no re-render between the wheel and\n * the pixels. Scrolling only re-renders when an edge is genuinely crossed.\n *\n * Everything dimensional is a CSS variable rather than a prop, which is how the\n * per-side control the design asks for costs no API surface:\n *\n * <ScrollArea className=\"[--cl-scroll-edge-block-end:0px]\" />\n *\n * turns the bottom edge off, and scoping `--cl-scroll-blur` to one `[data-edge]`\n * gives that side its own sigma.\n */\nexport function ScrollArea({\n className,\n wrapperClassName,\n viewportClassName,\n contentClassName,\n orientation = \"both\",\n edge = \"blur\",\n scrollbars,\n radius = \"medium\",\n smoothing,\n viewportRef,\n children,\n ...props\n}: ScrollAreaProps) {\n const visibility = resolveScrollbars(scrollbars);\n const vertical = orientation !== \"horizontal\";\n const horizontal = orientation !== \"vertical\";\n\n const activeEdges =\n edge === \"blur\"\n ? [...(vertical ? EDGES.vertical : []), ...(horizontal ? EDGES.horizontal : [])]\n : [];\n\n return (\n <Squircle asChild radius={radius} smoothing={smoothing} wrapperClassName={wrapperClassName}>\n <BaseScrollArea.Root\n data-cl-slot=\"scroll-area\"\n className={cn(\"cl-scroll-area\", className)}\n {...props}\n >\n <BaseScrollArea.Viewport\n ref={viewportRef}\n data-cl-slot=\"scroll-area-viewport\"\n // `size-full` is load-bearing, not cosmetic. Base UI gives the\n // viewport `overflow: scroll` and nothing else, so left to itself it\n // is an auto-height block that grows to its content and therefore\n // never overflows: the area looks right, because the surface clips\n // it, and scrolls nowhere. The height has to come from the surface.\n className={cn(\n \"size-full overscroll-contain\",\n edge !== \"none\" && \"cl-scroll-viewport\",\n viewportClassName,\n )}\n // Base UI writes `overflow: scroll`; a locked axis is layered on top\n // of it rather than replacing it, so the element stays a scroller and\n // keeps reporting the other axis' overflow.\n style={\n vertical && horizontal\n ? undefined\n : vertical\n ? { overflowX: \"hidden\" }\n : { overflowY: \"hidden\" }\n }\n >\n <BaseScrollArea.Content\n data-cl-slot=\"scroll-area-content\"\n className={contentClassName}\n // Base UI writes `min-width: fit-content` here inline, which no\n // class can outrank — and inside a scroll container that keyword\n // measures the content rather than the scrollport, so it is wrong\n // in both directions: a scrollable axis is still capped at the\n // viewport, and a locked axis is widened past it, where nothing can\n // reach it. Each axis wants the opposite.\n style={{ minWidth: horizontal ? \"max-content\" : 0 }}\n >\n {children}\n </BaseScrollArea.Content>\n </BaseScrollArea.Viewport>\n\n {activeEdges.map((side) => (\n <ScrollEdge key={side} edge={side} />\n ))}\n\n {vertical && visibility.y !== \"hidden\" && (\n <BaseScrollArea.Scrollbar\n orientation=\"vertical\"\n data-cl-slot=\"scroll-area-scrollbar\"\n data-cl-visibility={visibility.y}\n className=\"cl-scrollbar\"\n >\n <BaseScrollArea.Thumb data-cl-slot=\"scroll-area-thumb\" className=\"cl-scroll-thumb\" />\n </BaseScrollArea.Scrollbar>\n )}\n\n {horizontal && visibility.x !== \"hidden\" && (\n <BaseScrollArea.Scrollbar\n orientation=\"horizontal\"\n data-cl-slot=\"scroll-area-scrollbar\"\n data-cl-visibility={visibility.x}\n className=\"cl-scrollbar\"\n >\n <BaseScrollArea.Thumb data-cl-slot=\"scroll-area-thumb\" className=\"cl-scroll-thumb\" />\n </BaseScrollArea.Scrollbar>\n )}\n </BaseScrollArea.Root>\n </Squircle>\n );\n}\n"],"mappings":";;;;;;;AAiCA,MAAa,iBAA6CA,WAAe;AACzE,MAAa,qBAAqDA,WAAe;AACjF,MAAa,oBAAmDA,WAAe;AAC/E,MAAa,sBAAuDA,WAAe;AACnF,MAAa,kBAA+CA,WAAe;AAC3E,MAAa,mBAAiDA,WAAe;AAE7E,MAAM,QAAQ;CACZ,UAAU,CAAC,eAAe,WAAW;CACrC,YAAY,CAAC,gBAAgB,YAAY;AAC3C;;;;;;;AAQA,SAAS,WAAW,EAAE,QAA8D;CAClF,OACE,qBAAC,OAAD;EAAK,gBAAa;EAAmB,aAAW;EAAM,WAAU;EAAiB,eAAA;EAAjF,UAAA;GACE,oBAAC,OAAD,EAAK,WAAU,uBAAwB,CAAA;GACvC,oBAAC,OAAD,EAAK,WAAU,uBAAwB,CAAA;GACvC,oBAAC,OAAD,EAAK,WAAU,uBAAwB,CAAA;EACpC;;AAET;AAuDA,SAAS,kBAAkB,OAAsC;CAC/D,IAAI,UAAU,KAAA,GAAW,OAAO;EAAE,GAAG;EAAQ,GAAG;CAAO;CACvD,IAAI,OAAO,UAAU,UAAU,OAAO;EAAE,GAAG;EAAO,GAAG;CAAM;CAC3D,OAAO;EAAE,GAAG,MAAM,KAAK;EAAQ,GAAG,MAAM,KAAK;CAAO;AACtD;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgBC,aAAW,EACzB,WACA,kBACA,mBACA,kBACA,cAAc,QACd,OAAO,QACP,YACA,SAAS,UACT,WACA,aACA,UACA,GAAG,SACe;CAClB,MAAM,aAAa,kBAAkB,UAAU;CAC/C,MAAM,WAAW,gBAAgB;CACjC,MAAM,aAAa,gBAAgB;CAEnC,MAAM,cACJ,SAAS,SACL,CAAC,GAAI,WAAW,MAAM,WAAW,CAAC,GAAI,GAAI,aAAa,MAAM,aAAa,CAAC,CAAE,IAC7E,CAAC;CAEP,OACE,oBAAC,UAAD;EAAU,SAAA;EAAgB;EAAmB;EAA6B;EACxE,UAAA,qBAACD,WAAe,MAAhB;GACE,gBAAa;GACb,WAAW,GAAG,kBAAkB,SAAS;GACzC,GAAI;GAHN,UAAA;IAKE,oBAACA,WAAe,UAAhB;KACE,KAAK;KACL,gBAAa;KAMb,WAAW,GACT,gCACA,SAAS,UAAU,sBACnB,iBACF;KAIA,OACE,YAAY,aACR,KAAA,IACA,WACE,EAAE,WAAW,SAAS,IACtB,EAAE,WAAW,SAAS;KAG9B,UAAA,oBAACA,WAAe,SAAhB;MACE,gBAAa;MACb,WAAW;MAOX,OAAO,EAAE,UAAU,aAAa,gBAAgB,EAAE;MAEjD;KACqB,CAAA;IACD,CAAA;IAExB,YAAY,KAAK,SAChB,oBAAC,YAAD,EAAuB,MAAM,KAAO,GAAnB,IAAmB,CACrC;IAEA,YAAY,WAAW,MAAM,YAC5B,oBAACA,WAAe,WAAhB;KACE,aAAY;KACZ,gBAAa;KACb,sBAAoB,WAAW;KAC/B,WAAU;KAEV,UAAA,oBAACA,WAAe,OAAhB;MAAsB,gBAAa;MAAoB,WAAU;KAAmB,CAAA;IAC5D,CAAA;IAG3B,cAAc,WAAW,MAAM,YAC9B,oBAACA,WAAe,WAAhB;KACE,aAAY;KACZ,gBAAa;KACb,sBAAoB,WAAW;KAC/B,WAAU;KAEV,UAAA,oBAACA,WAAe,OAAhB;MAAsB,gBAAa;MAAoB,WAAU;KAAmB,CAAA;IAC5D,CAAA;GAET;;CACb,CAAA;AAEd"}
@@ -0,0 +1,113 @@
1
+ import { ComponentProps } from "react";
2
+ import { Select } from "@base-ui/react/select";
3
+ //#region src/ui/select.d.ts
4
+ declare const Select$1: typeof Select.Root;
5
+ /** Re-exported unstyled, for building something other than the default content. */
6
+ export declare const SelectPortal: typeof Select.Portal;
7
+ export declare const SelectPositioner: typeof Select.Positioner;
8
+ export declare const SelectPopup: typeof Select.Popup;
9
+ export declare const SelectList: typeof Select.List;
10
+ export type SelectTriggerProps = Omit<ComponentProps<typeof Select.Trigger>, "className"> & {
11
+ className?: string;
12
+ /** Applied to the wrapper, which is what a caller's layout sizes. */
13
+ wrapperClassName?: string;
14
+ /**
15
+ * Shared control-height tokens. Defaults to `md` rather than
16
+ * the button's `lg`, because a select is usually one control among several in
17
+ * a dense row.
18
+ */
19
+ size?: "sm" | "md" | "lg";
20
+ };
21
+ export declare function SelectTrigger({ className, wrapperClassName, size, ...props }: SelectTriggerProps): import("react").JSX.Element;
22
+ export type SelectValueProps = Omit<ComponentProps<typeof Select.Value>, "className"> & {
23
+ className?: string;
24
+ };
25
+ export declare function SelectValue({ className, ...props }: SelectValueProps): import("react").JSX.Element;
26
+ export type SelectIconProps = Omit<ComponentProps<typeof Select.Icon>, "className"> & {
27
+ className?: string;
28
+ };
29
+ /**
30
+ * Flips with the popup and is `aria-hidden` because Base UI already exposes the
31
+ * expanded state; the glyph is decoration, not information.
32
+ */
33
+ export declare function SelectIcon({ className, ...props }: SelectIconProps): import("react").JSX.Element;
34
+ export type SelectContentProps = Omit<ComponentProps<typeof Select.Popup>, "className"> & {
35
+ /** Applied to the clipped element: the frost, padding and text. */
36
+ className?: string;
37
+ /** Applied to the wrapper, which is what is positioned and animated. */
38
+ wrapperClassName?: string;
39
+ /** Gap between the trigger and the popup, in px. */
40
+ sideOffset?: number;
41
+ /** Preferred side; Base UI flips when there is not enough room. */
42
+ side?: ComponentProps<typeof Select.Positioner>["side"];
43
+ align?: ComponentProps<typeof Select.Positioner>["align"];
44
+ };
45
+ /**
46
+ * Portal, positioner and popup in the composition everyone actually wants.
47
+ *
48
+ * Two details come straight from Base UI:
49
+ *
50
+ * - `origin-[var(--transform-origin)]` — the positioner computes where the
51
+ * popup should *appear to grow from* based on the trigger's position, so the
52
+ * scale-in reads as the trigger unfolding rather than a box fading in.
53
+ * - `--available-height` / `--anchor-width` — measured space, so the list never
54
+ * spills past the viewport and the popup can match the trigger's width.
55
+ */
56
+ export declare function SelectContent({ className, wrapperClassName, children, sideOffset, side, align, ...props }: SelectContentProps): import("react").JSX.Element;
57
+ export type SelectItemProps = Omit<ComponentProps<typeof Select.Item>, "className"> & {
58
+ className?: string;
59
+ };
60
+ /**
61
+ * The item radius has its own token so nested corners remain comfortable
62
+ * inside the medium-radius popup.
63
+ */
64
+ export declare function SelectItem({ className, ...props }: SelectItemProps): import("react").JSX.Element;
65
+ export type SelectItemIndicatorProps = Omit<ComponentProps<typeof Select.ItemIndicator>, "className"> & {
66
+ className?: string;
67
+ };
68
+ /**
69
+ * The selected mark, on the **trailing** edge of its item.
70
+ *
71
+ * The row is `[leading] [label] [gap] [check]`, which is the design's own — the
72
+ * check belongs after the value, where the eye already is, and it is what keeps
73
+ * the row honest in two ways that are easy to lose by reordering the JSX:
74
+ *
75
+ * - every row's label starts in the same column, because an unselected row has no
76
+ * indicator at all and a leading one would indent only the selected row;
77
+ * - Base UI aligns the popup so the selected item's *text* sits over the
78
+ * trigger's value text (native `<select>`, and the design's own overlap). A
79
+ * leading indicator makes that text column 24px wider than the trigger's, so the
80
+ * whole popup lands that far to the left of its anchor.
81
+ *
82
+ * `ml-auto` states the position in the indicator rather than relying on a sibling
83
+ * growing, so a row without a label still keeps its mark on the trailing edge.
84
+ */
85
+ export declare function SelectItemIndicator({ className, ...props }: SelectItemIndicatorProps): import("react").JSX.Element;
86
+ export type SelectItemTextProps = Omit<ComponentProps<typeof Select.ItemText>, "className"> & {
87
+ className?: string;
88
+ };
89
+ /**
90
+ * The label, which takes the row's free space so the trailing indicator is pushed
91
+ * against the far edge — the `Expanded` of the Flutter row, and what lets a long
92
+ * label truncate instead of moving the check out of the popup.
93
+ */
94
+ export declare function SelectItemText({ className, ...props }: SelectItemTextProps): import("react").JSX.Element;
95
+ export type SelectGroupProps = Omit<ComponentProps<typeof Select.Group>, "className"> & {
96
+ className?: string;
97
+ };
98
+ export declare function SelectGroup({ className, ...props }: SelectGroupProps): import("react").JSX.Element;
99
+ export type SelectGroupLabelProps = Omit<ComponentProps<typeof Select.GroupLabel>, "className"> & {
100
+ className?: string;
101
+ };
102
+ export declare function SelectGroupLabel({ className, ...props }: SelectGroupLabelProps): import("react").JSX.Element;
103
+ export type SelectSeparatorProps = Omit<ComponentProps<typeof Select.Separator>, "className"> & {
104
+ className?: string;
105
+ };
106
+ export declare function SelectSeparator({ className, ...props }: SelectSeparatorProps): import("react").JSX.Element;
107
+ export type SelectLabelProps = Omit<ComponentProps<typeof Select.Label>, "className"> & {
108
+ className?: string;
109
+ };
110
+ export declare function SelectLabel({ className, ...props }: SelectLabelProps): import("react").JSX.Element;
111
+ //#endregion
112
+ export { Select$1 as Select };
113
+ //# sourceMappingURL=select.d.ts.map