doom-design-system 0.1.14 → 0.2.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.
Files changed (44) hide show
  1. package/dist/components/Accordion/Accordion.d.ts +7 -6
  2. package/dist/components/Accordion/Accordion.js +36 -28
  3. package/dist/components/Accordion/Accordion.module.css +78 -22
  4. package/dist/components/Avatar/Avatar.d.ts +4 -4
  5. package/dist/components/Avatar/Avatar.js +6 -6
  6. package/dist/components/Badge/Badge.module.css +3 -3
  7. package/dist/components/Button/Button.module.css +1 -1
  8. package/dist/components/Checkbox/Checkbox.d.ts +2 -2
  9. package/dist/components/Checkbox/Checkbox.js +7 -7
  10. package/dist/components/Drawer/Drawer.js +5 -3
  11. package/dist/components/Drawer/Drawer.module.css +8 -6
  12. package/dist/components/Form/Form.module.css +1 -0
  13. package/dist/components/Input/Input.d.ts +3 -2
  14. package/dist/components/Input/Input.js +15 -3
  15. package/dist/components/Input/Input.module.css +33 -0
  16. package/dist/components/Modal/Modal.d.ts +5 -4
  17. package/dist/components/Modal/Modal.js +13 -6
  18. package/dist/components/Modal/Modal.module.css +64 -29
  19. package/dist/components/Popover/Popover.d.ts +3 -3
  20. package/dist/components/Popover/Popover.js +38 -36
  21. package/dist/components/ProgressBar/ProgressBar.d.ts +2 -1
  22. package/dist/components/ProgressBar/ProgressBar.js +10 -5
  23. package/dist/components/ProgressBar/ProgressBar.module.css +7 -0
  24. package/dist/components/Select/Select.js +6 -4
  25. package/dist/components/Select/Select.module.css +2 -2
  26. package/dist/components/Sheet/Sheet.d.ts +2 -2
  27. package/dist/components/Sheet/Sheet.js +18 -16
  28. package/dist/components/Sheet/Sheet.module.css +1 -2
  29. package/dist/components/Slider/Slider.d.ts +3 -3
  30. package/dist/components/Slider/Slider.js +11 -7
  31. package/dist/components/Slider/Slider.module.css +1 -1
  32. package/dist/components/SplitButton/SplitButton.d.ts +2 -2
  33. package/dist/components/SplitButton/SplitButton.js +8 -8
  34. package/dist/components/Tabs/Tabs.js +2 -2
  35. package/dist/components/Tabs/Tabs.module.css +9 -7
  36. package/dist/components/Textarea/Textarea.d.ts +8 -3
  37. package/dist/components/Textarea/Textarea.js +25 -6
  38. package/dist/components/Textarea/Textarea.module.css +71 -0
  39. package/dist/styles/globals.css +138 -1
  40. package/dist/styles/themes/definitions.d.ts +312 -300
  41. package/dist/styles/themes/definitions.js +60 -60
  42. package/dist/tsconfig.build.tsbuildinfo +1 -0
  43. package/package.json +2 -2
  44. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,21 +1,3 @@
1
- @keyframes fadeIn {
2
- from {
3
- opacity: 0;
4
- }
5
- to {
6
- opacity: 1;
7
- }
8
- }
9
- @keyframes slideUp {
10
- from {
11
- transform: translateY(20px);
12
- opacity: 0;
13
- }
14
- to {
15
- transform: translateY(0);
16
- opacity: 1;
17
- }
18
- }
19
1
  .overlay {
20
2
  position: fixed;
21
3
  inset: 0;
@@ -26,32 +8,85 @@
26
8
  padding: var(--spacing-md);
27
9
  backdrop-filter: blur(4px);
28
10
  background-color: rgba(0, 0, 0, var(--overlay-opacity));
29
- animation: fadeIn 0.2s ease-out;
11
+ opacity: 0;
12
+ visibility: hidden;
13
+ transition: opacity 0.2s ease-out, visibility 0.2s ease-out;
14
+ }
15
+ .overlay.isOpen {
16
+ opacity: 1;
17
+ visibility: visible;
18
+ }
19
+ .overlay.isOpen .contentContainer {
20
+ transform: translateY(0);
21
+ opacity: 1;
30
22
  }
31
23
 
