@codraoss/ui 0.9.4 → 0.9.5

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.
@@ -36,4 +36,4 @@ export {
36
36
  fmtStat,
37
37
  formatPreciseDuration
38
38
  };
39
- //# sourceMappingURL=chunk-HCQJTSV3.js.map
39
+ //# sourceMappingURL=chunk-GNGWMNUA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function fmtNumber(n: number) {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(n >= 10_000 ? 0 : 1)}k`;\n return n.toLocaleString();\n}\n\n/**\n * Like {@link fmtNumber} but returns the numeric part and its unit suffix\n * separately, so a card can render \"1.4\" large and \"M\" as a smaller unit.\n */\nexport function fmtStat(n: number): { value: string; unit: string } {\n if (n >= 1_000_000) return { value: (n / 1_000_000).toFixed(1), unit: 'M' };\n if (n >= 1_000) return { value: (n / 1_000).toFixed(n >= 10_000 ? 0 : 1), unit: 'k' };\n return { value: n.toLocaleString(), unit: '' };\n}\n\nexport function formatPreciseDuration(ms: number | null | undefined): string {\n if (ms == null) return '';\n // Sub-minute: show one decimal so e.g. a 724ms review reads as \"0.7s\" rather than \"0s\".\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const totalSeconds = Math.round(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) {\n return `${minutes}m ${seconds}s`;\n }\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}h ${remainingMinutes}m`;\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;AAEO,SAAS,UAAU,GAAW;AACnC,MAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACxD,MAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAO,QAAQ,KAAK,MAAS,IAAI,CAAC,CAAC;AACtE,SAAO,EAAE,eAAe;AAC1B;AAMO,SAAS,QAAQ,GAA4C;AAClE,MAAI,KAAK,IAAW,QAAO,EAAE,QAAQ,IAAI,KAAW,QAAQ,CAAC,GAAG,MAAM,IAAI;AAC1E,MAAI,KAAK,IAAW,QAAO,EAAE,QAAQ,IAAI,KAAO,QAAQ,KAAK,MAAS,IAAI,CAAC,GAAG,MAAM,IAAI;AACxF,SAAO,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,GAAG;AAC/C;AAEO,SAAS,sBAAsB,IAAuC;AAC3E,MAAI,MAAM,KAAM,QAAO;AAEvB,MAAI,KAAK,KAAQ;AACf,WAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAAA,EAClC;AACA,QAAM,eAAe,KAAK,MAAM,KAAK,GAAI;AACzC,QAAM,UAAU,KAAK,MAAM,eAAe,EAAE;AAC5C,QAAM,UAAU,eAAe;AAC/B,MAAI,UAAU,IAAI;AAChB,WAAO,GAAG,OAAO,KAAK,OAAO;AAAA,EAC/B;AACA,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,QAAM,mBAAmB,UAAU;AACnC,SAAO,GAAG,KAAK,KAAK,gBAAgB;AACtC;","names":[]}
@@ -19,28 +19,25 @@ type ScrollToOptions = {
19
19
  duration?: number;
20
20
  };
21
21
  type SmoothScrollApi = {
22
- /** Underlying Lenis instance, or null on the reduced-motion / native path. */
22
+ /** Null on the reduced-motion / native path. */
23
23
  lenis: Lenis | null;
24
- /** Current scroll offset in px. */
25
24
  scrollY: MotionValue<number>;
26
- /** Scroll position as 0..1 of the scrollable height. */
27
25
  progress: MotionValue<number>;
28
- /** Signed scroll velocity (px/frame). */
26
+ /** px/frame. */
29
27
  velocity: MotionValue<number>;
30
- /** Programmatic smooth scroll. Respects reduced motion (jumps instantly). */
28
+ /** Jumps instantly under reduced motion. */
31
29
  scrollTo: (target: ScrollTarget, options?: ScrollToOptions) => void;
32
30
  };
33
31
  interface SmoothScrollProps {
34
32
  children: ReactNode;
35
- /** Drive the page (window) when true, or a contained scroll area when false. */
33
+ /** True drives window scroll; false scrolls a contained area. */
36
34
  root?: boolean;
37
- /** Smoothing factor; lower is smoother and heavier. */
35
+ /** Lower = smoother, heavier. */
38
36
  lerp?: number;
39
- /** Wheel / programmatic ease duration in seconds. */
40
37
  duration?: number;
41
38
  orientation?: 'vertical' | 'horizontal';
42
39
  wheelMultiplier?: number;
43
- /** Off by default - native touch momentum is already good on mobile. */
40
+ /** Off by default: native touch momentum is already good on mobile. */
44
41
  touch?: boolean;
45
42
  className?: string;
46
43
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cn
3
- } from "../../chunk-HCQJTSV3.js";
3
+ } from "../../chunk-GNGWMNUA.js";
4
4
  import {
5
5
  useIsDarkMode
6
6
  } from "../../chunk-TXNSYK4G.js";
