@flikk/ui 1.0.0-beta.23 → 1.0.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/components/charts/AreaChart/AreaChart.types.d.ts +2 -2
  2. package/dist/components/charts/BarChart/BarChart.types.d.ts +2 -2
  3. package/dist/components/charts/ComboChart/ComboChart.types.d.ts +2 -2
  4. package/dist/components/charts/LineChart/LineChart.types.d.ts +2 -2
  5. package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +2 -2
  6. package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +2 -2
  7. package/dist/components/core/Accordion/AccordionTrigger.js +28 -1
  8. package/dist/components/core/Alert/Alert.js +2 -1
  9. package/dist/components/core/AlertDialog/AlertDialog.js +1 -1
  10. package/dist/components/core/Badge/Badge.js +6 -17
  11. package/dist/components/core/Breadcrumbs/Breadcrumbs.js +17 -28
  12. package/dist/components/core/Calendar/Calendar.js +1 -1
  13. package/dist/components/core/Carousel/CarouselBody.js +6 -1
  14. package/dist/components/core/ContextMenu/ContextMenuBody.js +6 -3
  15. package/dist/components/core/ContextMenu/ContextMenuSubBody.js +6 -3
  16. package/dist/components/core/DragDrop/DragDrop.js +170 -17
  17. package/dist/components/core/DragDrop/DragDrop.types.d.ts +6 -0
  18. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  19. package/dist/components/core/Drawer/Drawer.js +2 -0
  20. package/dist/components/core/Drawer/Drawer.types.d.ts +2 -0
  21. package/dist/components/core/Drawer/DrawerTitle.d.ts +1 -1
  22. package/dist/components/core/Drawer/DrawerTitle.js +2 -2
  23. package/dist/components/core/Dropdown/DropdownMenu.js +2 -30
  24. package/dist/components/core/Masonry/Masonry.js +7 -2
  25. package/dist/components/core/Modal/Modal.d.ts +1 -1
  26. package/dist/components/core/Modal/Modal.js +3 -3
  27. package/dist/components/core/Modal/Modal.types.d.ts +2 -0
  28. package/dist/components/core/Modal/ModalTitle.d.ts +1 -1
  29. package/dist/components/core/Modal/ModalTitle.js +2 -2
  30. package/dist/components/core/NavItem/NavItem.js +13 -8
  31. package/dist/components/core/Pagination/Pagination.js +1 -1
  32. package/dist/components/core/Popover/PopoverBody.js +3 -27
  33. package/dist/components/core/Popover/PopoverTrigger.js +1 -1
  34. package/dist/components/core/Progress/Progress.js +4 -4
  35. package/dist/components/core/Rating/Rating.js +1 -1
  36. package/dist/components/core/ScrollArea/ScrollArea.js +3 -2
  37. package/dist/components/core/Segmented/Segmented.js +6 -6
  38. package/dist/components/core/Segmented/SegmentedItem.js +28 -2
  39. package/dist/components/core/Skeleton/Skeleton.js +2 -2
  40. package/dist/components/core/Sortable/Sortable.d.ts +1 -1
  41. package/dist/components/core/Sortable/Sortable.js +20 -4
  42. package/dist/components/core/Sortable/Sortable.types.d.ts +2 -0
  43. package/dist/components/core/Tabs/Tabs.js +6 -4
  44. package/dist/components/core/Tabs/Tabs.types.d.ts +2 -0
  45. package/dist/components/core/Tabs/TabsBody.js +3 -3
  46. package/dist/components/core/Tabs/TabsList.js +19 -21
  47. package/dist/components/core/Tabs/TabsTrigger.js +47 -28
  48. package/dist/components/core/Toast/Toast.js +1 -1
  49. package/dist/components/core/Toast/ToastProvider.js +3 -2
  50. package/dist/components/core/Tooltip/Tooltip.js +25 -34
  51. package/dist/components/core/Tree/Tree.js +178 -8
  52. package/dist/components/data-display/GanttChart/GanttSplitter.js +15 -1
  53. package/dist/components/data-display/Table/Table.js +2 -2
  54. package/dist/components/data-display/Table/Table.types.d.ts +2 -0
  55. package/dist/components/data-display/Table/TableFilter.js +21 -18
  56. package/dist/components/effects/CustomCursor/CustomCursor.js +3 -7
  57. package/dist/components/effects/Overlay/Overlay.js +4 -9
  58. package/dist/components/effects/PageTransition/PageTransition.js +17 -6
  59. package/dist/components/effects/SpotlightBorder/SpotlightBorder.js +3 -4
  60. package/dist/components/forms/Checkbox/Checkbox.js +11 -1
  61. package/dist/components/forms/Checkbox/Checkbox.theme.js +4 -1
  62. package/dist/components/forms/Checkbox/Checkbox.types.d.ts +7 -5
  63. package/dist/components/forms/Checkbox/CheckboxGroup.js +9 -4
  64. package/dist/components/forms/ColorPicker/ColorPicker.js +7 -4
  65. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
  66. package/dist/components/forms/ColorPicker/ColorPickerBody.js +5 -3
  67. package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +3 -3
  68. package/dist/components/forms/ColorPicker/ColorPickerGradient.js +8 -8
  69. package/dist/components/forms/ColorPicker/ColorPickerInput.js +1 -1
  70. package/dist/components/forms/ColorPicker/index.d.ts +1 -1
  71. package/dist/components/forms/Combobox/Combobox.js +20 -45
  72. package/dist/components/forms/Combobox/Combobox.types.d.ts +4 -2
  73. package/dist/components/forms/CronInput/CronInput.js +10 -4
  74. package/dist/components/forms/CronInput/CronInput.types.d.ts +12 -1
  75. package/dist/components/forms/DatePicker/DatePicker.js +2 -2
  76. package/dist/components/forms/DatePicker/DatePicker.types.d.ts +4 -2
  77. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -29
  78. package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
  79. package/dist/components/forms/DateRangePicker/DateRangePicker.js +3 -3
  80. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +4 -2
  81. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -28
  82. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
  83. package/dist/components/forms/FileUpload/FileUpload.js +14 -10
  84. package/dist/components/forms/FileUpload/FileUpload.types.d.ts +15 -0
  85. package/dist/components/forms/FormLabel/FormLabel.js +2 -2
  86. package/dist/components/forms/Input/Input.js +5 -3
  87. package/dist/components/forms/Input/Input.types.d.ts +2 -0
  88. package/dist/components/forms/InputAddress/InputAddress.d.ts +1 -1
  89. package/dist/components/forms/InputAddress/InputAddress.js +8 -9
  90. package/dist/components/forms/InputCounter/InputCounter.js +25 -18
  91. package/dist/components/forms/InputCounter/InputCounter.types.d.ts +8 -1
  92. package/dist/components/forms/InputCreditCard/InputCreditCard.d.ts +1 -1
  93. package/dist/components/forms/InputCreditCard/InputCreditCard.js +27 -9
  94. package/dist/components/forms/InputCreditCard/InputCreditCard.types.d.ts +5 -0
  95. package/dist/components/forms/InputOTP/InputOTP.js +26 -17
  96. package/dist/components/forms/InputOTP/InputOTP.types.d.ts +21 -4
  97. package/dist/components/forms/InputTag/InputTag.js +12 -39
  98. package/dist/components/forms/InputTag/InputTag.types.d.ts +2 -2
  99. package/dist/components/forms/Mention/Mention.js +13 -6
  100. package/dist/components/forms/Mention/Mention.types.d.ts +9 -0
  101. package/dist/components/forms/Radio/Radio.js +12 -2
  102. package/dist/components/forms/Radio/Radio.theme.js +5 -1
  103. package/dist/components/forms/Radio/Radio.types.d.ts +7 -5
  104. package/dist/components/forms/Radio/RadioGroup.js +8 -3
  105. package/dist/components/forms/RichTextEditor/RichTextEditor.js +21 -21
  106. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +2 -2
  107. package/dist/components/forms/Select/Select.d.ts +2 -0
  108. package/dist/components/forms/Select/Select.js +26 -56
  109. package/dist/components/forms/Select/Select.types.d.ts +14 -0
  110. package/dist/components/forms/Signature/Signature.js +1 -1
  111. package/dist/components/forms/Signature/Signature.types.d.ts +3 -3
  112. package/dist/components/forms/Slider/Slider.js +18 -4
  113. package/dist/components/forms/Slider/Slider.types.d.ts +2 -2
  114. package/dist/components/forms/Switch/Switch.js +12 -19
  115. package/dist/components/forms/Switch/Switch.theme.js +12 -2
  116. package/dist/components/forms/Switch/Switch.types.d.ts +20 -2
  117. package/dist/components/forms/Textarea/Textarea.js +8 -3
  118. package/dist/components/forms/Textarea/Textarea.types.d.ts +2 -0
  119. package/dist/components/forms/TimePicker/TimePicker.js +1 -1
  120. package/dist/components/forms/TimePicker/TimePicker.types.d.ts +6 -2
  121. package/dist/components/forms/TimePicker/TimePickerContent.js +2 -29
  122. package/dist/components/forms/TimePicker/TimePickerTrigger.js +2 -2
  123. package/dist/components/forms/index.js +1 -1
  124. package/dist/components/layout/index.js +4 -0
  125. package/dist/hooks/index.d.ts +1 -0
  126. package/dist/hooks/useClickOutside.d.ts +10 -4
  127. package/dist/hooks/useClickOutside.js +44 -24
  128. package/dist/hooks/useDarkMode.d.ts +1 -0
  129. package/dist/hooks/useDarkMode.js +42 -0
  130. package/dist/hooks/useFormStateMachine.d.ts +1 -1
  131. package/dist/hooks/useNetworkStatus.js +1 -1
  132. package/dist/hooks/useOverlay.js +4 -0
  133. package/dist/hooks/useScaleBackground.js +5 -2
  134. package/dist/hooks/useSelectPortal.js +14 -5
  135. package/dist/index.d.ts +0 -2
  136. package/dist/index.js +1 -57
  137. package/dist/shadcn-compat.css +80 -0
  138. package/dist/styles.css +1 -1
  139. package/dist/utils/stateMachine.d.ts +4 -4
  140. package/package.json +11 -10
  141. package/tailwind.preset.cjs +32 -3
  142. /package/{src/theme-plugin.css → dist/theme.css} +0 -0