32
24
  .contentContainer {
33
25
  width: 100%;
34
- max-width: 28rem;
35
- animation: slideUp 0.3s ease-out;
26
+ max-width: 32rem;
27
+ transform: translateY(20px);
28
+ opacity: 0;
29
+ transition: transform 0.3s ease-out, opacity 0.3s ease-out;
30
+ }
31
+
32
+ .modalCard {
33
+ /* Prevent sub-pixel slivers by matching the card background to the header color */
34
+ background-color: var(--primary);
36
35
  }
37
36
 
38
37
  .header {
39
38
  padding: var(--spacing-lg);
40
- border-bottom: var(--border-width) solid var(--card-border);
41
- background: var(--background);
39
+ background-color: var(--primary);
40
+ color: var(--primary-foreground);
41
+ border-bottom: none;
42
+ }
43
+
44
+ .headerContent {
45
+ flex: 1;
46
+ max-width: 85%;
42
47
  }
43
- .header h2 {
44
- font-size: var(--text-xl);
45
- font-weight: bold;
46
- margin: 0;
48
+
49
+ .closeButton {
50
+ flex-shrink: 0;
51
+ background-color: var(--error) !important;
52
+ color: white !important;
53
+ border: var(--border-width) solid var(--card-border) !important;
54
+ border-radius: var(--radius) !important;
55
+ height: 36px !important;
56
+ width: 36px !important;
57
+ min-width: 36px !important;
58
+ display: flex !important;
59
+ align-items: center;
60
+ justify-content: center;
61
+ padding: 0 !important;
62
+ /* Use a semi-transparent black shadow instead of a theme variable to guarantee visibility on dark primary headers */
63
+ box-shadow: 2px 2px 0px 0px rgba(0, 0, 0, 0.4) !important;
64
+ transition: all 0.2s ease;
65
+ cursor: pointer;
66
+ }
67
+ .closeButton:hover {
68
+ filter: brightness(1.1);
69
+ transform: translate(-1px, -1px);
70
+ box-shadow: 3px 3px 0px 0px rgba(0, 0, 0, 0.4) !important;
71
+ }
72
+ .closeButton:active {
73
+ transform: translate(1px, 1px);
74
+ box-shadow: 1px 1px 0px 0px rgba(0, 0, 0, 0.4) !important;
75
+ }
76
+
77
+ .modalContent {
78
+ background-color: var(--card-bg);
79
+ /* Slight bleed to bridge any sub-pixel gaps at the header junction */
80
+ padding-top: 1px;
81
+ margin-top: -1px;
47
82
  }
48
83
 
49
84
  .body {
50
85
  padding: var(--spacing-lg);
86
+ color: var(--foreground);
51
87
  }
52
88
 
53
89
  .footer {
54
90
  padding: var(--spacing-lg);
55
- border-top: var(--border-width) solid var(--card-border);
56
- background: var(--background);
91
+ padding-top: 0;
57
92
  }
@@ -1,11 +1,11 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  interface PopoverProps {
3
3
  trigger: React.ReactNode;
4
4
  content: React.ReactNode;
5
5
  isOpen: boolean;
6
6
  onClose: () => void;
7
- placement?: 'bottom-start' | 'bottom-end' | 'bottom-center' | 'top-start' | 'top-end' | 'top-center';
7
+ placement?: "bottom-start" | "bottom-end" | "bottom-center" | "top-start" | "top-end" | "top-center";
8
8
  offset?: number;
9
9
  }
10
- export declare function Popover({ trigger, content, isOpen, onClose, placement, offset }: PopoverProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function Popover({ trigger, content, isOpen, onClose, placement, offset, }: PopoverProps): import("react/jsx-runtime").JSX.Element;
11
11
  export {};
@@ -1,13 +1,13 @@
1
- 'use client';
1
+ "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createPortal } from 'react-dom';
4
- import styles from './Popover.module.css';
5
- import { useState, useRef, useEffect, useCallback, useLayoutEffect } from 'react';
6
- export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom-start', offset = 8 }) {
3
+ import { createPortal } from "react-dom";
4
+ import styles from "./Popover.module.css";
5
+ import { useState, useRef, useEffect, useCallback, useLayoutEffect, } from "react";
6
+ export function Popover({ trigger, content, isOpen, onClose, placement = "bottom-start", offset = 8, }) {
7
7
  const triggerRef = useRef(null);
8
8
  const contentRef = useRef(null);
9
9
  const [position, setPosition] = useState({ top: 0, left: 0 });
10
- const [transformOrigin, setTransformOrigin] = useState('top left');
10
+ const [transformOrigin, setTransformOrigin] = useState("top left");
11
11
  const updatePosition = useCallback(() => {
12
12
  if (!isOpen || !triggerRef.current || !contentRef.current)
13
13
  return;
@@ -17,24 +17,24 @@ export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom
17
17
  const viewportHeight = window.innerHeight;
18
18
  let top = 0;
19
19
  let left = 0;
20
- let origin = 'top center';
20
+ let origin = "top center";
21
21
  // Edge Config
22
22
  const padding = 16;
23
- const isTop = placement.startsWith('top');
23
+ const isTop = placement.startsWith("top");
24
24
  if (isTop) {
25
25
  top = triggerRect.top - contentRect.height - offset;
26
- origin = 'bottom';
26
+ origin = "bottom";
27
27
  if (top < 0) {
28
28
  top = triggerRect.bottom + offset;
29
- origin = 'top';
29
+ origin = "top";
30
30
  }
31
31
  }
32
32
  else {
33
33
  top = triggerRect.bottom + offset;
34
- origin = 'top';
34
+ origin = "top";
35
35
  if (top + contentRect.height > viewportHeight) {
36
36
  top = triggerRect.top - contentRect.height - offset;
37
- origin = 'bottom';
37
+ origin = "bottom";
38
38
  if (top < 0)
39
39
  top = padding;
40
40
  }
@@ -46,6 +46,19 @@ export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom
46
46
  if (top + contentRect.height > viewportHeight - padding) {
47
47
  top = viewportHeight - contentRect.height - padding;
48
48
  }
49
+ const align = placement.split("-")[1];
50
+ if (align === "start") {
51
+ left = triggerRect.left;
52
+ origin += " left";
53
+ }
54
+ else if (align === "end") {
55
+ left = triggerRect.right - contentRect.width;
56
+ origin += " right";
57
+ }
58
+ else {
59
+ left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2;
60
+ origin += " center";
61
+ }
49
62
  // Horizontal Clamping
50
63
  if (left + contentRect.width > viewportWidth - padding) {
51
64
  left = viewportWidth - contentRect.width - padding;
@@ -53,19 +66,6 @@ export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom
53
66
  if (left < padding) {
54
67
  left = padding;
55
68
  }
56
- const align = placement.split('-')[1];
57
- if (align === 'start') {
58
- left = triggerRect.left;
59
- origin += ' left';
60
- }
61
- else if (align === 'end') {
62
- left = triggerRect.right - contentRect.width;
63
- origin += ' right';
64
- }
65
- else {
66
- left = triggerRect.left + (triggerRect.width / 2) - (contentRect.width / 2);
67
- origin += ' center';
68
- }
69
69
  setPosition({ top, left });
70
70
  setTransformOrigin(origin);
71
71
  }, [isOpen, placement, offset]);
@@ -73,12 +73,12 @@ export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom
73
73
  useLayoutEffect(() => {
74
74
  if (isOpen) {
75
75
  updatePosition();
76
- window.addEventListener('resize', updatePosition);
77
- window.addEventListener('scroll', updatePosition, true);
76
+ window.addEventListener("resize", updatePosition);
77
+ window.addEventListener("scroll", updatePosition, true);
78
78
  }
79
79
  return () => {
80
- window.removeEventListener('resize', updatePosition);
81
- window.removeEventListener('scroll', updatePosition, true);
80
+ window.removeEventListener("resize", updatePosition);
81
+ window.removeEventListener("scroll", updatePosition, true);
82
82
  };
83
83
  }, [isOpen, updatePosition]);
84
84
  // Handle click outside
@@ -93,12 +93,14 @@ export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom
93
93
  onClose();
94
94
  }
95
95
  }
96
- document.addEventListener('mousedown', handleClickOutside);
97
- return () => document.removeEventListener('mousedown', handleClickOutside);
96
+ document.addEventListener("mousedown", handleClickOutside);
97
+ return () => document.removeEventListener("mousedown", handleClickOutside);
98
98
  }, [isOpen, onClose]);
99
- return (_jsxs(_Fragment, { children: [_jsx("div", { ref: triggerRef, className: styles.triggerWrapper, children: trigger }), isOpen && typeof document !== 'undefined' && createPortal(_jsx("div", { ref: contentRef, className: styles.popover, style: {
100
- top: position.top,
101
- left: position.left,
102
- transformOrigin: transformOrigin,
103
- }, children: content }), document.body)] }));
99
+ return (_jsxs(_Fragment, { children: [_jsx("div", { ref: triggerRef, className: styles.triggerWrapper, children: trigger }), isOpen &&
100
+ typeof document !== "undefined" &&
101
+ createPortal(_jsx("div", { ref: contentRef, className: styles.popover, style: {
102
+ top: position.top,
103
+ left: position.left,
104
+ transformOrigin: transformOrigin,
105
+ }, children: content }), document.body)] }));
104
106
  }
