@spark-ui/components 17.4.1 → 17.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion/index.js.map +1 -1
- package/dist/accordion/index.mjs.map +1 -1
- package/dist/alert-dialog/index.js.map +1 -1
- package/dist/alert-dialog/index.mjs.map +1 -1
- package/dist/avatar/index.js +1 -1
- package/dist/avatar/index.js.map +1 -1
- package/dist/avatar/index.mjs +8 -2
- package/dist/avatar/index.mjs.map +1 -1
- package/dist/badge/index.js.map +1 -1
- package/dist/badge/index.mjs.map +1 -1
- package/dist/breadcrumb/index.js.map +1 -1
- package/dist/breadcrumb/index.mjs.map +1 -1
- package/dist/button-B-sMnDc_.js.map +1 -1
- package/dist/button-C6nlNPdv.mjs.map +1 -1
- package/dist/card/index.js.map +1 -1
- package/dist/card/index.mjs.map +1 -1
- package/dist/carousel/index.js.map +1 -1
- package/dist/carousel/index.mjs.map +1 -1
- package/dist/checkbox-DjwbAH09.js.map +1 -1
- package/dist/checkbox-xsURzANi.mjs.map +1 -1
- package/dist/chip/index.js.map +1 -1
- package/dist/chip/index.mjs.map +1 -1
- package/dist/circular-meter/index.js.map +1 -1
- package/dist/circular-meter/index.mjs.map +1 -1
- package/dist/collapsible/index.js.map +1 -1
- package/dist/collapsible/index.mjs.map +1 -1
- package/dist/combobox/index.js.map +1 -1
- package/dist/combobox/index.mjs.map +1 -1
- package/dist/dialog/index.js.map +1 -1
- package/dist/dialog/index.mjs.map +1 -1
- package/dist/divider/index.js.map +1 -1
- package/dist/divider/index.mjs.map +1 -1
- package/dist/drawer/index.js.map +1 -1
- package/dist/drawer/index.mjs.map +1 -1
- package/dist/dropdown/index.js.map +1 -1
- package/dist/dropdown/index.mjs.map +1 -1
- package/dist/file-upload/index.js.map +1 -1
- package/dist/file-upload/index.mjs.map +1 -1
- package/dist/form-field-81wzFxM0.js.map +1 -1
- package/dist/form-field-GTAuK_nO.mjs.map +1 -1
- package/dist/icon-CRPcdgYp.js.map +1 -1
- package/dist/icon-D05Uqh8_.mjs.map +1 -1
- package/dist/icon-button-CYz_Fitz.js.map +1 -1
- package/dist/icon-button-DpucUC_L.mjs.map +1 -1
- package/dist/input-BUSYZ_VO.js.map +1 -1
- package/dist/input-CiWFuTs_.mjs.map +1 -1
- package/dist/input-otp/index.js.map +1 -1
- package/dist/input-otp/index.mjs.map +1 -1
- package/dist/kbd/index.js.map +1 -1
- package/dist/kbd/index.mjs.map +1 -1
- package/dist/label-BCSEss4U.js.map +1 -1
- package/dist/label-DDBRKLUX.mjs.map +1 -1
- package/dist/link-box/index.js.map +1 -1
- package/dist/link-box/index.mjs.map +1 -1
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pagination/index.js.map +1 -1
- package/dist/pagination/index.mjs.map +1 -1
- package/dist/popover-CrKp_TKk.js.map +1 -1
- package/dist/popover-DsBY8eYl.mjs.map +1 -1
- package/dist/portal/index.js.map +1 -1
- package/dist/portal/index.mjs.map +1 -1
- package/dist/progress-BjqJSRnK.js.map +1 -1
- package/dist/progress-C3w4PmxY.mjs.map +1 -1
- package/dist/progress-tracker/index.js.map +1 -1
- package/dist/progress-tracker/index.mjs.map +1 -1
- package/dist/radio-group/index.js.map +1 -1
- package/dist/radio-group/index.mjs.map +1 -1
- package/dist/rating/index.js.map +1 -1
- package/dist/rating/index.mjs.map +1 -1
- package/dist/rating-display/index.js.map +1 -1
- package/dist/rating-display/index.mjs.map +1 -1
- package/dist/scrolling-list/index.js.map +1 -1
- package/dist/scrolling-list/index.mjs.map +1 -1
- package/dist/segmented-control/index.js.map +1 -1
- package/dist/segmented-control/index.mjs.map +1 -1
- package/dist/segmented-gauge/index.js.map +1 -1
- package/dist/segmented-gauge/index.mjs.map +1 -1
- package/dist/select/index.js.map +1 -1
- package/dist/select/index.mjs.map +1 -1
- package/dist/skeleton/index.js.map +1 -1
- package/dist/skeleton/index.mjs.map +1 -1
- package/dist/slider/index.js.map +1 -1
- package/dist/slider/index.mjs.map +1 -1
- package/dist/slot/index.js.map +1 -1
- package/dist/slot/index.mjs.map +1 -1
- package/dist/spinner-DFUoYvmm.js.map +1 -1
- package/dist/spinner-DULLiM6a.mjs.map +1 -1
- package/dist/src/accordion/index.d.mts +3 -0
- package/dist/src/accordion/index.d.ts +3 -0
- package/dist/src/alert-dialog/index.d.mts +3 -0
- package/dist/src/alert-dialog/index.d.ts +3 -0
- package/dist/src/avatar/index.d.mts +7 -5
- package/dist/src/avatar/index.d.ts +7 -5
- package/dist/src/badge/Badge.d.ts +3 -0
- package/dist/src/breadcrumb/index.d.mts +3 -0
- package/dist/src/breadcrumb/index.d.ts +3 -0
- package/dist/src/button/Button.d.ts +3 -0
- package/dist/src/card/index.d.mts +3 -0
- package/dist/src/card/index.d.ts +3 -0
- package/dist/src/carousel/index.d.mts +3 -0
- package/dist/src/carousel/index.d.ts +3 -0
- package/dist/src/checkbox/Checkbox.d.ts +3 -0
- package/dist/src/checkbox/CheckboxGroup.d.ts +4 -0
- package/dist/src/chip/index.d.mts +3 -0
- package/dist/src/chip/index.d.ts +3 -0
- package/dist/src/circular-meter/index.d.mts +3 -0
- package/dist/src/circular-meter/index.d.ts +3 -0
- package/dist/src/collapsible/index.d.mts +3 -0
- package/dist/src/collapsible/index.d.ts +3 -0
- package/dist/src/combobox/index.d.mts +3 -0
- package/dist/src/combobox/index.d.ts +3 -0
- package/dist/src/dialog/index.d.mts +3 -0
- package/dist/src/dialog/index.d.ts +3 -0
- package/dist/src/divider/index.d.mts +3 -0
- package/dist/src/divider/index.d.ts +3 -0
- package/dist/src/drawer/index.d.mts +3 -0
- package/dist/src/drawer/index.d.ts +3 -0
- package/dist/src/dropdown/index.d.mts +3 -0
- package/dist/src/dropdown/index.d.ts +3 -0
- package/dist/src/file-upload/index.d.mts +3 -0
- package/dist/src/file-upload/index.d.ts +3 -0
- package/dist/src/form-field/index.d.mts +3 -0
- package/dist/src/form-field/index.d.ts +3 -0
- package/dist/src/icon/Icon.d.ts +3 -0
- package/dist/src/icon-button/IconButton.d.ts +3 -0
- package/dist/src/input/Input.d.ts +3 -0
- package/dist/src/input/index.d.mts +4 -0
- package/dist/src/input/index.d.ts +4 -0
- package/dist/src/input-otp/index.d.mts +3 -0
- package/dist/src/input-otp/index.d.ts +3 -0
- package/dist/src/kbd/Kbd.d.ts +3 -0
- package/dist/src/label/index.d.mts +3 -0
- package/dist/src/label/index.d.ts +3 -0
- package/dist/src/link-box/index.d.mts +3 -0
- package/dist/src/link-box/index.d.ts +3 -0
- package/dist/src/meter/index.d.mts +3 -0
- package/dist/src/meter/index.d.ts +3 -0
- package/dist/src/pagination/index.d.mts +3 -0
- package/dist/src/pagination/index.d.ts +3 -0
- package/dist/src/popover/index.d.mts +3 -0
- package/dist/src/popover/index.d.ts +3 -0
- package/dist/src/portal/Portal.d.ts +3 -0
- package/dist/src/progress/index.d.mts +3 -0
- package/dist/src/progress/index.d.ts +3 -0
- package/dist/src/progress-tracker/index.d.mts +3 -0
- package/dist/src/progress-tracker/index.d.ts +3 -0
- package/dist/src/radio-group/index.d.mts +3 -0
- package/dist/src/radio-group/index.d.ts +3 -0
- package/dist/src/rating/Rating.d.ts +3 -0
- package/dist/src/rating-display/index.d.mts +3 -0
- package/dist/src/rating-display/index.d.ts +3 -0
- package/dist/src/scrolling-list/index.d.mts +3 -0
- package/dist/src/scrolling-list/index.d.ts +3 -0
- package/dist/src/segmented-control/index.d.mts +3 -0
- package/dist/src/segmented-control/index.d.ts +3 -0
- package/dist/src/segmented-gauge/index.d.mts +3 -0
- package/dist/src/segmented-gauge/index.d.ts +3 -0
- package/dist/src/select/index.d.mts +3 -0
- package/dist/src/select/index.d.ts +3 -0
- package/dist/src/skeleton/index.d.mts +3 -0
- package/dist/src/skeleton/index.d.ts +3 -0
- package/dist/src/slider/index.d.mts +3 -0
- package/dist/src/slider/index.d.ts +3 -0
- package/dist/src/slot/Slot.d.ts +4 -0
- package/dist/src/spinner/Spinner.d.ts +3 -0
- package/dist/src/stepper/index.d.mts +3 -0
- package/dist/src/stepper/index.d.ts +3 -0
- package/dist/src/switch/Switch.d.ts +3 -0
- package/dist/src/table/index.d.mts +6 -2
- package/dist/src/table/index.d.ts +6 -2
- package/dist/src/table/internal/TableRootWrapper.d.ts +3 -0
- package/dist/src/tabs/index.d.mts +3 -0
- package/dist/src/tabs/index.d.ts +3 -0
- package/dist/src/tag/Tag.d.ts +3 -0
- package/dist/src/text-link/TextLink.d.ts +3 -0
- package/dist/src/textarea/Textarea.d.ts +3 -0
- package/dist/src/textarea/index.d.mts +4 -0
- package/dist/src/textarea/index.d.ts +4 -0
- package/dist/src/toast/index.d.mts +3 -0
- package/dist/src/toast/index.d.ts +3 -0
- package/dist/src/visually-hidden/VisuallyHidden.d.ts +3 -0
- package/dist/stepper/index.js.map +1 -1
- package/dist/stepper/index.mjs.map +1 -1
- package/dist/switch/index.js.map +1 -1
- package/dist/switch/index.mjs.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table/index.js.map +1 -1
- package/dist/table/index.mjs +1 -1
- package/dist/table/index.mjs.map +1 -1
- package/dist/tabs/index.js.map +1 -1
- package/dist/tabs/index.mjs.map +1 -1
- package/dist/tag/index.js.map +1 -1
- package/dist/tag/index.mjs.map +1 -1
- package/dist/text-link/index.js.map +1 -1
- package/dist/text-link/index.mjs.map +1 -1
- package/dist/textarea/index.js.map +1 -1
- package/dist/textarea/index.mjs.map +1 -1
- package/dist/toast/index.js.map +1 -1
- package/dist/toast/index.mjs.map +1 -1
- package/dist/visually-hidden/index.js.map +1 -1
- package/dist/visually-hidden/index.mjs.map +1 -1
- package/package.json +16 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/circular-meter/CircularMeter.styles.ts","../../src/circular-meter/CircularMeterContext.tsx","../../src/circular-meter/CircularMeter.tsx","../../src/circular-meter/CircularMeterContent.tsx","../../src/circular-meter/useIntersectionAnimation.ts","../../src/circular-meter/CircularMeterTrack.tsx","../../src/circular-meter/CircularMeterLabel.tsx","../../src/circular-meter/CircularMeterValue.tsx","../../src/circular-meter/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const circularMeterStyles = cva(['focus-visible:u-outline gap-md flex items-center'], {\n variants: {\n orientation: {\n vertical: ['default:flex-col'],\n horizontal: ['default:flex-row'],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport type CircularMeterStylesProps = VariantProps<typeof circularMeterStyles>\n","import { createContext, useContext } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { CircularMeterSize } from './CircularMeter'\n\nexport interface CircularMeterContextValue {\n value: number\n max: number\n min: number\n intent: MeterIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n /**\n * Size variant of the circular meter.\n */\n sizeProp: CircularMeterSize\n /**\n * Orientation of the circular meter.\n */\n orientation: 'vertical' | 'horizontal'\n /**\n * Diameter of the SVG circle in pixels.\n */\n size: number\n /**\n * Radius of the SVG circle in pixels.\n */\n radius: number\n /**\n * Circumference of the SVG circle in pixels.\n */\n circumference: number\n /**\n * Stroke width of the SVG circle in pixels.\n */\n strokeWidth: number\n}\n\nexport const CircularMeterContext = createContext<CircularMeterContextValue | null>(null)\n\nexport const ID_PREFIX = ':circular-meter'\n\nexport const useCircularMeter = () => {\n const context = useContext(CircularMeterContext)\n\n if (!context) {\n throw new Error('useCircularMeter must be used within a CircularMeter provider')\n }\n\n return context\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { circularMeterStyles, CircularMeterStylesProps } from './CircularMeter.styles'\nimport { CircularMeterContext } from './CircularMeterContext'\n\nexport type CircularMeterSize = 'sm' | 'md' | 'lg' | 'xl'\n\nconst CIRCULAR_METER_SIZE_CONFIG: Record<\n CircularMeterSize,\n { diameter: number; strokeWidth: number }\n> = {\n sm: { diameter: 24, strokeWidth: 4 },\n md: { diameter: 64, strokeWidth: 8 },\n lg: { diameter: 96, strokeWidth: 8 },\n xl: { diameter: 128, strokeWidth: 8 },\n}\n\nexport interface CircularMeterProps\n extends\n Omit<ComponentProps<typeof BaseMeter.Root>, 'render'>,\n Pick<MeterIndicatorStylesProps, 'intent'>,\n CircularMeterStylesProps {\n /**\n * Size of the circle.\n *\n * - `sm`: 24px diameter, 4px stroke width\n * - `md`: 64px diameter, 8px stroke width\n * - `lg`: 96px diameter, 8px stroke width\n * - `xl`: 128px diameter, 8px stroke width\n *\n * Defaults to `md`.\n */\n size?: CircularMeterSize\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n /**\n * Orientation of the circular meter.\n *\n * - `vertical`: Elements are stacked vertically (default)\n * - `horizontal`: Elements are arranged horizontally\n */\n orientation?: 'vertical' | 'horizontal'\n}\n\nexport const CircularMeter = ({\n className,\n value,\n max = 100,\n min = 0,\n size: sizeProp = 'lg',\n intent = 'support',\n orientation = 'vertical',\n children,\n ref,\n ...others\n}: PropsWithChildren<CircularMeterProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const { diameter: size, strokeWidth } = CIRCULAR_METER_SIZE_CONFIG[sizeProp]\n\n const radius = size / 2 - strokeWidth / 2\n const circumference = 2 * Math.PI * radius\n\n const contextValue = useMemo(() => {\n return {\n value: value ?? 0,\n max,\n min,\n intent,\n onLabelId: setLabelId,\n sizeProp,\n orientation: orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n }\n }, [\n max,\n min,\n value,\n intent,\n setLabelId,\n sizeProp,\n orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n ])\n\n return (\n <CircularMeterContext.Provider value={contextValue}>\n <BaseMeter.Root\n data-spark-component=\"circular-meter\"\n ref={ref}\n className={cx(circularMeterStyles({ orientation }), className)}\n style={others.style}\n value={value}\n max={max}\n min={min}\n aria-labelledby={labelId}\n {...others}\n >\n {children}\n </BaseMeter.Root>\n </CircularMeterContext.Provider>\n )\n}\n\nCircularMeter.displayName = 'CircularMeter'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\n\nexport type CircularMeterContentProps = ComponentProps<'div'> & PropsWithChildren\n\nexport const CircularMeterContent = ({\n className,\n children,\n ...others\n}: CircularMeterContentProps) => {\n const { orientation } = useCircularMeter()\n\n return (\n <div\n data-spark-component=\"circular-meter-content\"\n className={cx(\n 'gap-xs flex default:flex-col',\n orientation === 'vertical' && 'default:text-center',\n className\n )}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nCircularMeterContent.displayName = 'CircularMeter.Content'\n","import { RefObject, useEffect, useRef } from 'react'\n\nexport interface UseIntersectionAnimationOptions {\n /**\n * The threshold at which the callback should be triggered.\n * A value of 0 means as soon as any part of the element is visible.\n * A value of 1 means the entire element must be visible.\n * @default 0.1\n */\n threshold?: number\n /**\n * The root margin for the Intersection Observer.\n * This can be used to trigger the animation before the element enters the viewport.\n * @default undefined\n */\n rootMargin?: string\n}\n\n/**\n * Hook to trigger an animation callback when an element enters the viewport.\n * The callback is only triggered once, when the element first becomes visible.\n *\n * @param elementRef - Reference to the element to observe\n * @param onIntersect - Callback to execute when the element enters the viewport\n * @param options - Configuration options for the Intersection Observer\n * @returns Whether the animation has been triggered\n */\nexport function useIntersectionAnimation(\n elementRef: RefObject<Element | null>,\n onIntersect: () => void,\n options: UseIntersectionAnimationOptions = {}\n): boolean {\n const { threshold = 0.1, rootMargin } = options\n const hasTriggeredRef = useRef(false)\n const callbackRef = useRef(onIntersect)\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = onIntersect\n }, [onIntersect])\n\n useEffect(() => {\n const element = elementRef.current\n if (!element || hasTriggeredRef.current) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !hasTriggeredRef.current) {\n // Use requestAnimationFrame to ensure the callback runs at the right time\n requestAnimationFrame(() => {\n if (!hasTriggeredRef.current) {\n hasTriggeredRef.current = true\n callbackRef.current()\n // Disconnect observer after callback is triggered (only trigger once)\n observer.disconnect()\n }\n })\n }\n })\n },\n {\n threshold,\n rootMargin,\n }\n )\n\n observer.observe(element)\n\n return () => {\n observer.disconnect()\n }\n }, [elementRef, threshold, rootMargin])\n\n return hasTriggeredRef.current\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva, cx } from 'class-variance-authority'\nimport {\n ComponentProps,\n createContext,\n PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useIntersectionAnimation } from './useIntersectionAnimation'\n\nconst CircularMeterTrackContext = createContext<boolean>(false)\n\nexport const useCircularMeterTrack = () => {\n return useContext(CircularMeterTrackContext)\n}\n\nexport type CircularMeterTrackProps = Omit<ComponentProps<typeof BaseMeter.Track>, 'render'> &\n PropsWithChildren\n\nconst circularMeterTrackStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main/dim-4'],\n support: ['text-support/dim-4'],\n success: ['text-success/dim-4'],\n alert: ['text-alert/dim-4'],\n danger: ['text-error/dim-4'],\n info: ['text-info/dim-4'],\n },\n },\n})\n\nconst circularMeterIndicatorStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main'],\n support: ['text-support'],\n success: ['text-success'],\n alert: ['text-alert'],\n danger: ['text-error'],\n info: ['text-info'],\n },\n },\n})\n\nexport const CircularMeterTrack = ({ className, children, ...others }: CircularMeterTrackProps) => {\n const { value, max, min, intent, size, radius, circumference, strokeWidth } = useCircularMeter()\n const percentage = ((value - min) / (max - min)) * 100\n const offset = circumference - (percentage / 100) * circumference\n\n const intentClasses = circularMeterIndicatorStyles({ intent })\n const svgRef = useRef<SVGSVGElement>(null)\n const [hasAnimated, setHasAnimated] = useState(false)\n\n // Trigger animation when component enters viewport\n useIntersectionAnimation(svgRef, () => {\n setHasAnimated(true)\n })\n\n return (\n <BaseMeter.Track data-spark-component=\"circular-meter-track\" className={className} {...others}>\n <CircularMeterTrackContext.Provider value={true}>\n <svg ref={svgRef} width={size} height={size} viewBox={`0 0 ${size} ${size}`}>\n <g style={{ transform: 'rotate(-90deg)', transformOrigin: 'center' }}>\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className={circularMeterTrackStyles({ intent })}\n />\n <circle\n data-spark-component=\"circular-meter-indicator\"\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={cx(\n intentClasses,\n 'ease-standard transition-[stroke-dashoffset] duration-700',\n 'motion-reduce:transition-none'\n )}\n style={\n {\n strokeDasharray: circumference,\n // Start at circumference (0% filled) for initial animation, then use offset for subsequent changes\n strokeDashoffset: hasAnimated ? offset : circumference,\n } as React.CSSProperties\n }\n />\n </g>\n {children && (\n <foreignObject x={8} y={8} width={size - 16} height={size - 16}>\n <div\n className=\"p-md flex h-full w-full flex-col items-center justify-center rounded-full text-center\"\n style={{ width: size - 16, height: size - 16 }}\n >\n {children}\n </div>\n </foreignObject>\n )}\n </svg>\n </CircularMeterTrackContext.Provider>\n </BaseMeter.Track>\n )\n}\n\nCircularMeterTrack.displayName = 'CircularMeter.Track'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterLabelProps = Omit<ComponentProps<typeof BaseMeter.Label>, 'render'>\n\nconst labelStyles = cva([], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: ['default:text-on-surface/dim-1'],\n false: ['default:text-on-surface'],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-small' },\n { size: 'md', inside: true, class: 'default:text-small ' },\n { size: 'lg', inside: true, class: 'default:text-caption' },\n { size: 'xl', inside: true, class: 'default:text-body-2' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1' },\n { size: 'md', inside: false, class: 'default:text-body-1' },\n { size: 'lg', inside: false, class: 'default:text-body-1' },\n { size: 'xl', inside: false, class: 'default:text-body-1' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterLabel = ({\n id: idProp,\n children,\n className,\n ref: forwardedRef,\n ...others\n}: CircularMeterLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId, sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <BaseMeter.Label\n data-spark-component=\"circular-meter-label\"\n id={id}\n className={labelStyles({ size: sizeProp, inside: isInside, className })}\n ref={ref}\n {...others}\n >\n {children}\n </BaseMeter.Label>\n )\n}\n\nCircularMeterLabel.displayName = 'CircularMeter.Label'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterValueProps = Omit<ComponentProps<typeof BaseMeter.Value>, 'render'>\n\nconst valueStyles = cva(['default:text-on-surface default:font-bold'], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: [],\n false: [],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'md', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'lg', inside: true, class: 'default:text-body-1 default:font-bold' },\n { size: 'xl', inside: true, class: 'default:text-display-3' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1 default:font-bold' },\n { size: 'md', inside: false, class: 'default:text-headline-2' },\n { size: 'lg', inside: false, class: 'default:text-headline-2' },\n { size: 'xl', inside: false, class: 'default:text-display-3' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterValue = ({\n className,\n children,\n ...others\n}: PropsWithChildren<CircularMeterValueProps>) => {\n const { sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n\n return (\n <BaseMeter.Value\n data-spark-component=\"circular-meter-value\"\n className={valueStyles({ size: sizeProp, inside: isInside, className })}\n {...others}\n >\n {children}\n </BaseMeter.Value>\n )\n}\n\nCircularMeterValue.displayName = 'CircularMeter.Value'\n","import { CircularMeter as Root } from './CircularMeter'\nimport { CircularMeterContent } from './CircularMeterContent'\nimport { CircularMeterLabel } from './CircularMeterLabel'\nimport { CircularMeterTrack } from './CircularMeterTrack'\nimport { CircularMeterValue } from './CircularMeterValue'\n\nexport const CircularMeter: typeof Root & {\n Content: typeof CircularMeterContent\n Label: typeof CircularMeterLabel\n Track: typeof CircularMeterTrack\n Value: typeof CircularMeterValue\n} = Object.assign(Root, {\n Content: CircularMeterContent,\n Label: CircularMeterLabel,\n Track: CircularMeterTrack,\n Value: CircularMeterValue,\n})\n\nCircularMeter.displayName = 'CircularMeter'\nCircularMeterContent.displayName = 'CircularMeter.Content'\nCircularMeterLabel.displayName = 'CircularMeter.Label'\nCircularMeterTrack.displayName = 'CircularMeter.Track'\nCircularMeterValue.displayName = 'CircularMeter.Value'\n\nexport { type CircularMeterProps } from './CircularMeter'\nexport { type CircularMeterContentProps } from './CircularMeterContent'\nexport { type CircularMeterLabelProps } from './CircularMeterLabel'\nexport { type CircularMeterTrackProps } from './CircularMeterTrack'\nexport { type CircularMeterValueProps } from './CircularMeterValue'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/circular-meter/CircularMeter.styles.ts","../../src/circular-meter/CircularMeterContext.tsx","../../src/circular-meter/CircularMeter.tsx","../../src/circular-meter/CircularMeterContent.tsx","../../src/circular-meter/useIntersectionAnimation.ts","../../src/circular-meter/CircularMeterTrack.tsx","../../src/circular-meter/CircularMeterLabel.tsx","../../src/circular-meter/CircularMeterValue.tsx","../../src/circular-meter/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const circularMeterStyles = cva(['focus-visible:u-outline gap-md flex items-center'], {\n variants: {\n orientation: {\n vertical: ['default:flex-col'],\n horizontal: ['default:flex-row'],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport type CircularMeterStylesProps = VariantProps<typeof circularMeterStyles>\n","import { createContext, useContext } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { CircularMeterSize } from './CircularMeter'\n\nexport interface CircularMeterContextValue {\n value: number\n max: number\n min: number\n intent: MeterIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n /**\n * Size variant of the circular meter.\n */\n sizeProp: CircularMeterSize\n /**\n * Orientation of the circular meter.\n */\n orientation: 'vertical' | 'horizontal'\n /**\n * Diameter of the SVG circle in pixels.\n */\n size: number\n /**\n * Radius of the SVG circle in pixels.\n */\n radius: number\n /**\n * Circumference of the SVG circle in pixels.\n */\n circumference: number\n /**\n * Stroke width of the SVG circle in pixels.\n */\n strokeWidth: number\n}\n\nexport const CircularMeterContext = createContext<CircularMeterContextValue | null>(null)\n\nexport const ID_PREFIX = ':circular-meter'\n\nexport const useCircularMeter = () => {\n const context = useContext(CircularMeterContext)\n\n if (!context) {\n throw new Error('useCircularMeter must be used within a CircularMeter provider')\n }\n\n return context\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { circularMeterStyles, CircularMeterStylesProps } from './CircularMeter.styles'\nimport { CircularMeterContext } from './CircularMeterContext'\n\nexport type CircularMeterSize = 'sm' | 'md' | 'lg' | 'xl'\n\nconst CIRCULAR_METER_SIZE_CONFIG: Record<\n CircularMeterSize,\n { diameter: number; strokeWidth: number }\n> = {\n sm: { diameter: 24, strokeWidth: 4 },\n md: { diameter: 64, strokeWidth: 8 },\n lg: { diameter: 96, strokeWidth: 8 },\n xl: { diameter: 128, strokeWidth: 8 },\n}\n\nexport interface CircularMeterProps\n extends\n Omit<ComponentProps<typeof BaseMeter.Root>, 'render'>,\n Pick<MeterIndicatorStylesProps, 'intent'>,\n CircularMeterStylesProps {\n /**\n * Size of the circle.\n *\n * - `sm`: 24px diameter, 4px stroke width\n * - `md`: 64px diameter, 8px stroke width\n * - `lg`: 96px diameter, 8px stroke width\n * - `xl`: 128px diameter, 8px stroke width\n *\n * Defaults to `md`.\n */\n size?: CircularMeterSize\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n /**\n * Orientation of the circular meter.\n *\n * - `vertical`: Elements are stacked vertically (default)\n * - `horizontal`: Elements are arranged horizontally\n */\n orientation?: 'vertical' | 'horizontal'\n}\n\nexport const CircularMeter = ({\n className,\n value,\n max = 100,\n min = 0,\n size: sizeProp = 'lg',\n intent = 'support',\n orientation = 'vertical',\n children,\n ref,\n ...others\n}: PropsWithChildren<CircularMeterProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const { diameter: size, strokeWidth } = CIRCULAR_METER_SIZE_CONFIG[sizeProp]\n\n const radius = size / 2 - strokeWidth / 2\n const circumference = 2 * Math.PI * radius\n\n const contextValue = useMemo(() => {\n return {\n value: value ?? 0,\n max,\n min,\n intent,\n onLabelId: setLabelId,\n sizeProp,\n orientation: orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n }\n }, [\n max,\n min,\n value,\n intent,\n setLabelId,\n sizeProp,\n orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n ])\n\n return (\n <CircularMeterContext.Provider value={contextValue}>\n <BaseMeter.Root\n data-spark-component=\"circular-meter\"\n ref={ref}\n className={cx(circularMeterStyles({ orientation }), className)}\n style={others.style}\n value={value}\n max={max}\n min={min}\n aria-labelledby={labelId}\n {...others}\n >\n {children}\n </BaseMeter.Root>\n </CircularMeterContext.Provider>\n )\n}\n\nCircularMeter.displayName = 'CircularMeter'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\n\nexport type CircularMeterContentProps = ComponentProps<'div'> & PropsWithChildren\n\nexport const CircularMeterContent = ({\n className,\n children,\n ...others\n}: CircularMeterContentProps) => {\n const { orientation } = useCircularMeter()\n\n return (\n <div\n data-spark-component=\"circular-meter-content\"\n className={cx(\n 'gap-xs flex default:flex-col',\n orientation === 'vertical' && 'default:text-center',\n className\n )}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nCircularMeterContent.displayName = 'CircularMeter.Content'\n","import { RefObject, useEffect, useRef } from 'react'\n\nexport interface UseIntersectionAnimationOptions {\n /**\n * The threshold at which the callback should be triggered.\n * A value of 0 means as soon as any part of the element is visible.\n * A value of 1 means the entire element must be visible.\n * @default 0.1\n */\n threshold?: number\n /**\n * The root margin for the Intersection Observer.\n * This can be used to trigger the animation before the element enters the viewport.\n * @default undefined\n */\n rootMargin?: string\n}\n\n/**\n * Hook to trigger an animation callback when an element enters the viewport.\n * The callback is only triggered once, when the element first becomes visible.\n *\n * @param elementRef - Reference to the element to observe\n * @param onIntersect - Callback to execute when the element enters the viewport\n * @param options - Configuration options for the Intersection Observer\n * @returns Whether the animation has been triggered\n */\nexport function useIntersectionAnimation(\n elementRef: RefObject<Element | null>,\n onIntersect: () => void,\n options: UseIntersectionAnimationOptions = {}\n): boolean {\n const { threshold = 0.1, rootMargin } = options\n const hasTriggeredRef = useRef(false)\n const callbackRef = useRef(onIntersect)\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = onIntersect\n }, [onIntersect])\n\n useEffect(() => {\n const element = elementRef.current\n if (!element || hasTriggeredRef.current) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !hasTriggeredRef.current) {\n // Use requestAnimationFrame to ensure the callback runs at the right time\n requestAnimationFrame(() => {\n if (!hasTriggeredRef.current) {\n hasTriggeredRef.current = true\n callbackRef.current()\n // Disconnect observer after callback is triggered (only trigger once)\n observer.disconnect()\n }\n })\n }\n })\n },\n {\n threshold,\n rootMargin,\n }\n )\n\n observer.observe(element)\n\n return () => {\n observer.disconnect()\n }\n }, [elementRef, threshold, rootMargin])\n\n return hasTriggeredRef.current\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva, cx } from 'class-variance-authority'\nimport {\n ComponentProps,\n createContext,\n PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useIntersectionAnimation } from './useIntersectionAnimation'\n\nconst CircularMeterTrackContext = createContext<boolean>(false)\n\nexport const useCircularMeterTrack = () => {\n return useContext(CircularMeterTrackContext)\n}\n\nexport type CircularMeterTrackProps = Omit<ComponentProps<typeof BaseMeter.Track>, 'render'> &\n PropsWithChildren\n\nconst circularMeterTrackStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main/dim-4'],\n support: ['text-support/dim-4'],\n success: ['text-success/dim-4'],\n alert: ['text-alert/dim-4'],\n danger: ['text-error/dim-4'],\n info: ['text-info/dim-4'],\n },\n },\n})\n\nconst circularMeterIndicatorStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main'],\n support: ['text-support'],\n success: ['text-success'],\n alert: ['text-alert'],\n danger: ['text-error'],\n info: ['text-info'],\n },\n },\n})\n\nexport const CircularMeterTrack = ({ className, children, ...others }: CircularMeterTrackProps) => {\n const { value, max, min, intent, size, radius, circumference, strokeWidth } = useCircularMeter()\n const percentage = ((value - min) / (max - min)) * 100\n const offset = circumference - (percentage / 100) * circumference\n\n const intentClasses = circularMeterIndicatorStyles({ intent })\n const svgRef = useRef<SVGSVGElement>(null)\n const [hasAnimated, setHasAnimated] = useState(false)\n\n // Trigger animation when component enters viewport\n useIntersectionAnimation(svgRef, () => {\n setHasAnimated(true)\n })\n\n return (\n <BaseMeter.Track data-spark-component=\"circular-meter-track\" className={className} {...others}>\n <CircularMeterTrackContext.Provider value={true}>\n <svg ref={svgRef} width={size} height={size} viewBox={`0 0 ${size} ${size}`}>\n <g style={{ transform: 'rotate(-90deg)', transformOrigin: 'center' }}>\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className={circularMeterTrackStyles({ intent })}\n />\n <circle\n data-spark-component=\"circular-meter-indicator\"\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={cx(\n intentClasses,\n 'ease-standard transition-[stroke-dashoffset] duration-700',\n 'motion-reduce:transition-none'\n )}\n style={\n {\n strokeDasharray: circumference,\n // Start at circumference (0% filled) for initial animation, then use offset for subsequent changes\n strokeDashoffset: hasAnimated ? offset : circumference,\n } as React.CSSProperties\n }\n />\n </g>\n {children && (\n <foreignObject x={8} y={8} width={size - 16} height={size - 16}>\n <div\n className=\"p-md flex h-full w-full flex-col items-center justify-center rounded-full text-center\"\n style={{ width: size - 16, height: size - 16 }}\n >\n {children}\n </div>\n </foreignObject>\n )}\n </svg>\n </CircularMeterTrackContext.Provider>\n </BaseMeter.Track>\n )\n}\n\nCircularMeterTrack.displayName = 'CircularMeter.Track'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterLabelProps = Omit<ComponentProps<typeof BaseMeter.Label>, 'render'>\n\nconst labelStyles = cva([], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: ['default:text-on-surface/dim-1'],\n false: ['default:text-on-surface'],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-small' },\n { size: 'md', inside: true, class: 'default:text-small ' },\n { size: 'lg', inside: true, class: 'default:text-caption' },\n { size: 'xl', inside: true, class: 'default:text-body-2' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1' },\n { size: 'md', inside: false, class: 'default:text-body-1' },\n { size: 'lg', inside: false, class: 'default:text-body-1' },\n { size: 'xl', inside: false, class: 'default:text-body-1' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterLabel = ({\n id: idProp,\n children,\n className,\n ref: forwardedRef,\n ...others\n}: CircularMeterLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId, sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <BaseMeter.Label\n data-spark-component=\"circular-meter-label\"\n id={id}\n className={labelStyles({ size: sizeProp, inside: isInside, className })}\n ref={ref}\n {...others}\n >\n {children}\n </BaseMeter.Label>\n )\n}\n\nCircularMeterLabel.displayName = 'CircularMeter.Label'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterValueProps = Omit<ComponentProps<typeof BaseMeter.Value>, 'render'>\n\nconst valueStyles = cva(['default:text-on-surface default:font-bold'], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: [],\n false: [],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'md', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'lg', inside: true, class: 'default:text-body-1 default:font-bold' },\n { size: 'xl', inside: true, class: 'default:text-display-3' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1 default:font-bold' },\n { size: 'md', inside: false, class: 'default:text-headline-2' },\n { size: 'lg', inside: false, class: 'default:text-headline-2' },\n { size: 'xl', inside: false, class: 'default:text-display-3' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterValue = ({\n className,\n children,\n ...others\n}: PropsWithChildren<CircularMeterValueProps>) => {\n const { sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n\n return (\n <BaseMeter.Value\n data-spark-component=\"circular-meter-value\"\n className={valueStyles({ size: sizeProp, inside: isInside, className })}\n {...others}\n >\n {children}\n </BaseMeter.Value>\n )\n}\n\nCircularMeterValue.displayName = 'CircularMeter.Value'\n","import { CircularMeter as Root } from './CircularMeter'\nimport { CircularMeterContent } from './CircularMeterContent'\nimport { CircularMeterLabel } from './CircularMeterLabel'\nimport { CircularMeterTrack } from './CircularMeterTrack'\nimport { CircularMeterValue } from './CircularMeterValue'\n\n/**\n * A circular progress indicator that displays a value within a defined range.\n */\nexport const CircularMeter: typeof Root & {\n Content: typeof CircularMeterContent\n Label: typeof CircularMeterLabel\n Track: typeof CircularMeterTrack\n Value: typeof CircularMeterValue\n} = Object.assign(Root, {\n Content: CircularMeterContent,\n Label: CircularMeterLabel,\n Track: CircularMeterTrack,\n Value: CircularMeterValue,\n})\n\nCircularMeter.displayName = 'CircularMeter'\nCircularMeterContent.displayName = 'CircularMeter.Content'\nCircularMeterLabel.displayName = 'CircularMeter.Label'\nCircularMeterTrack.displayName = 'CircularMeter.Track'\nCircularMeterValue.displayName = 'CircularMeter.Value'\n\nexport { type CircularMeterProps } from './CircularMeter'\nexport { type CircularMeterContentProps } from './CircularMeterContent'\nexport { type CircularMeterLabelProps } from './CircularMeterLabel'\nexport { type CircularMeterTrackProps } from './CircularMeterTrack'\nexport { type CircularMeterValueProps } from './CircularMeterValue'\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/circular-meter/CircularMeter.styles.ts","../../src/circular-meter/CircularMeterContext.tsx","../../src/circular-meter/CircularMeter.tsx","../../src/circular-meter/CircularMeterContent.tsx","../../src/circular-meter/useIntersectionAnimation.ts","../../src/circular-meter/CircularMeterTrack.tsx","../../src/circular-meter/CircularMeterLabel.tsx","../../src/circular-meter/CircularMeterValue.tsx","../../src/circular-meter/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const circularMeterStyles = cva(['focus-visible:u-outline gap-md flex items-center'], {\n variants: {\n orientation: {\n vertical: ['default:flex-col'],\n horizontal: ['default:flex-row'],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport type CircularMeterStylesProps = VariantProps<typeof circularMeterStyles>\n","import { createContext, useContext } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { CircularMeterSize } from './CircularMeter'\n\nexport interface CircularMeterContextValue {\n value: number\n max: number\n min: number\n intent: MeterIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n /**\n * Size variant of the circular meter.\n */\n sizeProp: CircularMeterSize\n /**\n * Orientation of the circular meter.\n */\n orientation: 'vertical' | 'horizontal'\n /**\n * Diameter of the SVG circle in pixels.\n */\n size: number\n /**\n * Radius of the SVG circle in pixels.\n */\n radius: number\n /**\n * Circumference of the SVG circle in pixels.\n */\n circumference: number\n /**\n * Stroke width of the SVG circle in pixels.\n */\n strokeWidth: number\n}\n\nexport const CircularMeterContext = createContext<CircularMeterContextValue | null>(null)\n\nexport const ID_PREFIX = ':circular-meter'\n\nexport const useCircularMeter = () => {\n const context = useContext(CircularMeterContext)\n\n if (!context) {\n throw new Error('useCircularMeter must be used within a CircularMeter provider')\n }\n\n return context\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { circularMeterStyles, CircularMeterStylesProps } from './CircularMeter.styles'\nimport { CircularMeterContext } from './CircularMeterContext'\n\nexport type CircularMeterSize = 'sm' | 'md' | 'lg' | 'xl'\n\nconst CIRCULAR_METER_SIZE_CONFIG: Record<\n CircularMeterSize,\n { diameter: number; strokeWidth: number }\n> = {\n sm: { diameter: 24, strokeWidth: 4 },\n md: { diameter: 64, strokeWidth: 8 },\n lg: { diameter: 96, strokeWidth: 8 },\n xl: { diameter: 128, strokeWidth: 8 },\n}\n\nexport interface CircularMeterProps\n extends\n Omit<ComponentProps<typeof BaseMeter.Root>, 'render'>,\n Pick<MeterIndicatorStylesProps, 'intent'>,\n CircularMeterStylesProps {\n /**\n * Size of the circle.\n *\n * - `sm`: 24px diameter, 4px stroke width\n * - `md`: 64px diameter, 8px stroke width\n * - `lg`: 96px diameter, 8px stroke width\n * - `xl`: 128px diameter, 8px stroke width\n *\n * Defaults to `md`.\n */\n size?: CircularMeterSize\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n /**\n * Orientation of the circular meter.\n *\n * - `vertical`: Elements are stacked vertically (default)\n * - `horizontal`: Elements are arranged horizontally\n */\n orientation?: 'vertical' | 'horizontal'\n}\n\nexport const CircularMeter = ({\n className,\n value,\n max = 100,\n min = 0,\n size: sizeProp = 'lg',\n intent = 'support',\n orientation = 'vertical',\n children,\n ref,\n ...others\n}: PropsWithChildren<CircularMeterProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const { diameter: size, strokeWidth } = CIRCULAR_METER_SIZE_CONFIG[sizeProp]\n\n const radius = size / 2 - strokeWidth / 2\n const circumference = 2 * Math.PI * radius\n\n const contextValue = useMemo(() => {\n return {\n value: value ?? 0,\n max,\n min,\n intent,\n onLabelId: setLabelId,\n sizeProp,\n orientation: orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n }\n }, [\n max,\n min,\n value,\n intent,\n setLabelId,\n sizeProp,\n orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n ])\n\n return (\n <CircularMeterContext.Provider value={contextValue}>\n <BaseMeter.Root\n data-spark-component=\"circular-meter\"\n ref={ref}\n className={cx(circularMeterStyles({ orientation }), className)}\n style={others.style}\n value={value}\n max={max}\n min={min}\n aria-labelledby={labelId}\n {...others}\n >\n {children}\n </BaseMeter.Root>\n </CircularMeterContext.Provider>\n )\n}\n\nCircularMeter.displayName = 'CircularMeter'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\n\nexport type CircularMeterContentProps = ComponentProps<'div'> & PropsWithChildren\n\nexport const CircularMeterContent = ({\n className,\n children,\n ...others\n}: CircularMeterContentProps) => {\n const { orientation } = useCircularMeter()\n\n return (\n <div\n data-spark-component=\"circular-meter-content\"\n className={cx(\n 'gap-xs flex default:flex-col',\n orientation === 'vertical' && 'default:text-center',\n className\n )}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nCircularMeterContent.displayName = 'CircularMeter.Content'\n","import { RefObject, useEffect, useRef } from 'react'\n\nexport interface UseIntersectionAnimationOptions {\n /**\n * The threshold at which the callback should be triggered.\n * A value of 0 means as soon as any part of the element is visible.\n * A value of 1 means the entire element must be visible.\n * @default 0.1\n */\n threshold?: number\n /**\n * The root margin for the Intersection Observer.\n * This can be used to trigger the animation before the element enters the viewport.\n * @default undefined\n */\n rootMargin?: string\n}\n\n/**\n * Hook to trigger an animation callback when an element enters the viewport.\n * The callback is only triggered once, when the element first becomes visible.\n *\n * @param elementRef - Reference to the element to observe\n * @param onIntersect - Callback to execute when the element enters the viewport\n * @param options - Configuration options for the Intersection Observer\n * @returns Whether the animation has been triggered\n */\nexport function useIntersectionAnimation(\n elementRef: RefObject<Element | null>,\n onIntersect: () => void,\n options: UseIntersectionAnimationOptions = {}\n): boolean {\n const { threshold = 0.1, rootMargin } = options\n const hasTriggeredRef = useRef(false)\n const callbackRef = useRef(onIntersect)\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = onIntersect\n }, [onIntersect])\n\n useEffect(() => {\n const element = elementRef.current\n if (!element || hasTriggeredRef.current) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !hasTriggeredRef.current) {\n // Use requestAnimationFrame to ensure the callback runs at the right time\n requestAnimationFrame(() => {\n if (!hasTriggeredRef.current) {\n hasTriggeredRef.current = true\n callbackRef.current()\n // Disconnect observer after callback is triggered (only trigger once)\n observer.disconnect()\n }\n })\n }\n })\n },\n {\n threshold,\n rootMargin,\n }\n )\n\n observer.observe(element)\n\n return () => {\n observer.disconnect()\n }\n }, [elementRef, threshold, rootMargin])\n\n return hasTriggeredRef.current\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva, cx } from 'class-variance-authority'\nimport {\n ComponentProps,\n createContext,\n PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useIntersectionAnimation } from './useIntersectionAnimation'\n\nconst CircularMeterTrackContext = createContext<boolean>(false)\n\nexport const useCircularMeterTrack = () => {\n return useContext(CircularMeterTrackContext)\n}\n\nexport type CircularMeterTrackProps = Omit<ComponentProps<typeof BaseMeter.Track>, 'render'> &\n PropsWithChildren\n\nconst circularMeterTrackStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main/dim-4'],\n support: ['text-support/dim-4'],\n success: ['text-success/dim-4'],\n alert: ['text-alert/dim-4'],\n danger: ['text-error/dim-4'],\n info: ['text-info/dim-4'],\n },\n },\n})\n\nconst circularMeterIndicatorStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main'],\n support: ['text-support'],\n success: ['text-success'],\n alert: ['text-alert'],\n danger: ['text-error'],\n info: ['text-info'],\n },\n },\n})\n\nexport const CircularMeterTrack = ({ className, children, ...others }: CircularMeterTrackProps) => {\n const { value, max, min, intent, size, radius, circumference, strokeWidth } = useCircularMeter()\n const percentage = ((value - min) / (max - min)) * 100\n const offset = circumference - (percentage / 100) * circumference\n\n const intentClasses = circularMeterIndicatorStyles({ intent })\n const svgRef = useRef<SVGSVGElement>(null)\n const [hasAnimated, setHasAnimated] = useState(false)\n\n // Trigger animation when component enters viewport\n useIntersectionAnimation(svgRef, () => {\n setHasAnimated(true)\n })\n\n return (\n <BaseMeter.Track data-spark-component=\"circular-meter-track\" className={className} {...others}>\n <CircularMeterTrackContext.Provider value={true}>\n <svg ref={svgRef} width={size} height={size} viewBox={`0 0 ${size} ${size}`}>\n <g style={{ transform: 'rotate(-90deg)', transformOrigin: 'center' }}>\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className={circularMeterTrackStyles({ intent })}\n />\n <circle\n data-spark-component=\"circular-meter-indicator\"\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={cx(\n intentClasses,\n 'ease-standard transition-[stroke-dashoffset] duration-700',\n 'motion-reduce:transition-none'\n )}\n style={\n {\n strokeDasharray: circumference,\n // Start at circumference (0% filled) for initial animation, then use offset for subsequent changes\n strokeDashoffset: hasAnimated ? offset : circumference,\n } as React.CSSProperties\n }\n />\n </g>\n {children && (\n <foreignObject x={8} y={8} width={size - 16} height={size - 16}>\n <div\n className=\"p-md flex h-full w-full flex-col items-center justify-center rounded-full text-center\"\n style={{ width: size - 16, height: size - 16 }}\n >\n {children}\n </div>\n </foreignObject>\n )}\n </svg>\n </CircularMeterTrackContext.Provider>\n </BaseMeter.Track>\n )\n}\n\nCircularMeterTrack.displayName = 'CircularMeter.Track'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterLabelProps = Omit<ComponentProps<typeof BaseMeter.Label>, 'render'>\n\nconst labelStyles = cva([], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: ['default:text-on-surface/dim-1'],\n false: ['default:text-on-surface'],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-small' },\n { size: 'md', inside: true, class: 'default:text-small ' },\n { size: 'lg', inside: true, class: 'default:text-caption' },\n { size: 'xl', inside: true, class: 'default:text-body-2' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1' },\n { size: 'md', inside: false, class: 'default:text-body-1' },\n { size: 'lg', inside: false, class: 'default:text-body-1' },\n { size: 'xl', inside: false, class: 'default:text-body-1' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterLabel = ({\n id: idProp,\n children,\n className,\n ref: forwardedRef,\n ...others\n}: CircularMeterLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId, sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <BaseMeter.Label\n data-spark-component=\"circular-meter-label\"\n id={id}\n className={labelStyles({ size: sizeProp, inside: isInside, className })}\n ref={ref}\n {...others}\n >\n {children}\n </BaseMeter.Label>\n )\n}\n\nCircularMeterLabel.displayName = 'CircularMeter.Label'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterValueProps = Omit<ComponentProps<typeof BaseMeter.Value>, 'render'>\n\nconst valueStyles = cva(['default:text-on-surface default:font-bold'], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: [],\n false: [],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'md', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'lg', inside: true, class: 'default:text-body-1 default:font-bold' },\n { size: 'xl', inside: true, class: 'default:text-display-3' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1 default:font-bold' },\n { size: 'md', inside: false, class: 'default:text-headline-2' },\n { size: 'lg', inside: false, class: 'default:text-headline-2' },\n { size: 'xl', inside: false, class: 'default:text-display-3' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterValue = ({\n className,\n children,\n ...others\n}: PropsWithChildren<CircularMeterValueProps>) => {\n const { sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n\n return (\n <BaseMeter.Value\n data-spark-component=\"circular-meter-value\"\n className={valueStyles({ size: sizeProp, inside: isInside, className })}\n {...others}\n >\n {children}\n </BaseMeter.Value>\n )\n}\n\nCircularMeterValue.displayName = 'CircularMeter.Value'\n","import { CircularMeter as Root } from './CircularMeter'\nimport { CircularMeterContent } from './CircularMeterContent'\nimport { CircularMeterLabel } from './CircularMeterLabel'\nimport { CircularMeterTrack } from './CircularMeterTrack'\nimport { CircularMeterValue } from './CircularMeterValue'\n\nexport const CircularMeter: typeof Root & {\n Content: typeof CircularMeterContent\n Label: typeof CircularMeterLabel\n Track: typeof CircularMeterTrack\n Value: typeof CircularMeterValue\n} = Object.assign(Root, {\n Content: CircularMeterContent,\n Label: CircularMeterLabel,\n Track: CircularMeterTrack,\n Value: CircularMeterValue,\n})\n\nCircularMeter.displayName = 'CircularMeter'\nCircularMeterContent.displayName = 'CircularMeter.Content'\nCircularMeterLabel.displayName = 'CircularMeter.Label'\nCircularMeterTrack.displayName = 'CircularMeter.Track'\nCircularMeterValue.displayName = 'CircularMeter.Value'\n\nexport { type CircularMeterProps } from './CircularMeter'\nexport { type CircularMeterContentProps } from './CircularMeterContent'\nexport { type CircularMeterLabelProps } from './CircularMeterLabel'\nexport { type CircularMeterTrackProps } from './CircularMeterTrack'\nexport { type CircularMeterValueProps } from './CircularMeterValue'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/circular-meter/CircularMeter.styles.ts","../../src/circular-meter/CircularMeterContext.tsx","../../src/circular-meter/CircularMeter.tsx","../../src/circular-meter/CircularMeterContent.tsx","../../src/circular-meter/useIntersectionAnimation.ts","../../src/circular-meter/CircularMeterTrack.tsx","../../src/circular-meter/CircularMeterLabel.tsx","../../src/circular-meter/CircularMeterValue.tsx","../../src/circular-meter/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const circularMeterStyles = cva(['focus-visible:u-outline gap-md flex items-center'], {\n variants: {\n orientation: {\n vertical: ['default:flex-col'],\n horizontal: ['default:flex-row'],\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport type CircularMeterStylesProps = VariantProps<typeof circularMeterStyles>\n","import { createContext, useContext } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { CircularMeterSize } from './CircularMeter'\n\nexport interface CircularMeterContextValue {\n value: number\n max: number\n min: number\n intent: MeterIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n /**\n * Size variant of the circular meter.\n */\n sizeProp: CircularMeterSize\n /**\n * Orientation of the circular meter.\n */\n orientation: 'vertical' | 'horizontal'\n /**\n * Diameter of the SVG circle in pixels.\n */\n size: number\n /**\n * Radius of the SVG circle in pixels.\n */\n radius: number\n /**\n * Circumference of the SVG circle in pixels.\n */\n circumference: number\n /**\n * Stroke width of the SVG circle in pixels.\n */\n strokeWidth: number\n}\n\nexport const CircularMeterContext = createContext<CircularMeterContextValue | null>(null)\n\nexport const ID_PREFIX = ':circular-meter'\n\nexport const useCircularMeter = () => {\n const context = useContext(CircularMeterContext)\n\n if (!context) {\n throw new Error('useCircularMeter must be used within a CircularMeter provider')\n }\n\n return context\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { MeterIndicatorStylesProps } from '../meter/MeterTrack.styles'\nimport { circularMeterStyles, CircularMeterStylesProps } from './CircularMeter.styles'\nimport { CircularMeterContext } from './CircularMeterContext'\n\nexport type CircularMeterSize = 'sm' | 'md' | 'lg' | 'xl'\n\nconst CIRCULAR_METER_SIZE_CONFIG: Record<\n CircularMeterSize,\n { diameter: number; strokeWidth: number }\n> = {\n sm: { diameter: 24, strokeWidth: 4 },\n md: { diameter: 64, strokeWidth: 8 },\n lg: { diameter: 96, strokeWidth: 8 },\n xl: { diameter: 128, strokeWidth: 8 },\n}\n\nexport interface CircularMeterProps\n extends\n Omit<ComponentProps<typeof BaseMeter.Root>, 'render'>,\n Pick<MeterIndicatorStylesProps, 'intent'>,\n CircularMeterStylesProps {\n /**\n * Size of the circle.\n *\n * - `sm`: 24px diameter, 4px stroke width\n * - `md`: 64px diameter, 8px stroke width\n * - `lg`: 96px diameter, 8px stroke width\n * - `xl`: 128px diameter, 8px stroke width\n *\n * Defaults to `md`.\n */\n size?: CircularMeterSize\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n /**\n * Orientation of the circular meter.\n *\n * - `vertical`: Elements are stacked vertically (default)\n * - `horizontal`: Elements are arranged horizontally\n */\n orientation?: 'vertical' | 'horizontal'\n}\n\nexport const CircularMeter = ({\n className,\n value,\n max = 100,\n min = 0,\n size: sizeProp = 'lg',\n intent = 'support',\n orientation = 'vertical',\n children,\n ref,\n ...others\n}: PropsWithChildren<CircularMeterProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const { diameter: size, strokeWidth } = CIRCULAR_METER_SIZE_CONFIG[sizeProp]\n\n const radius = size / 2 - strokeWidth / 2\n const circumference = 2 * Math.PI * radius\n\n const contextValue = useMemo(() => {\n return {\n value: value ?? 0,\n max,\n min,\n intent,\n onLabelId: setLabelId,\n sizeProp,\n orientation: orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n }\n }, [\n max,\n min,\n value,\n intent,\n setLabelId,\n sizeProp,\n orientation,\n size,\n radius,\n circumference,\n strokeWidth,\n ])\n\n return (\n <CircularMeterContext.Provider value={contextValue}>\n <BaseMeter.Root\n data-spark-component=\"circular-meter\"\n ref={ref}\n className={cx(circularMeterStyles({ orientation }), className)}\n style={others.style}\n value={value}\n max={max}\n min={min}\n aria-labelledby={labelId}\n {...others}\n >\n {children}\n </BaseMeter.Root>\n </CircularMeterContext.Provider>\n )\n}\n\nCircularMeter.displayName = 'CircularMeter'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\n\nexport type CircularMeterContentProps = ComponentProps<'div'> & PropsWithChildren\n\nexport const CircularMeterContent = ({\n className,\n children,\n ...others\n}: CircularMeterContentProps) => {\n const { orientation } = useCircularMeter()\n\n return (\n <div\n data-spark-component=\"circular-meter-content\"\n className={cx(\n 'gap-xs flex default:flex-col',\n orientation === 'vertical' && 'default:text-center',\n className\n )}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nCircularMeterContent.displayName = 'CircularMeter.Content'\n","import { RefObject, useEffect, useRef } from 'react'\n\nexport interface UseIntersectionAnimationOptions {\n /**\n * The threshold at which the callback should be triggered.\n * A value of 0 means as soon as any part of the element is visible.\n * A value of 1 means the entire element must be visible.\n * @default 0.1\n */\n threshold?: number\n /**\n * The root margin for the Intersection Observer.\n * This can be used to trigger the animation before the element enters the viewport.\n * @default undefined\n */\n rootMargin?: string\n}\n\n/**\n * Hook to trigger an animation callback when an element enters the viewport.\n * The callback is only triggered once, when the element first becomes visible.\n *\n * @param elementRef - Reference to the element to observe\n * @param onIntersect - Callback to execute when the element enters the viewport\n * @param options - Configuration options for the Intersection Observer\n * @returns Whether the animation has been triggered\n */\nexport function useIntersectionAnimation(\n elementRef: RefObject<Element | null>,\n onIntersect: () => void,\n options: UseIntersectionAnimationOptions = {}\n): boolean {\n const { threshold = 0.1, rootMargin } = options\n const hasTriggeredRef = useRef(false)\n const callbackRef = useRef(onIntersect)\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = onIntersect\n }, [onIntersect])\n\n useEffect(() => {\n const element = elementRef.current\n if (!element || hasTriggeredRef.current) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting && !hasTriggeredRef.current) {\n // Use requestAnimationFrame to ensure the callback runs at the right time\n requestAnimationFrame(() => {\n if (!hasTriggeredRef.current) {\n hasTriggeredRef.current = true\n callbackRef.current()\n // Disconnect observer after callback is triggered (only trigger once)\n observer.disconnect()\n }\n })\n }\n })\n },\n {\n threshold,\n rootMargin,\n }\n )\n\n observer.observe(element)\n\n return () => {\n observer.disconnect()\n }\n }, [elementRef, threshold, rootMargin])\n\n return hasTriggeredRef.current\n}\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva, cx } from 'class-variance-authority'\nimport {\n ComponentProps,\n createContext,\n PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useIntersectionAnimation } from './useIntersectionAnimation'\n\nconst CircularMeterTrackContext = createContext<boolean>(false)\n\nexport const useCircularMeterTrack = () => {\n return useContext(CircularMeterTrackContext)\n}\n\nexport type CircularMeterTrackProps = Omit<ComponentProps<typeof BaseMeter.Track>, 'render'> &\n PropsWithChildren\n\nconst circularMeterTrackStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main/dim-4'],\n support: ['text-support/dim-4'],\n success: ['text-success/dim-4'],\n alert: ['text-alert/dim-4'],\n danger: ['text-error/dim-4'],\n info: ['text-info/dim-4'],\n },\n },\n})\n\nconst circularMeterIndicatorStyles = cva([], {\n variants: {\n intent: {\n main: ['text-main'],\n support: ['text-support'],\n success: ['text-success'],\n alert: ['text-alert'],\n danger: ['text-error'],\n info: ['text-info'],\n },\n },\n})\n\nexport const CircularMeterTrack = ({ className, children, ...others }: CircularMeterTrackProps) => {\n const { value, max, min, intent, size, radius, circumference, strokeWidth } = useCircularMeter()\n const percentage = ((value - min) / (max - min)) * 100\n const offset = circumference - (percentage / 100) * circumference\n\n const intentClasses = circularMeterIndicatorStyles({ intent })\n const svgRef = useRef<SVGSVGElement>(null)\n const [hasAnimated, setHasAnimated] = useState(false)\n\n // Trigger animation when component enters viewport\n useIntersectionAnimation(svgRef, () => {\n setHasAnimated(true)\n })\n\n return (\n <BaseMeter.Track data-spark-component=\"circular-meter-track\" className={className} {...others}>\n <CircularMeterTrackContext.Provider value={true}>\n <svg ref={svgRef} width={size} height={size} viewBox={`0 0 ${size} ${size}`}>\n <g style={{ transform: 'rotate(-90deg)', transformOrigin: 'center' }}>\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n className={circularMeterTrackStyles({ intent })}\n />\n <circle\n data-spark-component=\"circular-meter-indicator\"\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={cx(\n intentClasses,\n 'ease-standard transition-[stroke-dashoffset] duration-700',\n 'motion-reduce:transition-none'\n )}\n style={\n {\n strokeDasharray: circumference,\n // Start at circumference (0% filled) for initial animation, then use offset for subsequent changes\n strokeDashoffset: hasAnimated ? offset : circumference,\n } as React.CSSProperties\n }\n />\n </g>\n {children && (\n <foreignObject x={8} y={8} width={size - 16} height={size - 16}>\n <div\n className=\"p-md flex h-full w-full flex-col items-center justify-center rounded-full text-center\"\n style={{ width: size - 16, height: size - 16 }}\n >\n {children}\n </div>\n </foreignObject>\n )}\n </svg>\n </CircularMeterTrackContext.Provider>\n </BaseMeter.Track>\n )\n}\n\nCircularMeterTrack.displayName = 'CircularMeter.Track'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterLabelProps = Omit<ComponentProps<typeof BaseMeter.Label>, 'render'>\n\nconst labelStyles = cva([], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: ['default:text-on-surface/dim-1'],\n false: ['default:text-on-surface'],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-small' },\n { size: 'md', inside: true, class: 'default:text-small ' },\n { size: 'lg', inside: true, class: 'default:text-caption' },\n { size: 'xl', inside: true, class: 'default:text-body-2' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1' },\n { size: 'md', inside: false, class: 'default:text-body-1' },\n { size: 'lg', inside: false, class: 'default:text-body-1' },\n { size: 'xl', inside: false, class: 'default:text-body-1' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterLabel = ({\n id: idProp,\n children,\n className,\n ref: forwardedRef,\n ...others\n}: CircularMeterLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId, sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <BaseMeter.Label\n data-spark-component=\"circular-meter-label\"\n id={id}\n className={labelStyles({ size: sizeProp, inside: isInside, className })}\n ref={ref}\n {...others}\n >\n {children}\n </BaseMeter.Label>\n )\n}\n\nCircularMeterLabel.displayName = 'CircularMeter.Label'\n","import { Meter as BaseMeter } from '@base-ui/react/meter'\nimport { cva } from 'class-variance-authority'\nimport { ComponentProps, PropsWithChildren } from 'react'\n\nimport { useCircularMeter } from './CircularMeterContext'\nimport { useCircularMeterTrack } from './CircularMeterTrack'\n\nexport type CircularMeterValueProps = Omit<ComponentProps<typeof BaseMeter.Value>, 'render'>\n\nconst valueStyles = cva(['default:text-on-surface default:font-bold'], {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n inside: {\n true: [],\n false: [],\n },\n },\n compoundVariants: [\n // Inside the track\n { size: 'sm', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'md', inside: true, class: 'default:text-body-2 default:font-bold' },\n { size: 'lg', inside: true, class: 'default:text-body-1 default:font-bold' },\n { size: 'xl', inside: true, class: 'default:text-display-3' },\n // Outside the track\n { size: 'sm', inside: false, class: 'default:text-body-1 default:font-bold' },\n { size: 'md', inside: false, class: 'default:text-headline-2' },\n { size: 'lg', inside: false, class: 'default:text-headline-2' },\n { size: 'xl', inside: false, class: 'default:text-display-3' },\n ],\n defaultVariants: {\n size: 'lg',\n inside: true,\n },\n})\n\nexport const CircularMeterValue = ({\n className,\n children,\n ...others\n}: PropsWithChildren<CircularMeterValueProps>) => {\n const { sizeProp } = useCircularMeter()\n const isInside = useCircularMeterTrack()\n\n return (\n <BaseMeter.Value\n data-spark-component=\"circular-meter-value\"\n className={valueStyles({ size: sizeProp, inside: isInside, className })}\n {...others}\n >\n {children}\n </BaseMeter.Value>\n )\n}\n\nCircularMeterValue.displayName = 'CircularMeter.Value'\n","import { CircularMeter as Root } from './CircularMeter'\nimport { CircularMeterContent } from './CircularMeterContent'\nimport { CircularMeterLabel } from './CircularMeterLabel'\nimport { CircularMeterTrack } from './CircularMeterTrack'\nimport { CircularMeterValue } from './CircularMeterValue'\n\n/**\n * A circular progress indicator that displays a value within a defined range.\n */\nexport const CircularMeter: typeof Root & {\n Content: typeof CircularMeterContent\n Label: typeof CircularMeterLabel\n Track: typeof CircularMeterTrack\n Value: typeof CircularMeterValue\n} = Object.assign(Root, {\n Content: CircularMeterContent,\n Label: CircularMeterLabel,\n Track: CircularMeterTrack,\n Value: CircularMeterValue,\n})\n\nCircularMeter.displayName = 'CircularMeter'\nCircularMeterContent.displayName = 'CircularMeter.Content'\nCircularMeterLabel.displayName = 'CircularMeter.Label'\nCircularMeterTrack.displayName = 'CircularMeter.Track'\nCircularMeterValue.displayName = 'CircularMeter.Value'\n\nexport { type CircularMeterProps } from './CircularMeter'\nexport { type CircularMeterContentProps } from './CircularMeterContent'\nexport { type CircularMeterLabelProps } from './CircularMeterLabel'\nexport { type CircularMeterTrackProps } from './CircularMeterTrack'\nexport { type CircularMeterValueProps } from './CircularMeterValue'\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/collapsible/useRenderSlot.tsx","../../src/collapsible/Content.tsx","../../src/collapsible/Root.tsx","../../src/collapsible/Trigger.tsx","../../src/collapsible/index.ts"],"sourcesContent":["import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean, defaultTag: string) {\n const Component = asChild ? Slot : defaultTag\n\n return asChild ? ({ ...props }) => <Component {...props} /> : undefined\n}\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface ContentProps extends ComponentProps<typeof Collapsible.Panel> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Content = ({\n asChild = false,\n className,\n children,\n hiddenUntilFound = true,\n ...props\n}: ContentProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Panel\n data-spark-component=\"collapsible-content\"\n className={cx(\n 'overflow-hidden',\n 'h-[var(--collapsible-panel-height)]',\n 'transition-all duration-200',\n 'motion-reduce:transition-none',\n 'data-[starting-style]:h-0',\n 'data-[ending-style]:h-0',\n className\n )}\n render={renderSlot}\n hiddenUntilFound={hiddenUntilFound}\n {...props}\n >\n {children}\n </Collapsible.Panel>\n )\n}\n\nContent.displayName = 'Collapsible.Content'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface RootProps extends ComponentProps<typeof Collapsible.Root> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Root = ({ asChild = false, children, ...props }: RootProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Root data-spark-component=\"collapsible\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Root>\n )\n}\n\nRoot.displayName = 'Collapsible'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface TriggerProps extends ComponentProps<'button'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Trigger = ({ asChild = false, children, ...props }: TriggerProps) => {\n const renderSlot = useRenderSlot(asChild, 'button')\n\n return (\n <Collapsible.Trigger data-spark-component=\"collapsible-trigger\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Trigger>\n )\n}\n\nTrigger.displayName = 'Collapsible.Trigger'\n","import { Content } from './Content'\nimport { Root } from './Root'\nimport { Trigger } from './Trigger'\n\nexport const Collapsible: typeof Root & {\n Trigger: typeof Trigger\n Content: typeof Content\n} = Object.assign(Root, {\n Trigger,\n Content,\n})\n\nCollapsible.displayName = 'Collapsible'\nTrigger.displayName = 'Collapsible.Trigger'\nContent.displayName = 'Collapsible.Content'\n"],"mappings":"wPAEA,SAAgB,EAAc,EAAkB,EAAoB,CAClE,IAAM,EAAY,EAAU,EAAA,KAAO,EAEnC,OAAO,GAAW,CAAE,GAAG,MAAY,EAAA,EAAA,KAAC,EAAD,CAAW,GAAI,EAAS,CAAA,CAAG,IAAA,GCQhE,IAAa,GAAW,CACtB,UAAU,GACV,YACA,WACA,mBAAmB,GACnB,GAAG,KACe,CAClB,IAAM,EAAa,EAAc,EAAS,MAAM,CAEhD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,MAAb,CACE,uBAAqB,sBACrB,WAAA,EAAA,EAAA,IACE,kBACA,sCACA,8BACA,gCACA,4BACA,0BACA,EACD,CACD,OAAQ,EACU,mBAClB,GAAI,EAEH,WACiB,CAAA,EAIxB,EAAQ,YAAc,sBC/BtB,IAAa,GAAQ,CAAE,UAAU,GAAO,WAAU,GAAG,KAAuB,CAC1E,IAAM,EAAa,EAAc,EAAS,MAAM,CAEhD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,KAAb,CAAkB,uBAAqB,cAAc,OAAQ,EAAY,GAAI,EAC1E,WACgB,CAAA,EAIvB,EAAK,YAAc,cCVnB,IAAa,GAAW,CAAE,UAAU,GAAO,WAAU,GAAG,KAA0B,CAChF,IAAM,EAAa,EAAc,EAAS,SAAS,CAEnD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,QAAb,CAAqB,uBAAqB,sBAAsB,OAAQ,EAAY,GAAI,EACrF,WACmB,CAAA,EAI1B,EAAQ,YAAc,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/collapsible/useRenderSlot.tsx","../../src/collapsible/Content.tsx","../../src/collapsible/Root.tsx","../../src/collapsible/Trigger.tsx","../../src/collapsible/index.ts"],"sourcesContent":["import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean, defaultTag: string) {\n const Component = asChild ? Slot : defaultTag\n\n return asChild ? ({ ...props }) => <Component {...props} /> : undefined\n}\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface ContentProps extends ComponentProps<typeof Collapsible.Panel> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Content = ({\n asChild = false,\n className,\n children,\n hiddenUntilFound = true,\n ...props\n}: ContentProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Panel\n data-spark-component=\"collapsible-content\"\n className={cx(\n 'overflow-hidden',\n 'h-[var(--collapsible-panel-height)]',\n 'transition-all duration-200',\n 'motion-reduce:transition-none',\n 'data-[starting-style]:h-0',\n 'data-[ending-style]:h-0',\n className\n )}\n render={renderSlot}\n hiddenUntilFound={hiddenUntilFound}\n {...props}\n >\n {children}\n </Collapsible.Panel>\n )\n}\n\nContent.displayName = 'Collapsible.Content'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface RootProps extends ComponentProps<typeof Collapsible.Root> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Root = ({ asChild = false, children, ...props }: RootProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Root data-spark-component=\"collapsible\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Root>\n )\n}\n\nRoot.displayName = 'Collapsible'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface TriggerProps extends ComponentProps<'button'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Trigger = ({ asChild = false, children, ...props }: TriggerProps) => {\n const renderSlot = useRenderSlot(asChild, 'button')\n\n return (\n <Collapsible.Trigger data-spark-component=\"collapsible-trigger\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Trigger>\n )\n}\n\nTrigger.displayName = 'Collapsible.Trigger'\n","import { Content } from './Content'\nimport { Root } from './Root'\nimport { Trigger } from './Trigger'\n\n/**\n * A component that allows users to expand and collapse content sections.\n */\nexport const Collapsible: typeof Root & {\n Trigger: typeof Trigger\n Content: typeof Content\n} = Object.assign(Root, {\n Trigger,\n Content,\n})\n\nCollapsible.displayName = 'Collapsible'\nTrigger.displayName = 'Collapsible.Trigger'\nContent.displayName = 'Collapsible.Content'\n"],"mappings":"wPAEA,SAAgB,EAAc,EAAkB,EAAoB,CAClE,IAAM,EAAY,EAAU,EAAA,KAAO,EAEnC,OAAO,GAAW,CAAE,GAAG,MAAY,EAAA,EAAA,KAAC,EAAD,CAAW,GAAI,EAAS,CAAA,CAAG,IAAA,GCQhE,IAAa,GAAW,CACtB,UAAU,GACV,YACA,WACA,mBAAmB,GACnB,GAAG,KACe,CAClB,IAAM,EAAa,EAAc,EAAS,MAAM,CAEhD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,MAAb,CACE,uBAAqB,sBACrB,WAAA,EAAA,EAAA,IACE,kBACA,sCACA,8BACA,gCACA,4BACA,0BACA,EACD,CACD,OAAQ,EACU,mBAClB,GAAI,EAEH,WACiB,CAAA,EAIxB,EAAQ,YAAc,sBC/BtB,IAAa,GAAQ,CAAE,UAAU,GAAO,WAAU,GAAG,KAAuB,CAC1E,IAAM,EAAa,EAAc,EAAS,MAAM,CAEhD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,KAAb,CAAkB,uBAAqB,cAAc,OAAQ,EAAY,GAAI,EAC1E,WACgB,CAAA,EAIvB,EAAK,YAAc,cCVnB,IAAa,GAAW,CAAE,UAAU,GAAO,WAAU,GAAG,KAA0B,CAChF,IAAM,EAAa,EAAc,EAAS,SAAS,CAEnD,OACE,EAAA,EAAA,KAAC,EAAA,YAAY,QAAb,CAAqB,uBAAqB,sBAAsB,OAAQ,EAAY,GAAI,EACrF,WACmB,CAAA,EAI1B,EAAQ,YAAc,sBCftB,IAAa,EAGT,OAAO,OAAO,EAAM,CACtB,UACA,UACD,CAAC,CAEF,EAAY,YAAc,cAC1B,EAAQ,YAAc,sBACtB,EAAQ,YAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/collapsible/useRenderSlot.tsx","../../src/collapsible/Content.tsx","../../src/collapsible/Root.tsx","../../src/collapsible/Trigger.tsx","../../src/collapsible/index.ts"],"sourcesContent":["import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean, defaultTag: string) {\n const Component = asChild ? Slot : defaultTag\n\n return asChild ? ({ ...props }) => <Component {...props} /> : undefined\n}\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface ContentProps extends ComponentProps<typeof Collapsible.Panel> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Content = ({\n asChild = false,\n className,\n children,\n hiddenUntilFound = true,\n ...props\n}: ContentProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Panel\n data-spark-component=\"collapsible-content\"\n className={cx(\n 'overflow-hidden',\n 'h-[var(--collapsible-panel-height)]',\n 'transition-all duration-200',\n 'motion-reduce:transition-none',\n 'data-[starting-style]:h-0',\n 'data-[ending-style]:h-0',\n className\n )}\n render={renderSlot}\n hiddenUntilFound={hiddenUntilFound}\n {...props}\n >\n {children}\n </Collapsible.Panel>\n )\n}\n\nContent.displayName = 'Collapsible.Content'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface RootProps extends ComponentProps<typeof Collapsible.Root> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Root = ({ asChild = false, children, ...props }: RootProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Root data-spark-component=\"collapsible\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Root>\n )\n}\n\nRoot.displayName = 'Collapsible'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface TriggerProps extends ComponentProps<'button'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Trigger = ({ asChild = false, children, ...props }: TriggerProps) => {\n const renderSlot = useRenderSlot(asChild, 'button')\n\n return (\n <Collapsible.Trigger data-spark-component=\"collapsible-trigger\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Trigger>\n )\n}\n\nTrigger.displayName = 'Collapsible.Trigger'\n","import { Content } from './Content'\nimport { Root } from './Root'\nimport { Trigger } from './Trigger'\n\nexport const Collapsible: typeof Root & {\n Trigger: typeof Trigger\n Content: typeof Content\n} = Object.assign(Root, {\n Trigger,\n Content,\n})\n\nCollapsible.displayName = 'Collapsible'\nTrigger.displayName = 'Collapsible.Trigger'\nContent.displayName = 'Collapsible.Content'\n"],"mappings":";;;;;AAEA,SAAgB,EAAc,GAAkB,GAAoB;CAClE,IAAM,IAAY,IAAU,IAAO;AAEnC,QAAO,KAAW,EAAE,GAAG,QAAY,kBAAC,GAAD,EAAW,GAAI,GAAS,CAAA,GAAG,KAAA;;;;ACQhE,IAAa,KAAW,EACtB,aAAU,IACV,cACA,aACA,sBAAmB,IACnB,GAAG,QACe;CAClB,IAAM,IAAa,EAAc,GAAS,MAAM;AAEhD,QACE,kBAAC,EAAY,OAAb;EACE,wBAAqB;EACrB,WAAW,EACT,mBACA,uCACA,+BACA,iCACA,6BACA,2BACA,EACD;EACD,QAAQ;EACU;EAClB,GAAI;EAEH;EACiB,CAAA;;AAIxB,EAAQ,cAAc;;;AC/BtB,IAAa,KAAQ,EAAE,aAAU,IAAO,aAAU,GAAG,QAAuB;CAC1E,IAAM,IAAa,EAAc,GAAS,MAAM;AAEhD,QACE,kBAAC,EAAY,MAAb;EAAkB,wBAAqB;EAAc,QAAQ;EAAY,GAAI;EAC1E;EACgB,CAAA;;AAIvB,EAAK,cAAc;;;ACVnB,IAAa,KAAW,EAAE,aAAU,IAAO,aAAU,GAAG,QAA0B;CAChF,IAAM,IAAa,EAAc,GAAS,SAAS;AAEnD,QACE,kBAAC,EAAY,SAAb;EAAqB,wBAAqB;EAAsB,QAAQ;EAAY,GAAI;EACrF;EACmB,CAAA;;AAI1B,EAAQ,cAAc;;;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/collapsible/useRenderSlot.tsx","../../src/collapsible/Content.tsx","../../src/collapsible/Root.tsx","../../src/collapsible/Trigger.tsx","../../src/collapsible/index.ts"],"sourcesContent":["import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean, defaultTag: string) {\n const Component = asChild ? Slot : defaultTag\n\n return asChild ? ({ ...props }) => <Component {...props} /> : undefined\n}\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface ContentProps extends ComponentProps<typeof Collapsible.Panel> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Content = ({\n asChild = false,\n className,\n children,\n hiddenUntilFound = true,\n ...props\n}: ContentProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Panel\n data-spark-component=\"collapsible-content\"\n className={cx(\n 'overflow-hidden',\n 'h-[var(--collapsible-panel-height)]',\n 'transition-all duration-200',\n 'motion-reduce:transition-none',\n 'data-[starting-style]:h-0',\n 'data-[ending-style]:h-0',\n className\n )}\n render={renderSlot}\n hiddenUntilFound={hiddenUntilFound}\n {...props}\n >\n {children}\n </Collapsible.Panel>\n )\n}\n\nContent.displayName = 'Collapsible.Content'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface RootProps extends ComponentProps<typeof Collapsible.Root> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Root = ({ asChild = false, children, ...props }: RootProps) => {\n const renderSlot = useRenderSlot(asChild, 'div')\n\n return (\n <Collapsible.Root data-spark-component=\"collapsible\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Root>\n )\n}\n\nRoot.displayName = 'Collapsible'\n","import { Collapsible } from '@base-ui/react/collapsible'\nimport { type ComponentProps } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface TriggerProps extends ComponentProps<'button'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n}\n\nexport const Trigger = ({ asChild = false, children, ...props }: TriggerProps) => {\n const renderSlot = useRenderSlot(asChild, 'button')\n\n return (\n <Collapsible.Trigger data-spark-component=\"collapsible-trigger\" render={renderSlot} {...props}>\n {children}\n </Collapsible.Trigger>\n )\n}\n\nTrigger.displayName = 'Collapsible.Trigger'\n","import { Content } from './Content'\nimport { Root } from './Root'\nimport { Trigger } from './Trigger'\n\n/**\n * A component that allows users to expand and collapse content sections.\n */\nexport const Collapsible: typeof Root & {\n Trigger: typeof Trigger\n Content: typeof Content\n} = Object.assign(Root, {\n Trigger,\n Content,\n})\n\nCollapsible.displayName = 'Collapsible'\nTrigger.displayName = 'Collapsible.Trigger'\nContent.displayName = 'Collapsible.Content'\n"],"mappings":";;;;;AAEA,SAAgB,EAAc,GAAkB,GAAoB;CAClE,IAAM,IAAY,IAAU,IAAO;AAEnC,QAAO,KAAW,EAAE,GAAG,QAAY,kBAAC,GAAD,EAAW,GAAI,GAAS,CAAA,GAAG,KAAA;;;;ACQhE,IAAa,KAAW,EACtB,aAAU,IACV,cACA,aACA,sBAAmB,IACnB,GAAG,QACe;CAClB,IAAM,IAAa,EAAc,GAAS,MAAM;AAEhD,QACE,kBAAC,EAAY,OAAb;EACE,wBAAqB;EACrB,WAAW,EACT,mBACA,uCACA,+BACA,iCACA,6BACA,2BACA,EACD;EACD,QAAQ;EACU;EAClB,GAAI;EAEH;EACiB,CAAA;;AAIxB,EAAQ,cAAc;;;AC/BtB,IAAa,KAAQ,EAAE,aAAU,IAAO,aAAU,GAAG,QAAuB;CAC1E,IAAM,IAAa,EAAc,GAAS,MAAM;AAEhD,QACE,kBAAC,EAAY,MAAb;EAAkB,wBAAqB;EAAc,QAAQ;EAAY,GAAI;EAC1E;EACgB,CAAA;;AAIvB,EAAK,cAAc;;;ACVnB,IAAa,KAAW,EAAE,aAAU,IAAO,aAAU,GAAG,QAA0B;CAChF,IAAM,IAAa,EAAc,GAAS,SAAS;AAEnD,QACE,kBAAC,EAAY,SAAb;EAAqB,wBAAqB;EAAsB,QAAQ;EAAY,GAAI;EACrF;EACmB,CAAA;;AAI1B,EAAQ,cAAc;;;ACftB,IAAa,IAGT,OAAO,OAAO,GAAM;CACtB;CACA;CACD,CAAC;AAEF,EAAY,cAAc,eAC1B,EAAQ,cAAc,uBACtB,EAAQ,cAAc"}
|