@epilot/spark-ui 0.20.1 → 0.21.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/components/accordion.cjs +5 -5
- package/dist/components/accordion.cjs.map +1 -1
- package/dist/components/alert-dialog.cjs +9 -9
- package/dist/components/alert-dialog.cjs.map +1 -1
- package/dist/components/attachment.cjs +10 -10
- package/dist/components/attachment.cjs.map +1 -1
- package/dist/components/attachment.d.cts +2 -2
- package/dist/components/attachment.d.ts +2 -2
- package/dist/components/autocomplete.cjs +12 -12
- package/dist/components/autocomplete.cjs.map +1 -1
- package/dist/components/avatar.cjs +2 -2
- package/dist/components/avatar.cjs.map +1 -1
- package/dist/components/avatar.js +1 -1
- package/dist/components/badge.cjs +2 -2
- package/dist/components/badge.cjs.map +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/bar-chart.cjs +3 -3
- package/dist/components/bar-chart.cjs.map +1 -1
- package/dist/components/box.cjs +2 -2
- package/dist/components/box.cjs.map +1 -1
- package/dist/components/box.js +1 -1
- package/dist/components/breadcrumbs.cjs +7 -7
- package/dist/components/breadcrumbs.cjs.map +1 -1
- package/dist/components/bubble.cjs +5 -5
- package/dist/components/bubble.cjs.map +1 -1
- package/dist/components/bubble.d.cts +1 -1
- package/dist/components/bubble.d.ts +1 -1
- package/dist/components/button-group.cjs +5 -5
- package/dist/components/button-group.cjs.map +1 -1
- package/dist/components/button-group.js +1 -1
- package/dist/components/button.cjs +2 -2
- package/dist/components/button.cjs.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js +1 -1
- package/dist/components/calendar.cjs +8 -8
- package/dist/components/calendar.cjs.map +1 -1
- package/dist/components/callout.cjs +7 -7
- package/dist/components/callout.cjs.map +1 -1
- package/dist/components/callout.d.cts +1 -1
- package/dist/components/callout.d.ts +1 -1
- package/dist/components/card.cjs +16 -16
- package/dist/components/card.cjs.map +1 -1
- package/dist/components/card.js +2 -2
- package/dist/components/card.js.map +1 -1
- package/dist/components/chart.cjs +2 -2
- package/dist/components/chart.cjs.map +1 -1
- package/dist/components/checkbox.cjs +2 -2
- package/dist/components/checkbox.cjs.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/circular-gauge.cjs +3 -3
- package/dist/components/circular-gauge.cjs.map +1 -1
- package/dist/components/day-of-week-picker.cjs +4 -4
- package/dist/components/day-of-week-picker.cjs.map +1 -1
- package/dist/components/dialog.cjs +8 -8
- package/dist/components/dialog.cjs.map +1 -1
- package/dist/components/drawer.cjs +8 -8
- package/dist/components/drawer.cjs.map +1 -1
- package/dist/components/dropdown-menu.cjs +10 -10
- package/dist/components/dropdown-menu.cjs.map +1 -1
- package/dist/components/entity-card.cjs +11 -11
- package/dist/components/entity-card.cjs.map +1 -1
- package/dist/components/field.cjs +15 -15
- package/dist/components/field.cjs.map +1 -1
- package/dist/components/hero-metric.cjs +4 -4
- package/dist/components/hero-metric.cjs.map +1 -1
- package/dist/components/icon.cjs +2 -2
- package/dist/components/icon.cjs.map +1 -1
- package/dist/components/icon.js +1 -1
- package/dist/components/info-block.cjs +9 -9
- package/dist/components/info-block.cjs.map +1 -1
- package/dist/components/info-block.d.cts +1 -1
- package/dist/components/info-block.d.ts +1 -1
- package/dist/components/input-date.cjs +2 -2
- package/dist/components/input-date.cjs.map +1 -1
- package/dist/components/input-group.cjs +5 -5
- package/dist/components/input-group.cjs.map +1 -1
- package/dist/components/input-group.d.cts +1 -1
- package/dist/components/input-group.d.ts +1 -1
- package/dist/components/input-otp.cjs +3 -3
- package/dist/components/input-otp.cjs.map +1 -1
- package/dist/components/input-otp.js +1 -1
- package/dist/components/input.cjs +3 -3
- package/dist/components/input.cjs.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/label.cjs +2 -2
- package/dist/components/label.cjs.map +1 -1
- package/dist/components/layout.cjs +2 -2
- package/dist/components/layout.cjs.map +1 -1
- package/dist/components/line-chart.cjs +4 -4
- package/dist/components/line-chart.cjs.map +1 -1
- package/dist/components/list.cjs +10 -10
- package/dist/components/list.cjs.map +1 -1
- package/dist/components/list.js +1 -1
- package/dist/components/list.js.map +1 -1
- package/dist/components/marker.cjs +4 -4
- package/dist/components/marker.cjs.map +1 -1
- package/dist/components/marker.d.cts +1 -1
- package/dist/components/marker.d.ts +1 -1
- package/dist/components/message-scroller.cjs +7 -7
- package/dist/components/message-scroller.cjs.map +1 -1
- package/dist/components/message-scroller.js +2 -2
- package/dist/components/message-scroller.js.map +1 -1
- package/dist/components/message.cjs +7 -7
- package/dist/components/message.cjs.map +1 -1
- package/dist/components/page-header.cjs +5 -5
- package/dist/components/page-header.cjs.map +1 -1
- package/dist/components/page-header.d.cts +1 -1
- package/dist/components/page-header.d.ts +1 -1
- package/dist/components/period-tabs.cjs +6 -6
- package/dist/components/period-tabs.cjs.map +1 -1
- package/dist/components/pill.cjs +2 -2
- package/dist/components/pill.cjs.map +1 -1
- package/dist/components/pill.js +1 -1
- package/dist/components/popover.cjs +2 -2
- package/dist/components/popover.cjs.map +1 -1
- package/dist/components/power-history-chart.cjs +2 -2
- package/dist/components/power-history-chart.cjs.map +1 -1
- package/dist/components/power-network.cjs +9 -9
- package/dist/components/power-network.cjs.map +1 -1
- package/dist/components/progress.cjs +2 -2
- package/dist/components/progress.cjs.map +1 -1
- package/dist/components/radio-card-group.cjs +3 -3
- package/dist/components/radio-card-group.cjs.map +1 -1
- package/dist/components/radio.cjs +3 -3
- package/dist/components/radio.cjs.map +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/sankey-chart.cjs +2 -2
- package/dist/components/sankey-chart.cjs.map +1 -1
- package/dist/components/schedule-editor.cjs +9 -9
- package/dist/components/schedule-editor.cjs.map +1 -1
- package/dist/components/schedule-list.cjs +10 -10
- package/dist/components/schedule-list.cjs.map +1 -1
- package/dist/components/scroll-area.cjs +3 -3
- package/dist/components/scroll-area.cjs.map +1 -1
- package/dist/components/segmented-control.cjs +4 -4
- package/dist/components/segmented-control.cjs.map +1 -1
- package/dist/components/select.cjs +12 -12
- package/dist/components/select.cjs.map +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/separator.cjs +3 -3
- package/dist/components/separator.cjs.map +1 -1
- package/dist/components/series-legend.cjs +4 -4
- package/dist/components/series-legend.cjs.map +1 -1
- package/dist/components/sheet.cjs +8 -8
- package/dist/components/sheet.cjs.map +1 -1
- package/dist/components/skeleton.cjs +3 -3
- package/dist/components/skeleton.cjs.map +1 -1
- package/dist/components/slider.cjs +11 -11
- package/dist/components/slider.cjs.map +1 -1
- package/dist/components/solar-forecast-chart.cjs +2 -2
- package/dist/components/solar-forecast-chart.cjs.map +1 -1
- package/dist/components/sortable-list.cjs +3 -3
- package/dist/components/sortable-list.cjs.map +1 -1
- package/dist/components/spinner.cjs +2 -2
- package/dist/components/spinner.cjs.map +1 -1
- package/dist/components/stat-card.cjs +8 -8
- package/dist/components/stat-card.cjs.map +1 -1
- package/dist/components/stepper.cjs +2 -2
- package/dist/components/stepper.cjs.map +1 -1
- package/dist/components/switch.cjs +3 -3
- package/dist/components/switch.cjs.map +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/table.cjs +8 -8
- package/dist/components/table.cjs.map +1 -1
- package/dist/components/tabs.cjs +7 -7
- package/dist/components/tabs.cjs.map +1 -1
- package/dist/components/textarea.cjs +3 -3
- package/dist/components/textarea.cjs.map +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/theme.cjs +2 -2
- package/dist/components/theme.cjs.map +1 -1
- package/dist/components/theme.js +1 -1
- package/dist/components/thumbnail.cjs +3 -3
- package/dist/components/thumbnail.cjs.map +1 -1
- package/dist/components/time-picker.cjs +3 -3
- package/dist/components/time-picker.cjs.map +1 -1
- package/dist/components/toast.cjs +7 -7
- package/dist/components/toast.cjs.map +1 -1
- package/dist/components/tooltip.cjs +3 -3
- package/dist/components/tooltip.cjs.map +1 -1
- package/dist/components/typography.cjs +6 -6
- package/dist/components/typography.cjs.map +1 -1
- package/dist/components/wizard-layout.cjs +8 -8
- package/dist/components/wizard-layout.cjs.map +1 -1
- package/dist/lib/input-box-variants.cjs +9 -9
- package/dist/lib/input-box-variants.cjs.map +1 -1
- package/dist/styles/spark-default.css +11 -0
- package/dist/utils/cn.cjs +2 -2
- package/dist/utils/cn.d.cts +1 -1
- package/dist/utils/cn.d.ts +1 -1
- package/dist/utils/cn.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-date.cjs","names":["React","Popover","PopoverAnchor","InputGroup","InputGroupInput","InputGroupAddon","PopoverTrigger","Button","CalendarMonth","PopoverContent","Calendar"],"sources":["../../src/components/input-date.tsx"],"sourcesContent":["'use client'\n\nimport { CalendarMonth } from '@epilot/spark-icons'\nimport { apply, formatDate, isDateMaskKey, parseDate } from 'ictus'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { Button } from './button'\nimport { Calendar, type CalendarProps } from './calendar'\nimport { InputGroup, InputGroupAddon, InputGroupInput } from './input-group'\nimport {\n Popover,\n PopoverAnchor,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\nfunction useControllableState<T>({\n defaultProp,\n onChange,\n prop,\n}: {\n defaultProp: T\n onChange?: (value: T) => void\n prop?: T\n}) {\n const [uncontrolled, setUncontrolled] = React.useState(defaultProp)\n const isControlled = prop !== undefined\n const value = isControlled ? prop : uncontrolled\n\n const setValue = React.useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next)\n onChange?.(next)\n },\n [isControlled, onChange],\n )\n\n return [value, setValue] as const\n}\n\nexport type InputDateProps = Omit<\n React.ComponentProps<'input'>,\n 'children' | 'defaultValue' | 'onChange' | 'readOnly' | 'type' | 'value'\n> & {\n calendarLabel: string\n calendarProps?: Omit<CalendarProps, 'mode' | 'onSelect' | 'selected'>\n defaultOpen?: boolean\n defaultValue?: string\n onDateChange?: (date: Date | undefined) => void\n onOpenChange?: (open: boolean) => void\n onValueChange?: (value: string) => void\n open?: boolean\n pickerOnly?: boolean\n separator?: string\n value?: string\n}\n\nconst InputDate = React.forwardRef<HTMLInputElement, InputDateProps>(\n function InputDate(\n {\n calendarLabel,\n calendarProps,\n className,\n defaultOpen = false,\n defaultValue = '',\n disabled,\n id,\n onDateChange,\n onKeyDown,\n onOpenChange,\n onValueChange,\n open: openProp,\n pickerOnly = false,\n placeholder,\n separator = '.',\n value: valueProp,\n ...props\n },\n ref,\n ) {\n const inputRef = React.useRef<HTMLInputElement>(null)\n const [text, setText] = useControllableState({\n defaultProp: defaultValue,\n onChange: onValueChange,\n prop: valueProp,\n })\n const [open, setOpenState] = useControllableState({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: openProp,\n })\n const selected = parseDate(text)\n const [month, setMonth] = React.useState<Date | undefined>(\n () => selected ?? calendarProps?.month,\n )\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (next && calendarProps?.month === undefined) {\n setMonth(parseDate(text) ?? new Date())\n }\n setOpenState(next)\n },\n [calendarProps?.month, setOpenState, text],\n )\n\n const commit = React.useCallback(\n (next: string) => {\n if (next === text) return\n setText(next)\n onDateChange?.(parseDate(next))\n },\n [onDateChange, setText, text],\n )\n\n const setInputRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n },\n [ref],\n )\n\n return (\n <Popover onOpenChange={setOpen} open={open}>\n <PopoverAnchor render={<InputGroup className={className} />}>\n <InputGroupInput\n autoComplete=\"off\"\n {...props}\n className={cn(pickerOnly && 'cursor-pointer')}\n disabled={disabled}\n id={id}\n inputMode={pickerOnly ? undefined : 'numeric'}\n onChange={() => {}}\n onClick={\n pickerOnly && !disabled\n ? (event) => {\n props.onClick?.(event)\n if (!event.defaultPrevented) setOpen(true)\n }\n : props.onClick\n }\n onKeyDown={(event) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n setOpen(true)\n return\n }\n if (pickerOnly || !isDateMaskKey(event.key)) return\n event.preventDefault()\n const next = apply({\n caret: event.currentTarget.selectionStart ?? 0,\n key: event.key,\n selectionEnd: event.currentTarget.selectionEnd ?? undefined,\n separator,\n value: event.currentTarget.value,\n })\n commit(next.value)\n const caret = next.caret\n const input = inputRef.current\n requestAnimationFrame(() => {\n input?.setSelectionRange(caret, caret)\n })\n }}\n placeholder={placeholder ?? `DD${separator}MM${separator}YYYY`}\n readOnly={pickerOnly}\n ref={setInputRef}\n spellCheck={false}\n value={text}\n />\n <InputGroupAddon align=\"inline-end\">\n <PopoverTrigger\n render={\n <Button\n aria-label={calendarLabel}\n color=\"neutral\"\n disabled={disabled}\n size=\"icon-small\"\n styleVariant=\"ghost\"\n >\n <CalendarMonth />\n </Button>\n }\n />\n </InputGroupAddon>\n </PopoverAnchor>\n <PopoverContent\n align=\"start\"\n aria-label={calendarLabel}\n className=\"w-auto p-0\"\n >\n <Calendar\n {...calendarProps}\n mode=\"single\"\n month={calendarProps?.month ?? month}\n onMonthChange={(next) => {\n calendarProps?.onMonthChange?.(next)\n if (calendarProps?.month === undefined) setMonth(next)\n }}\n onSelect={(next) => {\n commit(next ? formatDate(next, separator) : '')\n setOpen(false)\n }}\n selected={selected}\n />\n </PopoverContent>\n </Popover>\n )\n },\n)\n\nexport { InputDate }\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAS,qBAAwB,EAC/B,aACA,UACA,QAKC;CACD,MAAM,CAAC,cAAc,mBAAmBA,MAAM,SAAS,WAAW;CAClE,MAAM,eAAe,SAAS,KAAA;CAW9B,OAAO,CAVO,eAAe,OAAO,cAEnBA,MAAM,aACpB,SAAY;EACX,IAAI,CAAC,cAAc,gBAAgB,IAAI;EACvC,WAAW,IAAI;CACjB,GACA,CAAC,cAAc,QAAQ,CAGH,CAAC;AACzB;AAmBA,MAAM,YAAYA,MAAM,WACtB,SAAS,UACP,EACE,eACA,eACA,WACA,cAAc,OACd,eAAe,IACf,UACA,IACA,cACA,WACA,cACA,eACA,MAAM,UACN,aAAa,OACb,aACA,YAAY,KACZ,OAAO,WACP,GAAG,SAEL,KACA;CACA,MAAM,WAAWA,MAAM,OAAyB,IAAI;CACpD,MAAM,CAAC,MAAM,WAAW,qBAAqB;EAC3C,aAAa;EACb,UAAU;EACV,MAAM;CACR,CAAC;CACD,MAAM,CAAC,MAAM,gBAAgB,qBAAqB;EAChD,aAAa;EACb,UAAU;EACV,MAAM;CACR,CAAC;CACD,MAAM,YAAA,GAAA,MAAA,WAAqB,IAAI;CAC/B,MAAM,CAAC,OAAO,YAAYA,MAAM,eACxB,YAAY,eAAe,KACnC;CACA,MAAM,UAAUA,MAAM,aACnB,SAAkB;EACjB,IAAI,QAAQ,eAAe,UAAU,KAAA,GACnC,UAAA,GAAA,MAAA,WAAmB,IAAI,qBAAK,IAAI,KAAK,CAAC;EAExC,aAAa,IAAI;CACnB,GACA;EAAC,eAAe;EAAO;EAAc;CAAI,CAC3C;CAEA,MAAM,SAASA,MAAM,aAClB,SAAiB;EAChB,IAAI,SAAS,MAAM;EACnB,QAAQ,IAAI;EACZ,gBAAA,GAAA,MAAA,WAAyB,IAAI,CAAC;CAChC,GACA;EAAC;EAAc;EAAS;CAAI,CAC9B;CAEA,MAAM,cAAcA,MAAM,aACvB,SAAkC;EACjC,SAAS,UAAU;EACnB,IAAI,OAAO,QAAQ,YAAY,IAAI,IAAI;OAClC,IAAI,KAAK,IAAI,UAAU;CAC9B,GACA,CAAC,GAAG,CACN;CAEA,OACE,iBAAA,GAAA,kBAAA,MAACC,2BAAAA,SAAD;EAAS,cAAc;EAAe;YAAtC,CACE,iBAAA,GAAA,kBAAA,MAACC,2BAAAA,eAAD;GAAe,QAAQ,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,YAAD,EAAuB,UAAY,CAAA;aAA1D,CACE,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,iBAAD;IACE,cAAa;IACb,GAAI;IACJ,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"input-date.cjs","names":["React","Popover","PopoverAnchor","InputGroup","InputGroupInput","InputGroupAddon","PopoverTrigger","Button","CalendarMonth","PopoverContent","Calendar"],"sources":["../../src/components/input-date.tsx"],"sourcesContent":["'use client'\n\nimport { CalendarMonth } from '@epilot/spark-icons'\nimport { apply, formatDate, isDateMaskKey, parseDate } from 'ictus'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { Button } from './button'\nimport { Calendar, type CalendarProps } from './calendar'\nimport { InputGroup, InputGroupAddon, InputGroupInput } from './input-group'\nimport {\n Popover,\n PopoverAnchor,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\nfunction useControllableState<T>({\n defaultProp,\n onChange,\n prop,\n}: {\n defaultProp: T\n onChange?: (value: T) => void\n prop?: T\n}) {\n const [uncontrolled, setUncontrolled] = React.useState(defaultProp)\n const isControlled = prop !== undefined\n const value = isControlled ? prop : uncontrolled\n\n const setValue = React.useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next)\n onChange?.(next)\n },\n [isControlled, onChange],\n )\n\n return [value, setValue] as const\n}\n\nexport type InputDateProps = Omit<\n React.ComponentProps<'input'>,\n 'children' | 'defaultValue' | 'onChange' | 'readOnly' | 'type' | 'value'\n> & {\n calendarLabel: string\n calendarProps?: Omit<CalendarProps, 'mode' | 'onSelect' | 'selected'>\n defaultOpen?: boolean\n defaultValue?: string\n onDateChange?: (date: Date | undefined) => void\n onOpenChange?: (open: boolean) => void\n onValueChange?: (value: string) => void\n open?: boolean\n pickerOnly?: boolean\n separator?: string\n value?: string\n}\n\nconst InputDate = React.forwardRef<HTMLInputElement, InputDateProps>(\n function InputDate(\n {\n calendarLabel,\n calendarProps,\n className,\n defaultOpen = false,\n defaultValue = '',\n disabled,\n id,\n onDateChange,\n onKeyDown,\n onOpenChange,\n onValueChange,\n open: openProp,\n pickerOnly = false,\n placeholder,\n separator = '.',\n value: valueProp,\n ...props\n },\n ref,\n ) {\n const inputRef = React.useRef<HTMLInputElement>(null)\n const [text, setText] = useControllableState({\n defaultProp: defaultValue,\n onChange: onValueChange,\n prop: valueProp,\n })\n const [open, setOpenState] = useControllableState({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: openProp,\n })\n const selected = parseDate(text)\n const [month, setMonth] = React.useState<Date | undefined>(\n () => selected ?? calendarProps?.month,\n )\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (next && calendarProps?.month === undefined) {\n setMonth(parseDate(text) ?? new Date())\n }\n setOpenState(next)\n },\n [calendarProps?.month, setOpenState, text],\n )\n\n const commit = React.useCallback(\n (next: string) => {\n if (next === text) return\n setText(next)\n onDateChange?.(parseDate(next))\n },\n [onDateChange, setText, text],\n )\n\n const setInputRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n },\n [ref],\n )\n\n return (\n <Popover onOpenChange={setOpen} open={open}>\n <PopoverAnchor render={<InputGroup className={className} />}>\n <InputGroupInput\n autoComplete=\"off\"\n {...props}\n className={cn(pickerOnly && 'cursor-pointer')}\n disabled={disabled}\n id={id}\n inputMode={pickerOnly ? undefined : 'numeric'}\n onChange={() => {}}\n onClick={\n pickerOnly && !disabled\n ? (event) => {\n props.onClick?.(event)\n if (!event.defaultPrevented) setOpen(true)\n }\n : props.onClick\n }\n onKeyDown={(event) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n setOpen(true)\n return\n }\n if (pickerOnly || !isDateMaskKey(event.key)) return\n event.preventDefault()\n const next = apply({\n caret: event.currentTarget.selectionStart ?? 0,\n key: event.key,\n selectionEnd: event.currentTarget.selectionEnd ?? undefined,\n separator,\n value: event.currentTarget.value,\n })\n commit(next.value)\n const caret = next.caret\n const input = inputRef.current\n requestAnimationFrame(() => {\n input?.setSelectionRange(caret, caret)\n })\n }}\n placeholder={placeholder ?? `DD${separator}MM${separator}YYYY`}\n readOnly={pickerOnly}\n ref={setInputRef}\n spellCheck={false}\n value={text}\n />\n <InputGroupAddon align=\"inline-end\">\n <PopoverTrigger\n render={\n <Button\n aria-label={calendarLabel}\n color=\"neutral\"\n disabled={disabled}\n size=\"icon-small\"\n styleVariant=\"ghost\"\n >\n <CalendarMonth />\n </Button>\n }\n />\n </InputGroupAddon>\n </PopoverAnchor>\n <PopoverContent\n align=\"start\"\n aria-label={calendarLabel}\n className=\"w-auto p-0\"\n >\n <Calendar\n {...calendarProps}\n mode=\"single\"\n month={calendarProps?.month ?? month}\n onMonthChange={(next) => {\n calendarProps?.onMonthChange?.(next)\n if (calendarProps?.month === undefined) setMonth(next)\n }}\n onSelect={(next) => {\n commit(next ? formatDate(next, separator) : '')\n setOpen(false)\n }}\n selected={selected}\n />\n </PopoverContent>\n </Popover>\n )\n },\n)\n\nexport { InputDate }\n"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ let react = require("react");
|
|
|
9
9
|
react = require_chunk.__toESM(react);
|
|
10
10
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
11
|
let class_variance_authority = require("class-variance-authority");
|
|
12
|
-
let
|
|
12
|
+
let cn = require("cn");
|
|
13
13
|
//#region src/components/input-group.tsx
|
|
14
14
|
const GHOST = "rounded-none border-0 border-b-2 px-0 focus-within:border-b-input-active has-[[data-slot=input][aria-invalid=true]]:border-b-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-b-red-a8! group-data-[invalid=true]/field:border-b-input-invalid! group-data-[invalid=true]/field:focus-within:border-b-red-a8!";
|
|
15
15
|
const inputGroupVariants = (0, class_variance_authority.cva)("group/input-group relative flex h-10 w-full min-w-0 items-center gap-2 bg-transparent transition-[color,border-color] outline-none motion-reduce:transition-none", {
|
|
@@ -113,7 +113,7 @@ function InputGroup({ className, ...props }) {
|
|
|
113
113
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
114
114
|
"data-slot": "input-group",
|
|
115
115
|
role: "group",
|
|
116
|
-
className: (0,
|
|
116
|
+
className: (0, cn.cn)(inputGroupVariants({
|
|
117
117
|
chrome: field?.labelPosition === "inset" ? "inset" : "box",
|
|
118
118
|
inputStyle,
|
|
119
119
|
inputColor
|
|
@@ -133,7 +133,7 @@ function InputGroupAddon({ className, align = "inline-start", ...props }) {
|
|
|
133
133
|
role: "presentation",
|
|
134
134
|
"data-slot": "input-group-addon",
|
|
135
135
|
"data-align": align,
|
|
136
|
-
className: (0,
|
|
136
|
+
className: (0, cn.cn)(inputGroupAddonVariants({ align }), className),
|
|
137
137
|
onClick: (event) => {
|
|
138
138
|
if (event.target.closest("button")) return;
|
|
139
139
|
event.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
@@ -143,7 +143,7 @@ function InputGroupAddon({ className, align = "inline-start", ...props }) {
|
|
|
143
143
|
}
|
|
144
144
|
function InputGroupText({ className, ...props }) {
|
|
145
145
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
146
|
-
className: (0,
|
|
146
|
+
className: (0, cn.cn)("flex items-center gap-2 text-xs text-gray-light [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4", className),
|
|
147
147
|
...props
|
|
148
148
|
});
|
|
149
149
|
}
|
|
@@ -151,7 +151,7 @@ const InputGroupInput = react.forwardRef(function InputGroupInput({ className, .
|
|
|
151
151
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_input.Input, {
|
|
152
152
|
"data-slot": "input",
|
|
153
153
|
variant: "none",
|
|
154
|
-
className: (0,
|
|
154
|
+
className: (0, cn.cn)("flex-1", className),
|
|
155
155
|
ref,
|
|
156
156
|
...props
|
|
157
157
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.cjs","names":["useFieldContext","useTheme","React","Input"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { useFieldContext } from './field'\nimport { Input, type InputProps } from './input'\nimport { useTheme } from './theme'\n\nconst GHOST =\n 'rounded-none border-0 border-b-2 px-0 focus-within:border-b-input-active has-[[data-slot=input][aria-invalid=true]]:border-b-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-b-red-a8! group-data-[invalid=true]/field:border-b-input-invalid! group-data-[invalid=true]/field:focus-within:border-b-red-a8!'\n\nconst inputGroupVariants = cva(\n 'group/input-group relative flex h-10 w-full min-w-0 items-center gap-2 bg-transparent transition-[color,border-color] outline-none motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; the group keeps the\n // classic underline (inputs inside stay chrome-less)\n inset: GHOST,\n // h-11 matches the standalone Input box\n box: 'h-11 rounded-md px-3 transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n // invalid hover deepens the error tint instead of the accent hover\n class:\n 'group-data-[invalid=true]/field:bg-base-error-soft focus-within:ring-2 focus-within:ring-offset-2 group-data-[invalid=true]/field:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]]:bg-base-error-soft has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]:not(:disabled)]:hover:bg-red-a4 group-data-[invalid=true]/field:has-[input:not(:disabled)]:hover:bg-red-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base focus-within:ring-input-active has-[input:not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft focus-within:ring-gray-a8 has-[input:not(:disabled)]:hover:bg-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: ['surface', 'outlined'],\n class:\n 'border group-data-[invalid=true]/field:border-input-invalid focus-within:ring-1 group-data-[invalid=true]/field:focus-within:border-input-invalid! group-data-[invalid=true]/field:focus-within:ring-red-a4! has-[[data-slot=input][aria-invalid=true]]:border-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-input-invalid! has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a4!',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class:\n 'border-input bg-base-accent-surface focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class:\n 'border-input-gray bg-base-gray-surface focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class:\n 'border-input focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class:\n 'border-input-gray focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n { chrome: 'box', inputStyle: 'ghost', class: GHOST },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: 'border-b-input',\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: 'border-b-input-gray',\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\n// The group carries the box + focus/invalid states; inputs inside are\n// chrome-less (variant=\"none\"). Style follows the enclosing Field's knobs,\n// else the <Theme> input-style/input-color knobs.\nfunction InputGroup({ className, ...props }: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const theme = useTheme()\n const inputStyle = field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n inputGroupVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n 'flex h-auto cursor-text items-center justify-center gap-2 py-2 text-sm font-medium text-gray-light select-none [&_svg:not([class*=size-])]:size-4',\n {\n variants: {\n align: {\n // button addons bring their own inner padding — pull them halfway\n // into the group's px so the visual gap matches the text side\n 'inline-start': 'order-first has-[>button]:-ml-2',\n 'inline-end': 'order-last has-[>button]:-mr-2',\n },\n },\n defaultVariants: {\n align: 'inline-start',\n },\n },\n)\n\nfunction InputGroupAddon({\n className,\n align = 'inline-start',\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n // chrome, not a control: the click only forwards focus to the input the\n // way a label would, and Tab already reaches that input directly\n role=\"presentation\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(event) => {\n if ((event.target as HTMLElement).closest('button')) return\n event.currentTarget.parentElement?.querySelector('input')?.focus()\n }}\n {...props}\n />\n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn(\n 'flex items-center gap-2 text-xs text-gray-light [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst InputGroupInput = React.forwardRef<HTMLInputElement, InputProps>(\n function InputGroupInput({ className, ...props }, ref) {\n return (\n <Input\n data-slot=\"input\"\n variant=\"none\"\n className={cn('flex-1', className)}\n ref={ref}\n {...props}\n />\n )\n },\n)\n\nexport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText }\n"],"mappings":";;;;;;;;;;;;;AASA,MAAM,QACJ;AAEF,MAAM,sBAAA,GAAA,yBAAA,KACJ,oKACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAO;GAEP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GAEZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY,CAAC,WAAW,UAAU;GAClC,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GAAE,QAAQ;GAAO,YAAY;GAAS,OAAO;EAAM;EACnD;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAKA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,MAAM,QAAQA,yBAAAA,gBAAgB;CAC9B,MAAM,QAAQC,yBAAAA,SAAS;CACvB,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAC5D,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"input-group.cjs","names":["useFieldContext","useTheme","React","Input"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { useFieldContext } from './field'\nimport { Input, type InputProps } from './input'\nimport { useTheme } from './theme'\n\nconst GHOST =\n 'rounded-none border-0 border-b-2 px-0 focus-within:border-b-input-active has-[[data-slot=input][aria-invalid=true]]:border-b-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-b-red-a8! group-data-[invalid=true]/field:border-b-input-invalid! group-data-[invalid=true]/field:focus-within:border-b-red-a8!'\n\nconst inputGroupVariants = cva(\n 'group/input-group relative flex h-10 w-full min-w-0 items-center gap-2 bg-transparent transition-[color,border-color] outline-none motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; the group keeps the\n // classic underline (inputs inside stay chrome-less)\n inset: GHOST,\n // h-11 matches the standalone Input box\n box: 'h-11 rounded-md px-3 transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n // invalid hover deepens the error tint instead of the accent hover\n class:\n 'group-data-[invalid=true]/field:bg-base-error-soft focus-within:ring-2 focus-within:ring-offset-2 group-data-[invalid=true]/field:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]]:bg-base-error-soft has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]:not(:disabled)]:hover:bg-red-a4 group-data-[invalid=true]/field:has-[input:not(:disabled)]:hover:bg-red-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base focus-within:ring-input-active has-[input:not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft focus-within:ring-gray-a8 has-[input:not(:disabled)]:hover:bg-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: ['surface', 'outlined'],\n class:\n 'border group-data-[invalid=true]/field:border-input-invalid focus-within:ring-1 group-data-[invalid=true]/field:focus-within:border-input-invalid! group-data-[invalid=true]/field:focus-within:ring-red-a4! has-[[data-slot=input][aria-invalid=true]]:border-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-input-invalid! has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a4!',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class:\n 'border-input bg-base-accent-surface focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class:\n 'border-input-gray bg-base-gray-surface focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class:\n 'border-input focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class:\n 'border-input-gray focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n { chrome: 'box', inputStyle: 'ghost', class: GHOST },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: 'border-b-input',\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: 'border-b-input-gray',\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\n// The group carries the box + focus/invalid states; inputs inside are\n// chrome-less (variant=\"none\"). Style follows the enclosing Field's knobs,\n// else the <Theme> input-style/input-color knobs.\nfunction InputGroup({ className, ...props }: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const theme = useTheme()\n const inputStyle = field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n inputGroupVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n 'flex h-auto cursor-text items-center justify-center gap-2 py-2 text-sm font-medium text-gray-light select-none [&_svg:not([class*=size-])]:size-4',\n {\n variants: {\n align: {\n // button addons bring their own inner padding — pull them halfway\n // into the group's px so the visual gap matches the text side\n 'inline-start': 'order-first has-[>button]:-ml-2',\n 'inline-end': 'order-last has-[>button]:-mr-2',\n },\n },\n defaultVariants: {\n align: 'inline-start',\n },\n },\n)\n\nfunction InputGroupAddon({\n className,\n align = 'inline-start',\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n // chrome, not a control: the click only forwards focus to the input the\n // way a label would, and Tab already reaches that input directly\n role=\"presentation\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(event) => {\n if ((event.target as HTMLElement).closest('button')) return\n event.currentTarget.parentElement?.querySelector('input')?.focus()\n }}\n {...props}\n />\n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn(\n 'flex items-center gap-2 text-xs text-gray-light [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst InputGroupInput = React.forwardRef<HTMLInputElement, InputProps>(\n function InputGroupInput({ className, ...props }, ref) {\n return (\n <Input\n data-slot=\"input\"\n variant=\"none\"\n className={cn('flex-1', className)}\n ref={ref}\n {...props}\n />\n )\n },\n)\n\nexport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText }\n"],"mappings":";;;;;;;;;;;;;AASA,MAAM,QACJ;AAEF,MAAM,sBAAA,GAAA,yBAAA,KACJ,oKACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAO;GAEP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GAEZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY,CAAC,WAAW,UAAU;GAClC,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GAAE,QAAQ;GAAO,YAAY;GAAS,OAAO;EAAM;EACnD;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAKA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,MAAM,QAAQA,yBAAAA,gBAAgB;CAC9B,MAAM,QAAQC,yBAAAA,SAAS;CACvB,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAC5D,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,YAAA,GAAA,GAAA,IACE,mBAAmB;GAAE,QANZ,OAAO,kBAAkB,UAAU,UAAU;GAMzB;GAAY;EAAW,CAAC,GACrD,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,2BAAA,GAAA,yBAAA,KACJ,qJACA;CACE,UAAU,EACR,OAAO;EAGL,gBAAgB;EAChB,cAAc;CAChB,EACF;CACA,iBAAiB,EACf,OAAO,eACT;AACF,CACF;AAEA,SAAS,gBAAgB,EACvB,WACA,QAAQ,gBACR,GAAG,SAC0E;CAC7E,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAGE,MAAK;EACL,aAAU;EACV,cAAY;EACZ,YAAA,GAAA,GAAA,IAAc,wBAAwB,EAAE,MAAM,CAAC,GAAG,SAAS;EAC3D,UAAU,UAAU;GAClB,IAAK,MAAM,OAAuB,QAAQ,QAAQ,GAAG;GACrD,MAAM,cAAc,eAAe,cAAc,OAAO,GAAG,MAAM;EACnE;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;EACE,YAAA,GAAA,GAAA,IACE,kHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,kBAAkBC,MAAM,WAC5B,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,OAAD;EACE,aAAU;EACV,SAAQ;EACR,YAAA,GAAA,GAAA,IAAc,UAAU,SAAS;EAC5B;EACL,GAAI;CACL,CAAA;AAEL,CACF"}
|
|
@@ -10,7 +10,7 @@ declare function InputGroup({
|
|
|
10
10
|
...props
|
|
11
11
|
}: React$1.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
declare const inputGroupAddonVariants: (props?: ({
|
|
13
|
-
align?: "inline-
|
|
13
|
+
align?: "inline-start" | "inline-end" | null | undefined;
|
|
14
14
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
15
|
declare function InputGroupAddon({
|
|
16
16
|
className,
|
|
@@ -10,7 +10,7 @@ declare function InputGroup({
|
|
|
10
10
|
...props
|
|
11
11
|
}: React$1.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
declare const inputGroupAddonVariants: (props?: ({
|
|
13
|
-
align?: "inline-
|
|
13
|
+
align?: "inline-start" | "inline-end" | null | undefined;
|
|
14
14
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
15
|
declare function InputGroupAddon({
|
|
16
16
|
className,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_components_field = require("./field.cjs");
|
|
4
3
|
const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
|
|
4
|
+
const require_components_field = require("./field.cjs");
|
|
5
5
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
6
|
let class_variance_authority = require("class-variance-authority");
|
|
7
7
|
let _base_ui_react_otp_field = require("@base-ui/react/otp-field");
|
|
8
|
-
let
|
|
8
|
+
let cn = require("cn");
|
|
9
9
|
//#region src/components/input-otp.tsx
|
|
10
10
|
const slotVariants = (0, class_variance_authority.cva)("flex w-11 min-w-0 items-center justify-center bg-transparent text-center text-base font-medium text-gray tabular-nums outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none", {
|
|
11
11
|
variants: {
|
|
@@ -94,7 +94,7 @@ function InputOtp({ length = 6, className, id: idProp, onComplete, slotAriaLabel
|
|
|
94
94
|
id,
|
|
95
95
|
validationType,
|
|
96
96
|
onValueComplete: onComplete,
|
|
97
|
-
className: (0,
|
|
97
|
+
className: (0, cn.cn)("flex items-center gap-2", className),
|
|
98
98
|
...props,
|
|
99
99
|
children: Array.from({ length }, (_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_otp_field.OTPField.Input, {
|
|
100
100
|
"aria-label": index === 0 ? void 0 : slotAriaLabel(index),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-otp.cjs","names":["GHOST_UNDERLINE","boxChrome","useFieldControl","OTPField"],"sources":["../../src/components/input-otp.tsx"],"sourcesContent":["import { OTPField, type OTPFieldRootProps } from '@base-ui/react/otp-field'\nimport { cva } from 'class-variance-authority'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\n// One code box per slot. Mirrors Input's box/underline carrier model so the\n// slots read like the rest of the input family across every style/color knob.\nconst slotVariants = cva(\n 'flex w-11 min-w-0 items-center justify-center bg-transparent text-center text-base font-medium text-gray tabular-nums outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; slots keep the classic\n // underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputOtpProps extends Pick<\n OTPFieldRootProps,\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'disabled'\n | 'className'\n | 'id'\n | 'validationType'\n> {\n /** Number of code slots. */\n length?: number\n /** Fired when every slot is filled. */\n onComplete?: OTPFieldRootProps['onValueComplete']\n /** Accessible name per slot (for localization). */\n slotAriaLabel?: (index: number) => string\n}\n\nfunction InputOtp({\n length = 6,\n className,\n id: idProp,\n onComplete,\n slotAriaLabel = (index) => `Character ${index + 1}`,\n validationType = 'alphanumeric',\n ...props\n}: InputOtpProps) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({ id: idProp })\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n\n return (\n <OTPField.Root\n data-slot=\"input-otp\"\n length={length}\n id={id}\n validationType={validationType}\n onValueComplete={onComplete}\n className={cn('flex items-center gap-2', className)}\n {...props}\n >\n {Array.from({ length }, (_, index) => (\n <OTPField.Input\n key={index}\n // the first slot is named by the Field label (Base UI ignores\n // aria-label there); the rest get a positional name for a11y\n aria-label={index === 0 ? undefined : slotAriaLabel(index)}\n aria-describedby={index === 0 ? ariaDescribedBy : undefined}\n aria-invalid={index === 0 ? ariaInvalid : undefined}\n className={slotVariants({ chrome, inputStyle, inputColor })}\n />\n ))}\n </OTPField.Root>\n )\n}\n\nexport { InputOtp }\nexport type { InputOtpProps }\n"],"mappings":";;;;;;;;;AAQA,MAAM,gBAAA,GAAA,yBAAA,KACJ,0XACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAoBA,SAAS,SAAS,EAChB,SAAS,GACT,WACA,IAAI,QACJ,YACA,iBAAiB,UAAU,aAAa,QAAQ,KAChD,iBAAiB,gBACjB,GAAG,SACa;CAChB,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB,EAAE,IAAI,OAAO,CAAC;CAChC,MAAM,SAAS,OAAO,kBAAkB,UAAU,UAAU;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,SAAS,MAAV;EACE,aAAU;EACF;EACJ;EACY;EAChB,iBAAiB;EACjB,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"input-otp.cjs","names":["GHOST_UNDERLINE","boxChrome","useFieldControl","OTPField"],"sources":["../../src/components/input-otp.tsx"],"sourcesContent":["import { OTPField, type OTPFieldRootProps } from '@base-ui/react/otp-field'\nimport { cva } from 'class-variance-authority'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\n// One code box per slot. Mirrors Input's box/underline carrier model so the\n// slots read like the rest of the input family across every style/color knob.\nconst slotVariants = cva(\n 'flex w-11 min-w-0 items-center justify-center bg-transparent text-center text-base font-medium text-gray tabular-nums outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; slots keep the classic\n // underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputOtpProps extends Pick<\n OTPFieldRootProps,\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'disabled'\n | 'className'\n | 'id'\n | 'validationType'\n> {\n /** Number of code slots. */\n length?: number\n /** Fired when every slot is filled. */\n onComplete?: OTPFieldRootProps['onValueComplete']\n /** Accessible name per slot (for localization). */\n slotAriaLabel?: (index: number) => string\n}\n\nfunction InputOtp({\n length = 6,\n className,\n id: idProp,\n onComplete,\n slotAriaLabel = (index) => `Character ${index + 1}`,\n validationType = 'alphanumeric',\n ...props\n}: InputOtpProps) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({ id: idProp })\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n\n return (\n <OTPField.Root\n data-slot=\"input-otp\"\n length={length}\n id={id}\n validationType={validationType}\n onValueComplete={onComplete}\n className={cn('flex items-center gap-2', className)}\n {...props}\n >\n {Array.from({ length }, (_, index) => (\n <OTPField.Input\n key={index}\n // the first slot is named by the Field label (Base UI ignores\n // aria-label there); the rest get a positional name for a11y\n aria-label={index === 0 ? undefined : slotAriaLabel(index)}\n aria-describedby={index === 0 ? ariaDescribedBy : undefined}\n aria-invalid={index === 0 ? ariaInvalid : undefined}\n className={slotVariants({ chrome, inputStyle, inputColor })}\n />\n ))}\n </OTPField.Root>\n )\n}\n\nexport { InputOtp }\nexport type { InputOtpProps }\n"],"mappings":";;;;;;;;;AAQA,MAAM,gBAAA,GAAA,yBAAA,KACJ,0XACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAoBA,SAAS,SAAS,EAChB,SAAS,GACT,WACA,IAAI,QACJ,YACA,iBAAiB,UAAU,aAAa,QAAQ,KAChD,iBAAiB,gBACjB,GAAG,SACa;CAChB,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB,EAAE,IAAI,OAAO,CAAC;CAChC,MAAM,SAAS,OAAO,kBAAkB,UAAU,UAAU;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,SAAS,MAAV;EACE,aAAU;EACF;EACJ;EACY;EAChB,iBAAiB;EACjB,YAAA,GAAA,GAAA,IAAc,2BAA2B,SAAS;EAClD,GAAI;YAEH,MAAM,KAAK,EAAE,OAAO,IAAI,GAAG,UAC1B,iBAAA,GAAA,kBAAA,KAACA,yBAAAA,SAAS,OAAV;GAIE,cAAY,UAAU,IAAI,KAAA,IAAY,cAAc,KAAK;GACzD,oBAAkB,UAAU,IAAI,kBAAkB,KAAA;GAClD,gBAAc,UAAU,IAAI,cAAc,KAAA;GAC1C,WAAW,aAAa;IAAE;IAAQ;IAAY;GAAW,CAAC;EAC3D,GAPM,KAON,CACF;CACY,CAAA;AAEnB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../utils/cn.js";
|
|
3
|
-
import { useFieldControl } from "./field.js";
|
|
4
3
|
import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
|
|
4
|
+
import { useFieldControl } from "./field.js";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
import { cva } from "class-variance-authority";
|
|
7
7
|
import { OTPField } from "@base-ui/react/otp-field";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require_chunk = require("../chunk-DY84GLCh.cjs");
|
|
4
|
-
const require_components_field = require("./field.cjs");
|
|
5
4
|
const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
|
|
5
|
+
const require_components_field = require("./field.cjs");
|
|
6
6
|
let react = require("react");
|
|
7
7
|
react = require_chunk.__toESM(react);
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
9
|
let class_variance_authority = require("class-variance-authority");
|
|
10
|
-
let
|
|
10
|
+
let cn = require("cn");
|
|
11
11
|
//#region src/components/input.tsx
|
|
12
12
|
const inputVariants = (0, class_variance_authority.cva)("flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none", {
|
|
13
13
|
variants: {
|
|
@@ -96,7 +96,7 @@ const Input = react.forwardRef(function Input({ variant, className, id: idProp,
|
|
|
96
96
|
});
|
|
97
97
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
98
98
|
"data-slot": "input",
|
|
99
|
-
className: (0,
|
|
99
|
+
className: (0, cn.cn)(inputVariants({
|
|
100
100
|
chrome: variant === "none" ? "none" : !variant && field?.labelPosition === "inset" ? "inset" : "box",
|
|
101
101
|
inputStyle,
|
|
102
102
|
inputColor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.cjs","names":["GHOST_UNDERLINE","boxChrome","React","useFieldControl"],"sources":["../../src/components/input.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport type { SparkInputStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\ntype InputVariant = SparkInputStyle | 'none'\n\nconst inputVariants = cva(\n 'flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n {\n variants: {\n chrome: {\n none: 'border-0 px-0',\n // inside an inset field the shell is the box; the input keeps the\n // classic underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md px-3 py-1 text-base transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputProps extends React.ComponentProps<'input'> {\n variant?: InputVariant\n}\n\n// forwardRef keeps refs working for React 18 consumers (ref-as-prop is 19-only)\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n variant,\n className,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n ...props\n },\n ref,\n) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({\n id: idProp,\n ariaDescribedBy: ariaDescribedByProp,\n variant: variant !== 'none' ? variant : undefined,\n })\n // an explicit variant prop keeps the box even inside an inset field\n const chrome =\n variant === 'none'\n ? 'none'\n : !variant && field?.labelPosition === 'inset'\n ? 'inset'\n : 'box'\n\n return (\n <input\n data-slot=\"input\"\n className={cn(\n inputVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n id={id}\n ref={ref}\n aria-invalid={ariaInvalid}\n {...props}\n aria-describedby={ariaDescribedBy}\n />\n )\n})\n\nexport { Input }\nexport type { InputProps, InputVariant }\n"],"mappings":";;;;;;;;;;;AASA,MAAM,iBAAA,GAAA,yBAAA,KACJ,2aACA;CACE,UAAU;EACR,QAAQ;GACN,MAAM;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAOA,MAAM,QAAQC,MAAM,WAAyC,SAAS,MACpE,EACE,SACA,WACA,IAAI,QACJ,oBAAoB,qBACpB,GAAG,SAEL,KACA;CACA,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB;EACd,IAAI;EACJ,iBAAiB;EACjB,SAAS,YAAY,SAAS,UAAU,KAAA;CAC1C,CAAC;CASH,OACE,iBAAA,GAAA,kBAAA,KAAC,SAAD;EACE,aAAU;EACV,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"input.cjs","names":["GHOST_UNDERLINE","boxChrome","React","useFieldControl"],"sources":["../../src/components/input.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport type { SparkInputStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\ntype InputVariant = SparkInputStyle | 'none'\n\nconst inputVariants = cva(\n 'flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n {\n variants: {\n chrome: {\n none: 'border-0 px-0',\n // inside an inset field the shell is the box; the input keeps the\n // classic underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md px-3 py-1 text-base transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputProps extends React.ComponentProps<'input'> {\n variant?: InputVariant\n}\n\n// forwardRef keeps refs working for React 18 consumers (ref-as-prop is 19-only)\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n variant,\n className,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n ...props\n },\n ref,\n) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({\n id: idProp,\n ariaDescribedBy: ariaDescribedByProp,\n variant: variant !== 'none' ? variant : undefined,\n })\n // an explicit variant prop keeps the box even inside an inset field\n const chrome =\n variant === 'none'\n ? 'none'\n : !variant && field?.labelPosition === 'inset'\n ? 'inset'\n : 'box'\n\n return (\n <input\n data-slot=\"input\"\n className={cn(\n inputVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n id={id}\n ref={ref}\n aria-invalid={ariaInvalid}\n {...props}\n aria-describedby={ariaDescribedBy}\n />\n )\n})\n\nexport { Input }\nexport type { InputProps, InputVariant }\n"],"mappings":";;;;;;;;;;;AASA,MAAM,iBAAA,GAAA,yBAAA,KACJ,2aACA;CACE,UAAU;EACR,QAAQ;GACN,MAAM;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAOA,MAAM,QAAQC,MAAM,WAAyC,SAAS,MACpE,EACE,SACA,WACA,IAAI,QACJ,oBAAoB,qBACpB,GAAG,SAEL,KACA;CACA,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB;EACd,IAAI;EACJ,iBAAiB;EACjB,SAAS,YAAY,SAAS,UAAU,KAAA;CAC1C,CAAC;CASH,OACE,iBAAA,GAAA,kBAAA,KAAC,SAAD;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,cAAc;GAAE,QAVpB,YAAY,SACR,SACA,CAAC,WAAW,OAAO,kBAAkB,UACnC,UACA;GAMsB;GAAY;EAAW,CAAC,GAChD,SACF;EACI;EACC;EACL,gBAAc;EACd,GAAI;EACJ,oBAAkB;CACnB,CAAA;AAEL,CAAC"}
|
package/dist/components/input.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../utils/cn.js";
|
|
3
|
-
import { useFieldControl } from "./field.js";
|
|
4
3
|
import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
|
|
4
|
+
import { useFieldControl } from "./field.js";
|
|
5
5
|
import * as React$1 from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
@@ -4,10 +4,10 @@ const require_chunk = require("../chunk-DY84GLCh.cjs");
|
|
|
4
4
|
let react = require("react");
|
|
5
5
|
react = require_chunk.__toESM(react);
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
-
let
|
|
7
|
+
let cn = require("cn");
|
|
8
8
|
//#region src/components/label.tsx
|
|
9
9
|
const Label = react.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
10
|
-
className: (0,
|
|
10
|
+
className: (0, cn.cn)("text-sm leading-5 font-normal text-gray", className),
|
|
11
11
|
ref,
|
|
12
12
|
...props
|
|
13
13
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.cjs","names":["React"],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}\n\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label\n className={cn('text-sm leading-5 font-normal text-gray', className)}\n ref={ref}\n {...props}\n />\n ),\n)\n\nLabel.displayName = 'Label'\n\nexport { Label }\nexport type { LabelProps }\n"],"mappings":";;;;;;;;AAKA,MAAM,QAAQA,MAAM,YACjB,EAAE,WAAW,GAAG,SAAS,QACxB,iBAAA,GAAA,kBAAA,KAAC,SAAD;CACE,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"label.cjs","names":["React"],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}\n\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label\n className={cn('text-sm leading-5 font-normal text-gray', className)}\n ref={ref}\n {...props}\n />\n ),\n)\n\nLabel.displayName = 'Label'\n\nexport { Label }\nexport type { LabelProps }\n"],"mappings":";;;;;;;;AAKA,MAAM,QAAQA,MAAM,YACjB,EAAE,WAAW,GAAG,SAAS,QACxB,iBAAA,GAAA,kBAAA,KAAC,SAAD;CACE,YAAA,GAAA,GAAA,IAAc,2CAA2C,SAAS;CAC7D;CACL,GAAI;AACL,CAAA,CAEL;AAEA,MAAM,cAAc"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
-
let
|
|
3
|
+
let cn = require("cn");
|
|
4
4
|
//#region src/components/layout.tsx
|
|
5
5
|
const PageContainer = ({ className, gap = 4, style, ...rest }) => {
|
|
6
6
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7
|
-
className: (0,
|
|
7
|
+
className: (0, cn.cn)("mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152", className),
|
|
8
8
|
style: {
|
|
9
9
|
"--page-container-gap-steps": gap,
|
|
10
10
|
...style
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.cjs","names":[],"sources":["../../src/components/layout.tsx"],"sourcesContent":["import type React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface PageContainerProps extends React.ComponentProps<'div'> {\n /** How many `--spark-layout-gap` units apart each section sits. */\n gap?: number\n}\n\nconst PageContainer = ({\n className,\n gap = 4,\n style,\n ...rest\n}: PageContainerProps) => {\n return (\n <div\n className={cn(\n 'mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152',\n className,\n )}\n style={\n {\n '--page-container-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n />\n )\n}\n\nexport default PageContainer\nexport type { PageContainerProps }\n"],"mappings":";;;;AAQA,MAAM,iBAAiB,EACrB,WACA,MAAM,GACN,OACA,GAAG,WACqB;CACxB,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"layout.cjs","names":[],"sources":["../../src/components/layout.tsx"],"sourcesContent":["import type React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface PageContainerProps extends React.ComponentProps<'div'> {\n /** How many `--spark-layout-gap` units apart each section sits. */\n gap?: number\n}\n\nconst PageContainer = ({\n className,\n gap = 4,\n style,\n ...rest\n}: PageContainerProps) => {\n return (\n <div\n className={cn(\n 'mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152',\n className,\n )}\n style={\n {\n '--page-container-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n />\n )\n}\n\nexport default PageContainer\nexport type { PageContainerProps }\n"],"mappings":";;;;AAQA,MAAM,iBAAiB,EACrB,WACA,MAAM,GACN,OACA,GAAG,WACqB;CACxB,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,GAAA,IACE,mHACA,SACF;EACA,OACE;GACE,8BAA8B;GAC9B,GAAG;EACL;EAEF,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -17,7 +17,7 @@ let _visx_shape = require("@visx/shape");
|
|
|
17
17
|
let _visx_curve = require("@visx/curve");
|
|
18
18
|
let _visx_tooltip = require("@visx/tooltip");
|
|
19
19
|
let _visx_vendor_d3_array = require("@visx/vendor/d3-array");
|
|
20
|
-
let
|
|
20
|
+
let cn = require("cn");
|
|
21
21
|
//#region src/components/line-chart.tsx
|
|
22
22
|
const DEFAULT_MARGIN = {
|
|
23
23
|
top: 16,
|
|
@@ -241,7 +241,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
|
|
|
241
241
|
});
|
|
242
242
|
if (width < 10 || height < 10) return null;
|
|
243
243
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
244
|
-
className: (0,
|
|
244
|
+
className: (0, cn.cn)("relative", className),
|
|
245
245
|
children: [
|
|
246
246
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
247
247
|
className: "block",
|
|
@@ -346,7 +346,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
|
|
|
346
346
|
clipPath: `url(#${plotClipId})`,
|
|
347
347
|
"data-testid": "chart-plot-clip",
|
|
348
348
|
children: series.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_shape.LinePath, {
|
|
349
|
-
className: (0,
|
|
349
|
+
className: (0, cn.cn)(LINE_COLORS[i % LINE_COLORS.length], s.className),
|
|
350
350
|
curve: resolveCurve(s.curve ?? defaultCurve),
|
|
351
351
|
data: s.data,
|
|
352
352
|
fill: "none",
|
|
@@ -477,7 +477,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
|
|
|
477
477
|
const d = nearestDatum(s.data, tooltipData.date);
|
|
478
478
|
if (!d || !withinDomain(s.data, tooltipData.date)) return null;
|
|
479
479
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
480
|
-
className: s.color ? void 0 : (0,
|
|
480
|
+
className: s.color ? void 0 : (0, cn.cn)(DOT_COLORS[i % DOT_COLORS.length]),
|
|
481
481
|
cx: xScale(d.date),
|
|
482
482
|
cy: yScale(d.value),
|
|
483
483
|
fill: s.color,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-chart.cjs","names":["curveMonotoneX","curveStep","curveStepAfter","curveStepBefore","curveLinear","localeNumberFormat","formatYAxisTick","React","useChartZoom","useReducedMotion","buildYAxisScale","useAnimatedChartDomain","buildTimeTicks","useMeasuredSize","clampTooltipPosition","Group","LinePath","ChartZoomResetButton","ChartTooltipCard"],"sources":["../../src/components/line-chart.tsx"],"sourcesContent":["import {\n curveLinear,\n curveMonotoneX,\n curveStep,\n curveStepAfter,\n curveStepBefore,\n} from '@visx/curve'\nimport { localPoint } from '@visx/event'\nimport { Group } from '@visx/group'\nimport { scaleLinear, scaleTime } from '@visx/scale'\nimport { LinePath } from '@visx/shape'\nimport { useTooltip } from '@visx/tooltip'\nimport { bisector, extent } from '@visx/vendor/d3-array'\nimport * as React from 'react'\nimport { useCallback, useMemo } from 'react'\nimport { useAnimatedChartDomain, useChartZoom } from '../hooks/use-chart-zoom'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { buildYAxisScale, formatYAxisTick } from '../utils/chart-scale'\nimport { buildTimeTicks } from '../utils/chart-time-ticks'\nimport type { TimeDomain } from '../utils/chart-zoom'\nimport { cn } from '../utils/cn'\nimport { localeNumberFormat } from '../utils/format'\nimport {\n ChartTooltipCard,\n type ChartTooltipRow,\n ChartZoomResetButton,\n clampTooltipPosition,\n useMeasuredSize,\n} from './chart'\n\nexport interface LineChartDatum {\n date: Date\n value: number\n}\n\nexport type LineChartCurve =\n | 'monotone'\n | 'step'\n | 'step-after'\n | 'step-before'\n | 'linear'\n\nexport interface LineChartSeries {\n id: string\n data: LineChartDatum[]\n /** Label shown in the hover tooltip. Defaults to `id`. */\n label?: React.ReactNode\n className?: string\n /**\n * CSS color for the tooltip swatch and hover dot (e.g. `var(--orange-9)`).\n * Defaults to the palette color for the series index. Set this whenever\n * `className` overrides the stroke so the tooltip stays in sync.\n */\n color?: string\n /** Curve interpolation type. Default: inherits from LineChartProps.curve */\n curve?: LineChartCurve\n /** Render as a dashed line */\n dashed?: boolean\n /** Custom dash pattern (e.g. \"8,4\" or \"4,2,1,2\"). Only applies when dashed is true. */\n dashPattern?: string\n}\n\nexport interface LineChartProps {\n series: LineChartSeries[]\n width: number\n height: number\n margin?: { top: number; right: number; bottom: number; left: number }\n /** Default curve for all series. Default: 'monotone' */\n curve?: LineChartCurve\n showGrid?: boolean\n showTooltip?: boolean\n className?: string\n xTickCount?: number\n yTickCount?: number\n /** Fixes the y-axis to an explicit `[min, max]`. Defaults to the data extent. */\n yDomain?: [number, number]\n /** Formats the x-axis tick labels. */\n formatDate?: (date: Date) => string\n /** Formats the tooltip title. Defaults to `formatDate`. */\n formatTooltipDate?: (date: Date) => string\n formatValue?: (value: number) => string\n /**\n * Unit shown once at the top of the y-axis (e.g. \"kW\"). When set, y-axis tick\n * labels render as plain numbers (matching BarChart / PowerHistoryChart)\n * instead of repeating `formatValue` on every tick. `formatValue` still feeds\n * the tooltip. Omit to keep the per-tick `formatValue` labels.\n */\n yAxisUnit?: string\n /** Overrides the y-axis tick formatter used when `yAxisUnit` is set. Defaults to the shared compact formatter. */\n formatYTick?: (value: number) => string\n /**\n * Vertical reference markers positioned on the time axis (e.g. sunrise /\n * sunset). Each renders a dashed line across the plot with an optional label.\n */\n referenceLines?: Array<{ key: string; date: Date; label?: React.ReactNode }>\n /**\n * HTML content pinned to the top of the plot at a given time (e.g. an hourly\n * weather icon). Positioned by the same time scale as the series, so it lines\n * up with the curve below it.\n */\n topContent?: Array<{ key: string; date: Date; content: React.ReactNode }>\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\nconst DEFAULT_MARGIN = { top: 16, right: 16, bottom: 40, left: 48 }\nconst DETAILED_X_AXIS_THRESHOLD = 6 * 60 * 60 * 1000\n\nconst CURVE_MAP = {\n monotone: curveMonotoneX,\n step: curveStep,\n 'step-after': curveStepAfter,\n 'step-before': curveStepBefore,\n linear: curveLinear,\n} as const\n\nconst resolveCurve = (type: LineChartCurve) => CURVE_MAP[type]\n\nconst dateBisector = bisector<LineChartDatum, Date>((d) => d.date)\nconst bisectDate = (data: LineChartDatum[], x: Date, lo?: number) =>\n dateBisector.left(data, x, lo)\n\n/** Whether `date` falls within a series' own x-range (data is sorted ascending). */\nfunction withinDomain(data: LineChartDatum[], date: Date): boolean {\n const first = data[0]\n const last = data[data.length - 1]\n if (!first || !last) return false\n const t = date.valueOf()\n return t >= first.date.valueOf() && t <= last.date.valueOf()\n}\n\n/**\n * y-domain padded 10% beyond the data extent. The baseline is pinned to 0 so\n * all-positive series render from the axis up; a series that dips below 0\n * (signed grid / battery power) extends the domain downward to keep the zero\n * crossing visible.\n */\nfunction computeYDomain(data: LineChartDatum[]): [number, number] {\n let min = 0\n let max = 0\n for (const d of data) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n if (min === max) return [min, min + 1]\n return [min * 1.1, max * 1.1]\n}\n\nfunction nearestDatum(\n data: LineChartDatum[],\n date: Date,\n): LineChartDatum | undefined {\n if (data.length === 0) return undefined\n const index = bisectDate(data, date, 1)\n const d0 = data[index - 1]\n const d1 = data[index]\n if (!d0) return d1\n if (!d1) return d0\n return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf()\n ? d1\n : d0\n}\n\nconst defaultFormatDate = (date: Date) =>\n date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n\nconst defaultValueFormat = localeNumberFormat()\nconst defaultFormatValue = (value: number) => defaultValueFormat.format(value)\n\nconst LINE_COLORS = [\n 'stroke-spark-9',\n 'stroke-green-9',\n 'stroke-blue-9',\n 'stroke-orange-9',\n 'stroke-red-9',\n]\n\nconst DOT_COLORS = [\n 'fill-spark-9',\n 'fill-green-9',\n 'fill-blue-9',\n 'fill-orange-9',\n 'fill-red-9',\n]\n\n// CSS-var colours matching LINE_COLORS, used for the tooltip legend dots.\nconst LEGEND_COLORS = [\n 'var(--spark-9)',\n 'var(--green-9)',\n 'var(--blue-9)',\n 'var(--orange-9)',\n 'var(--red-9)',\n]\n\nfunction toTimeDomain(dates: [Date, Date]): TimeDomain {\n return [dates[0].valueOf(), dates[1].valueOf()]\n}\n\nfunction fromTimeDomain(domain: TimeDomain): [Date, Date] {\n return [new Date(domain[0]), new Date(domain[1])]\n}\n\nfunction touchDistance(a: React.Touch, b: React.Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\n}\n\nfunction touchMidpoint(\n a: React.Touch,\n b: React.Touch,\n): {\n clientX: number\n clientY: number\n} {\n return {\n clientX: (a.clientX + b.clientX) / 2,\n clientY: (a.clientY + b.clientY) / 2,\n }\n}\n\nconst LineChart: React.FC<LineChartProps> = ({\n series,\n width,\n height,\n margin = DEFAULT_MARGIN,\n curve: defaultCurve = 'monotone',\n showGrid = true,\n showTooltip: enableTooltip = true,\n className,\n xTickCount = 5,\n yTickCount = 4,\n formatDate = defaultFormatDate,\n formatTooltipDate,\n formatValue = defaultFormatValue,\n yAxisUnit,\n formatYTick = formatYAxisTick,\n yDomain,\n referenceLines,\n topContent,\n zoomable = false,\n zoomResetLabel,\n zoomDomain: zoomDomainProp,\n onZoomDomainChange,\n}) => {\n const plotClipId = React.useId()\n const {\n showTooltip,\n hideTooltip,\n tooltipData,\n tooltipLeft,\n tooltipTop,\n tooltipOpen,\n } = useTooltip<{ date: Date }>()\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n const allData = useMemo(() => series.flatMap((s) => s.data), [series])\n\n const fullDomain = useMemo((): TimeDomain | null => {\n const ext = extent(allData, (d) => d.date.valueOf())\n if (ext[0] == null || ext[1] == null) return null\n return [ext[0], ext[1]]\n }, [allData])\n\n const controlledZoomDomain =\n zoomDomainProp === undefined\n ? undefined\n : zoomDomainProp == null\n ? null\n : toTimeDomain(zoomDomainProp)\n\n const handleZoomDomainChange = useCallback(\n (domain: TimeDomain | null) => {\n onZoomDomainChange?.(domain ? fromTimeDomain(domain) : null)\n },\n [onZoomDomainChange],\n )\n\n const zoom = useChartZoom({\n enabled: zoomable,\n fullDomain,\n zoomDomain: controlledZoomDomain,\n onZoomDomainChange: handleZoomDomainChange,\n })\n\n const xDomain = useMemo((): [Date, Date] => {\n if (zoom.zoomWindow) return fromTimeDomain(zoom.zoomWindow)\n const ext = extent(allData, (d) => d.date) as\n | [Date, Date]\n | [undefined, undefined]\n if (ext[0] && ext[1]) return [ext[0], ext[1]]\n const now = new Date()\n return [now, now]\n }, [allData, zoom.zoomWindow])\n\n const xScale = useMemo(\n () =>\n scaleTime({\n range: [0, innerWidth],\n domain: xDomain,\n }),\n [innerWidth, xDomain],\n )\n\n const visibleData = useMemo(() => {\n const [start, end] = xDomain\n const t0 = start.valueOf()\n const t1 = end.valueOf()\n return allData.filter((d) => {\n const t = d.date.valueOf()\n return t >= t0 && t <= t1\n })\n }, [allData, xDomain])\n\n const reducedMotion = useReducedMotion()\n\n // With a unit, the y-axis is generated by the shared scale util (nice ticks\n // + rounded bounds) so it matches BarChart / PowerHistoryChart exactly.\n const yAxisScale = useMemo(() => {\n if (yAxisUnit === undefined) return null\n let min = 0\n let max = 0\n for (const d of visibleData) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n return buildYAxisScale(min, max)\n }, [visibleData, yAxisUnit])\n\n const targetYDomain = useMemo((): TimeDomain => {\n if (yDomain) return yDomain\n if (yAxisScale) return [yAxisScale.min, yAxisScale.max]\n return scaleLinear({\n domain: computeYDomain(visibleData),\n nice: true,\n }).domain() as [number, number]\n }, [visibleData, yAxisScale, yDomain])\n\n const displayedYDomain = useAnimatedChartDomain(targetYDomain, {\n animateChanges: zoom.isPinching,\n reducedMotion,\n })\n\n const yScale = useMemo(\n () =>\n scaleLinear({\n range: [innerHeight, 0],\n domain: [displayedYDomain[0], displayedYDomain[1]],\n }),\n [displayedYDomain, innerHeight],\n )\n\n const xTicks = zoom.isZoomed\n ? buildTimeTicks(\n xDomain[0].valueOf(),\n xDomain[1].valueOf(),\n xTickCount,\n ).map((tick) => new Date(tick))\n : xScale.ticks(xTickCount)\n const yTicks = yAxisScale ? yAxisScale.ticks : yScale.ticks(yTickCount)\n const formatAxisDate =\n zoom.isZoomed &&\n xDomain[1].valueOf() - xDomain[0].valueOf() <= DETAILED_X_AXIS_THRESHOLD\n ? (formatTooltipDate ?? formatDate)\n : formatDate\n\n const domainXFromEvent = useCallback(\n (\n event:\n | React.MouseEvent<SVGRectElement>\n | React.PointerEvent<SVGRectElement>\n | React.TouchEvent<SVGRectElement>,\n ) => {\n const point = localPoint(event)\n if (!point) return null\n return xScale.invert(point.x - margin.left).valueOf()\n },\n [margin.left, xScale],\n )\n\n const handleTooltip = useCallback(\n (\n event:\n | React.TouchEvent<SVGRectElement>\n | React.MouseEvent<SVGRectElement>,\n ) => {\n if (!enableTooltip || zoom.isBrushing || zoom.isPanning) return\n\n const point = localPoint(event)\n if (!point) return\n\n const x0 = xScale.invert(point.x - margin.left)\n\n // Snap to the data point closest to the cursor across all series, so the\n // cursor line + tooltip line up with real values.\n let anchorDate: Date | null = null\n let bestDistance = Infinity\n for (const s of series) {\n const d = nearestDatum(s.data, x0)\n if (!d) continue\n const distance = Math.abs(d.date.valueOf() - x0.valueOf())\n if (distance < bestDistance) {\n bestDistance = distance\n anchorDate = d.date\n }\n }\n\n if (!anchorDate) return\n\n showTooltip({\n tooltipData: { date: anchorDate },\n tooltipLeft: xScale(anchorDate) + margin.left,\n tooltipTop: margin.top,\n })\n },\n [\n enableTooltip,\n margin,\n series,\n showTooltip,\n xScale,\n zoom.isBrushing,\n zoom.isPanning,\n ],\n )\n\n const tooltipRows: ChartTooltipRow[] = tooltipData\n ? series.flatMap((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return []\n return [\n {\n key: s.id,\n label: s.label ?? s.id,\n color:\n s.color ?? (LEGEND_COLORS[i % LEGEND_COLORS.length] as string),\n value: formatValue(d.value),\n marker: s.dashed ? ('dashed-line' as const) : ('dot' as const),\n },\n ]\n })\n : []\n\n const [tooltipRef, tooltipSize] = useMeasuredSize<HTMLDivElement>()\n const tooltipPos = clampTooltipPosition({\n anchorX: tooltipLeft ?? 0,\n anchorY: tooltipTop ?? margin.top,\n width,\n height,\n tipWidth: tooltipSize.width,\n tipHeight: tooltipSize.height,\n placement: 'beside',\n })\n\n if (width < 10 || height < 10) return null\n\n return (\n <div className={cn('relative', className)}>\n <svg className=\"block\" height={height} width={width}>\n <defs>\n <clipPath id={plotClipId}>\n <rect height={innerHeight} width={innerWidth} x={0} y={0} />\n </clipPath>\n </defs>\n <Group left={margin.left} top={margin.top}>\n {/* Grid lines */}\n {showGrid &&\n yTicks.map((tick) => (\n <line\n className=\"stroke-gray-a4\"\n key={`grid-y-${tick}`}\n strokeDasharray=\"4,4\"\n x1={0}\n x2={innerWidth}\n y1={yScale(tick)}\n y2={yScale(tick)}\n />\n ))}\n\n {/* X axis */}\n <line\n className=\"stroke-gray-a6\"\n x1={0}\n x2={innerWidth}\n y1={innerHeight}\n y2={innerHeight}\n />\n\n {/* Reference markers (e.g. sunrise / sunset) */}\n {referenceLines?.map((ref) => {\n const x = xScale(ref.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n // Sit the label beside the line, on whichever side keeps it in\n // frame: right of a left-half marker, left of a right-half one.\n const anchorEnd = x > innerWidth / 2\n return (\n <g key={ref.key} pointerEvents=\"none\">\n <line\n className=\"stroke-orange-8\"\n strokeDasharray=\"3,3\"\n x1={x}\n x2={x}\n y1={0}\n y2={innerHeight}\n />\n {ref.label != null && (\n <text\n className=\"fill-orange-11 text-[10px]\"\n dy=\"0.9em\"\n textAnchor={anchorEnd ? 'end' : 'start'}\n x={x + (anchorEnd ? -4 : 4)}\n y={0}\n >\n {ref.label}\n </text>\n )}\n </g>\n )\n })}\n\n {/* X axis labels */}\n {xTicks.map((tick, index) => (\n <text\n dy=\"1em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n key={`x-${tick.valueOf()}`}\n textAnchor={\n index === 0\n ? 'start'\n : index === xTicks.length - 1\n ? 'end'\n : 'middle'\n }\n x={xScale(tick)}\n y={innerHeight + 8}\n >\n {formatAxisDate(tick)}\n </text>\n ))}\n\n {/* Y axis. With `yAxisUnit`, matches BarChart: a vertical axis line,\n short tick marks, plain numeric ticks, and the unit as a bold\n top-left header (top tick hidden). Without it, ticks repeat\n `formatValue` and no axis line/marks are drawn. */}\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a6)\"\n strokeWidth={1}\n x1={0}\n x2={0}\n y1={0}\n y2={innerHeight}\n />\n )}\n {yTicks.map((tick) => {\n const y = yScale(tick)\n return (\n <g key={`y-${tick}`}>\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a8)\"\n strokeWidth={1}\n x1={-4}\n x2={0}\n y1={y}\n y2={y}\n />\n )}\n <text\n dy=\"0.32em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n textAnchor=\"end\"\n x={yAxisUnit !== undefined ? -7 : -4}\n y={y}\n >\n {yAxisUnit !== undefined\n ? formatYTick(tick)\n : formatValue(tick)}\n </text>\n </g>\n )\n })}\n {yAxisUnit !== undefined && (\n <text\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n fontWeight={600}\n textAnchor=\"start\"\n x={-margin.left}\n y={-6}\n >\n {yAxisUnit}\n </text>\n )}\n\n <g clipPath={`url(#${plotClipId})`} data-testid=\"chart-plot-clip\">\n {series.map((s, i) => (\n <LinePath\n className={cn(LINE_COLORS[i % LINE_COLORS.length], s.className)}\n curve={resolveCurve(s.curve ?? defaultCurve)}\n data={s.data}\n fill=\"none\"\n key={s.id}\n strokeDasharray={\n s.dashed ? (s.dashPattern ?? '6,4') : undefined\n }\n strokeWidth={2}\n x={(d) => xScale(d.date)}\n y={(d) => yScale(d.value)}\n />\n ))}\n </g>\n\n {zoom.brushBand && (\n <rect\n data-testid=\"chart-brush-band\"\n fill=\"var(--spark-a4)\"\n height={innerHeight}\n pointerEvents=\"none\"\n width={Math.abs(\n xScale(new Date(zoom.brushBand[1])) -\n xScale(new Date(zoom.brushBand[0])),\n )}\n x={Math.min(\n xScale(new Date(zoom.brushBand[0])),\n xScale(new Date(zoom.brushBand[1])),\n )}\n y={0}\n />\n )}\n\n {(enableTooltip || zoomable) && (\n <rect\n fill=\"transparent\"\n height={innerHeight}\n style={zoomable ? { touchAction: 'pan-y' } : undefined}\n width={innerWidth}\n x={0}\n y={0}\n onMouseLeave={() => {\n if (!zoom.isBrushing) hideTooltip()\n }}\n onMouseMove={(event) => {\n if (zoom.isBrushing) {\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n return\n }\n handleTooltip(event)\n }}\n onPointerDown={(event) => {\n if (!zoomable || event.pointerType === 'touch') return\n if (event.button !== 0) return\n const domainX = domainXFromEvent(event)\n if (domainX == null) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n hideTooltip()\n zoom.onPointerDown(domainX)\n }}\n onPointerMove={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n }}\n onPointerUp={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerUp(domainX)\n else zoom.onPointerCancel()\n }}\n onPointerCancel={() => {\n zoom.onPointerCancel()\n }}\n onDoubleClick={() => {\n if (zoomable) zoom.onDoubleClick()\n }}\n onTouchStart={(event) => {\n if (!zoomable) return\n if (event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchStart(touchDistance(a, b), midpoint)\n hideTooltip()\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanStart({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n hideTooltip()\n }\n }}\n onTouchMove={(event) => {\n if (zoomable && event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchMove(touchDistance(a, b), midpoint)\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanMove({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n return\n }\n if (event.touches.length === 1) handleTooltip(event)\n }}\n onTouchEnd={(event) => {\n if (zoomable && event.touches.length < 2) zoom.onPinchEnd()\n if (event.touches.length === 0) {\n if (zoomable) zoom.onPanEnd()\n if (zoomable) zoom.onTap()\n hideTooltip()\n }\n }}\n onTouchCancel={() => {\n zoom.onPinchEnd()\n zoom.onPanEnd()\n }}\n />\n )}\n\n {/* Cursor line + a dot per series */}\n {tooltipOpen &&\n tooltipData &&\n !zoom.isBrushing &&\n !zoom.isPanning && (\n <>\n <line\n className=\"stroke-gray-a6\"\n pointerEvents=\"none\"\n strokeDasharray=\"4,4\"\n x1={xScale(tooltipData.date)}\n x2={xScale(tooltipData.date)}\n y1={0}\n y2={innerHeight}\n />\n {series.map((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return null\n return (\n <circle\n key={s.id}\n className={\n s.color\n ? undefined\n : cn(DOT_COLORS[i % DOT_COLORS.length])\n }\n cx={xScale(d.date)}\n cy={yScale(d.value)}\n fill={s.color}\n pointerEvents=\"none\"\n r={4}\n stroke=\"white\"\n strokeWidth={2}\n />\n )\n })}\n </>\n )}\n </Group>\n </svg>\n\n {topContent && topContent.length > 0 && (\n <div\n className=\"pointer-events-none absolute overflow-hidden\"\n style={{\n height: margin.top,\n left: margin.left,\n top: 0,\n width: innerWidth,\n }}\n >\n {topContent.map((item) => {\n const x = xScale(item.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n return (\n <div\n key={item.key}\n className=\"absolute -translate-x-1/2\"\n style={{ left: x, top: 0 }}\n >\n {item.content}\n </div>\n )\n })}\n </div>\n )}\n\n {zoom.isZoomed && zoomResetLabel && (\n <ChartZoomResetButton label={zoomResetLabel} onReset={zoom.resetZoom} />\n )}\n\n <div\n ref={tooltipRef}\n className=\"pointer-events-none absolute z-10\"\n style={{\n left: tooltipPos.left,\n top: tooltipPos.top,\n opacity:\n tooltipOpen && tooltipData && !zoom.isPanning && !zoom.isBrushing\n ? 1\n : 0,\n transition: reducedMotion\n ? 'opacity 140ms ease-out'\n : 'left 140ms ease-out, top 140ms ease-out, opacity 140ms ease-out',\n }}\n >\n {tooltipData && (\n <ChartTooltipCard\n label={(formatTooltipDate ?? formatDate)(tooltipData.date)}\n rows={tooltipRows}\n />\n )}\n </div>\n </div>\n )\n}\n\nexport { LineChart }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"line-chart.cjs","names":["curveMonotoneX","curveStep","curveStepAfter","curveStepBefore","curveLinear","localeNumberFormat","formatYAxisTick","React","useChartZoom","useReducedMotion","buildYAxisScale","useAnimatedChartDomain","buildTimeTicks","useMeasuredSize","clampTooltipPosition","Group","LinePath","ChartZoomResetButton","ChartTooltipCard"],"sources":["../../src/components/line-chart.tsx"],"sourcesContent":["import {\n curveLinear,\n curveMonotoneX,\n curveStep,\n curveStepAfter,\n curveStepBefore,\n} from '@visx/curve'\nimport { localPoint } from '@visx/event'\nimport { Group } from '@visx/group'\nimport { scaleLinear, scaleTime } from '@visx/scale'\nimport { LinePath } from '@visx/shape'\nimport { useTooltip } from '@visx/tooltip'\nimport { bisector, extent } from '@visx/vendor/d3-array'\nimport * as React from 'react'\nimport { useCallback, useMemo } from 'react'\nimport { useAnimatedChartDomain, useChartZoom } from '../hooks/use-chart-zoom'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { buildYAxisScale, formatYAxisTick } from '../utils/chart-scale'\nimport { buildTimeTicks } from '../utils/chart-time-ticks'\nimport type { TimeDomain } from '../utils/chart-zoom'\nimport { cn } from '../utils/cn'\nimport { localeNumberFormat } from '../utils/format'\nimport {\n ChartTooltipCard,\n type ChartTooltipRow,\n ChartZoomResetButton,\n clampTooltipPosition,\n useMeasuredSize,\n} from './chart'\n\nexport interface LineChartDatum {\n date: Date\n value: number\n}\n\nexport type LineChartCurve =\n | 'monotone'\n | 'step'\n | 'step-after'\n | 'step-before'\n | 'linear'\n\nexport interface LineChartSeries {\n id: string\n data: LineChartDatum[]\n /** Label shown in the hover tooltip. Defaults to `id`. */\n label?: React.ReactNode\n className?: string\n /**\n * CSS color for the tooltip swatch and hover dot (e.g. `var(--orange-9)`).\n * Defaults to the palette color for the series index. Set this whenever\n * `className` overrides the stroke so the tooltip stays in sync.\n */\n color?: string\n /** Curve interpolation type. Default: inherits from LineChartProps.curve */\n curve?: LineChartCurve\n /** Render as a dashed line */\n dashed?: boolean\n /** Custom dash pattern (e.g. \"8,4\" or \"4,2,1,2\"). Only applies when dashed is true. */\n dashPattern?: string\n}\n\nexport interface LineChartProps {\n series: LineChartSeries[]\n width: number\n height: number\n margin?: { top: number; right: number; bottom: number; left: number }\n /** Default curve for all series. Default: 'monotone' */\n curve?: LineChartCurve\n showGrid?: boolean\n showTooltip?: boolean\n className?: string\n xTickCount?: number\n yTickCount?: number\n /** Fixes the y-axis to an explicit `[min, max]`. Defaults to the data extent. */\n yDomain?: [number, number]\n /** Formats the x-axis tick labels. */\n formatDate?: (date: Date) => string\n /** Formats the tooltip title. Defaults to `formatDate`. */\n formatTooltipDate?: (date: Date) => string\n formatValue?: (value: number) => string\n /**\n * Unit shown once at the top of the y-axis (e.g. \"kW\"). When set, y-axis tick\n * labels render as plain numbers (matching BarChart / PowerHistoryChart)\n * instead of repeating `formatValue` on every tick. `formatValue` still feeds\n * the tooltip. Omit to keep the per-tick `formatValue` labels.\n */\n yAxisUnit?: string\n /** Overrides the y-axis tick formatter used when `yAxisUnit` is set. Defaults to the shared compact formatter. */\n formatYTick?: (value: number) => string\n /**\n * Vertical reference markers positioned on the time axis (e.g. sunrise /\n * sunset). Each renders a dashed line across the plot with an optional label.\n */\n referenceLines?: Array<{ key: string; date: Date; label?: React.ReactNode }>\n /**\n * HTML content pinned to the top of the plot at a given time (e.g. an hourly\n * weather icon). Positioned by the same time scale as the series, so it lines\n * up with the curve below it.\n */\n topContent?: Array<{ key: string; date: Date; content: React.ReactNode }>\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\nconst DEFAULT_MARGIN = { top: 16, right: 16, bottom: 40, left: 48 }\nconst DETAILED_X_AXIS_THRESHOLD = 6 * 60 * 60 * 1000\n\nconst CURVE_MAP = {\n monotone: curveMonotoneX,\n step: curveStep,\n 'step-after': curveStepAfter,\n 'step-before': curveStepBefore,\n linear: curveLinear,\n} as const\n\nconst resolveCurve = (type: LineChartCurve) => CURVE_MAP[type]\n\nconst dateBisector = bisector<LineChartDatum, Date>((d) => d.date)\nconst bisectDate = (data: LineChartDatum[], x: Date, lo?: number) =>\n dateBisector.left(data, x, lo)\n\n/** Whether `date` falls within a series' own x-range (data is sorted ascending). */\nfunction withinDomain(data: LineChartDatum[], date: Date): boolean {\n const first = data[0]\n const last = data[data.length - 1]\n if (!first || !last) return false\n const t = date.valueOf()\n return t >= first.date.valueOf() && t <= last.date.valueOf()\n}\n\n/**\n * y-domain padded 10% beyond the data extent. The baseline is pinned to 0 so\n * all-positive series render from the axis up; a series that dips below 0\n * (signed grid / battery power) extends the domain downward to keep the zero\n * crossing visible.\n */\nfunction computeYDomain(data: LineChartDatum[]): [number, number] {\n let min = 0\n let max = 0\n for (const d of data) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n if (min === max) return [min, min + 1]\n return [min * 1.1, max * 1.1]\n}\n\nfunction nearestDatum(\n data: LineChartDatum[],\n date: Date,\n): LineChartDatum | undefined {\n if (data.length === 0) return undefined\n const index = bisectDate(data, date, 1)\n const d0 = data[index - 1]\n const d1 = data[index]\n if (!d0) return d1\n if (!d1) return d0\n return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf()\n ? d1\n : d0\n}\n\nconst defaultFormatDate = (date: Date) =>\n date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n\nconst defaultValueFormat = localeNumberFormat()\nconst defaultFormatValue = (value: number) => defaultValueFormat.format(value)\n\nconst LINE_COLORS = [\n 'stroke-spark-9',\n 'stroke-green-9',\n 'stroke-blue-9',\n 'stroke-orange-9',\n 'stroke-red-9',\n]\n\nconst DOT_COLORS = [\n 'fill-spark-9',\n 'fill-green-9',\n 'fill-blue-9',\n 'fill-orange-9',\n 'fill-red-9',\n]\n\n// CSS-var colours matching LINE_COLORS, used for the tooltip legend dots.\nconst LEGEND_COLORS = [\n 'var(--spark-9)',\n 'var(--green-9)',\n 'var(--blue-9)',\n 'var(--orange-9)',\n 'var(--red-9)',\n]\n\nfunction toTimeDomain(dates: [Date, Date]): TimeDomain {\n return [dates[0].valueOf(), dates[1].valueOf()]\n}\n\nfunction fromTimeDomain(domain: TimeDomain): [Date, Date] {\n return [new Date(domain[0]), new Date(domain[1])]\n}\n\nfunction touchDistance(a: React.Touch, b: React.Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\n}\n\nfunction touchMidpoint(\n a: React.Touch,\n b: React.Touch,\n): {\n clientX: number\n clientY: number\n} {\n return {\n clientX: (a.clientX + b.clientX) / 2,\n clientY: (a.clientY + b.clientY) / 2,\n }\n}\n\nconst LineChart: React.FC<LineChartProps> = ({\n series,\n width,\n height,\n margin = DEFAULT_MARGIN,\n curve: defaultCurve = 'monotone',\n showGrid = true,\n showTooltip: enableTooltip = true,\n className,\n xTickCount = 5,\n yTickCount = 4,\n formatDate = defaultFormatDate,\n formatTooltipDate,\n formatValue = defaultFormatValue,\n yAxisUnit,\n formatYTick = formatYAxisTick,\n yDomain,\n referenceLines,\n topContent,\n zoomable = false,\n zoomResetLabel,\n zoomDomain: zoomDomainProp,\n onZoomDomainChange,\n}) => {\n const plotClipId = React.useId()\n const {\n showTooltip,\n hideTooltip,\n tooltipData,\n tooltipLeft,\n tooltipTop,\n tooltipOpen,\n } = useTooltip<{ date: Date }>()\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n const allData = useMemo(() => series.flatMap((s) => s.data), [series])\n\n const fullDomain = useMemo((): TimeDomain | null => {\n const ext = extent(allData, (d) => d.date.valueOf())\n if (ext[0] == null || ext[1] == null) return null\n return [ext[0], ext[1]]\n }, [allData])\n\n const controlledZoomDomain =\n zoomDomainProp === undefined\n ? undefined\n : zoomDomainProp == null\n ? null\n : toTimeDomain(zoomDomainProp)\n\n const handleZoomDomainChange = useCallback(\n (domain: TimeDomain | null) => {\n onZoomDomainChange?.(domain ? fromTimeDomain(domain) : null)\n },\n [onZoomDomainChange],\n )\n\n const zoom = useChartZoom({\n enabled: zoomable,\n fullDomain,\n zoomDomain: controlledZoomDomain,\n onZoomDomainChange: handleZoomDomainChange,\n })\n\n const xDomain = useMemo((): [Date, Date] => {\n if (zoom.zoomWindow) return fromTimeDomain(zoom.zoomWindow)\n const ext = extent(allData, (d) => d.date) as\n | [Date, Date]\n | [undefined, undefined]\n if (ext[0] && ext[1]) return [ext[0], ext[1]]\n const now = new Date()\n return [now, now]\n }, [allData, zoom.zoomWindow])\n\n const xScale = useMemo(\n () =>\n scaleTime({\n range: [0, innerWidth],\n domain: xDomain,\n }),\n [innerWidth, xDomain],\n )\n\n const visibleData = useMemo(() => {\n const [start, end] = xDomain\n const t0 = start.valueOf()\n const t1 = end.valueOf()\n return allData.filter((d) => {\n const t = d.date.valueOf()\n return t >= t0 && t <= t1\n })\n }, [allData, xDomain])\n\n const reducedMotion = useReducedMotion()\n\n // With a unit, the y-axis is generated by the shared scale util (nice ticks\n // + rounded bounds) so it matches BarChart / PowerHistoryChart exactly.\n const yAxisScale = useMemo(() => {\n if (yAxisUnit === undefined) return null\n let min = 0\n let max = 0\n for (const d of visibleData) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n return buildYAxisScale(min, max)\n }, [visibleData, yAxisUnit])\n\n const targetYDomain = useMemo((): TimeDomain => {\n if (yDomain) return yDomain\n if (yAxisScale) return [yAxisScale.min, yAxisScale.max]\n return scaleLinear({\n domain: computeYDomain(visibleData),\n nice: true,\n }).domain() as [number, number]\n }, [visibleData, yAxisScale, yDomain])\n\n const displayedYDomain = useAnimatedChartDomain(targetYDomain, {\n animateChanges: zoom.isPinching,\n reducedMotion,\n })\n\n const yScale = useMemo(\n () =>\n scaleLinear({\n range: [innerHeight, 0],\n domain: [displayedYDomain[0], displayedYDomain[1]],\n }),\n [displayedYDomain, innerHeight],\n )\n\n const xTicks = zoom.isZoomed\n ? buildTimeTicks(\n xDomain[0].valueOf(),\n xDomain[1].valueOf(),\n xTickCount,\n ).map((tick) => new Date(tick))\n : xScale.ticks(xTickCount)\n const yTicks = yAxisScale ? yAxisScale.ticks : yScale.ticks(yTickCount)\n const formatAxisDate =\n zoom.isZoomed &&\n xDomain[1].valueOf() - xDomain[0].valueOf() <= DETAILED_X_AXIS_THRESHOLD\n ? (formatTooltipDate ?? formatDate)\n : formatDate\n\n const domainXFromEvent = useCallback(\n (\n event:\n | React.MouseEvent<SVGRectElement>\n | React.PointerEvent<SVGRectElement>\n | React.TouchEvent<SVGRectElement>,\n ) => {\n const point = localPoint(event)\n if (!point) return null\n return xScale.invert(point.x - margin.left).valueOf()\n },\n [margin.left, xScale],\n )\n\n const handleTooltip = useCallback(\n (\n event:\n | React.TouchEvent<SVGRectElement>\n | React.MouseEvent<SVGRectElement>,\n ) => {\n if (!enableTooltip || zoom.isBrushing || zoom.isPanning) return\n\n const point = localPoint(event)\n if (!point) return\n\n const x0 = xScale.invert(point.x - margin.left)\n\n // Snap to the data point closest to the cursor across all series, so the\n // cursor line + tooltip line up with real values.\n let anchorDate: Date | null = null\n let bestDistance = Infinity\n for (const s of series) {\n const d = nearestDatum(s.data, x0)\n if (!d) continue\n const distance = Math.abs(d.date.valueOf() - x0.valueOf())\n if (distance < bestDistance) {\n bestDistance = distance\n anchorDate = d.date\n }\n }\n\n if (!anchorDate) return\n\n showTooltip({\n tooltipData: { date: anchorDate },\n tooltipLeft: xScale(anchorDate) + margin.left,\n tooltipTop: margin.top,\n })\n },\n [\n enableTooltip,\n margin,\n series,\n showTooltip,\n xScale,\n zoom.isBrushing,\n zoom.isPanning,\n ],\n )\n\n const tooltipRows: ChartTooltipRow[] = tooltipData\n ? series.flatMap((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return []\n return [\n {\n key: s.id,\n label: s.label ?? s.id,\n color:\n s.color ?? (LEGEND_COLORS[i % LEGEND_COLORS.length] as string),\n value: formatValue(d.value),\n marker: s.dashed ? ('dashed-line' as const) : ('dot' as const),\n },\n ]\n })\n : []\n\n const [tooltipRef, tooltipSize] = useMeasuredSize<HTMLDivElement>()\n const tooltipPos = clampTooltipPosition({\n anchorX: tooltipLeft ?? 0,\n anchorY: tooltipTop ?? margin.top,\n width,\n height,\n tipWidth: tooltipSize.width,\n tipHeight: tooltipSize.height,\n placement: 'beside',\n })\n\n if (width < 10 || height < 10) return null\n\n return (\n <div className={cn('relative', className)}>\n <svg className=\"block\" height={height} width={width}>\n <defs>\n <clipPath id={plotClipId}>\n <rect height={innerHeight} width={innerWidth} x={0} y={0} />\n </clipPath>\n </defs>\n <Group left={margin.left} top={margin.top}>\n {/* Grid lines */}\n {showGrid &&\n yTicks.map((tick) => (\n <line\n className=\"stroke-gray-a4\"\n key={`grid-y-${tick}`}\n strokeDasharray=\"4,4\"\n x1={0}\n x2={innerWidth}\n y1={yScale(tick)}\n y2={yScale(tick)}\n />\n ))}\n\n {/* X axis */}\n <line\n className=\"stroke-gray-a6\"\n x1={0}\n x2={innerWidth}\n y1={innerHeight}\n y2={innerHeight}\n />\n\n {/* Reference markers (e.g. sunrise / sunset) */}\n {referenceLines?.map((ref) => {\n const x = xScale(ref.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n // Sit the label beside the line, on whichever side keeps it in\n // frame: right of a left-half marker, left of a right-half one.\n const anchorEnd = x > innerWidth / 2\n return (\n <g key={ref.key} pointerEvents=\"none\">\n <line\n className=\"stroke-orange-8\"\n strokeDasharray=\"3,3\"\n x1={x}\n x2={x}\n y1={0}\n y2={innerHeight}\n />\n {ref.label != null && (\n <text\n className=\"fill-orange-11 text-[10px]\"\n dy=\"0.9em\"\n textAnchor={anchorEnd ? 'end' : 'start'}\n x={x + (anchorEnd ? -4 : 4)}\n y={0}\n >\n {ref.label}\n </text>\n )}\n </g>\n )\n })}\n\n {/* X axis labels */}\n {xTicks.map((tick, index) => (\n <text\n dy=\"1em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n key={`x-${tick.valueOf()}`}\n textAnchor={\n index === 0\n ? 'start'\n : index === xTicks.length - 1\n ? 'end'\n : 'middle'\n }\n x={xScale(tick)}\n y={innerHeight + 8}\n >\n {formatAxisDate(tick)}\n </text>\n ))}\n\n {/* Y axis. With `yAxisUnit`, matches BarChart: a vertical axis line,\n short tick marks, plain numeric ticks, and the unit as a bold\n top-left header (top tick hidden). Without it, ticks repeat\n `formatValue` and no axis line/marks are drawn. */}\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a6)\"\n strokeWidth={1}\n x1={0}\n x2={0}\n y1={0}\n y2={innerHeight}\n />\n )}\n {yTicks.map((tick) => {\n const y = yScale(tick)\n return (\n <g key={`y-${tick}`}>\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a8)\"\n strokeWidth={1}\n x1={-4}\n x2={0}\n y1={y}\n y2={y}\n />\n )}\n <text\n dy=\"0.32em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n textAnchor=\"end\"\n x={yAxisUnit !== undefined ? -7 : -4}\n y={y}\n >\n {yAxisUnit !== undefined\n ? formatYTick(tick)\n : formatValue(tick)}\n </text>\n </g>\n )\n })}\n {yAxisUnit !== undefined && (\n <text\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n fontWeight={600}\n textAnchor=\"start\"\n x={-margin.left}\n y={-6}\n >\n {yAxisUnit}\n </text>\n )}\n\n <g clipPath={`url(#${plotClipId})`} data-testid=\"chart-plot-clip\">\n {series.map((s, i) => (\n <LinePath\n className={cn(LINE_COLORS[i % LINE_COLORS.length], s.className)}\n curve={resolveCurve(s.curve ?? defaultCurve)}\n data={s.data}\n fill=\"none\"\n key={s.id}\n strokeDasharray={\n s.dashed ? (s.dashPattern ?? '6,4') : undefined\n }\n strokeWidth={2}\n x={(d) => xScale(d.date)}\n y={(d) => yScale(d.value)}\n />\n ))}\n </g>\n\n {zoom.brushBand && (\n <rect\n data-testid=\"chart-brush-band\"\n fill=\"var(--spark-a4)\"\n height={innerHeight}\n pointerEvents=\"none\"\n width={Math.abs(\n xScale(new Date(zoom.brushBand[1])) -\n xScale(new Date(zoom.brushBand[0])),\n )}\n x={Math.min(\n xScale(new Date(zoom.brushBand[0])),\n xScale(new Date(zoom.brushBand[1])),\n )}\n y={0}\n />\n )}\n\n {(enableTooltip || zoomable) && (\n <rect\n fill=\"transparent\"\n height={innerHeight}\n style={zoomable ? { touchAction: 'pan-y' } : undefined}\n width={innerWidth}\n x={0}\n y={0}\n onMouseLeave={() => {\n if (!zoom.isBrushing) hideTooltip()\n }}\n onMouseMove={(event) => {\n if (zoom.isBrushing) {\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n return\n }\n handleTooltip(event)\n }}\n onPointerDown={(event) => {\n if (!zoomable || event.pointerType === 'touch') return\n if (event.button !== 0) return\n const domainX = domainXFromEvent(event)\n if (domainX == null) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n hideTooltip()\n zoom.onPointerDown(domainX)\n }}\n onPointerMove={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n }}\n onPointerUp={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerUp(domainX)\n else zoom.onPointerCancel()\n }}\n onPointerCancel={() => {\n zoom.onPointerCancel()\n }}\n onDoubleClick={() => {\n if (zoomable) zoom.onDoubleClick()\n }}\n onTouchStart={(event) => {\n if (!zoomable) return\n if (event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchStart(touchDistance(a, b), midpoint)\n hideTooltip()\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanStart({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n hideTooltip()\n }\n }}\n onTouchMove={(event) => {\n if (zoomable && event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchMove(touchDistance(a, b), midpoint)\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanMove({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n return\n }\n if (event.touches.length === 1) handleTooltip(event)\n }}\n onTouchEnd={(event) => {\n if (zoomable && event.touches.length < 2) zoom.onPinchEnd()\n if (event.touches.length === 0) {\n if (zoomable) zoom.onPanEnd()\n if (zoomable) zoom.onTap()\n hideTooltip()\n }\n }}\n onTouchCancel={() => {\n zoom.onPinchEnd()\n zoom.onPanEnd()\n }}\n />\n )}\n\n {/* Cursor line + a dot per series */}\n {tooltipOpen &&\n tooltipData &&\n !zoom.isBrushing &&\n !zoom.isPanning && (\n <>\n <line\n className=\"stroke-gray-a6\"\n pointerEvents=\"none\"\n strokeDasharray=\"4,4\"\n x1={xScale(tooltipData.date)}\n x2={xScale(tooltipData.date)}\n y1={0}\n y2={innerHeight}\n />\n {series.map((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return null\n return (\n <circle\n key={s.id}\n className={\n s.color\n ? undefined\n : cn(DOT_COLORS[i % DOT_COLORS.length])\n }\n cx={xScale(d.date)}\n cy={yScale(d.value)}\n fill={s.color}\n pointerEvents=\"none\"\n r={4}\n stroke=\"white\"\n strokeWidth={2}\n />\n )\n })}\n </>\n )}\n </Group>\n </svg>\n\n {topContent && topContent.length > 0 && (\n <div\n className=\"pointer-events-none absolute overflow-hidden\"\n style={{\n height: margin.top,\n left: margin.left,\n top: 0,\n width: innerWidth,\n }}\n >\n {topContent.map((item) => {\n const x = xScale(item.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n return (\n <div\n key={item.key}\n className=\"absolute -translate-x-1/2\"\n style={{ left: x, top: 0 }}\n >\n {item.content}\n </div>\n )\n })}\n </div>\n )}\n\n {zoom.isZoomed && zoomResetLabel && (\n <ChartZoomResetButton label={zoomResetLabel} onReset={zoom.resetZoom} />\n )}\n\n <div\n ref={tooltipRef}\n className=\"pointer-events-none absolute z-10\"\n style={{\n left: tooltipPos.left,\n top: tooltipPos.top,\n opacity:\n tooltipOpen && tooltipData && !zoom.isPanning && !zoom.isBrushing\n ? 1\n : 0,\n transition: reducedMotion\n ? 'opacity 140ms ease-out'\n : 'left 140ms ease-out, top 140ms ease-out, opacity 140ms ease-out',\n }}\n >\n {tooltipData && (\n <ChartTooltipCard\n label={(formatTooltipDate ?? formatDate)(tooltipData.date)}\n rows={tooltipRows}\n />\n )}\n </div>\n </div>\n )\n}\n\nexport { LineChart }\n"],"mappings":"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"}
|