@@ -5,6 +5,7 @@ interface ProgressBarProps extends React.HTMLAttributes<HTMLDivElement> {
5
5
  height?: string | number;
6
6
  color?: string;
7
7
  showStripes?: boolean;
8
+ label?: React.ReactNode;
8
9
  }
9
- export declare function ProgressBar({ value, max, height, color, showStripes, className, style, ...props }: ProgressBarProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function ProgressBar({ value, max, height, color, showStripes, label, className, style, id, ...props }: ProgressBarProps): import("react/jsx-runtime").JSX.Element;
10
11
  export {};
@@ -13,13 +13,18 @@ var __rest = (this && this.__rest) || function (s, e) {
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import clsx from "clsx";
15
15
  import styles from "./ProgressBar.module.css";
16
+ import React from "react";
17
+ import { Label } from "../Label/Label.js";
16
18
  export function ProgressBar(_a) {
17
- var { value, max = 100, height = "24px", color = "var(--primary)", showStripes = true, className, style } = _a, props = __rest(_a, ["value", "max", "height", "color", "showStripes", "className", "style"]);
19
+ var { value, max = 100, height = "24px", color = "var(--primary)", showStripes = true, label, className, style, id } = _a, props = __rest(_a, ["value", "max", "height", "color", "showStripes", "label", "className", "style", "id"]);
20
+ const reactId = React.useId();
21
+ const barId = id || `progress-${reactId}`;
22
+ const labelId = `label-${reactId}`;
18
23
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
19
24
  const clampedValue = Math.min(Math.max(value, 0), max);
20
25
  const heightStyle = typeof height === "number" ? `${height}px` : height;
21
- return (_jsxs("div", Object.assign({ role: "progressbar", "aria-valuenow": clampedValue, "aria-valuemin": 0, "aria-valuemax": max, className: clsx(styles.container, className), style: Object.assign({ "--height": heightStyle }, style) }, props, { children: [_jsx("div", { className: styles.fill, style: {
22
- "--percentage": `${percentage}%`,
23
- "--color": color,
24
- }, "data-complete": percentage >= 100 }), showStripes && _jsx("div", { className: styles.stripes })] })));
26
+ return (_jsxs("div", { className: clsx(styles.wrapper, className), children: [label && _jsx(Label, { id: labelId, children: label }), _jsxs("div", Object.assign({ id: barId, role: "progressbar", "aria-valuenow": clampedValue, "aria-valuemin": 0, "aria-valuemax": max, "aria-labelledby": label ? labelId : undefined, "aria-label": !label ? props["aria-label"] || "Progress" : undefined, className: styles.container, style: Object.assign({ "--height": heightStyle }, style) }, props, { children: [_jsx("div", { className: styles.fill, style: {
27
+ "--percentage": `${percentage}%`,
28
+ "--color": color,
29
+ }, "data-complete": percentage >= 100 }), showStripes && _jsx("div", { className: styles.stripes })] }))] }));
25
30
  }
@@ -1,3 +1,10 @@
1
+ .wrapper {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.5rem;
5
+ width: 100%;
6
+ }
7
+
1
8
  .container {
2
9
  height: var(--height, 24px);
3
10
  width: 100%;
@@ -13,9 +13,9 @@ var __rest = (this && this.__rest) || function (s, e) {
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { useState, useRef, useEffect, useId, } from "react";
15
15
  import clsx from "clsx";
16
- import { Text } from "../Text/Text.js";
17
16
  import { Popover } from "../Popover/Popover.js";
18
17
  import { Check, ChevronDown } from "lucide-react";
18
+ import { Label } from "../Label/Label.js";
19
19
  import styles from "./Select.module.css";
20
20
  export function Select(_a) {
21
21
  var _b;
@@ -101,11 +101,13 @@ export function Select(_a) {
101
101
  break;
102
102
  }
103
103
  };
104
- return (_jsxs("div", { className: clsx(styles.container, className), style: style, children: [label && (_jsx(Text, { as: "label", id: labelId, variant: "small", weight: "bold", color: "muted", className: "mb-1 block", htmlFor: selectId, children: label })), _jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-start", trigger: _jsxs("button", Object.assign({ ref: triggerRef, className: styles.trigger, type: "button", id: selectId, onClick: () => setIsOpen(!isOpen), onKeyDown: handleKeyDown, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, "aria-required": required, disabled: disabled, autoFocus: autoFocus }, props, { children: [_jsx("span", { children: selectedOption
104
+ return (_jsxs("div", { className: clsx(styles.container, className), style: style, children: [label && (_jsx(Label, { htmlFor: selectId, required: required, children: label })), _jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-start", trigger: _jsxs("button", Object.assign({ ref: triggerRef, className: styles.trigger, type: "button", id: selectId, onClick: () => setIsOpen(!isOpen), onKeyDown: handleKeyDown, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": isOpen ? listboxId : undefined, "aria-labelledby": label ? labelId : undefined, "aria-label": !label
105
+ ? (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) || placeholder || "Select option"
106
+ : undefined, "aria-required": required, disabled: disabled, autoFocus: autoFocus }, props, { children: [_jsx("span", { children: selectedOption
105
107
  ? selectedOption.label
106
- : placeholder || "Select..." }), _jsx(ChevronDown, { size: 16, strokeWidth: 2.5, style: { marginLeft: "0.5rem" } })] })), content: _jsx("ul", { id: listboxId, role: "listbox", "aria-labelledby": label ? labelId : undefined, className: styles.optionsList, style: { width: (_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth }, children: options.map((opt, index) => {
108
+ : placeholder || "Select..." }), _jsx(ChevronDown, { size: 16, strokeWidth: 2.5, style: { marginLeft: "0.5rem" }, "aria-hidden": "true" })] })), content: _jsx("ul", { id: listboxId, role: "listbox", "aria-labelledby": label ? labelId : selectId, className: styles.optionsList, style: { width: (_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth }, children: options.map((opt, index) => {
107
109
  const isSelected = String(opt.value) === String(currentValue);
108
110
  const isHighlighted = index === highlightedIndex;
109
111
  return (_jsxs("li", { id: `${listboxId}-option-${index}`, role: "option", "aria-selected": isSelected, className: clsx(styles.optionItem, isSelected && styles.selected, isHighlighted && styles.highlighted), onClick: () => handleSelect(opt.value), onMouseEnter: () => setHighlightedIndex(index), children: [_jsx("span", { children: opt.label }), isSelected && (_jsx(Check, { size: 14, strokeWidth: 3, "aria-hidden": "true" }))] }, opt.value));
110
- }) }) }), _jsx("input", { type: "hidden", name: name, value: currentValue, required: required, "aria-hidden": "true" })] }));
112
+ }) }) }), _jsx("input", { type: "hidden", name: name, value: currentValue, required: required, "aria-hidden": "true", "aria-labelledby": label ? labelId : undefined })] }));
111
113
  }
