@efiche/design 0.1.4 → 0.1.6

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/index.js CHANGED
@@ -50,11 +50,6 @@ var useTheme = () => {
50
50
  // src/components/Accordion/Accordion.tsx
51
51
  import { useState as useState2 } from "react";
52
52
  import { ChevronDown } from "lucide-react";
53
-
54
- // src/components/Accordion/Accordion.module.css
55
- var Accordion_default = {};
56
-
57
- // src/components/Accordion/Accordion.tsx
58
53
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
59
54
  var Accordion = ({ items, defaultValue, multiple = false }) => {
60
55
  const [open, setOpen] = useState2(() => {
@@ -62,6 +57,7 @@ var Accordion = ({ items, defaultValue, multiple = false }) => {
62
57
  if (Array.isArray(defaultValue)) return new Set(defaultValue);
63
58
  return /* @__PURE__ */ new Set([defaultValue]);
64
59
  });
60
+ const [hovered, setHovered] = useState2(null);
65
61
  const toggle = (value) => {
66
62
  setOpen((prev) => {
67
63
  const next = new Set(prev);
@@ -74,32 +70,76 @@ var Accordion = ({ items, defaultValue, multiple = false }) => {
74
70
  return next;
75
71
  });
76
72
  };
77
- return /* @__PURE__ */ jsx2("div", { className: Accordion_default.root, children: items.map((item) => {
73
+ return /* @__PURE__ */ jsx2("div", { style: {
74
+ border: "1px solid var(--ds-border, #e2e8f0)",
75
+ borderRadius: "0.5rem",
76
+ overflow: "hidden"
77
+ }, children: items.map((item, index) => {
78
78
  const isOpen = open.has(item.value);
79
- return /* @__PURE__ */ jsxs("div", { className: Accordion_default.item, children: [
80
- /* @__PURE__ */ jsxs(
81
- "button",
82
- {
83
- className: Accordion_default.trigger,
84
- onClick: () => toggle(item.value),
85
- "aria-expanded": isOpen,
86
- children: [
87
- /* @__PURE__ */ jsx2("span", { children: item.trigger }),
88
- /* @__PURE__ */ jsx2(
89
- ChevronDown,
90
- {
91
- size: 16,
92
- className: `${Accordion_default.chevron} ${isOpen ? Accordion_default["chevron-open"] : ""}`
93
- }
94
- )
95
- ]
96
- }
97
- ),
98
- /* @__PURE__ */ jsx2("div", { className: `${Accordion_default.panel} ${isOpen ? Accordion_default["panel-open"] : ""}`, children: /* @__PURE__ */ jsx2("div", { className: Accordion_default.content, children: item.content }) })
99
- ] }, item.value);
79
+ const isHovered = hovered === item.value;
80
+ const isLast = index === items.length - 1;
81
+ return /* @__PURE__ */ jsxs(
82
+ "div",
83
+ {
84
+ style: {
85
+ borderBottom: isLast ? "none" : "1px solid var(--ds-border, #e2e8f0)"
86
+ },
87
+ children: [
88
+ /* @__PURE__ */ jsxs(
89
+ "button",
90
+ {
91
+ style: {
92
+ display: "flex",
93
+ alignItems: "center",
94
+ justifyContent: "space-between",
95
+ width: "100%",
96
+ padding: "1rem",
97
+ fontSize: "0.875rem",
98
+ fontWeight: 500,
99
+ background: isHovered ? "var(--ds-muted, #f1f5f9)" : "transparent",
100
+ border: "none",
101
+ cursor: "pointer",
102
+ textAlign: "left",
103
+ color: "var(--ds-text-primary, #0f172a)",
104
+ transition: "background-color 0.15s"
105
+ },
106
+ onClick: () => toggle(item.value),
107
+ onMouseEnter: () => setHovered(item.value),
108
+ onMouseLeave: () => setHovered(null),
109
+ "aria-expanded": isOpen,
110
+ children: [
111
+ /* @__PURE__ */ jsx2("span", { children: item.trigger }),
112
+ /* @__PURE__ */ jsx2(
113
+ ChevronDown,
114
+ {
115
+ size: 16,
116
+ style: {
117
+ flexShrink: 0,
118
+ color: "var(--ds-text-secondary, #64748b)",
119
+ transition: "transform 0.2s ease",
120
+ transform: isOpen ? "rotate(180deg)" : "rotate(0deg)"
121
+ }
122
+ }
123
+ )
124
+ ]
125
+ }
126
+ ),
127
+ /* @__PURE__ */ jsx2("div", { style: {
128
+ maxHeight: isOpen ? "300px" : "0",
129
+ overflow: "hidden",
130
+ transition: "max-height 0.25s ease"
131
+ }, children: /* @__PURE__ */ jsx2("div", { style: {
132
+ padding: "0 1rem 1rem",
133
+ fontSize: "0.875rem",
134
+ color: "var(--ds-text-secondary, #64748b)"
135
+ }, children: item.content }) })
136
+ ]
137
+ },
138
+ item.value
139
+ );
100
140
  }) });
101
141
  };
102
- var Accordion_default2 = Accordion;
142
+ var Accordion_default = Accordion;
103
143
 
104
144
  // src/components/Alert/Alert.tsx
105
145
  import { Info, CheckCircle2, AlertTriangle, AlertCircle } from "lucide-react";
@@ -167,12 +207,39 @@ var Breadcrumb_default2 = Breadcrumb;
167
207
 
168
208
  // src/components/Button/Button.tsx
169
209
  import { LoaderCircle } from "lucide-react";
170
-
171
- // src/components/Button/Button.module.css
172
- var Button_default = {};
173
-
174
- // src/components/Button/Button.tsx
210
+ import { useEffect, useState as useState3 } from "react";
175
211
  import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
212
+ var variantStyles = {
213
+ solid: { backgroundColor: "var(--ds-primary, #3b82f6)", color: "#fff", borderColor: "transparent" },
214
+ outline: { backgroundColor: "transparent", color: "var(--ds-primary, #3b82f6)", borderColor: "var(--ds-primary, #3b82f6)" },
215
+ ghost: { backgroundColor: "var(--ds-muted, #f1f5f9)", color: "var(--ds-text-primary, #0f172a)", borderColor: "transparent" },
216
+ danger: { backgroundColor: "var(--ds-danger, #ef4444)", color: "#fff", borderColor: "transparent" },
217
+ warning: { backgroundColor: "var(--ds-warning, #f59e0b)", color: "#fff", borderColor: "transparent" },
218
+ info: { backgroundColor: "var(--ds-info, #3b82f6)", color: "#fff", borderColor: "transparent" },
219
+ success: { backgroundColor: "var(--ds-success, #22c55e)", color: "#fff", borderColor: "transparent" }
220
+ };
221
+ var variantHoverStyles = {
222
+ solid: { opacity: 0.88 },
223
+ outline: { backgroundColor: "var(--ds-muted, #f1f5f9)" },
224
+ ghost: { backgroundColor: "var(--ds-card, #ffffff)" },
225
+ danger: { opacity: 0.88 },
226
+ warning: { opacity: 0.88 },
227
+ info: { opacity: 0.88 },
228
+ success: { opacity: 0.88 }
229
+ };
230
+ var sizeStyles = {
231
+ sm: { padding: "0.25rem 0.625rem", fontSize: "0.8rem" },
232
+ md: { padding: "0.5rem 1rem", fontSize: "0.875rem" },
233
+ lg: { padding: "0.75rem 1.5rem", fontSize: "1rem" }
234
+ };
235
+ function injectSpinKeyframe() {
236
+ if (typeof document === "undefined") return;
237
+ if (document.getElementById("ds-spin-keyframe")) return;
238
+ const style = document.createElement("style");
239
+ style.id = "ds-spin-keyframe";
240
+ style.textContent = "@keyframes ds-spin { to { transform: rotate(360deg); } }";
241
+ document.head.appendChild(style);
242
+ }
176
243
  var Button = (_a) => {
177
244
  var _b = _a, {
178
245
  text,
@@ -191,7 +258,7 @@ var Button = (_a) => {
191
258
  small = false,
192
259
  large = false,
193
260
  size,
194
- className
261
+ style: styleProp
195
262
  } = _b, props = __objRest(_b, [
196
263
  "text",
197
264
  "children",
@@ -209,27 +276,45 @@ var Button = (_a) => {
209
276
  "small",
210
277
  "large",
211
278
  "size",
212
- "className"
279
+ "style"
213
280
  ]);
281
+ const [hovered, setHovered] = useState3(false);
282
+ useEffect(() => {
283
+ injectSpinKeyframe();
284
+ }, []);
214
285
  const resolvedVariant = variant != null ? variant : danger ? "danger" : warning ? "warning" : info ? "info" : success ? "success" : ghost ? "ghost" : outline ? "outline" : "solid";
215
286
  const resolvedSize = size != null ? size : small ? "sm" : large ? "lg" : "md";
287
+ const isDisabled = disabled || loading;
216
288
  const content = children != null ? children : text;
217
289
  const showIcon = icon && !loading;
218
- const classes = [
219
- Button_default.button,
220
- Button_default[resolvedVariant],
221
- Button_default[resolvedSize],
222
- loading ? Button_default.loading : "",
223
- className != null ? className : ""
224
- ].filter(Boolean).join(" ");
290
+ const computedStyle = __spreadValues(__spreadValues(__spreadValues(__spreadValues({
291
+ display: "inline-flex",
292
+ alignItems: "center",
293
+ gap: "0.5rem",
294
+ border: "1px solid transparent",
295
+ borderRadius: "0.375rem",
296
+ fontWeight: 500,
297
+ cursor: isDisabled ? "not-allowed" : "pointer",
298
+ transition: "opacity 0.15s, background-color 0.15s",
299
+ opacity: isDisabled ? 0.5 : 1,
300
+ pointerEvents: loading ? "none" : void 0
301
+ }, variantStyles[resolvedVariant]), sizeStyles[resolvedSize]), hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}), styleProp);
225
302
  return /* @__PURE__ */ jsxs4(
226
303
  "button",
227
304
  __spreadProps(__spreadValues({
228
- disabled: disabled || loading,
229
- className: classes
305
+ disabled: isDisabled,
306
+ style: computedStyle,
307
+ onMouseEnter: () => setHovered(true),
308
+ onMouseLeave: () => setHovered(false)
230
309
  }, props), {
231
310
  children: [
232
- loading ? /* @__PURE__ */ jsx7(LoaderCircle, { className: Button_default.spinner, "aria-hidden": true }) : null,
311
+ loading ? /* @__PURE__ */ jsx7(
312
+ LoaderCircle,
313
+ {
314
+ "aria-hidden": true,
315
+ style: { width: "1em", height: "1em", animation: "ds-spin 0.75s linear infinite" }
316
+ }
317
+ ) : null,
233
318
  showIcon && iconPosition === "left" ? icon : null,
234
319
  content,
235
320
  showIcon && iconPosition === "right" ? icon : null
@@ -237,7 +322,7 @@ var Button = (_a) => {
237
322
  })
238
323
  );
239
324
  };
240
- var Button_default2 = Button;
325
+ var Button_default = Button;
241
326
 
242
327
  // src/components/Card/Card.module.css
243
328
  var Card_default = {};
@@ -270,7 +355,7 @@ var CardFooter = (_a) => {
270
355
  };
271
356
 
272
357
  // src/components/Checkbox/Checkbox.tsx
273
- import { useState as useState3 } from "react";
358
+ import { useState as useState4 } from "react";
274
359
 
275
360
  // src/components/Checkbox/Checkbox.module.css
276
361
  var Checkbox_default = {};
@@ -285,7 +370,7 @@ var Checkbox = ({
285
370
  id,
286
371
  onChange
287
372
  }) => {
288
- const [internal, setInternal] = useState3(defaultChecked);
373
+ const [internal, setInternal] = useState4(defaultChecked);
289
374
  const isChecked = checked !== void 0 ? checked : internal;
290
375
  const handleChange = () => {
291
376
  if (disabled) return;
@@ -313,7 +398,7 @@ var Checkbox_default2 = Checkbox;
313
398
 
314
399
  // src/components/CopyButton/CopyButton.tsx
315
400
  import { Check, Copy } from "lucide-react";
316
- import { useState as useState4 } from "react";
401
+ import { useState as useState5 } from "react";
317
402
 
318
403
  // src/components/CopyButton/CopyButton.module.css
319
404
  var CopyButton_default = {};
@@ -321,7 +406,7 @@ var CopyButton_default = {};
321
406
  // src/components/CopyButton/CopyButton.tsx
322
407
  import { jsx as jsx10 } from "react/jsx-runtime";
323
408
  var CopyButton = ({ text }) => {
324
- const [copied, setCopied] = useState4(false);
409
+ const [copied, setCopied] = useState5(false);
325
410
  const handleCopy = () => {
326
411
  navigator.clipboard.writeText(text);
327
412
  setCopied(true);
@@ -341,7 +426,7 @@ var CopyButton_default2 = CopyButton;
341
426
 
342
427
  // src/components/FileUpload/FileUpload.tsx
343
428
  import { Upload } from "lucide-react";
344
- import { useRef, useState as useState5 } from "react";
429
+ import { useRef, useState as useState6 } from "react";
345
430
 
346
431
  // src/components/FileUpload/FileUpload.module.css
347
432
  var FileUpload_default = {};
@@ -349,8 +434,8 @@ var FileUpload_default = {};
349
434
  // src/components/FileUpload/FileUpload.tsx
350
435
  import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
351
436
  var FileUpload = ({ accept, multiple, disabled, onFileSelect }) => {
352
- const [isDragging, setIsDragging] = useState5(false);
353
- const [fileNames, setFileNames] = useState5([]);
437
+ const [isDragging, setIsDragging] = useState6(false);
438
+ const [fileNames, setFileNames] = useState6([]);
354
439
  const inputRef = useRef(null);
355
440
  const handleFiles = (list) => {
356
441
  setFileNames(Array.from(list).map((f) => f.name));
@@ -449,10 +534,10 @@ var Label_default2 = Label;
449
534
 
450
535
  // src/components/PasswordInput/PasswordInput.tsx
451
536
  import { Eye, EyeOff } from "lucide-react";
452
- import { useState as useState6 } from "react";
537
+ import { useState as useState7 } from "react";
453
538
  import { jsx as jsx14 } from "react/jsx-runtime";
454
539
  var PasswordInput = (props) => {
455
- const [visible, setVisible] = useState6(false);
540
+ const [visible, setVisible] = useState7(false);
456
541
  return /* @__PURE__ */ jsx14(
457
542
  Input_default2,
458
543
  __spreadProps(__spreadValues({}, props), {
@@ -494,7 +579,7 @@ var Progress = ({ value = 0 }) => {
494
579
  var Progress_default2 = Progress;
495
580
 
496
581
  // src/components/RadioGroup/RadioGroup.tsx
497
- import { useState as useState7 } from "react";
582
+ import { useState as useState8 } from "react";
498
583
 
499
584
  // src/components/RadioGroup/RadioGroup.module.css
500
585
  var RadioGroup_default = {};
@@ -509,7 +594,7 @@ var RadioGroup = ({
509
594
  disabled,
510
595
  onChange
511
596
  }) => {
512
- const [internal, setInternal] = useState7(defaultValue);
597
+ const [internal, setInternal] = useState8(defaultValue);
513
598
  const selected = value !== void 0 ? value : internal;
514
599
  const handleChange = (val) => {
515
600
  if (disabled) return;
@@ -544,7 +629,7 @@ var RadioGroup_default2 = RadioGroup;
544
629
 
545
630
  // src/components/Select/Select.tsx
546
631
  import { Check as Check2, ChevronDown as ChevronDown2 } from "lucide-react";
547
- import { useEffect, useRef as useRef2, useState as useState8 } from "react";
632
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState9 } from "react";
548
633
 
549
634
  // src/components/Select/Select.module.css
550
635
  var Select_default = {};
@@ -560,8 +645,8 @@ var Select = ({
560
645
  onChange
561
646
  }) => {
562
647
  var _a;
563
- const [internal, setInternal] = useState8(defaultValue);
564
- const [open, setOpen] = useState8(false);
648
+ const [internal, setInternal] = useState9(defaultValue);
649
+ const [open, setOpen] = useState9(false);
565
650
  const ref = useRef2(null);
566
651
  const selected = value !== void 0 ? value : internal;
567
652
  const selectedLabel = (_a = options.find((o) => o.value === selected)) == null ? void 0 : _a.label;
@@ -570,7 +655,7 @@ var Select = ({
570
655
  setOpen(false);
571
656
  onChange == null ? void 0 : onChange(val);
572
657
  };
573
- useEffect(() => {
658
+ useEffect2(() => {
574
659
  const handleOutside = (e) => {
575
660
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
576
661
  };
@@ -623,7 +708,7 @@ var Skeleton = ({ height = "1rem", width = "100%", circle = false }) => /* @__PU
623
708
  var Skeleton_default2 = Skeleton;
624
709
 
625
710
  // src/components/Slider/Slider.tsx
626
- import { useState as useState9 } from "react";
711
+ import { useState as useState10 } from "react";
627
712
 
628
713
  // src/components/Slider/Slider.module.css
629
714
  var Slider_default = {};
@@ -639,7 +724,7 @@ var Slider = ({
639
724
  disabled,
640
725
  onChange
641
726
  }) => {
642
- const [internal, setInternal] = useState9(defaultValue);
727
+ const [internal, setInternal] = useState10(defaultValue);
643
728
  const current = value !== void 0 ? value : internal;
644
729
  const fill = `${(current - min) / (max - min) * 100}%`;
645
730
  const handleChange = (e) => {
@@ -677,7 +762,7 @@ var Spinner = ({ size = "md" }) => /* @__PURE__ */ jsx20(Loader2, { size: sizePx
677
762
  var Spinner_default2 = Spinner;
678
763
 
679
764
  // src/components/Switch/Switch.tsx
680
- import { useState as useState10 } from "react";
765
+ import { useState as useState11 } from "react";
681
766
 
682
767
  // src/components/Switch/Switch.module.css
683
768
  var Switch_default = {};
@@ -692,7 +777,7 @@ var Switch = ({
692
777
  id,
693
778
  onChange
694
779
  }) => {
695
- const [internal, setInternal] = useState10(defaultChecked);
780
+ const [internal, setInternal] = useState11(defaultChecked);
696
781
  const isOn = checked !== void 0 ? checked : internal;
697
782
  const handleToggle = () => {
698
783
  if (disabled) return;
@@ -743,7 +828,7 @@ var TableCell = (_a) => {
743
828
  };
744
829
 
745
830
  // src/components/Tabs/Tabs.tsx
746
- import { useState as useState11 } from "react";
831
+ import { useState as useState12 } from "react";
747
832
 
748
833
  // src/components/Tabs/Tabs.module.css
749
834
  var Tabs_default = {};
@@ -752,7 +837,7 @@ var Tabs_default = {};
752
837
  import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
753
838
  var Tabs = ({ tabs, defaultValue }) => {
754
839
  var _a, _b;
755
- const [active, setActive] = useState11((_b = defaultValue != null ? defaultValue : (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : "");
840
+ const [active, setActive] = useState12((_b = defaultValue != null ? defaultValue : (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : "");
756
841
  const activeTab = tabs.find((t) => t.value === active);
757
842
  return /* @__PURE__ */ jsxs12("div", { className: Tabs_default.root, children: [
758
843
  /* @__PURE__ */ jsx23("div", { className: Tabs_default.list, role: "tablist", children: tabs.map((tab) => /* @__PURE__ */ jsxs12(
@@ -801,12 +886,12 @@ var Tooltip = ({ content, children, position = "top" }) => /* @__PURE__ */ jsxs1
801
886
  ] });
802
887
  var Tooltip_default2 = Tooltip;
803
888
  export {
804
- Accordion_default2 as Accordion,
889
+ Accordion_default as Accordion,
805
890
  Alert_default2 as Alert,
806
891
  Avatar_default2 as Avatar,
807
892
  Badge_default2 as Badge,
808
893
  Breadcrumb_default2 as Breadcrumb,
809
- Button_default2 as Button,
894
+ Button_default as Button,
810
895
  Card,
811
896
  CardContent,
812
897
  CardDescription,