@@ -4,7 +4,7 @@ import { FormLabel } from '../FormLabel/FormLabel.js';
4
4
  import { textareaTheme } from './Textarea.theme.js';
5
5
  import { cn } from '../../../utils/cn.js';
6
6
 
7
- const Textarea = React__default.forwardRef(({ size = "md", state = "default", className = "", label, labelClassName = "", helperText, helperTextClassName = "", wrapperClassName = "", inputGroupClassName = "", id, theme = {}, required, rows = 3, cols, unstyled = false, ...props }, ref) => {
7
+ const Textarea = React__default.forwardRef(({ size = "md", state = "default", className = "", label, labelClassName = "", helperText, helperTextClassName = "", wrapperClassName = "", inputGroupClassName = "", id, theme = {}, required, rows = 3, cols, unstyled = false, onValueChange, ...props }, ref) => {
8
8
  var _a, _b, _c, _d;
9
9
  const [isFocused, setIsFocused] = useState(false);
10
10
  const generatedId = React__default.useId();
@@ -30,6 +30,8 @@ const Textarea = React__default.forwardRef(({ size = "md", state = "default", cl
30
30
  : isDisabled
31
31
  ? "state-disabled"
32
32
  : "state-default";
33
+ // Pull onChange out of props so the explicit handler below isn't overwritten by the spread
34
+ const { onChange: propsOnChange, ...restProps } = props;
33
35
  // Get theme classes
34
36
  const wrapperClasses = theme.wrapperStyle || textareaTheme.wrapperStyle || "";
35
37
  const inputGroupClasses = theme.inputGroupStyle || textareaTheme.inputGroupStyle || "";
@@ -37,7 +39,7 @@ const Textarea = React__default.forwardRef(({ size = "md", state = "default", cl
37
39
  const sizeClasses = ((_a = theme.sizes) === null || _a === void 0 ? void 0 : _a[size]) || ((_b = textareaTheme.sizes) === null || _b === void 0 ? void 0 : _b[size]) || "";
38
40
  const stateClasses = ((_c = theme.states) === null || _c === void 0 ? void 0 : _c[state]) || ((_d = textareaTheme.states) === null || _d === void 0 ? void 0 : _d[state]) || "";
39
41
  const helperTextClasses = theme.helperText || textareaTheme.helperText || "";
40
- return (jsxs("div", { className: cn(wrapperClasses, stateClass, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx("div", { className: "mb-1", children: jsx(FormLabel, { htmlFor: inputId, className: labelClassName, state: state, required: required, children: label }) })) : (label)), jsx("div", { children: jsx("div", { className: cn(inputGroupClasses, stateClasses, inputGroupClassName), children: jsx("div", { className: "relative flex-1", children: jsx("textarea", { ref: ref, id: inputId, className: cn(baseClasses, sizeClasses, className), disabled: isDisabled, "aria-invalid": isInvalid, required: required, rows: rows, cols: cols, onFocus: (e) => {
42
+ return (jsxs("div", { className: cn(wrapperClasses, stateClass, wrapperClassName), children: [label && (typeof label === 'string' ? (jsx("div", { className: "mb-1", children: jsx(FormLabel, { htmlFor: inputId, className: labelClassName, state: state, required: required, children: label }) })) : (label)), jsx("div", { children: jsx("div", { className: cn(inputGroupClasses, stateClasses, inputGroupClassName), children: jsx("div", { className: "relative flex-1", children: jsx("textarea", { ref: ref, id: inputId, className: cn(baseClasses, sizeClasses, className), disabled: isDisabled, "aria-invalid": isInvalid, "aria-describedby": helperText ? `${inputId}-helper` : undefined, required: required, rows: rows, cols: cols, onFocus: (e) => {
41
43
  var _a;
42
44
  setIsFocused(true);
43
45
  (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
@@ -45,7 +47,10 @@ const Textarea = React__default.forwardRef(({ size = "md", state = "default", cl
45
47
  var _a;
46
48
  setIsFocused(false);
47
49
  (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
48
- }, ...props }) }) }) }), helperText && (typeof helperText === 'string' ? (jsx("div", { className: cn(helperTextClasses, helperTextClassName), children: helperText })) : (helperText))] }));
50
+ }, onChange: (e) => {
51
+ propsOnChange === null || propsOnChange === void 0 ? void 0 : propsOnChange(e);
52
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(e.target.value);
53
+ }, ...restProps }) }) }) }), helperText && (typeof helperText === 'string' ? (jsx("div", { id: `${inputId}-helper`, className: cn(helperTextClasses, helperTextClassName), children: helperText })) : (helperText))] }));
49
54
  });
50
55
  Textarea.displayName = "Textarea";
51
56
 
@@ -35,6 +35,8 @@ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextArea
35
35
  cols?: number;
36
36
  /** Render only the textarea element without wrapper, label, or helper text */
37
37
  unstyled?: boolean;
38
+ /** Callback fired with the raw string value on every change — convenience alternative to reading e.target.value from onChange */
39
+ onValueChange?: (value: string) => void;
38
40
  }
39
41
  export type TextareaSize = 'sm' | 'md' | 'lg';
40
42
  export type TextareaState = 'default' | 'disabled' | 'invalid';
@@ -447,7 +447,7 @@ const TimePicker = React__default.forwardRef(({ value, defaultValue, onChange, f
447
447
  else if (ref) {
448
448
  ref.current = el;
449
449
  }
450
- }, className: cn(mergedTheme.containerStyle, className), children: [label && (jsx(FormLabel, { htmlFor: inputId, className: labelClassName, state: finalState, required: props.required, children: label })), jsx(TimePickerTrigger, { id: inputId, disabled: disabled, isOpen: isOpen, state: finalState, size: size, clearable: clearable, onClear: handleClear, iconStart: iconStart, iconEnd: iconEnd, inputValue: inputDisplayValue, onInputChange: handleInputChange, onInputFocus: handleInputFocus, onInputKeyDown: handleInputKeyDown, format: format, period: currentPeriod, onPeriodToggle: handlePeriodToggle, placeholder: placeholder }), jsxs(TimePickerContent, { isOpen: isOpen, onCancel: handleCancel, onSave: handleSave, portal: true, placement: "bottom-start", offset: 4, dropdownRef: dropdownRef, children: [jsx(WheelColumn, { label: "Hour", options: hourOptions, value: getDisplayHour(wheelTime.hour, format), onChange: handleHourChange, theme: mergedTheme }), jsx(WheelColumn, { label: "Min", options: minuteOptions, value: wheelTime.minute, onChange: handleMinuteChange, theme: mergedTheme }), format === "12h" && (jsx(WheelColumn, { label: "", options: periodOptions, value: wheelTime.period || "AM", onChange: handlePeriodChange, theme: mergedTheme }))] }), (helperText || validationError) && (jsx("p", { className: cn(mergedTheme.helperTextStyle, (_a = mergedTheme.helperTextStates) === null || _a === void 0 ? void 0 : _a[finalState], helperTextClassName), children: validationError || helperText }))] }) }));
450
+ }, className: cn(mergedTheme.containerStyle, className), children: [label && (typeof label === 'string' ? (jsx(FormLabel, { htmlFor: inputId, className: labelClassName, state: finalState, required: props.required, children: label })) : (label)), jsx(TimePickerTrigger, { id: inputId, disabled: disabled, isOpen: isOpen, state: finalState, size: size, clearable: clearable, onClear: handleClear, iconStart: iconStart, iconEnd: iconEnd, inputValue: inputDisplayValue, onInputChange: handleInputChange, onInputFocus: handleInputFocus, onInputKeyDown: handleInputKeyDown, format: format, period: currentPeriod, onPeriodToggle: handlePeriodToggle, placeholder: placeholder, "aria-invalid": finalState === 'invalid' || undefined, "aria-describedby": helperText ? `${inputId}-helper` : undefined }), jsxs(TimePickerContent, { isOpen: isOpen, onCancel: handleCancel, onSave: handleSave, portal: true, placement: "bottom-start", offset: 4, dropdownRef: dropdownRef, children: [jsx(WheelColumn, { label: "Hour", options: hourOptions, value: getDisplayHour(wheelTime.hour, format), onChange: handleHourChange, theme: mergedTheme }), jsx(WheelColumn, { label: "Min", options: minuteOptions, value: wheelTime.minute, onChange: handleMinuteChange, theme: mergedTheme }), format === "12h" && (jsx(WheelColumn, { label: "", options: periodOptions, value: wheelTime.period || "AM", onChange: handlePeriodChange, theme: mergedTheme }))] }), (helperText || validationError) && (typeof helperText === 'string' || validationError ? (jsx("p", { id: `${inputId}-helper`, className: cn(mergedTheme.helperTextStyle, (_a = mergedTheme.helperTextStates) === null || _a === void 0 ? void 0 : _a[finalState], helperTextClassName), children: validationError || helperText })) : (helperText))] }) }));
451
451
  });