@@ -71,11 +71,11 @@
71
71
  }
72
72
  .optionItem:hover {
73
73
  background-color: color-mix(in srgb, var(--primary), transparent 85%);
74
- color: var(--primary);
74
+ color: color-mix(in srgb, var(--primary), var(--foreground) 25%);
75
75
  }
76
76
  .optionItem.highlighted {
77
77
  background: color-mix(in srgb, var(--primary), transparent 85%);
78
- color: var(--primary);
78
+ color: color-mix(in srgb, var(--primary), var(--foreground) 25%);
79
79
  }
80
80
  .optionItem.selected {
81
81
  background: var(--primary);
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  interface SheetProps {
3
3
  isOpen: boolean;
4
4
  onClose: () => void;
@@ -6,5 +6,5 @@ interface SheetProps {
6
6
  children: React.ReactNode;
7
7
  className?: string;
8
8
  }
9
- export declare function Sheet({ isOpen, onClose, title, children, className }: SheetProps): React.ReactPortal | null;
9
+ export declare function Sheet({ isOpen, onClose, title, children, className, }: SheetProps): React.ReactPortal | null;
10
10
  export {};
@@ -1,36 +1,38 @@
1
- 'use client';
1
+ "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useEffect, useState } from 'react';
4
- import { createPortal } from 'react-dom';
5
- import clsx from 'clsx';
6
- import { Button } from '../Button/Button.js';
7
- import { Flex } from '../Layout/Layout.js';
8
- import styles from './Sheet.module.css';
9
- import { X } from 'lucide-react';
10
- export function Sheet({ isOpen, onClose, title, children, className }) {
3
+ import React, { useEffect, useState } from "react";
4
+ import { createPortal } from "react-dom";
5
+ import clsx from "clsx";
6
+ import { Button } from "../Button/Button.js";
7
+ import { Flex } from "../Layout/Layout.js";
8
+ import styles from "./Sheet.module.css";
9
+ import { X } from "lucide-react";
10
+ export function Sheet({ isOpen, onClose, title, children, className, }) {
11
+ const reactId = React.useId();
12
+ const titleId = `sheet-title-${reactId}`;
11
13
  const [mounted, setMounted] = useState(false);
12
14
  useEffect(() => {
13
15
  setMounted(true);
14
16
  if (isOpen) {
15
- document.body.style.overflow = 'hidden';
17
+ document.body.style.overflow = "hidden";
16
18
  }
17
19
  else {
18
- document.body.style.overflow = '';
20
+ document.body.style.overflow = "";
19
21
  }
20
22
  return () => {
21
- document.body.style.overflow = '';
23
+ document.body.style.overflow = "";
22
24
  };
23
25
  }, [isOpen]);
24
26
  useEffect(() => {
25
27
  const handleEsc = (e) => {
26
- if (e.key === 'Escape')
28
+ if (e.key === "Escape")
27
29
  onClose();
28
30
  };
29
31
  if (isOpen)
30
- window.addEventListener('keydown', handleEsc);
31
- return () => window.removeEventListener('keydown', handleEsc);
32
+ window.addEventListener("keydown", handleEsc);
33
+ return () => window.removeEventListener("keydown", handleEsc);
32
34
  }, [isOpen, onClose]);
33
35
  if (!mounted)
34
36
  return null;
35
- return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", children: [_jsx("div", { className: styles.handleBar }), _jsxs(Flex, { align: "center", justify: "space-between", className: styles.header, children: [_jsx("h2", { className: styles.title, children: title }), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close sheet", children: _jsx(X, { size: 24 }) })] }), _jsx("div", { className: styles.content, children: children })] })] }), document.body);
37
+ return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? "Sheet" : undefined, children: [_jsx("div", { className: styles.handleBar }), _jsxs(Flex, { align: "center", justify: "space-between", className: styles.header, children: [title && (_jsx("h2", { id: titleId, className: styles.title, children: title })), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close sheet", children: _jsx(X, { size: 24 }) })] }), _jsx("div", { className: styles.content, children: children })] })] }), document.body);
36
38
  }
@@ -18,8 +18,7 @@
18
18
  bottom: 0;
19
19
  left: 0;
20
20
  right: 0;
21
- max-height: 65vh;
22
- min-height: 45vh;
21
+ height: 85vh;
23
22
  background-color: var(--card-bg);
24
23
  border-top: var(--border-width) solid var(--card-border);
25
24
  border-left: var(--border-width) solid var(--card-border);
@@ -1,10 +1,10 @@
1
- import React from 'react';
2
- interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
1
+ import React from "react";
2
+ interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
3
3
  label?: string;
4
4
  showValue?: boolean;
5
5
  value?: number;
6
6
  defaultValue?: number;
7
7
  onChange?: (value: number) => void;
8
8
  }
9
- export declare function Slider({ label, showValue, value, defaultValue, onChange, min, max, step, className, ...props }: SliderProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function Slider({ label, showValue, value, defaultValue, onChange, min, max, step, className, id, ...props }: SliderProps): import("react/jsx-runtime").JSX.Element;
10
10
  export {};
@@ -1,4 +1,4 @@
1
- 'use client';
1
+ "use client";
2
2
  var __rest = (this && this.__rest) || function (s, e) {
3
3
  var t = {};
4
4
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -11,11 +11,14 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  return t;
12
12
  };
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- import clsx from 'clsx';
15
- import styles from './Slider.module.css';
16
- import React from 'react';
14
+ import clsx from "clsx";
15
+ import styles from "./Slider.module.css";
16
+ import React from "react";
17
+ import { Label } from "../Label/Label.js";
17
18
  export function Slider(_a) {
18
- var { label, showValue, value, defaultValue, onChange, min = 0, max = 100, step = 1, className } = _a, props = __rest(_a, ["label", "showValue", "value", "defaultValue", "onChange", "min", "max", "step", "className"]);
19
+ var { label, showValue, value, defaultValue, onChange, min = 0, max = 100, step = 1, className, id } = _a, props = __rest(_a, ["label", "showValue", "value", "defaultValue", "onChange", "min", "max", "step", "className", "id"]);
20
+ const reactId = React.useId();
21
+ const inputId = id || `slider-${reactId}`;
19
22
  const [internalValue, setInternalValue] = React.useState(defaultValue !== undefined ? defaultValue : min);
20
23
  const isControlled = value !== undefined;
21
24
  const currentValue = isControlled ? value : internalValue;
@@ -26,6 +29,7 @@ export function Slider(_a) {
26
29
  }
27
30
  onChange === null || onChange === void 0 ? void 0 : onChange(newVal);
28
31
  };
29
- const percentage = ((currentValue - min) / (max - min)) * 100;
30
- return (_jsxs("div", { className: clsx(styles.container, className), children: [(label || showValue) && (_jsxs("div", { className: styles.labelRow, children: [label && _jsx("span", { children: label }), showValue && _jsx("span", { className: styles.valueDisplay, children: currentValue })] })), _jsxs("div", { className: styles.trackWrapper, children: [_jsx("div", { className: styles.progressFill, style: { '--percentage': `${percentage}%` } }), _jsx("input", Object.assign({ className: styles.rangeInput, type: "range", min: min, max: max, step: step, value: currentValue, onChange: handleChange }, props))] })] }));
32
+ const percentage = ((currentValue - min) / (max - min)) *
33
+ 100;
34
+ return (_jsxs("div", { className: clsx(styles.container, className), children: [(label || showValue) && (_jsxs("div", { className: styles.labelRow, children: [label && _jsx(Label, { htmlFor: inputId, children: label }), showValue && (_jsx("span", { className: styles.valueDisplay, children: currentValue }))] })), _jsxs("div", { className: styles.trackWrapper, children: [_jsx("div", { className: styles.progressFill, style: { "--percentage": `${percentage}%` } }), _jsx("input", Object.assign({ id: inputId, className: styles.rangeInput, type: "range", min: min, max: max, step: step, value: currentValue, onChange: handleChange, "aria-label": !label ? props["aria-label"] || "Slider" : undefined, "aria-valuenow": currentValue, "aria-valuemin": Number(min), "aria-valuemax": Number(max) }, props))] })] }));
31
35
  }
@@ -18,7 +18,7 @@
18
18
  .valueDisplay {
19
19
  font-family: var(--font-mono, monospace);
20
20
  font-weight: 700;
21
- color: var(--primary);
21
+ color: color-mix(in srgb, var(--primary), var(--foreground) 25%);
22
22
  font-size: var(--text-base);
23
23
  min-width: 3ch;
24
24
  text-align: right;
@@ -6,8 +6,8 @@ interface SplitButtonProps {
6
6
  primaryLabel: string;
7
7
  onPrimaryClick: () => void;
8
8
  items: SplitButtonItem[];
9
- variant?: 'primary' | 'secondary';
9
+ variant?: "primary" | "secondary";
10
10
  className?: string;
11
11
  }
12
- export declare function SplitButton({ primaryLabel, onPrimaryClick, items, variant, className }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function SplitButton({ primaryLabel, onPrimaryClick, items, variant, className, }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
13
13
  export {};
@@ -1,13 +1,13 @@
1
- 'use client';
1
+ "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import clsx from 'clsx';
4
- import { Popover } from '../Popover/Popover.js';
5
- import { ChevronDown } from 'lucide-react';
6
- import styles from './SplitButton.module.css';
7
- import { useState } from 'react';
8
- export function SplitButton({ primaryLabel, onPrimaryClick, items, variant = 'primary', className }) {
3
+ import clsx from "clsx";
4
+ import { Popover } from "../Popover/Popover.js";
5
+ import { ChevronDown } from "lucide-react";
6
+ import styles from "./SplitButton.module.css";
7
+ import { useState } from "react";
8
+ export function SplitButton({ primaryLabel, onPrimaryClick, items, variant = "primary", className, }) {
9
9
  const [isOpen, setIsOpen] = useState(false);
10
- return (_jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-end", trigger: _jsxs("div", { className: clsx(styles.container, styles[variant], className), "aria-expanded": isOpen, children: [_jsx("button", { className: styles.mainButton, onClick: onPrimaryClick, children: primaryLabel }), _jsx("button", { className: styles.dropdownTrigger, onClick: () => setIsOpen(!isOpen), children: _jsx(ChevronDown, { size: 16, strokeWidth: 3 }) })] }), content: _jsx("div", { className: styles.menu, children: items.map((item, index) => (_jsx("button", { className: styles.item, onClick: () => {
10
+ return (_jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-end", trigger: _jsxs("div", { className: clsx(styles.container, styles[variant], className), children: [_jsx("button", { className: styles.mainButton, onClick: onPrimaryClick, children: primaryLabel }), _jsx("button", { className: styles.dropdownTrigger, onClick: () => setIsOpen(!isOpen), "aria-expanded": isOpen, "aria-haspopup": "menu", "aria-label": `More ${primaryLabel} options`, children: _jsx(ChevronDown, { size: 16, strokeWidth: 3, "aria-hidden": "true" }) })] }), content: _jsx("div", { className: styles.menu, children: items.map((item, index) => (_jsx("button", { className: styles.item, onClick: () => {
11
11
  item.onClick();
12
12
  setIsOpen(false);
13
13
  }, children: item.label }, index))) }) }));