@@ -240,8 +240,7 @@ function SmoothScroll({
240
240
  smoothWheel: true,
241
241
  syncTouch: touch,
242
242
  easing: EASE_SCROLL,
243
- // Without this, Lenis preventDefault()s every wheel event, blocking nested scrollable
244
- // elements (log panes, drawers, option lists). Escape hatch: `data-lenis-prevent`.
243
+ // Else Lenis preventDefault()s every wheel event, blocking nested scroll areas.
245
244
  allowNestedScroll: true
246
245
  },
247
246
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/motion/shared-layout-bg.tsx","../../../src/components/motion/smooth-scroll.tsx","../../../src/components/motion/stepped-slider.tsx","../../../src/components/motion/tabs.tsx"],"sourcesContent":["// beui.dev/components/motion/shared-layout-bg\nimport {\n AnimatePresence,\n domMax,\n LazyMotion,\n m,\n useReducedMotion,\n type Variants,\n} from \"motion/react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useId,\n useState,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nconst SPRING_LAYOUT = {\n type: \"spring\" as const,\n stiffness: 400,\n damping: 40,\n mass: 0.6,\n};\n\nexport interface SharedLayoutBgProps {\n children: ReactNode;\n className?: string;\n pillClassName?: string;\n /** Horizontal inset of the pill relative to each row (px). */\n inset?: number;\n}\n\nconst variants: Variants = {\n initial: { opacity: 0, filter: \"blur(6px)\" },\n animate: { opacity: 1, filter: \"blur(0px)\" },\n exit: (isActive: boolean) =>\n !isActive ? { opacity: 0, filter: \"blur(6px)\" } : {},\n};\n\nconst reducedVariants: Variants = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: (isActive: boolean) => (!isActive ? { opacity: 0 } : {}),\n};\n\nexport function SharedLayoutBg({\n children,\n className,\n pillClassName,\n inset = 0,\n}: SharedLayoutBgProps) {\n const [activeId, setActiveId] = useState<string | null>(null);\n const uid = useId();\n const reduce = useReducedMotion();\n\n const rows: ReactNode[] = [];\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue;\n const el = child as ReactElement<{\n className?: string;\n onMouseEnter?: (e?: any) => void;\n children?: ReactNode;\n }>;\n // rows.length is the index among *valid* children, so keyless rows keep stable fallback keys.\n const childKey = el.key ? String(el.key) : `item-${rows.length}`;\n rows.push(\n cloneElement(\n el,\n {\n key: childKey,\n className: cn(\"relative z-10\", el.props.className),\n onMouseEnter: (e: any) => {\n el.props.onMouseEnter?.(e);\n setActiveId(childKey);\n },\n },\n <>\n <div className=\"pointer-events-none absolute inset-0 z-0\">\n <AnimatePresence custom={activeId !== null}>\n {activeId !== null ? (\n <m.div\n variants={reduce ? reducedVariants : variants}\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n custom={activeId !== null}\n className=\"absolute inset-0\"\n style={{ left: -inset, right: -inset, top: 0, bottom: 0 }}\n >\n {activeId === childKey ? (\n <m.div\n layoutId={`shared-bg-${uid}`}\n transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n className={cn(\n \"pointer-events-none h-full w-full rounded-lg\",\n pillClassName,\n )}\n />\n ) : null}\n </m.div>\n ) : null}\n </AnimatePresence>\n </div>\n {el}\n </>\n ),\n );\n }\n\n return (\n <LazyMotion features={domMax}>\n <m.div\n layoutRoot\n onMouseLeave={() => setActiveId(null)}\n className={cn(\"flex w-full flex-col\", className)}\n >\n {rows}\n </m.div>\n </LazyMotion>\n );\n}\n","// beui.dev/components/motion/scroll-animation\nimport type Lenis from 'lenis';\nimport { ReactLenis, useLenis } from 'lenis/react';\nimport { type MotionValue, useMotionValue, useReducedMotion } from 'motion/react';\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\n// Lenis' own expo-out curve, kept as a named fn (not a lib/ease token): tokens are bezier control\n// points for the motion lib, while Lenis needs a (t) => number easing fn.\nconst EASE_SCROLL = (t: number) => Math.min(1, 1.001 - 2 ** (-10 * t));\n\nexport type ScrollTarget = number | string | HTMLElement;\n\nexport type ScrollToOptions = {\n offset?: number;\n immediate?: boolean;\n duration?: number;\n};\n\nexport type SmoothScrollApi = {\n /** Underlying Lenis instance, or null on the reduced-motion / native path. */\n lenis: Lenis | null;\n /** Current scroll offset in px. */\n scrollY: MotionValue<number>;\n /** Scroll position as 0..1 of the scrollable height. */\n progress: MotionValue<number>;\n /** Signed scroll velocity (px/frame). */\n velocity: MotionValue<number>;\n /** Programmatic smooth scroll. Respects reduced motion (jumps instantly). */\n scrollTo: (target: ScrollTarget, options?: ScrollToOptions) => void;\n};\n\nconst SmoothScrollContext = createContext<SmoothScrollApi | null>(null);\n\nexport interface SmoothScrollProps {\n children: ReactNode;\n /** Drive the page (window) when true, or a contained scroll area when false. */\n root?: boolean;\n /** Smoothing factor; lower is smoother and heavier. */\n lerp?: number;\n /** Wheel / programmatic ease duration in seconds. */\n duration?: number;\n orientation?: 'vertical' | 'horizontal';\n wheelMultiplier?: number;\n /** Off by default - native touch momentum is already good on mobile. */\n touch?: boolean;\n className?: string;\n}\n\ntype ScrollSource = Window | HTMLElement;\n\nfunction readMetrics(target: ScrollSource) {\n if (target instanceof Window) {\n const max = Math.max(\n 0,\n document.documentElement.scrollHeight - window.innerHeight,\n );\n return { y: window.scrollY, max };\n }\n return {\n y: target.scrollTop,\n max: Math.max(0, target.scrollHeight - target.clientHeight),\n };\n}\n\nfunction resolveTop(\n target: ScrollTarget,\n source: ScrollSource,\n offset = 0,\n): number {\n if (typeof target === 'number') return target + offset;\n if (source instanceof Window) {\n const el =\n typeof target === 'string' ? document.querySelector(target) : target;\n if (!el) return window.scrollY;\n return el.getBoundingClientRect().top + window.scrollY + offset;\n }\n const el =\n typeof target === 'string' ? source.querySelector(target) : target;\n if (!(el instanceof HTMLElement)) return source.scrollTop;\n return el.offsetTop + offset;\n}\n\n/** Pushes Lenis' live scroll state into the shared motion values. */\nfunction LenisBridge({\n scrollY,\n progress,\n velocity,\n lenisRef,\n}: {\n scrollY: MotionValue<number>;\n progress: MotionValue<number>;\n velocity: MotionValue<number>;\n lenisRef: { current: Lenis | null };\n}) {\n const lenis = useLenis((instance) => {\n scrollY.set(instance.scroll);\n progress.set(instance.progress);\n velocity.set(instance.velocity);\n });\n useEffect(() => {\n lenisRef.current = lenis ?? null;\n return () => {\n lenisRef.current = null;\n };\n }, [lenis, lenisRef]);\n return null;\n}\n\n/** Native scroll listener for the reduced-motion path and the no-provider fallback. */\nfunction useNativeScrollSync(\n enabled: boolean,\n getTarget: () => ScrollSource | null,\n scrollY: MotionValue<number>,\n progress: MotionValue<number>,\n velocity: MotionValue<number>,\n) {\n useEffect(() => {\n if (!enabled) return;\n const target = getTarget();\n if (!target) return;\n let lastY = readMetrics(target).y;\n let lastT = performance.now();\n const onScroll = () => {\n const { y, max } = readMetrics(target);\n const now = performance.now();\n const dt = now - lastT || 16;\n scrollY.set(y);\n progress.set(max > 0 ? y / max : 0);\n velocity.set(((y - lastY) / dt) * 16);\n lastY = y;\n lastT = now;\n };\n onScroll();\n target.addEventListener('scroll', onScroll, { passive: true });\n return () => target.removeEventListener('scroll', onScroll);\n }, [enabled, getTarget, scrollY, progress, velocity]);\n}\n\nexport function SmoothScroll({\n children,\n root = true,\n lerp = 0.1,\n duration = 1.2,\n orientation = 'vertical',\n wheelMultiplier = 1,\n touch = false,\n className,\n}: SmoothScrollProps) {\n const reduce = useReducedMotion();\n const scrollY = useMotionValue(0);\n const progress = useMotionValue(0);\n const velocity = useMotionValue(0);\n const lenisRef = useRef<Lenis | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const nativeSource = useCallback(\n (): ScrollSource | null => (root ? window : containerRef.current),\n [root],\n );\n\n const scrollTo = useCallback(\n (target: ScrollTarget, options?: ScrollToOptions) => {\n const lenis = lenisRef.current;\n if (lenis && !reduce) {\n lenis.scrollTo(target, {\n offset: options?.offset,\n duration: options?.duration,\n immediate: options?.immediate,\n });\n return;\n }\n const source = nativeSource();\n const behavior = reduce || options?.immediate ? 'auto' : 'smooth';\n const top = resolveTop(target, source ?? window, options?.offset);\n (source ?? window).scrollTo({ top, behavior });\n },\n [reduce, nativeSource],\n );\n\n // Reduced motion drives the native listener; otherwise LenisBridge feeds the values instead.\n useNativeScrollSync(!!reduce, nativeSource, scrollY, progress, velocity);\n\n const api = useMemo<SmoothScrollApi>(\n () => ({ lenis: lenisRef.current, scrollY, progress, velocity, scrollTo }),\n [scrollY, progress, velocity, scrollTo],\n );\n\n if (reduce) {\n return (\n <SmoothScrollContext.Provider value={api}>\n <div ref={containerRef} className={className}>\n {children}\n </div>\n </SmoothScrollContext.Provider>\n );\n }\n\n return (\n <SmoothScrollContext.Provider value={api}>\n <ReactLenis\n root={root}\n className={className}\n options={{\n lerp,\n duration,\n orientation,\n wheelMultiplier,\n smoothWheel: true,\n syncTouch: touch,\n easing: EASE_SCROLL,\n // Without this, Lenis preventDefault()s every wheel event, blocking nested scrollable\n // elements (log panes, drawers, option lists). Escape hatch: `data-lenis-prevent`.\n allowNestedScroll: true,\n }}\n >\n <LenisBridge\n scrollY={scrollY}\n progress={progress}\n velocity={velocity}\n lenisRef={lenisRef}\n />\n {children}\n </ReactLenis>\n </SmoothScrollContext.Provider>\n );\n}\n","// Adapted from a min/max/step range slider so labeled steps (e.g. Low/Medium/High/Max) line up on\n// evenly spaced stops; the value readout sits statically above the track (no floating/portal tooltip).\nimport {\n domAnimation,\n LazyMotion,\n m,\n useMotionTemplate,\n useMotionValue,\n useReducedMotion,\n useSpring,\n useTransform,\n} from 'motion/react';\nimport {\n type KeyboardEvent,\n type PointerEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { cn } from '../../lib/utils';\nimport { useIsDarkMode } from '../../hooks/use-is-dark-mode';\n\nconst SPRING_GLIDE = { stiffness: 700, damping: 50, mass: 0.5 } as const;\nconst SPRING_BOUNCY = { type: 'spring', stiffness: 500, damping: 14, mass: 0.7 } as const;\n\n// Deterministic 0..1 seed from the slider's id, so two sliders maxed out at once get slightly\n// different hues/timing instead of pulsing in perfect unison.\nfunction seedFromId(id: string | undefined) {\n if (!id) return 0;\n let hash = 0;\n for (let i = 0; i < id.length; i += 1) {\n hash = (hash * 31 + id.charCodeAt(i)) >>> 0;\n }\n return (hash % 997) / 997;\n}\n\nexport interface SteppedSliderStep {\n value: number;\n label: string;\n}\n\nexport interface SteppedSliderProps {\n id?: string;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n /** Tick dots + labels rendered at each defined step. */\n steps?: SteppedSliderStep[];\n /** Live value readout shown above the track, and used as the accessible aria-valuetext. Defaults to the raw value. */\n formatValue?: (value: number) => string;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\nconst clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));\n\nexport function SteppedSlider({\n id,\n value,\n defaultValue = 0,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n steps = [],\n formatValue,\n disabled = false,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: SteppedSliderProps) {\n const reduce = useReducedMotion();\n const isDark = useIsDarkMode();\n const seed = useMemo(() => seedFromId(id), [id]);\n const trackRef = useRef<HTMLDivElement>(null);\n const [internal, setInternal] = useState(defaultValue);\n const [active, setActive] = useState(false);\n // Decoupled from the committed value so onValueChange fires once per gesture (on release),\n // not on every pointer-move tick. Mirrored in a ref so release can read the pending value\n // without doing the commit inside a state updater.\n const [dragValue, setDragValue] = useState<number | null>(null);\n const dragValueRef = useRef<number | null>(null);\n const controlled = value !== undefined;\n const committedValue = clamp(controlled ? (value as number) : internal, min, max);\n const current = active && dragValue !== null ? clamp(dragValue, min, max) : committedValue;\n const percent = ((current - min) / (max - min)) * 100;\n const isMaxed = current === max;\n\n // Hue-shifted and timed per instance so simultaneous maxed-out sliders don't pulse in unison.\n const hue = 185 + (seed - 0.5) * 16;\n const glowColor = isDark ? `oklch(68% 0.14 ${hue})` : `oklch(52% 0.13 ${hue})`;\n const fillGradient = isDark\n ? `linear-gradient(90deg, oklch(28% 0.08 ${hue}), oklch(62% 0.12 ${hue}))`\n : `linear-gradient(90deg, oklch(93% 0.03 ${hue}), oklch(56% 0.13 ${hue}))`;\n const dotDriftDuration = 1.4 + seed * 0.5;\n const glowDuration = 1.6 + seed * 0.6;\n\n const target = useMotionValue(percent);\n useEffect(() => {\n target.set(percent);\n }, [percent, target]);\n const smooth = useSpring(target, SPRING_GLIDE);\n const pos = reduce ? target : smooth;\n const left = useMotionTemplate`${pos}%`;\n const thumbX = useTransform(pos, (p) => `${-p}%`);\n\n const snapValue = useCallback(\n (next: number) => clamp(Math.round((next - min) / step) * step + min, min, max),\n [min, max, step],\n );\n\n const commit = useCallback(\n (next: number) => {\n const snapped = snapValue(next);\n if (!controlled) setInternal(snapped);\n onValueChange?.(snapped);\n },\n [controlled, onValueChange, snapValue],\n );\n\n const valueFromX = useCallback(\n (clientX: number) => {\n const rect = trackRef.current?.getBoundingClientRect();\n if (!rect) return committedValue;\n const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);\n return min + ratio * (max - min);\n },\n [committedValue, min, max],\n );\n\n const trackDragValue = useCallback((next: number | null) => {\n dragValueRef.current = next;\n setDragValue(next);\n }, []);\n\n const onPointerDown = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n setActive(true);\n trackDragValue(snapValue(valueFromX(event.clientX)));\n },\n [disabled, valueFromX, snapValue, trackDragValue],\n );\n\n const onPointerMove = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n if (!active || disabled) return;\n trackDragValue(snapValue(valueFromX(event.clientX)));\n },\n [active, disabled, valueFromX, snapValue, trackDragValue],\n );\n\n const endDrag = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n setActive(false);\n const pending = dragValueRef.current;\n trackDragValue(null);\n if (pending !== null) commit(pending);\n },\n [commit, trackDragValue],\n );\n\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n const map: Record<string, number> = {\n ArrowRight: committedValue + step,\n ArrowUp: committedValue + step,\n ArrowLeft: committedValue - step,\n ArrowDown: committedValue - step,\n Home: min,\n End: max,\n };\n if (event.key in map) {\n event.preventDefault();\n commit(map[event.key]);\n }\n },\n [disabled, committedValue, step, min, max, commit],\n );\n\n const valueLabel = formatValue ? formatValue(current) : String(current);\n\n return (\n <LazyMotion features={domAnimation}>\n <div className={cn('w-full', className)}>\n <div className=\"mb-1.5 flex justify-end\">\n <span className=\"text-xs font-medium text-foreground tabular-nums\">{valueLabel}</span>\n </div>\n\n <div\n ref={trackRef}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n className={cn(\n 'relative flex h-10 w-full touch-none select-none items-center overflow-hidden rounded-lg bg-muted',\n disabled ? 'pointer-events-none opacity-50' : 'cursor-grab active:cursor-grabbing',\n )}\n >\n {/* Pattern repeats every 10px, shifting by exactly one period, so the loop point is never visible. */}\n <m.div className=\"absolute inset-y-0 left-0 overflow-hidden\" style={{ width: left }}>\n {isMaxed ? (\n <div\n className=\"absolute inset-0\"\n style={{ backgroundImage: fillGradient }}\n >\n <m.div\n className=\"absolute inset-0\"\n style={{\n backgroundImage: 'radial-gradient(circle, rgba(255,255,255,0.85) 1.3px, transparent 1.3px)',\n backgroundSize: '10px 10px',\n }}\n animate={reduce ? undefined : { backgroundPositionX: ['0px', '10px'] }}\n transition={{ duration: dotDriftDuration, repeat: Infinity, ease: 'linear' }}\n />\n </div>\n ) : (\n <div className=\"absolute inset-0 bg-foreground/15\" />\n )}\n </m.div>\n\n {/* Inset so end dots don't clip; sized up at max so they don't blend into the dot texture. */}\n <div className=\"pointer-events-none absolute inset-x-2 inset-y-0\">\n {steps.map((tick) => {\n const tp = ((tick.value - min) / (max - min)) * 100;\n return (\n <span\n key={tick.value}\n className={cn(\n 'absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full',\n isMaxed ? 'size-1.5 bg-white shadow-[0_0_0_1.5px_rgba(0,0,0,0.35)]' : 'size-1 bg-foreground/25',\n )}\n style={{ left: `${tp}%` }}\n />\n );\n })}\n </div>\n\n {/* Own layer so only opacity animates - Motion's box-shadow interpolator can't parse CSS custom properties in the color stops. */}\n {isMaxed && !reduce && (\n <m.div\n aria-hidden\n className=\"pointer-events-none absolute top-1/2 h-5 w-1.5 rounded-sm\"\n style={{ left, x: thumbX, y: '-50%', boxShadow: `0 0 9px 3px ${glowColor}` }}\n animate={{ opacity: [0.25, 0.9, 0.25], scale: [1, 1.15, 1] }}\n transition={{ duration: glowDuration, repeat: Infinity, ease: 'easeInOut', delay: seed * 0.5 }}\n />\n )}\n\n <m.div\n id={id}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={Math.round(current)}\n aria-valuetext={valueLabel}\n aria-disabled={disabled || undefined}\n onKeyDown={onKeyDown}\n animate={reduce ? undefined : { scaleY: active ? 1.35 : 1 }}\n transition={SPRING_BOUNCY}\n className={cn(\n 'absolute top-1/2 h-5 w-1.5 rounded-sm bg-foreground shadow-sm outline-none ring-foreground/30 focus-visible:ring-4',\n // Background-colored ring keeps the thumb legible against the accent fill at any position.\n isMaxed && 'ring-2 ring-background',\n )}\n style={{ left, x: thumbX, y: '-50%' }}\n />\n </div>\n\n {steps.length > 0 && (\n <div className=\"relative mt-1.5 h-4\">\n <div className=\"absolute inset-x-2 inset-y-0\">\n {steps.map((tick, index) => {\n const isFirst = index === 0;\n const isLast = index === steps.length - 1;\n const tp = ((tick.value - min) / (max - min)) * 100;\n return (\n <span\n key={tick.value}\n className={cn(\n 'absolute text-[10px] font-medium text-muted-foreground',\n isFirst && 'left-0',\n isLast && 'right-0',\n !isFirst && !isLast && '-translate-x-1/2',\n )}\n style={!isFirst && !isLast ? { left: `${tp}%` } : undefined}\n >\n {tick.label}\n </span>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </LazyMotion>\n );\n}\n","// beui.dev/components/motion/tabs\n// domMax rather than domAnimation: the active-tab indicator animates via layoutId/layoutRoot, and\n// layout projection only ships in the max bundle.\nimport { LazyMotion, m, domMax, MotionConfig, useReducedMotion, type Transition } from 'motion/react';\nimport {\n createContext,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../lib/utils';\n\ntype Variant = 'pill' | 'underline' | 'segment';\n\ntype Ctx = {\n value: string;\n setValue: (v: string) => void;\n layoutId: string;\n variant: Variant;\n};\n\nconst TabsCtx = createContext<Ctx | null>(null);\n\nfunction useTabs() {\n const ctx = useContext(TabsCtx);\n if (!ctx) throw new Error('Tabs.* must be used inside <Tabs>');\n return ctx;\n}\n\n// A touch of overshoot so the active-tab indicator settles with life instead of snapping.\nconst transition: Transition = {\n type: 'spring',\n stiffness: 170,\n damping: 24,\n mass: 1.2,\n};\n\nexport function Tabs({\n defaultValue,\n value,\n onValueChange,\n variant = 'pill',\n children,\n className,\n}: {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n variant?: Variant;\n children: ReactNode;\n className?: string;\n}) {\n const [internal, setInternal] = useState(defaultValue ?? '');\n const layoutId = useId();\n const reduce = useReducedMotion();\n const controlled = value !== undefined;\n const current = controlled ? value : internal;\n const setValue = useCallback(\n (v: string) => {\n if (!controlled) setInternal(v);\n onValueChange?.(v);\n },\n [controlled, onValueChange],\n );\n const ctx = useMemo(\n () => ({ value: current, setValue, layoutId, variant }),\n [current, setValue, layoutId, variant],\n );\n return (\n <MotionConfig transition={reduce ? { duration: 0 } : transition}>\n <TabsCtx.Provider value={ctx}>\n <LazyMotion features={domMax}>\n {/* layoutRoot: the indicator's layoutId measures in page coordinates, so without this\n it would replay scroll offsets as movement inside fixed/scrolled containers. */}\n <m.div layoutRoot className={className}>\n {children}\n </m.div>\n </LazyMotion>\n </TabsCtx.Provider>\n </MotionConfig>\n );\n}\n\nconst listClasses: Record<Variant, string> = {\n pill: 'inline-flex items-center gap-1 rounded-full bg-card p-1',\n underline: 'inline-flex items-center gap-1 border-b border-border',\n segment: 'inline-flex items-center gap-0 rounded-md border border-ui-line bg-ui-fill/40 p-0.5',\n};\n\nexport function TabsList({ children, className }: { children: ReactNode; className?: string }) {\n const { variant } = useTabs();\n return (\n <div role=\"tablist\" className={cn(listClasses[variant], className)}>\n {children}\n </div>\n );\n}\n\nexport function TabsTrigger({\n value,\n children,\n className,\n indicatorClassName,\n}: {\n value: string;\n children: ReactNode;\n className?: string;\n indicatorClassName?: string;\n}) {\n const { value: current, setValue, layoutId, variant } = useTabs();\n const active = current === value;\n\n if (variant === 'underline') {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => setValue(value)}\n className={cn(\n 'relative isolate px-3 pb-2.5 pt-1 -mb-px text-sm font-medium transition-colors min-h-[44px] inline-flex items-center',\n active ? 'text-foreground' : 'text-muted-foreground hover:text-foreground',\n className,\n )}\n >\n {children}\n {active ? (\n <m.span\n layoutId={layoutId}\n className={cn('absolute -bottom-px left-0 right-0 h-px bg-primary', indicatorClassName)}\n />\n ) : null}\n </button>\n );\n }\n\n // Segment uses a neutral raised surface (vs. pill's max-contrast) so it reads as a standard segmented control.\n const isSegment = variant === 'segment';\n const radius = variant === 'pill' ? 'rounded-full' : 'rounded-[5px]';\n const indicatorBg = isSegment ? 'bg-ui-base shadow-sm ring-1 ring-ui-line' : 'bg-primary';\n const activeText = isSegment ? 'text-ui-strong' : 'text-primary-foreground';\n const inactiveText = isSegment\n ? 'text-ui-subtle hover:text-ui-default'\n : 'text-muted-foreground hover:text-foreground';\n\n return (\n <div className=\"relative\">\n {active ? (\n <m.span\n layoutId={layoutId}\n style={{ borderRadius: variant === 'pill' ? 9999 : 5 }}\n className={cn('absolute inset-0', indicatorBg, radius, indicatorClassName)}\n />\n ) : null}\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => setValue(value)}\n className={cn(\n 'relative z-10 inline-flex items-center justify-center whitespace-nowrap bg-transparent px-3.5 py-1.5 text-sm font-medium capitalize transition-colors outline-none',\n active ? activeText : inactiveText,\n radius,\n className,\n )}\n >\n {children}\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":["useReducedMotion","jsx","jsxs","el","LazyMotion","m","useMotionValue","useReducedMotion","useCallback","useEffect","useMemo","useRef","useState","jsx","jsxs","useReducedMotion","useMemo","useRef","useState","useMotionValue","useEffect","useCallback","LazyMotion","m","LazyMotion","m","domMax","useReducedMotion","createContext","useCallback","useId","useMemo","useState","jsx","jsxs","createContext","useState","useId","useReducedMotion","useCallback","useMemo","LazyMotion","domMax","m"]}
1
+ {"version":3,"sources":["../../../src/components/motion/shared-layout-bg.tsx","../../../src/components/motion/smooth-scroll.tsx","../../../src/components/motion/stepped-slider.tsx","../../../src/components/motion/tabs.tsx"],"sourcesContent":["// beui.dev/components/motion/shared-layout-bg\nimport {\n AnimatePresence,\n domMax,\n LazyMotion,\n m,\n useReducedMotion,\n type Variants,\n} from \"motion/react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useId,\n useState,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nconst SPRING_LAYOUT = {\n type: \"spring\" as const,\n stiffness: 400,\n damping: 40,\n mass: 0.6,\n};\n\nexport interface SharedLayoutBgProps {\n children: ReactNode;\n className?: string;\n pillClassName?: string;\n /** Horizontal inset of the pill relative to each row (px). */\n inset?: number;\n}\n\nconst variants: Variants = {\n initial: { opacity: 0, filter: \"blur(6px)\" },\n animate: { opacity: 1, filter: \"blur(0px)\" },\n exit: (isActive: boolean) =>\n !isActive ? { opacity: 0, filter: \"blur(6px)\" } : {},\n};\n\nconst reducedVariants: Variants = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: (isActive: boolean) => (!isActive ? { opacity: 0 } : {}),\n};\n\nexport function SharedLayoutBg({\n children,\n className,\n pillClassName,\n inset = 0,\n}: SharedLayoutBgProps) {\n const [activeId, setActiveId] = useState<string | null>(null);\n const uid = useId();\n const reduce = useReducedMotion();\n\n const rows: ReactNode[] = [];\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue;\n const el = child as ReactElement<{\n className?: string;\n onMouseEnter?: (e?: any) => void;\n children?: ReactNode;\n }>;\n // rows.length is the index among *valid* children, so keyless rows keep stable fallback keys.\n const childKey = el.key ? String(el.key) : `item-${rows.length}`;\n rows.push(\n cloneElement(\n el,\n {\n key: childKey,\n className: cn(\"relative z-10\", el.props.className),\n onMouseEnter: (e: any) => {\n el.props.onMouseEnter?.(e);\n setActiveId(childKey);\n },\n },\n <>\n <div className=\"pointer-events-none absolute inset-0 z-0\">\n <AnimatePresence custom={activeId !== null}>\n {activeId !== null ? (\n <m.div\n variants={reduce ? reducedVariants : variants}\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n custom={activeId !== null}\n className=\"absolute inset-0\"\n style={{ left: -inset, right: -inset, top: 0, bottom: 0 }}\n >\n {activeId === childKey ? (\n <m.div\n layoutId={`shared-bg-${uid}`}\n transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n className={cn(\n \"pointer-events-none h-full w-full rounded-lg\",\n pillClassName,\n )}\n />\n ) : null}\n </m.div>\n ) : null}\n </AnimatePresence>\n </div>\n {el}\n </>\n ),\n );\n }\n\n return (\n <LazyMotion features={domMax}>\n <m.div\n layoutRoot\n onMouseLeave={() => setActiveId(null)}\n className={cn(\"flex w-full flex-col\", className)}\n >\n {rows}\n </m.div>\n </LazyMotion>\n );\n}\n","// beui.dev/components/motion/scroll-animation\nimport type Lenis from 'lenis';\nimport { ReactLenis, useLenis } from 'lenis/react';\nimport { type MotionValue, useMotionValue, useReducedMotion } from 'motion/react';\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\n// Named fn, not a lib/ease token: Lenis needs a (t) => number easing fn, not bezier points.\nconst EASE_SCROLL = (t: number) => Math.min(1, 1.001 - 2 ** (-10 * t));\n\nexport type ScrollTarget = number | string | HTMLElement;\n\nexport type ScrollToOptions = {\n offset?: number;\n immediate?: boolean;\n duration?: number;\n};\n\nexport type SmoothScrollApi = {\n /** Null on the reduced-motion / native path. */\n lenis: Lenis | null;\n scrollY: MotionValue<number>;\n progress: MotionValue<number>;\n /** px/frame. */\n velocity: MotionValue<number>;\n /** Jumps instantly under reduced motion. */\n scrollTo: (target: ScrollTarget, options?: ScrollToOptions) => void;\n};\n\nconst SmoothScrollContext = createContext<SmoothScrollApi | null>(null);\n\nexport interface SmoothScrollProps {\n children: ReactNode;\n /** True drives window scroll; false scrolls a contained area. */\n root?: boolean;\n /** Lower = smoother, heavier. */\n lerp?: number;\n duration?: number;\n orientation?: 'vertical' | 'horizontal';\n wheelMultiplier?: number;\n /** Off by default: native touch momentum is already good on mobile. */\n touch?: boolean;\n className?: string;\n}\n\ntype ScrollSource = Window | HTMLElement;\n\nfunction readMetrics(target: ScrollSource) {\n if (target instanceof Window) {\n const max = Math.max(\n 0,\n document.documentElement.scrollHeight - window.innerHeight,\n );\n return { y: window.scrollY, max };\n }\n return {\n y: target.scrollTop,\n max: Math.max(0, target.scrollHeight - target.clientHeight),\n };\n}\n\nfunction resolveTop(\n target: ScrollTarget,\n source: ScrollSource,\n offset = 0,\n): number {\n if (typeof target === 'number') return target + offset;\n if (source instanceof Window) {\n const el =\n typeof target === 'string' ? document.querySelector(target) : target;\n if (!el) return window.scrollY;\n return el.getBoundingClientRect().top + window.scrollY + offset;\n }\n const el =\n typeof target === 'string' ? source.querySelector(target) : target;\n if (!(el instanceof HTMLElement)) return source.scrollTop;\n return el.offsetTop + offset;\n}\n\nfunction LenisBridge({\n scrollY,\n progress,\n velocity,\n lenisRef,\n}: {\n scrollY: MotionValue<number>;\n progress: MotionValue<number>;\n velocity: MotionValue<number>;\n lenisRef: { current: Lenis | null };\n}) {\n const lenis = useLenis((instance) => {\n scrollY.set(instance.scroll);\n progress.set(instance.progress);\n velocity.set(instance.velocity);\n });\n useEffect(() => {\n lenisRef.current = lenis ?? null;\n return () => {\n lenisRef.current = null;\n };\n }, [lenis, lenisRef]);\n return null;\n}\n\nfunction useNativeScrollSync(\n enabled: boolean,\n getTarget: () => ScrollSource | null,\n scrollY: MotionValue<number>,\n progress: MotionValue<number>,\n velocity: MotionValue<number>,\n) {\n useEffect(() => {\n if (!enabled) return;\n const target = getTarget();\n if (!target) return;\n let lastY = readMetrics(target).y;\n let lastT = performance.now();\n const onScroll = () => {\n const { y, max } = readMetrics(target);\n const now = performance.now();\n const dt = now - lastT || 16;\n scrollY.set(y);\n progress.set(max > 0 ? y / max : 0);\n velocity.set(((y - lastY) / dt) * 16);\n lastY = y;\n lastT = now;\n };\n onScroll();\n target.addEventListener('scroll', onScroll, { passive: true });\n return () => target.removeEventListener('scroll', onScroll);\n }, [enabled, getTarget, scrollY, progress, velocity]);\n}\n\nexport function SmoothScroll({\n children,\n root = true,\n lerp = 0.1,\n duration = 1.2,\n orientation = 'vertical',\n wheelMultiplier = 1,\n touch = false,\n className,\n}: SmoothScrollProps) {\n const reduce = useReducedMotion();\n const scrollY = useMotionValue(0);\n const progress = useMotionValue(0);\n const velocity = useMotionValue(0);\n const lenisRef = useRef<Lenis | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const nativeSource = useCallback(\n (): ScrollSource | null => (root ? window : containerRef.current),\n [root],\n );\n\n const scrollTo = useCallback(\n (target: ScrollTarget, options?: ScrollToOptions) => {\n const lenis = lenisRef.current;\n if (lenis && !reduce) {\n lenis.scrollTo(target, {\n offset: options?.offset,\n duration: options?.duration,\n immediate: options?.immediate,\n });\n return;\n }\n const source = nativeSource();\n const behavior = reduce || options?.immediate ? 'auto' : 'smooth';\n const top = resolveTop(target, source ?? window, options?.offset);\n (source ?? window).scrollTo({ top, behavior });\n },\n [reduce, nativeSource],\n );\n\n useNativeScrollSync(!!reduce, nativeSource, scrollY, progress, velocity);\n\n const api = useMemo<SmoothScrollApi>(\n () => ({ lenis: lenisRef.current, scrollY, progress, velocity, scrollTo }),\n [scrollY, progress, velocity, scrollTo],\n );\n\n if (reduce) {\n return (\n <SmoothScrollContext.Provider value={api}>\n <div ref={containerRef} className={className}>\n {children}\n </div>\n </SmoothScrollContext.Provider>\n );\n }\n\n return (\n <SmoothScrollContext.Provider value={api}>\n <ReactLenis\n root={root}\n className={className}\n options={{\n lerp,\n duration,\n orientation,\n wheelMultiplier,\n smoothWheel: true,\n syncTouch: touch,\n easing: EASE_SCROLL,\n // Else Lenis preventDefault()s every wheel event, blocking nested scroll areas.\n allowNestedScroll: true,\n }}\n >\n <LenisBridge\n scrollY={scrollY}\n progress={progress}\n velocity={velocity}\n lenisRef={lenisRef}\n />\n {children}\n </ReactLenis>\n </SmoothScrollContext.Provider>\n );\n}\n","// Adapted from a min/max/step range slider so labeled steps (e.g. Low/Medium/High/Max) line up on\n// evenly spaced stops; the value readout sits statically above the track (no floating/portal tooltip).\nimport {\n domAnimation,\n LazyMotion,\n m,\n useMotionTemplate,\n useMotionValue,\n useReducedMotion,\n useSpring,\n useTransform,\n} from 'motion/react';\nimport {\n type KeyboardEvent,\n type PointerEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { cn } from '../../lib/utils';\nimport { useIsDarkMode } from '../../hooks/use-is-dark-mode';\n\nconst SPRING_GLIDE = { stiffness: 700, damping: 50, mass: 0.5 } as const;\nconst SPRING_BOUNCY = { type: 'spring', stiffness: 500, damping: 14, mass: 0.7 } as const;\n\n// Deterministic 0..1 seed from the slider's id, so two sliders maxed out at once get slightly\n// different hues/timing instead of pulsing in perfect unison.\nfunction seedFromId(id: string | undefined) {\n if (!id) return 0;\n let hash = 0;\n for (let i = 0; i < id.length; i += 1) {\n hash = (hash * 31 + id.charCodeAt(i)) >>> 0;\n }\n return (hash % 997) / 997;\n}\n\nexport interface SteppedSliderStep {\n value: number;\n label: string;\n}\n\nexport interface SteppedSliderProps {\n id?: string;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n /** Tick dots + labels rendered at each defined step. */\n steps?: SteppedSliderStep[];\n /** Live value readout shown above the track, and used as the accessible aria-valuetext. Defaults to the raw value. */\n formatValue?: (value: number) => string;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\nconst clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));\n\nexport function SteppedSlider({\n id,\n value,\n defaultValue = 0,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n steps = [],\n formatValue,\n disabled = false,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: SteppedSliderProps) {\n const reduce = useReducedMotion();\n const isDark = useIsDarkMode();\n const seed = useMemo(() => seedFromId(id), [id]);\n const trackRef = useRef<HTMLDivElement>(null);\n const [internal, setInternal] = useState(defaultValue);\n const [active, setActive] = useState(false);\n // Decoupled from the committed value so onValueChange fires once per gesture (on release),\n // not on every pointer-move tick. Mirrored in a ref so release can read the pending value\n // without doing the commit inside a state updater.\n const [dragValue, setDragValue] = useState<number | null>(null);\n const dragValueRef = useRef<number | null>(null);\n const controlled = value !== undefined;\n const committedValue = clamp(controlled ? (value as number) : internal, min, max);\n const current = active && dragValue !== null ? clamp(dragValue, min, max) : committedValue;\n const percent = ((current - min) / (max - min)) * 100;\n const isMaxed = current === max;\n\n // Hue-shifted and timed per instance so simultaneous maxed-out sliders don't pulse in unison.\n const hue = 185 + (seed - 0.5) * 16;\n const glowColor = isDark ? `oklch(68% 0.14 ${hue})` : `oklch(52% 0.13 ${hue})`;\n const fillGradient = isDark\n ? `linear-gradient(90deg, oklch(28% 0.08 ${hue}), oklch(62% 0.12 ${hue}))`\n : `linear-gradient(90deg, oklch(93% 0.03 ${hue}), oklch(56% 0.13 ${hue}))`;\n const dotDriftDuration = 1.4 + seed * 0.5;\n const glowDuration = 1.6 + seed * 0.6;\n\n const target = useMotionValue(percent);\n useEffect(() => {\n target.set(percent);\n }, [percent, target]);\n const smooth = useSpring(target, SPRING_GLIDE);\n const pos = reduce ? target : smooth;\n const left = useMotionTemplate`${pos}%`;\n const thumbX = useTransform(pos, (p) => `${-p}%`);\n\n const snapValue = useCallback(\n (next: number) => clamp(Math.round((next - min) / step) * step + min, min, max),\n [min, max, step],\n );\n\n const commit = useCallback(\n (next: number) => {\n const snapped = snapValue(next);\n if (!controlled) setInternal(snapped);\n onValueChange?.(snapped);\n },\n [controlled, onValueChange, snapValue],\n );\n\n const valueFromX = useCallback(\n (clientX: number) => {\n const rect = trackRef.current?.getBoundingClientRect();\n if (!rect) return committedValue;\n const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);\n return min + ratio * (max - min);\n },\n [committedValue, min, max],\n );\n\n const trackDragValue = useCallback((next: number | null) => {\n dragValueRef.current = next;\n setDragValue(next);\n }, []);\n\n const onPointerDown = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n setActive(true);\n trackDragValue(snapValue(valueFromX(event.clientX)));\n },\n [disabled, valueFromX, snapValue, trackDragValue],\n );\n\n const onPointerMove = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n if (!active || disabled) return;\n trackDragValue(snapValue(valueFromX(event.clientX)));\n },\n [active, disabled, valueFromX, snapValue, trackDragValue],\n );\n\n const endDrag = useCallback(\n (event: PointerEvent<HTMLDivElement>) => {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n setActive(false);\n const pending = dragValueRef.current;\n trackDragValue(null);\n if (pending !== null) commit(pending);\n },\n [commit, trackDragValue],\n );\n\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n const map: Record<string, number> = {\n ArrowRight: committedValue + step,\n ArrowUp: committedValue + step,\n ArrowLeft: committedValue - step,\n ArrowDown: committedValue - step,\n Home: min,\n End: max,\n };\n if (event.key in map) {\n event.preventDefault();\n commit(map[event.key]);\n }\n },\n [disabled, committedValue, step, min, max, commit],\n );\n\n const valueLabel = formatValue ? formatValue(current) : String(current);\n\n return (\n <LazyMotion features={domAnimation}>\n <div className={cn('w-full', className)}>\n <div className=\"mb-1.5 flex justify-end\">\n <span className=\"text-xs font-medium text-foreground tabular-nums\">{valueLabel}</span>\n </div>\n\n <div\n ref={trackRef}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n className={cn(\n 'relative flex h-10 w-full touch-none select-none items-center overflow-hidden rounded-lg bg-muted',\n disabled ? 'pointer-events-none opacity-50' : 'cursor-grab active:cursor-grabbing',\n )}\n >\n {/* Pattern repeats every 10px, shifting by exactly one period, so the loop point is never visible. */}\n <m.div className=\"absolute inset-y-0 left-0 overflow-hidden\" style={{ width: left }}>\n {isMaxed ? (\n <div\n className=\"absolute inset-0\"\n style={{ backgroundImage: fillGradient }}\n >\n <m.div\n className=\"absolute inset-0\"\n style={{\n backgroundImage: 'radial-gradient(circle, rgba(255,255,255,0.85) 1.3px, transparent 1.3px)',\n backgroundSize: '10px 10px',\n }}\n animate={reduce ? undefined : { backgroundPositionX: ['0px', '10px'] }}\n transition={{ duration: dotDriftDuration, repeat: Infinity, ease: 'linear' }}\n />\n </div>\n ) : (\n <div className=\"absolute inset-0 bg-foreground/15\" />\n )}\n </m.div>\n\n {/* Inset so end dots don't clip; sized up at max so they don't blend into the dot texture. */}\n <div className=\"pointer-events-none absolute inset-x-2 inset-y-0\">\n {steps.map((tick) => {\n const tp = ((tick.value - min) / (max - min)) * 100;\n return (\n <span\n key={tick.value}\n className={cn(\n 'absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full',\n isMaxed ? 'size-1.5 bg-white shadow-[0_0_0_1.5px_rgba(0,0,0,0.35)]' : 'size-1 bg-foreground/25',\n )}\n style={{ left: `${tp}%` }}\n />\n );\n })}\n </div>\n\n {/* Own layer so only opacity animates - Motion's box-shadow interpolator can't parse CSS custom properties in the color stops. */}\n {isMaxed && !reduce && (\n <m.div\n aria-hidden\n className=\"pointer-events-none absolute top-1/2 h-5 w-1.5 rounded-sm\"\n style={{ left, x: thumbX, y: '-50%', boxShadow: `0 0 9px 3px ${glowColor}` }}\n animate={{ opacity: [0.25, 0.9, 0.25], scale: [1, 1.15, 1] }}\n transition={{ duration: glowDuration, repeat: Infinity, ease: 'easeInOut', delay: seed * 0.5 }}\n />\n )}\n\n <m.div\n id={id}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={Math.round(current)}\n aria-valuetext={valueLabel}\n aria-disabled={disabled || undefined}\n onKeyDown={onKeyDown}\n animate={reduce ? undefined : { scaleY: active ? 1.35 : 1 }}\n transition={SPRING_BOUNCY}\n className={cn(\n 'absolute top-1/2 h-5 w-1.5 rounded-sm bg-foreground shadow-sm outline-none ring-foreground/30 focus-visible:ring-4',\n // Background-colored ring keeps the thumb legible against the accent fill at any position.\n isMaxed && 'ring-2 ring-background',\n )}\n style={{ left, x: thumbX, y: '-50%' }}\n />\n </div>\n\n {steps.length > 0 && (\n <div className=\"relative mt-1.5 h-4\">\n <div className=\"absolute inset-x-2 inset-y-0\">\n {steps.map((tick, index) => {\n const isFirst = index === 0;\n const isLast = index === steps.length - 1;\n const tp = ((tick.value - min) / (max - min)) * 100;\n return (\n <span\n key={tick.value}\n className={cn(\n 'absolute text-[10px] font-medium text-muted-foreground',\n isFirst && 'left-0',\n isLast && 'right-0',\n !isFirst && !isLast && '-translate-x-1/2',\n )}\n style={!isFirst && !isLast ? { left: `${tp}%` } : undefined}\n >\n {tick.label}\n </span>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </LazyMotion>\n );\n}\n","// beui.dev/components/motion/tabs\n// domMax rather than domAnimation: the active-tab indicator animates via layoutId/layoutRoot, and\n// layout projection only ships in the max bundle.\nimport { LazyMotion, m, domMax, MotionConfig, useReducedMotion, type Transition } from 'motion/react';\nimport {\n createContext,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../lib/utils';\n\ntype Variant = 'pill' | 'underline' | 'segment';\n\ntype Ctx = {\n value: string;\n setValue: (v: string) => void;\n layoutId: string;\n variant: Variant;\n};\n\nconst TabsCtx = createContext<Ctx | null>(null);\n\nfunction useTabs() {\n const ctx = useContext(TabsCtx);\n if (!ctx) throw new Error('Tabs.* must be used inside <Tabs>');\n return ctx;\n}\n\n// A touch of overshoot so the active-tab indicator settles with life instead of snapping.\nconst transition: Transition = {\n type: 'spring',\n stiffness: 170,\n damping: 24,\n mass: 1.2,\n};\n\nexport function Tabs({\n defaultValue,\n value,\n onValueChange,\n variant = 'pill',\n children,\n className,\n}: {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n variant?: Variant;\n children: ReactNode;\n className?: string;\n}) {\n const [internal, setInternal] = useState(defaultValue ?? '');\n const layoutId = useId();\n const reduce = useReducedMotion();\n const controlled = value !== undefined;\n const current = controlled ? value : internal;\n const setValue = useCallback(\n (v: string) => {\n if (!controlled) setInternal(v);\n onValueChange?.(v);\n },\n [controlled, onValueChange],\n );\n const ctx = useMemo(\n () => ({ value: current, setValue, layoutId, variant }),\n [current, setValue, layoutId, variant],\n );\n return (\n <MotionConfig transition={reduce ? { duration: 0 } : transition}>\n <TabsCtx.Provider value={ctx}>\n <LazyMotion features={domMax}>\n {/* layoutRoot: the indicator's layoutId measures in page coordinates, so without this\n it would replay scroll offsets as movement inside fixed/scrolled containers. */}\n <m.div layoutRoot className={className}>\n {children}\n </m.div>\n </LazyMotion>\n </TabsCtx.Provider>\n </MotionConfig>\n );\n}\n\nconst listClasses: Record<Variant, string> = {\n pill: 'inline-flex items-center gap-1 rounded-full bg-card p-1',\n underline: 'inline-flex items-center gap-1 border-b border-border',\n segment: 'inline-flex items-center gap-0 rounded-md border border-ui-line bg-ui-fill/40 p-0.5',\n};\n\nexport function TabsList({ children, className }: { children: ReactNode; className?: string }) {\n const { variant } = useTabs();\n return (\n <div role=\"tablist\" className={cn(listClasses[variant], className)}>\n {children}\n </div>\n );\n}\n\nexport function TabsTrigger({\n value,\n children,\n className,\n indicatorClassName,\n}: {\n value: string;\n children: ReactNode;\n className?: string;\n indicatorClassName?: string;\n}) {\n const { value: current, setValue, layoutId, variant } = useTabs();\n const active = current === value;\n\n if (variant === 'underline') {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => setValue(value)}\n className={cn(\n 'relative isolate px-3 pb-2.5 pt-1 -mb-px text-sm font-medium transition-colors min-h-[44px] inline-flex items-center',\n active ? 'text-foreground' : 'text-muted-foreground hover:text-foreground',\n className,\n )}\n >\n {children}\n {active ? (\n <m.span\n layoutId={layoutId}\n className={cn('absolute -bottom-px left-0 right-0 h-px bg-primary', indicatorClassName)}\n />\n ) : null}\n </button>\n );\n }\n\n // Segment uses a neutral raised surface (vs. pill's max-contrast) so it reads as a standard segmented control.\n const isSegment = variant === 'segment';\n const radius = variant === 'pill' ? 'rounded-full' : 'rounded-[5px]';\n const indicatorBg = isSegment ? 'bg-ui-base shadow-sm ring-1 ring-ui-line' : 'bg-primary';\n const activeText = isSegment ? 'text-ui-strong' : 'text-primary-foreground';\n const inactiveText = isSegment\n ? 'text-ui-subtle hover:text-ui-default'\n : 'text-muted-foreground hover:text-foreground';\n\n return (\n <div className=\"relative\">\n {active ? (\n <m.span\n layoutId={layoutId}\n style={{ borderRadius: variant === 'pill' ? 9999 : 5 }}\n className={cn('absolute inset-0', indicatorBg, radius, indicatorClassName)}\n />\n ) : null}\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => setValue(value)}\n className={cn(\n 'relative z-10 inline-flex items-center justify-center whitespace-nowrap bg-transparent px-3.5 py-1.5 text-sm font-medium capitalize transition-colors outline-none',\n active ? activeText : inactiveText,\n radius,\n className,\n )}\n >\n {children}\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":["useReducedMotion","jsx","jsxs","el","LazyMotion","m","useMotionValue","useReducedMotion","useCallback","useEffect","useMemo","useRef","useState","jsx","jsxs","useReducedMotion","useMemo","useRef","useState","useMotionValue","useEffect","useCallback","LazyMotion","m","LazyMotion","m","domMax","useReducedMotion","createContext","useCallback","useId","useMemo","useState","jsx","jsxs","createContext","useState","useId","useReducedMotion","useCallback","useMemo","LazyMotion","domMax","m"]}
package/dist/index.d.ts CHANGED
@@ -217,10 +217,20 @@ declare function GraphShell({ title, icon, legend, children, className, }: {
217
217
  children: ReactNode;
218
218
  className?: string;
219
219
  }): React.JSX.Element;
220
- declare function LegendChip({ color, hatched, dashed, label, }: {
220
+ interface SeriesMarkerProps {
221
+ /** Flat CSS colour. Ignored when `hatched` is set, which paints its own fill. */
221
222
  color?: string;
223
+ /** The cross-hatched fill used for the input-token series. */
222
224
  hatched?: boolean;
225
+ /** A dashed rule instead of a swatch, for series drawn as a dashed line. */
223
226
  dashed?: boolean;
227
+ }
228
+ /**
229
+ * The swatch that identifies a series. Shared by the legend and the tooltip so a series looks the
230
+ * same in both - a tooltip dot that doesn't match its legend chip reads as a different series.
231
+ */
232
+ declare function SeriesMarker({ color, hatched, dashed }: SeriesMarkerProps): React.JSX.Element;
233
+ declare function LegendChip({ color, hatched, dashed, label, }: SeriesMarkerProps & {
224
234
  label: string;
225
235
  }): React.JSX.Element;
226
236
  declare function ChartDefs({ isDark }: {
@@ -238,4 +248,4 @@ declare function TickMeter({ label, value, max, color, valueLabel, }: {
238
248
  valueLabel: string;
239
249
  }): React.JSX.Element;
240
250
 
241
- export { Alert, Badge, BarSparkline, Button, type ButtonProps, CardDots, ChartDefs, ConfirmDialog, CopyButton, EmptyState, GithubMark, GraphShell, Input, type InputProps, LayerCard, LegendChip, LinkButton, LoadError, MeterList, SectionCard, Select, Skeleton, Switch, type SwitchProps, Text, TickMeter, badgeVariants, buttonVariants };
251
+ export { Alert, Badge, BarSparkline, Button, type ButtonProps, CardDots, ChartDefs, ConfirmDialog, CopyButton, EmptyState, GithubMark, GraphShell, Input, type InputProps, LayerCard, LegendChip, LinkButton, LoadError, MeterList, SectionCard, Select, SeriesMarker, type SeriesMarkerProps, Skeleton, Switch, type SwitchProps, Text, TickMeter, badgeVariants, buttonVariants };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cn
3
- } from "./chunk-HCQJTSV3.js";
3
+ } from "./chunk-GNGWMNUA.js";
4
4
  import {
5
5
  EASE_OUT
6
6
  } from "./chunk-OU66JJZD.js";
@@ -1025,15 +1025,53 @@ function GraphShell({
1025
1025
  children,
1026
1026
  className = ""
1027
1027
  }) {
1028
- return /* @__PURE__ */ jsxs11(LayerCard, { className: cn("relative flex flex-col overflow-hidden", className), children: [
1029
- /* @__PURE__ */ jsx19(CardDots, {}),
1030
- /* @__PURE__ */ jsxs11("div", { className: "relative flex items-center gap-2 px-4 pt-4 sm:px-5 sm:pt-5", children: [
1031
- icon && /* @__PURE__ */ jsx19("span", { className: "shrink-0 text-ui-subtle", children: icon }),
1032
- /* @__PURE__ */ jsx19("h3", { className: "truncate text-[11px] font-semibold uppercase tracking-[0.14em] text-ui-default", children: title })
1033
- ] }),
1034
- legend && /* @__PURE__ */ jsx19("div", { className: "relative flex flex-wrap items-center gap-x-4 gap-y-1.5 px-4 pt-3 sm:px-5", children: legend }),
1035
- /* @__PURE__ */ jsx19("div", { className: "relative flex flex-1 flex-col", children })
1036
- ] });
1028
+ return (
1029
+ // Same chrome as the dashboard stat cards: card face carries the title, the chart itself sits
1030
+ // in a recessed inner panel.
1031
+ /* @__PURE__ */ jsxs11(
1032
+ "div",
1033
+ {
1034
+ className: cn(
1035
+ "flex flex-col rounded-lg border border-ui-line bg-white p-3.5 dark:border-[oklch(0.27_0_0)] dark:bg-black",
1036
+ className
1037
+ ),
1038
+ children: [
1039
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-0.5", children: [
1040
+ icon && /* @__PURE__ */ jsx19("span", { className: "shrink-0 text-ui-subtle", children: icon }),
1041
+ /* @__PURE__ */ jsx19("h3", { className: "truncate text-[11px] font-semibold uppercase tracking-[0.14em] text-ui-default", children: title })
1042
+ ] }),
1043
+ /* @__PURE__ */ jsxs11("div", { className: "ui-well relative mt-3 flex flex-1 flex-col overflow-hidden rounded-md", children: [
1044
+ /* @__PURE__ */ jsx19(CardDots, {}),
1045
+ legend && /* @__PURE__ */ jsx19("div", { className: "relative flex flex-wrap items-center gap-x-4 gap-y-1.5 px-3.5 pt-3.5", children: legend }),
1046
+ /* @__PURE__ */ jsx19("div", { className: "relative flex flex-1 flex-col", children })
1047
+ ] })
1048
+ ]
1049
+ }
1050
+ )
1051
+ );
1052
+ }
1053
+ function SeriesMarker({ color, hatched, dashed }) {
1054
+ if (dashed) {
1055
+ return /* @__PURE__ */ jsx19(
1056
+ "span",
1057
+ {
1058
+ "aria-hidden": true,
1059
+ className: "h-0 w-3.5 shrink-0 border-t-2 border-dashed",
1060
+ style: { borderColor: color }
1061
+ }
1062
+ );
1063
+ }
1064
+ return /* @__PURE__ */ jsx19(
1065
+ "span",
1066
+ {
1067
+ "aria-hidden": true,
1068
+ className: "h-2.5 w-2.5 shrink-0 rounded-[3px]",
1069
+ style: hatched ? {
1070
+ backgroundImage: "repeating-linear-gradient(45deg, var(--ui-subtle) 0 1.5px, transparent 1.5px 3.5px)",
1071
+ backgroundColor: "color-mix(in oklch, var(--ui-fill) 60%, transparent)"
1072
+ } : { backgroundColor: color }
1073
+ }
1074
+ );
1037
1075
  }
1038
1076
  function LegendChip({
1039
1077
  color,
@@ -1042,22 +1080,7 @@ function LegendChip({
1042
1080
  label
1043
1081
  }) {
1044
1082
  return /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1.5 text-xs text-ui-subtle", children: [
1045
- dashed ? /* @__PURE__ */ jsx19(
1046
- "span",
1047
- {
1048
- className: "h-0 w-3.5 shrink-0 border-t-2 border-dashed",
1049
- style: { borderColor: color }
1050
- }
1051
- ) : /* @__PURE__ */ jsx19(
1052
- "span",
1053
- {
1054
- className: "h-2.5 w-2.5 shrink-0 rounded-[3px]",
1055
- style: hatched ? {
1056
- backgroundImage: "repeating-linear-gradient(45deg, var(--ui-subtle) 0 1.5px, transparent 1.5px 3.5px)",
1057
- backgroundColor: "color-mix(in oklch, var(--ui-fill) 60%, transparent)"
1058
- } : { backgroundColor: color }
1059
- }
1060
- ),
1083
+ /* @__PURE__ */ jsx19(SeriesMarker, { color, hatched, dashed }),
1061
1084
  label
1062
1085
  ] });
1063
1086
  }
@@ -1083,7 +1106,7 @@ var METER_ROW_PX = 20;
1083
1106
  var METER_GAP_PX = 14;
1084
1107
  function MeterList({ visible, children }) {
1085
1108
  const scrolls = Children.count(children) > visible;
1086
- return /* @__PURE__ */ jsx19("div", { className: "px-4 pb-5 pt-4 sm:px-5 sm:pb-6 sm:pt-5", children: /* @__PURE__ */ jsx19(
1109
+ return /* @__PURE__ */ jsx19("div", { className: "px-3.5 py-4 sm:px-4 sm:py-4.5", children: /* @__PURE__ */ jsx19(
1087
1110
  "div",
1088
1111
  {
1089
1112
  className: cn("space-y-3.5", scrolls && "overflow-y-auto pr-3"),
@@ -1134,6 +1157,7 @@ export {
1134
1157
  MeterList,
1135
1158
  SectionCard,
1136
1159
  Select,
1160
+ SeriesMarker,
1137
1161
  Skeleton,
1138
1162
  Switch,
1139
1163
  Text,