452
452
  TimePicker.displayName = "TimePicker";
453
453
 
@@ -44,9 +44,9 @@ export interface TimePickerProps extends Omit<React.InputHTMLAttributes<HTMLInpu
44
44
  /** Whether to show a clear button */
45
45
  clearable?: boolean;
46
46
  /** Optional label text */
47
- label?: string;
47
+ label?: React.ReactNode;
48
48
  /** Optional helper text */
49
- helperText?: string;
49
+ helperText?: React.ReactNode;
50
50
  /** Icon to display at the start (left side) */
51
51
  iconStart?: React.ReactNode;
52
52
  /** Icon to display at the end (right side) */
@@ -175,6 +175,10 @@ export interface TimePickerTriggerProps {
175
175
  id?: string;
176
176
  /** Whether the trigger is disabled */
177
177
  disabled?: boolean;
178
+ /** Whether the trigger has an invalid value */
179
+ "aria-invalid"?: boolean;
180
+ /** ID of the element that describes the trigger */
181
+ "aria-describedby"?: string;
178
182
  /** Whether the dropdown is open */
179
183
  isOpen?: boolean;
180
184
  /** Visual state of the trigger */
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useContext, useCallback, useState, useEffect } from 'react';
2
+ import { useContext, useCallback } from 'react';
3
3
  import { AnimatePresence, motion } from 'motion/react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { cn } from '../../../utils/cn.js';