@@ -31,7 +31,7 @@ export function Tabs(_a) {
31
31
  }
32
32
  export function TabsList(_a) {
33
33
  var { children, className } = _a, props = __rest(_a, ["children", "className"]);
34
- return (_jsx("div", Object.assign({ role: "tablist", "aria-orientation": "horizontal", className: clsx(styles.tabsList, className) }, props, { children: children })));
34
+ return (_jsx("div", Object.assign({ role: "tablist", "aria-orientation": "horizontal", "aria-label": props["aria-label"] || "Tabs", className: clsx(styles.tabsList, className) }, props, { children: children })));
35
35
  }
36
36
  export function TabsTrigger(_a) {
37
37
  var { value, children, className, onClick } = _a, props = __rest(_a, ["value", "children", "className", "onClick"]);
@@ -41,7 +41,7 @@ export function TabsTrigger(_a) {
41
41
  const isActive = context.activeTab === value;
42
42
  const triggerId = `tabs-trigger-${context.baseId}-${value}`;
43
43
  const contentId = `tabs-content-${context.baseId}-${value}`;
44
- return (_jsx("button", Object.assign({ id: triggerId, role: "tab", type: "button", "aria-selected": isActive, "aria-controls": contentId, className: clsx(styles.tabsTrigger, isActive && styles.active, className), onClick: (e) => {
44
+ return (_jsx("button", Object.assign({ id: triggerId, role: "tab", type: "button", "aria-selected": isActive, "aria-controls": isActive ? contentId : undefined, className: clsx(styles.tabsTrigger, isActive && styles.active, className), onClick: (e) => {
45
45
  context.setActiveTab(value);
46
46
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
47
47
  }, tabIndex: isActive ? 0 : -1 }, props, { children: children })));
@@ -22,11 +22,10 @@
22
22
  font-weight: 700;
23
23
  text-transform: uppercase;
24
24
  letter-spacing: 0.05em;
25
- background-color: var(--primary);
26
- color: var(--primary-foreground);
27
- opacity: 0.6;
25
+ background-color: transparent;
26
+ color: var(--foreground);
28
27
  border: var(--border-width) solid var(--card-border);
29
- border-bottom: var(--border-width) solid var(--card-border);
28
+ border-bottom: none;
30
29
  border-radius: var(--radius) var(--radius) 0 0;
31
30
  cursor: pointer;
32
31
  position: relative;
@@ -35,17 +34,20 @@
35
34
  transform: translateY(4px);
36
35
  }
37
36
  .tabsTrigger:hover {
38
- opacity: 0.8;
37
+ background-color: color-mix(in srgb, var(--primary), transparent 90%);
39
38
  transform: translateY(2px);
40
39
  }
41
40
  .tabsTrigger.active {
42
- opacity: 1;
41
+ background-color: var(--primary);
42
+ color: var(--primary-foreground);
43
43
  z-index: var(--z-elevated);
44
44
  transform: translateY(0);
45
45
  }
46
46
  .tabsTrigger.active:hover {
47
- opacity: 1;
47
+ background-color: var(--primary);
48
+ color: var(--primary-foreground);
48
49
  transform: translateY(0);
50
+ filter: brightness(1.05);
49
51
  }
50
52
 
51
53
  .tabsBody {
@@ -1,3 +1,8 @@
1
- import React from 'react';
2
- export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
3
- export declare function Textarea({ className, ...props }: TextareaProps): import("react/jsx-runtime").JSX.Element;
1
+ import React from "react";
2
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ label?: string;
4
+ error?: string;
5
+ helperText?: string;
6
+ showCount?: boolean;
7
+ }
8
+ export declare function Textarea({ label, error, helperText, showCount, className, style, id, required, maxLength, value, defaultValue, onChange, ...props }: TextareaProps): import("react/jsx-runtime").JSX.Element;