@@ -93,35 +93,8 @@ import '../../core/ContextMenu/ContextMenu.theme.js';
93
93
  import '../../core/Pill/Pill.js';
94
94
  import '../../core/Icon/Icon.js';
95
95
  import { useIsClient } from '../../../hooks/useIsClient.js';
96
+ import { useDarkMode } from '../../../hooks/useDarkMode.js';
96
97
 
97
- /**
98
- * Hook to detect dark mode state from document
99
- */
100
- const useDarkMode = () => {
101
- const [isDark, setIsDark] = useState(false);
102
- useEffect(() => {
103
- if (typeof document === "undefined")
104
- return;
105
- const checkDarkMode = () => {
106
- const hasDarkClass = document.documentElement.classList.contains("dark") ||
107
- document.body.classList.contains("dark") ||
108
- document.querySelector(".dark") !== null;
109
- setIsDark(hasDarkClass);
110
- };
111
- checkDarkMode();
112
- const observer = new MutationObserver(checkDarkMode);
113
- observer.observe(document.documentElement, {
114
- attributes: true,
115
- attributeFilter: ["class"],
116
- });
117
- observer.observe(document.body, {
118
- attributes: true,
119
- attributeFilter: ["class"],
120
- });
121
- return () => observer.disconnect();
122
- }, []);
123
- return isDark;
124
- };
125
98
  /**
126
99
  * TimePickerContent Component - contains the time selector dropdown
127
100
  * Uses portal positioning like Select and DatePicker components
@@ -9,7 +9,7 @@ import { TimePickerContext } from './TimePicker.js';
9
9
  * Displays a masked time input that opens the wheel picker on focus
10
10
  * Follows the same visual pattern as DatePickerTrigger and SelectButton
11
11
  */
12
- const TimePickerTrigger = ({ id, disabled, isOpen, state = 'default', size = 'md', clearable, onClear, iconStart, iconEnd, className, inputValue, onInputChange, onInputFocus, onInputKeyDown, format, period, onPeriodToggle, placeholder, }) => {
12
+ const TimePickerTrigger = ({ id, disabled, isOpen, state = 'default', size = 'md', clearable, onClear, iconStart, iconEnd, className, inputValue, onInputChange, onInputFocus, onInputKeyDown, format, period, onPeriodToggle, placeholder, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedby, }) => {
13
13
  var _a, _b, _c, _d;
14
14
  const context = useContext(TimePickerContext);
15
15
  if (!context) {
@@ -31,7 +31,7 @@ const TimePickerTrigger = ({ id, disabled, isOpen, state = 'default', size = 'md
31
31
  const hasStartIcon = iconStart !== undefined ? Boolean(iconStart) : true;
32
32
  const iconStartPadding = theme.iconStartPadding || "";
33
33
  return (jsx("div", { ref: triggerRef, className: "relative w-full", children: jsxs("div", { className: cn(baseStyle, stateStyle, hoverStateStyle, activeFocusState, 'w-full items-center', className // User overrides take highest precedence
34
- ), children: [jsxs("div", { className: "relative flex-1", children: [jsx("input", { ref: inputRef, id: id, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, placeholder: placeholder, maxLength: 5, disabled: disabled, className: cn(inputStyle, sizeStyle, hasStartIcon && iconStartPadding), "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-label": "Enter time", autoComplete: "off" }), iconStart !== undefined ? (iconStart && jsx("div", { className: iconStartStyle, children: iconStart })) : (jsx("div", { className: iconStartStyle, children: jsx(ClockIcon, { className: "h-4 w-4" }) }))] }), format === '12h' && (jsx("button", { type: "button", onClick: onPeriodToggle, disabled: disabled, className: cn(periodToggleStyle, "shrink-0"), "aria-label": `Toggle AM/PM, current: ${period}`, tabIndex: -1, children: period || 'AM' })), clearable && hasValue && !disabled && (jsx("button", { type: "button", onClick: (e) => {
34
+ ), children: [jsxs("div", { className: "relative flex-1", children: [jsx("input", { ref: inputRef, id: id, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, placeholder: placeholder, maxLength: 5, disabled: disabled, className: cn(inputStyle, sizeStyle, hasStartIcon && iconStartPadding), "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-label": "Enter time", "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, autoComplete: "off" }), iconStart !== undefined ? (iconStart && jsx("div", { className: iconStartStyle, children: iconStart })) : (jsx("div", { className: iconStartStyle, children: jsx(ClockIcon, { className: "h-4 w-4" }) }))] }), format === '12h' && (jsx("button", { type: "button", onClick: onPeriodToggle, disabled: disabled, className: cn(periodToggleStyle, "shrink-0"), "aria-label": `Toggle AM/PM, current: ${period}`, tabIndex: -1, children: period || 'AM' })), clearable && hasValue && !disabled && (jsx("button", { type: "button", onClick: (e) => {
35
35
  e.stopPropagation();
36
36
  onClear === null || onClear === void 0 ? void 0 : onClear();
37
37
  }, className: "shrink-0 p-0.5 rounded text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)] transition-colors", "aria-label": "Clear time", tabIndex: -1, children: jsx(XMarkIcon, { className: "w-4 h-4" }) })), iconEnd !== undefined ? (iconEnd && (jsx("span", { className: "shrink-0 flex items-center pr-3 pointer-events-none text-[var(--color-text-muted)] dark:text-[var(--color-neutral-500)]", children: iconEnd }))) : (jsx("span", { className: "shrink-0 flex items-center pr-3 pointer-events-none text-[var(--color-text-muted)] dark:text-[var(--color-neutral-500)]", children: jsx(ChevronUpDownIcon, { className: "h-4 w-4" }) }))] }) }));
@@ -138,7 +138,7 @@ export { inputTagTheme } from './InputTag/InputTag.theme.js';
138
138
  export { Combobox } from './Combobox/Combobox.js';
139
139
  export { comboboxTheme } from './Combobox/Combobox.theme.js';
140
140
  export { ColorPicker } from './ColorPicker/ColorPicker.js';
141
- export { ColorPickerContext, useColorPicker } from './ColorPicker/ColorPickerContext.js';
141
+ export { useColorPicker } from './ColorPicker/ColorPickerContext.js';
142
142
  export { ColorPickerTrigger } from './ColorPicker/ColorPickerTrigger.js';
143
143
  export { ColorPickerBody } from './ColorPicker/ColorPickerBody.js';
144
144
  export { ColorPicker2DCanvas } from './ColorPicker/ColorPicker2DCanvas.js';
@@ -0,0 +1,4 @@
1
+ export { FormLayout } from './FormLayout/FormLayout.js';
2
+ export { formLayoutTheme } from './FormLayout/FormLayout.theme.js';
3
+ export { PageLayout } from './PageLayout/PageLayout.js';
4
+ export { pageLayoutTheme } from './PageLayout/PageLayout.theme.js';
@@ -14,3 +14,4 @@ export { useClickOutside } from "./useClickOutside";
14
14
  export { useScaleBackground } from "./useScaleBackground";
15
15
  export type { UseScaleBackgroundOptions } from "./useScaleBackground";
16
16
  export { useMediaQuery } from "./useMediaQuery";
17
+ export { useDarkMode } from './useDarkMode';
@@ -1,7 +1,13 @@
1
1
  import { RefObject } from 'react';
2
2
  /**
3
- * Custom hook that handles clicks outside of the specified element
4
- * @param ref The reference to the element to detect clicks outside of
5
- * @param handler The callback function to execute when a click outside is detected
3
+ * Overload 1 legacy API: useClickOutside(ref, handler)
4
+ * Preserves backward compatibility with existing callers.
6
5
  */
7
- export declare const useClickOutside: <T extends HTMLElement | null>(ref: RefObject<T>, handler: (event: MouseEvent | TouchEvent) => void) => void;
6
+ export declare function useClickOutside<T extends HTMLElement | null>(ref: RefObject<T>, handler: (event: MouseEvent | TouchEvent) => void): void;
7
+ /**
8
+ * Overload 2 — new API: useClickOutside(callback, isActive?, additionalRefs?)
9
+ * Returns a ref to attach to the primary element.
10
+ * Accepts an optional array of additional refs whose contents count as "inside"
11
+ * (useful for trigger+content patterns).
12
+ */
13
+ export declare function useClickOutside(callback: () => void, isActive?: boolean, additionalRefs?: RefObject<HTMLElement | null>[]): RefObject<HTMLElement | null>;
@@ -1,28 +1,48 @@
1
- import { useRef, useEffect } from 'react';
1
+ import { useRef, useCallback, useEffect } from 'react';
2
2
 
3
- /**
4
- * Custom hook that handles clicks outside of the specified element
5
- * @param ref The reference to the element to detect clicks outside of
6
- * @param handler The callback function to execute when a click outside is detected
7
- */
8
- const useClickOutside = (ref, handler) => {
9
- const handlerRef = useRef(handler);
10
- handlerRef.current = handler;
11
- useEffect(() => {
12
- const listener = (event) => {
13
- const el = ref.current;
14
- if (!el || el.contains(event.target)) {
3
+ // Implementation
4
+ function useClickOutside(refOrCallback, handlerOrIsActive, additionalRefs) {
5
+ const internalRef = useRef(null);
6
+ const legacyHandlerRef = useRef(null);
7
+ // Keep legacy handler ref current
8
+ if (typeof refOrCallback !== 'function' && typeof handlerOrIsActive === 'function') {
9
+ legacyHandlerRef.current = handlerOrIsActive;
10
+ }
11
+ const isLegacy = typeof refOrCallback !== 'function';
12
+ const isActive = isLegacy
13
+ ? true
14
+ : typeof handlerOrIsActive === 'boolean'
15
+ ? handlerOrIsActive
16
+ : true;
17
+ const handleClickOutside = useCallback((event) => {
18
+ var _a;
19
+ const target = event.target;
20
+ if (isLegacy) {
21
+ const legacyRef = refOrCallback;
22
+ const el = legacyRef.current;
23
+ if (!el || el.contains(target))
24
+ return;
25
+ (_a = legacyHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(legacyHandlerRef, event);
26
+ }
27
+ else {
28
+ if (internalRef.current && internalRef.current.contains(target))
15
29
  return;
16
- }
17
- handlerRef.current(event);
18
- };
19
- document.addEventListener('mousedown', listener);
20
- document.addEventListener('touchstart', listener);
21
- return () => {
22
- document.removeEventListener('mousedown', listener);
23
- document.removeEventListener('touchstart', listener);
24
- };
25
- }, [ref]);
26
- };
30
+ if (additionalRefs === null || additionalRefs === void 0 ? void 0 : additionalRefs.some(r => { var _a; return (_a = r.current) === null || _a === void 0 ? void 0 : _a.contains(target); }))
31
+ return;
32
+ refOrCallback();
33
+ }
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps
35
+ }, [isLegacy, additionalRefs]);
36
+ useEffect(() => {
37
+ if (!isActive)
38
+ return;
39
+ document.addEventListener('mousedown', handleClickOutside);
40
+ return () => document.removeEventListener('mousedown', handleClickOutside);
41
+ }, [handleClickOutside, isActive]);
42
+ if (isLegacy) {
43
+ return;
44
+ }
45
+ return internalRef;
46
+ }
27
47
 
28
48
  export { useClickOutside };
@@ -0,0 +1 @@
1
+ export declare function useDarkMode(): boolean;
@@ -0,0 +1,42 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ const _subscribers = new Set();
4
+ let _observer = null;
5
+ function _getIsDark() {
6
+ if (typeof document === 'undefined')
7
+ return false;
8
+ return (document.documentElement.classList.contains('dark') ||
9
+ document.body.classList.contains('dark') ||
10
+ document.querySelector('.dark') !== null);
11
+ }
12
+ function _ensureObserver() {
13
+ if (_observer || typeof document === 'undefined')
14
+ return;
15
+ _getIsDark();
16
+ _observer = new MutationObserver(() => {
17
+ _getIsDark();
18
+ _subscribers.forEach((fn) => fn());
19
+ });
20
+ _observer.observe(document.documentElement, {
21
+ attributes: true,
22
+ attributeFilter: ['class'],
23
+ });
24
+ _observer.observe(document.body, {
25
+ attributes: true,
26
+ attributeFilter: ['class'],
27
+ });
28
+ }
29
+ function useDarkMode() {
30
+ const [, rerender] = useState(0);
31
+ useEffect(() => {
32
+ _ensureObserver();
33
+ const notify = () => rerender((n) => n + 1);
34
+ _subscribers.add(notify);
35
+ return () => {
36
+ _subscribers.delete(notify);
37
+ };
38
+ }, []);
39
+ return typeof document === 'undefined' ? false : _getIsDark();
40
+ }
41
+
42
+ export { useDarkMode };
@@ -1,5 +1,5 @@
1
1
  import { StateMachineConfig, StateIdentifier } from "../utils/stateMachine";
2
- export interface UseFormStateMachineOptions<TData = any> {
2
+ export interface UseFormStateMachineOptions<TData = unknown> {
3
3
  /** Initial form data */
4
4
  initialData?: TData;
5
5
  /** Callback when state changes */
@@ -32,7 +32,7 @@ const getConnection = () => {
32
32
  * }
33
33
  */
34
34
  const useNetworkStatus = () => {
35
- const [isOnline, setIsOnline] = useState(() => typeof navigator !== "undefined" ? navigator.onLine : true);
35
+ const [isOnline, setIsOnline] = useState(true);
36
36
  const [wasOffline, setWasOffline] = useState(false);
37
37
  const [networkInfo, setNetworkInfo] = useState({});
38
38
  const updateNetworkInfo = useCallback(() => {
@@ -7,6 +7,8 @@ let lockCount = 0;
7
7
  let savedOverflow = '';
8
8
  let savedPaddingRight = '';
9
9
  function lockScroll() {
10
+ if (typeof window === 'undefined')
11
+ return;
10
12
  lockCount++;
11
13
  if (lockCount === 1) {
12
14
  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
@@ -23,6 +25,8 @@ function lockScroll() {
23
25
  }
24
26
  }
25
27
  function unlockScroll() {
28
+ if (typeof window === 'undefined')
29
+ return;
26
30
  lockCount = Math.max(0, lockCount - 1);
27
31
  if (lockCount === 0) {
28
32
  document.body.style.overflow = savedOverflow;
@@ -1,6 +1,7 @@
1
- import { useRef, useLayoutEffect, useEffect } from 'react';
1
+ import { useRef, useEffect, useLayoutEffect } from 'react';
2
2
  import { animate } from 'motion/react';
3
3
 
4
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
4
5
  const WRAPPER_SELECTOR = "[data-flik-drawer-wrapper]";
5
6
  /**
6
7
  * useScaleBackground
@@ -22,7 +23,9 @@ function useScaleBackground({ isOpen, scale = 0.94, borderRadius = 24, position
22
23
  const controlsRef = useRef(null);
23
24
  // Track current animation progress so rapid toggling picks up where it left off
24
25
  const progressRef = useRef(0);
25
- useLayoutEffect(() => {
26
+ useIsomorphicLayoutEffect(() => {
27
+ if (typeof window === 'undefined')
28
+ return;
26
29
  // Skip if no scaling needed
27
30
  if (scale >= 1)
28
31
  return;
@@ -1,5 +1,6 @@
1
- import { useRef, useState, useCallback, useLayoutEffect } from 'react';
1
+ import { useRef, useState, useCallback, useLayoutEffect, useEffect } from 'react';
2
2
 
3
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
3
4
  /**
4
5
  * Fixed dropdown positioning hook
5
6
  * Uses position: fixed with pure viewport coordinates to properly follow scroll
@@ -288,7 +289,9 @@ const useSimpleDropdown = ({ triggerRef, isOpen, placement = "bottom-start", off
288
289
  contentRef.current.style.left = `${left}px`;
289
290
  }, [triggerRef, measureDropdownHeight, measureDropdownWidth, offset]);
290
291
  // Reset initial render flag when dropdown opens
291
- useLayoutEffect(() => {
292
+ useIsomorphicLayoutEffect(() => {
293
+ if (typeof window === 'undefined')
294
+ return;
292
295
  if (!isOpen) {
293
296
  if (rafIdRef.current !== null) {
294
297
  cancelAnimationFrame(rafIdRef.current);
@@ -319,7 +322,9 @@ const useSimpleDropdown = ({ triggerRef, isOpen, placement = "bottom-start", off
319
322
  };
320
323
  }, [isOpen, calculatePosition]);
321
324
  // Initial position calculation
322
- useLayoutEffect(() => {
325
+ useIsomorphicLayoutEffect(() => {
326
+ if (typeof window === 'undefined')
327
+ return;
323
328
  if (!isOpen)
324
329
  return;
325
330
  calculatePosition();
@@ -363,7 +368,9 @@ const useSimpleDropdown = ({ triggerRef, isOpen, placement = "bottom-start", off
363
368
  });
364
369
  }, [calculatePosition]);
365
370
  // Update position on scroll and resize - rAF-synced for smooth tracking
366
- useLayoutEffect(() => {
371
+ useIsomorphicLayoutEffect(() => {
372
+ if (typeof window === 'undefined')
373
+ return;
367
374
  if (!isOpen)
368
375
  return;
369
376
  window.addEventListener("scroll", handleScroll, { passive: true, capture: true });
@@ -378,7 +385,9 @@ const useSimpleDropdown = ({ triggerRef, isOpen, placement = "bottom-start", off
378
385
  };
379
386
  }, [isOpen, handleScroll, handleResize]);
380
387
  // Recalculate when dropdown content resizes (e.g. search filtering)
381
- useLayoutEffect(() => {
388
+ useIsomorphicLayoutEffect(() => {
389
+ if (typeof window === 'undefined')
390
+ return;
382
391
  if (!isOpen)
383
392
  return;
384
393
  if (!contentRef.current)
package/dist/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  export * from "./components/core";
2
2
  export * from "./components/data-display";
3
3
  export * from "./components/forms";
4
- export * from "./components/charts";
5
4
  export * from "./components/layout";
6
- export * from "./components/effects";
7
5
  export { cn } from "./utils/cn";
8
6
  export { debounce } from "./utils/debounce";
9
7
  export { useClickOutside } from "./hooks/useClickOutside";
package/dist/index.js CHANGED
@@ -174,7 +174,7 @@ export { inputTagTheme } from './components/forms/InputTag/InputTag.theme.js';
174
174
  export { Combobox } from './components/forms/Combobox/Combobox.js';
175
175
  export { comboboxTheme } from './components/forms/Combobox/Combobox.theme.js';
176
176
  export { ColorPicker } from './components/forms/ColorPicker/ColorPicker.js';
177
- export { ColorPickerContext, useColorPicker } from './components/forms/ColorPicker/ColorPickerContext.js';
177
+ export { useColorPicker } from './components/forms/ColorPicker/ColorPickerContext.js';
178
178
  export { ColorPickerTrigger } from './components/forms/ColorPicker/ColorPickerTrigger.js';
179
179
  export { ColorPickerBody } from './components/forms/ColorPicker/ColorPickerBody.js';
180
180
  export { ColorPicker2DCanvas } from './components/forms/ColorPicker/ColorPicker2DCanvas.js';
@@ -196,66 +196,10 @@ export { mentionTheme } from './components/forms/Mention/Mention.theme.js';
196
196
  export { CronInput } from './components/forms/CronInput/CronInput.js';
197
197
  export { cronInputTheme } from './components/forms/CronInput/CronInput.theme.js';
198
198
  export { CRON_PRESETS, cronToDescription, fieldsToCron, formatNextRun, getNextRuns, parseCron, validateCron } from './components/forms/CronInput/CronInput.utils.js';
199
- export { ChartContainer } from './components/charts/ChartContainer.js';
200
- export { BarChart } from './components/charts/BarChart/BarChart.js';
201
- export { StackedBarChart } from './components/charts/StackedBarChart/StackedBarChart.js';
202
- export { STACKED_BAR_CHART_DEFAULTS } from './components/charts/StackedBarChart/StackedBarChart.types.js';
203
- export { LineChart } from './components/charts/LineChart/LineChart.js';
204
- export { AreaChart } from './components/charts/AreaChart/AreaChart.js';
205
- export { DonutChart } from './components/charts/DonutChart/DonutChart.js';
206
- export { MultiSegmentDonutChart } from './components/charts/DonutChart/MultiSegmentDonutChart.js';
207
- export { Heatmap } from './components/charts/Heatmap/Heatmap.js';
208
- import './components/charts/Heatmap/HeatmapCell.js';
209
- export { calculateIntensity, createGridMatrix, formatAxisLabel, generateSampleData, getDefaultTooltipContent, processHeatmapData } from './components/charts/Heatmap/utils/heatmapUtils.js';
210
- export { FunnelChart } from './components/charts/FunnelChart/FunnelChart.js';
211
- export { ScatterPlot } from './components/charts/ScatterPlot/ScatterPlot.js';
212
- export { RadarChart } from './components/charts/RadarChart/RadarChart.js';
213
- export { ComboChart } from './components/charts/ComboChart/ComboChart.js';
214
- export { ActivityRings } from './components/charts/ActivityRings/ActivityRings.js';
215
- export { ChartTooltip } from './components/charts/shared/ChartTooltip/ChartTooltip.js';
216
- export { ChartLegend } from './components/charts/shared/ChartLegend/ChartLegend.js';
217
- export { ChartLegendContent } from './components/charts/shared/ChartLegend/ChartLegendContent.js';
218
- export { XAxis } from './components/charts/shared/ChartAxis/XAxis.js';
219
- export { YAxis } from './components/charts/shared/ChartAxis/YAxis.js';
220
- export { ChartText } from './components/charts/shared/ChartText/ChartText.js';
221
- export { ChartMarker } from './components/charts/shared/ChartMarker/ChartMarker.js';
222
- export { ChartCrosshair } from './components/charts/shared/ChartCrosshair/ChartCrosshair.js';
223
- export { HorizontalGrid } from './components/charts/shared/ChartGrid/HorizontalGrid.js';
224
- export { useChartTheme } from './components/charts/hooks/useChartTheme.js';
225
- export { useTooltipPosition } from './components/charts/hooks/useTooltipPosition.js';
226
- export { useChartAccessibility } from './components/charts/hooks/useChartAccessibility.js';
227
- export { useChartValidation } from './components/charts/hooks/useChartValidation.js';
228
- export { DEFAULT_CHART_COLORS, EXTENDED_CHART_COLORS, MINIMAL_CHART_COLORS, colorClassToVariable, combineClasses, createColorClass, extractFillClass, extractStrokeClass, generateColorPalette, generateSeriesColors, getContrastColor } from './components/charts/utils/color-utils.js';
229
- export { chartTheme } from './components/charts/theme/chart.theme.js';
230
- export { SafeMath, calculateSafeScaleRange, generateNiceTicks, niceNum, sanitizeChartData, validateChart, validateChartConfig, validateChartData } from './components/charts/utils/chart-validation.js';
231
- export { BAR_CHART_DEFAULTS } from './components/charts/BarChart/BarChart.types.js';
232
- export { LINE_CHART_DEFAULTS } from './components/charts/LineChart/LineChart.types.js';
233
- export { AREA_CHART_DEFAULTS } from './components/charts/AreaChart/AreaChart.types.js';
234
- export { ChartErrorBoundary } from './components/charts/shared/ChartErrorBoundary/ChartErrorBoundary.js';
235
199
  export { FormLayout } from './components/layout/FormLayout/FormLayout.js';
236
200
  export { formLayoutTheme } from './components/layout/FormLayout/FormLayout.theme.js';
237
201
  export { PageLayout } from './components/layout/PageLayout/PageLayout.js';
238
202
  export { pageLayoutTheme } from './components/layout/PageLayout/PageLayout.theme.js';
239
- export { CustomCursor, CustomCursorFollow, CustomCursorProvider, useCustomCursor } from './components/effects/CustomCursor/CustomCursor.js';
240
- export { GlassEffect } from './components/effects/GlassEffect/GlassEffect.js';
241
- export { Overlay } from './components/effects/Overlay/Overlay.js';
242
- export { GlassSurface } from './components/effects/GlassSurface/GlassSurface.js';
243
- export { Animated } from './components/effects/Animated/Animated.js';
244
- export { ProgressiveBlur } from './components/effects/ProgressiveBlur/ProgressiveBlur.js';
245
- export { Aurora } from './components/effects/Aurora/Aurora.js';
246
- export { MagneticElement } from './components/effects/MagneticElement/MagneticElement.js';
247
- export { MorphingText } from './components/effects/MorphingText/MorphingText.js';
248
- export { GridPattern } from './components/effects/GridPattern/GridPattern.js';
249
- export { DotPattern } from './components/effects/DotPattern/DotPattern.js';
250
- export { NoiseOverlay } from './components/effects/NoiseOverlay/NoiseOverlay.js';
251
- export { Spotlight } from './components/effects/Spotlight/Spotlight.js';
252
- export { ParallaxSection } from './components/effects/ParallaxSection/ParallaxSection.js';
253
- export { ScrollReveal } from './components/effects/ScrollReveal/ScrollReveal.js';
254
- export { StickyScroll } from './components/effects/StickyScroll/StickyScroll.js';
255
- export { PageTransition } from './components/effects/PageTransition/PageTransition.js';
256
- export { InteractiveCharacters } from './components/effects/InteractiveCharacters/InteractiveCharacters.js';
257
- export { InsetCircleButton } from './components/effects/Neumorphic/InsetCircleButton.js';
258
- export { InsetPill } from './components/effects/Neumorphic/InsetPill.js';
259
203
  export { debounce } from './utils/debounce.js';
260
204
  export { useClickOutside } from './hooks/useClickOutside.js';
261
205
  export { useOverlay } from './hooks/useOverlay.js';
@@ -0,0 +1,80 @@
1
+ /* Shadcn compatibility: alias shadcn variables to Flikkui variables */
2
+
3
+ :root {
4
+ /* Base surfaces */
5
+ --background: var(--color-background);
6
+ --foreground: var(--color-text-primary);
7
+ --card: var(--color-background);
8
+ --card-foreground: var(--color-text-primary);
9
+ --popover: var(--color-background);
10
+ --popover-foreground: var(--color-text-primary);
11
+
12
+ /* Primary system */
13
+ --primary: var(--color-primary);
14
+ --primary-foreground: var(--color-text-inverse);
15
+
16
+ /* Secondary/muted/accent map to neutrals */
17
+ --secondary: var(--color-background-secondary);
18
+ --secondary-foreground: var(--color-text-primary);
19
+ --muted: var(--color-background-tertiary);
20
+ --muted-foreground: var(--color-text-muted);
21
+ --accent: var(--color-background-quaternary);
22
+ --accent-foreground: var(--color-text-primary);
23
+
24
+ /* Destructive maps to danger */
25
+ --destructive: var(--color-danger-600);
26
+
27
+ /* Borders/inputs/ring */
28
+ --border: var(--color-border);
29
+ --input: var(--color-border);
30
+ --ring: var(--color-primary-600);
31
+
32
+ /* Typography & radius */
33
+ --radius: var(--form-rounded);
34
+
35
+ /* Charts (approximate) */
36
+ --chart-1: var(--color-primary-600);
37
+ --chart-2: var(--color-success-600);
38
+ --chart-3: var(--color-warning-600);
39
+ --chart-4: var(--color-danger-600);
40
+ --chart-5: var(--color-primary-400);
41
+
42
+ /* Sidebar */
43
+ --sidebar: var(--color-background-secondary);
44
+ --sidebar-foreground: var(--color-text-primary);
45
+ --sidebar-primary: var(--color-primary);
46
+ --sidebar-primary-foreground: var(--color-text-inverse);
47
+ --sidebar-accent: var(--color-background-tertiary);
48
+ --sidebar-accent-foreground: var(--color-text-primary);
49
+ --sidebar-border: var(--color-border);
50
+ --sidebar-ring: var(--color-primary-600);
51
+ }
52
+
53
+ .dark {
54
+ --background: oklch(0.145 0 0);
55
+ --foreground: var(--color-text-inverse);
56
+ --card: oklch(0.205 0 0);
57
+ --card-foreground: var(--color-text-inverse);
58
+ --popover: oklch(0.269 0 0);
59
+ --popover-foreground: var(--color-text-inverse);
60
+ --primary: var(--color-primary-400);
61
+ --primary-foreground: var(--color-text-inverse);
62
+ --secondary: oklch(0.269 0 0);
63
+ --secondary-foreground: var(--color-text-inverse);
64
+ --muted: oklch(0.269 0 0);
65
+ --muted-foreground: var(--color-text-muted);
66
+ --accent: oklch(0.371 0 0);
67
+ --accent-foreground: var(--color-text-inverse);
68
+ --destructive: var(--color-danger-500);
69
+ --border: color-mix(in oklab, var(--color-border) 80%, black);
70
+ --input: color-mix(in oklab, var(--color-border) 85%, black);
71
+ --ring: var(--color-primary-500);
72
+ --sidebar: oklch(0.205 0 0);
73
+ --sidebar-foreground: var(--color-text-inverse);
74
+ --sidebar-primary: var(--color-primary-400);
75
+ --sidebar-primary-foreground: var(--color-text-inverse);
76
+ --sidebar-accent: oklch(0.269 0 0);
77
+ --sidebar-accent-foreground: var(--color-text-inverse);
78
+ --sidebar-border: color-mix(in oklab, var(--color-border) 70%, black);
79
+ --sidebar-ring: var(--color-primary-500);
80
+ }