@efiche/design 0.1.6 → 0.1.7

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.cjs CHANGED
@@ -290,14 +290,6 @@ var sizeStyles = {
290
290
  md: { padding: "0.5rem 1rem", fontSize: "0.875rem" },
291
291
  lg: { padding: "0.75rem 1.5rem", fontSize: "1rem" }
292
292
  };
293
- function injectSpinKeyframe() {
294
- if (typeof document === "undefined") return;
295
- if (document.getElementById("ds-spin-keyframe")) return;
296
- const style = document.createElement("style");
297
- style.id = "ds-spin-keyframe";
298
- style.textContent = "@keyframes ds-spin { to { transform: rotate(360deg); } }";
299
- document.head.appendChild(style);
300
- }
301
293
  var Button = (_a) => {
302
294
  var _b = _a, {
303
295
  text,
@@ -337,9 +329,6 @@ var Button = (_a) => {
337
329
  "style"
338
330
  ]);
339
331
  const [hovered, setHovered] = (0, import_react3.useState)(false);
340
- (0, import_react3.useEffect)(() => {
341
- injectSpinKeyframe();
342
- }, []);
343
332
  const resolvedVariant = variant != null ? variant : danger ? "danger" : warning ? "warning" : info ? "info" : success ? "success" : ghost ? "ghost" : outline ? "outline" : "solid";
344
333
  const resolvedSize = size != null ? size : small ? "sm" : large ? "lg" : "md";
345
334
  const isDisabled = disabled || loading;
@@ -357,28 +346,31 @@ var Button = (_a) => {
357
346
  opacity: isDisabled ? 0.5 : 1,
358
347
  pointerEvents: loading ? "none" : void 0
359
348
  }, variantStyles[resolvedVariant]), sizeStyles[resolvedSize]), hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}), styleProp);
360
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
361
- "button",
362
- __spreadProps(__spreadValues({
363
- disabled: isDisabled,
364
- style: computedStyle,
365
- onMouseEnter: () => setHovered(true),
366
- onMouseLeave: () => setHovered(false)
367
- }, props), {
368
- children: [
369
- loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
370
- import_lucide_react4.LoaderCircle,
371
- {
372
- "aria-hidden": true,
373
- style: { width: "1em", height: "1em", animation: "ds-spin 0.75s linear infinite" }
374
- }
375
- ) : null,
376
- showIcon && iconPosition === "left" ? icon : null,
377
- content,
378
- showIcon && iconPosition === "right" ? icon : null
379
- ]
380
- })
381
- );
349
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
350
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { href: "ds-spin", precedence: "low", children: `@keyframes ds-spin { to { transform: rotate(360deg); } }` }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
352
+ "button",
353
+ __spreadProps(__spreadValues({
354
+ disabled: isDisabled,
355
+ style: computedStyle,
356
+ onMouseEnter: () => setHovered(true),
357
+ onMouseLeave: () => setHovered(false)
358
+ }, props), {
359
+ children: [
360
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
361
+ import_lucide_react4.LoaderCircle,
362
+ {
363
+ "aria-hidden": true,
364
+ style: { width: "1em", height: "1em", animation: "ds-spin 0.75s linear infinite" }
365
+ }
366
+ ) : null,
367
+ showIcon && iconPosition === "left" ? icon : null,
368
+ content,
369
+ showIcon && iconPosition === "right" ? icon : null
370
+ ]
371
+ })
372
+ )
373
+ ] });
382
374
  };
383
375
  var Button_default = Button;
384
376
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/index.ts","../src/components/ThemeProvider.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Alert/Alert.tsx","../src/components/Alert/Alert.module.css","../src/components/Avatar/Avatar.module.css","../src/components/Avatar/Avatar.tsx","../src/components/Badge/Badge.module.css","../src/components/Badge/Badge.tsx","../src/components/Breadcrumb/Breadcrumb.tsx","../src/components/Breadcrumb/Breadcrumb.module.css","../src/components/Button/Button.tsx","../src/components/Card/Card.module.css","../src/components/Card/Card.tsx","../src/components/Checkbox/Checkbox.tsx","../src/components/Checkbox/Checkbox.module.css","../src/components/CopyButton/CopyButton.tsx","../src/components/CopyButton/CopyButton.module.css","../src/components/FileUpload/FileUpload.tsx","../src/components/FileUpload/FileUpload.module.css","../src/components/Input/Input.module.css","../src/components/Input/Input.tsx","../src/components/Label/Label.module.css","../src/components/Label/Label.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/components/Progress/Progress.module.css","../src/components/Progress/Progress.tsx","../src/components/RadioGroup/RadioGroup.tsx","../src/components/RadioGroup/RadioGroup.module.css","../src/components/Select/Select.tsx","../src/components/Select/Select.module.css","../src/components/Skeleton/Skeleton.module.css","../src/components/Skeleton/Skeleton.tsx","../src/components/Slider/Slider.tsx","../src/components/Slider/Slider.module.css","../src/components/Spinner/Spinner.tsx","../src/components/Spinner/Spinner.module.css","../src/components/Switch/Switch.tsx","../src/components/Switch/Switch.module.css","../src/components/Table/Table.module.css","../src/components/Table/Table.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tabs.module.css","../src/components/Textarea/Textarea.module.css","../src/components/Textarea/Textarea.tsx","../src/components/Tooltip/Tooltip.module.css","../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["// Theme\nexport { ThemeProvider, useTheme } from './ThemeProvider'\n\n// Components\nexport { default as Accordion } from './Accordion/Accordion'\nexport { default as Alert } from './Alert/Alert'\nexport { default as Avatar } from './Avatar/Avatar'\nexport { default as Badge } from './Badge/Badge'\nexport { default as Breadcrumb } from './Breadcrumb/Breadcrumb'\nexport { default as Button } from './Button/Button'\nexport { Card, CardContent, CardDescription,\n CardFooter, CardHeader, CardTitle } from './Card/Card'\nexport { default as Checkbox } from './Checkbox/Checkbox'\nexport { default as CopyButton } from './CopyButton/CopyButton'\nexport { default as FileUpload } from './FileUpload/FileUpload'\nexport { default as Input } from './Input/Input'\nexport { default as Label } from './Label/Label'\nexport { default as PasswordInput } from './PasswordInput/PasswordInput'\nexport { default as Progress } from './Progress/Progress'\nexport { default as RadioGroup } from './RadioGroup/RadioGroup'\nexport { default as Select } from './Select/Select'\nexport { default as Skeleton } from './Skeleton/Skeleton'\nexport { default as Slider } from './Slider/Slider'\nexport { default as Spinner } from './Spinner/Spinner'\nexport { default as Switch } from './Switch/Switch'\nexport { Table, TableBody, TableCell,\n TableHead, TableHeader, TableRow } from './Table/Table'\nexport { default as Tabs } from './Tabs/Tabs'\nexport { default as Textarea } from './Textarea/Textarea'\nexport { default as Tooltip } from './Tooltip/Tooltip'\n","'use client'\nimport React, { createContext, useContext, useState } from 'react'\nimport '../styles/globals.css'\n\ntype Theme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n toggle: () => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: {\n children: React.ReactNode\n defaultTheme?: Theme\n}) => {\n const [theme, setTheme] = useState<Theme>(defaultTheme)\n return (\n <ThemeContext.Provider value={{ theme, toggle: () => setTheme(t => t === 'light' ? 'dark' : 'light') }}>\n <div className={theme === 'dark' ? 'ds-theme-dark' : undefined}>\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n\nexport const useTheme = () => {\n const ctx = useContext(ThemeContext)\n if (!ctx) throw new Error('useTheme must be used inside <ThemeProvider>')\n return ctx\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\n\nexport interface AccordionItem {\n value: string\n trigger: string\n content: string\n}\n\ninterface AccordionProps {\n items: AccordionItem[]\n defaultValue?: string | string[]\n multiple?: boolean\n}\n\nconst Accordion: FC<AccordionProps> = ({ items, defaultValue, multiple = false }) => {\n const [open, setOpen] = useState<Set<string>>(() => {\n if (!defaultValue) return new Set()\n if (Array.isArray(defaultValue)) return new Set(defaultValue)\n return new Set([defaultValue])\n })\n const [hovered, setHovered] = useState<string | null>(null)\n\n const toggle = (value: string) => {\n setOpen(prev => {\n const next = new Set(prev)\n if (next.has(value)) {\n next.delete(value)\n } else {\n if (!multiple) next.clear()\n next.add(value)\n }\n return next\n })\n }\n\n return (\n <div style={{\n border: '1px solid var(--ds-border, #e2e8f0)',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n }}>\n {items.map((item, index) => {\n const isOpen = open.has(item.value)\n const isHovered = hovered === item.value\n const isLast = index === items.length - 1\n return (\n <div\n key={item.value}\n style={{\n borderBottom: isLast ? 'none' : '1px solid var(--ds-border, #e2e8f0)',\n }}\n >\n <button\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n background: isHovered ? 'var(--ds-muted, #f1f5f9)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'var(--ds-text-primary, #0f172a)',\n transition: 'background-color 0.15s',\n }}\n onClick={() => toggle(item.value)}\n onMouseEnter={() => setHovered(item.value)}\n onMouseLeave={() => setHovered(null)}\n aria-expanded={isOpen}\n >\n <span>{item.trigger}</span>\n <ChevronDown\n size={16}\n style={{\n flexShrink: 0,\n color: 'var(--ds-text-secondary, #64748b)',\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n <div style={{\n maxHeight: isOpen ? '300px' : '0',\n overflow: 'hidden',\n transition: 'max-height 0.25s ease',\n }}>\n <div style={{\n padding: '0 1rem 1rem',\n fontSize: '0.875rem',\n color: 'var(--ds-text-secondary, #64748b)',\n }}>\n {item.content}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\nexport default Accordion\n\n/*\n * Accordion\n *\n * Renders a list of collapsible sections; by default only one section can be open at a time.\n *\n * Props:\n * items (AccordionItem[], required) — array of sections, each with:\n * value (string) — unique identifier\n * trigger (string) — heading text shown on the clickable row\n * content (string) — body text revealed when the section is open\n * defaultValue (string | string[], optional) — value(s) of sections that start open\n * multiple (boolean, optional) — when true, more than one section can be open simultaneously; defaults to false\n *\n * Usage:\n * <Accordion\n * items={[\n * { value: 'q1', trigger: 'What is eFiche?', content: 'eFiche is a medical records platform.' },\n * { value: 'q2', trigger: 'How do I log in?', content: 'Use your credentials at the login page.' },\n * ]}\n * />\n *\n * // Multiple sections open, first one pre-opened:\n * <Accordion items={faqItems} multiple defaultValue=\"q1\" />\n */\n","import React, { FC, ReactNode } from 'react'\nimport { Info, CheckCircle2, AlertTriangle, AlertCircle } from 'lucide-react'\nimport styles from './Alert.module.css'\n\ntype AlertVariant = 'info' | 'success' | 'warning' | 'danger'\n\ninterface AlertProps {\n variant?: AlertVariant\n title: string\n description: string\n}\n\nconst icons: Record<AlertVariant, ReactNode> = {\n info: <Info size={16} />,\n success: <CheckCircle2 size={16} />,\n warning: <AlertTriangle size={16} />,\n danger: <AlertCircle size={16} />,\n}\n\nconst Alert: FC<AlertProps> = ({ variant = 'info', title, description }) => (\n <div className={`${styles.alert} ${styles[variant]}`} role=\"alert\">\n <span className={styles.icon}>{icons[variant]}</span>\n <div className={styles.content}>\n <p className={styles.title}>{title}</p>\n <p className={styles.description}>{description}</p>\n </div>\n </div>\n)\n\nexport default Alert\n\n/*\n * Alert\n *\n * Displays an inline alert banner with an icon, a bold title, and a description line.\n *\n * Props:\n * title (string, required) — short heading for the alert\n * description (string, required) — supporting detail shown below the title\n * variant (\"info\" | \"success\" | \"warning\" | \"danger\", optional) — color and icon style; defaults to \"info\"\n *\n * Usage:\n * <Alert title=\"Saved\" description=\"Your changes have been saved.\" variant=\"success\" />\n *\n * // Warning:\n * <Alert title=\"Low storage\" description=\"You are using 90% of your quota.\" variant=\"warning\" />\n *\n * // Danger:\n * <Alert title=\"Error\" description=\"Something went wrong. Please try again.\" variant=\"danger\" />\n */\n",".alert {\n display: flex;\n gap: 0.75rem;\n padding: 1rem;\n border-radius: 0.5rem;\n border-left: 4px solid;\n}\n\n.icon {\n flex-shrink: 0;\n margin-top: 0.125rem;\n}\n\n.content {\n flex: 1;\n}\n\n.title {\n font-weight: 600;\n font-size: 0.875rem;\n margin-bottom: 0.25rem;\n margin-top: 0;\n}\n\n.description {\n font-size: 0.875rem;\n margin: 0;\n}\n\n/* Info */\n.info {\n background-color: var(--ds-info-bg, #eff6ff);\n border-left-color: var(--ds-info, #3b82f6);\n}\n.info .icon { color: var(--ds-info, #3b82f6); }\n.info .title { color: var(--ds-info-title, #1e3a8a); }\n.info .description { color: var(--ds-info-desc, #1e40af); }\n\n/* Success */\n.success {\n background-color: var(--ds-success-bg, #f0fdf4);\n border-left-color: var(--ds-success, #22c55e);\n}\n.success .icon { color: var(--ds-success, #22c55e); }\n.success .title { color: var(--ds-success-title, #14532d); }\n.success .description { color: var(--ds-success-desc, #166534); }\n\n/* Warning */\n.warning {\n background-color: var(--ds-warning-bg, #fffbeb);\n border-left-color: var(--ds-warning, #f59e0b);\n}\n.warning .icon { color: var(--ds-warning, #f59e0b); }\n.warning .title { color: var(--ds-warning-title, #78350f); }\n.warning .description { color: var(--ds-warning-desc, #92400e); }\n\n/* Danger */\n.danger {\n background-color: var(--ds-danger-bg, #fef2f2);\n border-left-color: var(--ds-danger, #ef4444);\n}\n.danger .icon { color: var(--ds-danger, #ef4444); }\n.danger .title { color: var(--ds-danger-title, #7f1d1d); }\n.danger .description { color: var(--ds-danger-desc, #991b1b); }\n",".avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n font-weight: 600;\n flex-shrink: 0;\n user-select: none;\n}\n\n.sm { width: 2rem; height: 2rem; font-size: 0.625rem; }\n.md { width: 2.5rem; height: 2.5rem; font-size: 0.875rem; }\n.lg { width: 4rem; height: 4rem; font-size: 1.25rem; }\n","import React, { FC } from 'react'\nimport styles from './Avatar.module.css'\n\ntype AvatarSize = 'sm' | 'md' | 'lg'\n\ninterface AvatarProps {\n fallback: string\n size?: AvatarSize\n style?: React.CSSProperties\n className?: string\n}\n\nconst Avatar: FC<AvatarProps> = ({ fallback, size = 'md', style, className }) => (\n <div\n className={`${styles.avatar} ${styles[size]}${className ? ` ${className}` : ''}`}\n style={style}\n aria-label={fallback}\n >\n {fallback}\n </div>\n)\n\nexport default Avatar\n\n/*\n * Avatar\n *\n * Renders a circular (or rounded) container showing initials or a short text fallback.\n *\n * Props:\n * fallback (string, required) — text displayed inside the avatar, typically initials (e.g. \"AB\")\n * size (\"sm\" | \"md\" | \"lg\", optional) — controls the diameter of the circle; defaults to \"md\"\n * style (React.CSSProperties, optional) — inline styles for custom background color, etc.\n * className (string, optional) — extra CSS class names\n *\n * Usage:\n * <Avatar fallback=\"JD\" />\n *\n * // Large avatar with a custom background:\n * <Avatar fallback=\"MB\" size=\"lg\" style={{ background: '#6366f1' }} />\n */\n",".badge {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n border-radius: 9999px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n/* Sizes */\n.sm { padding: 0.125rem 0.5rem; font-size: 0.625rem; }\n.md { padding: 0.25rem 0.625rem; font-size: 0.75rem; }\n.lg { padding: 0.375rem 0.875rem; font-size: 0.875rem; }\n\n/* Variants */\n.default { background-color: var(--ds-primary, #3b82f6); color: #fff; }\n.secondary { background-color: var(--ds-muted, #f1f5f9); color: var(--ds-text-secondary, #64748b); }\n.outline { background-color: transparent; border: 1px solid var(--ds-border, #e2e8f0); color: var(--ds-text-primary, #0f172a); }\n.danger { background-color: var(--ds-danger, #ef4444); color: #fff; }\n.success { background-color: var(--ds-success, #22c55e); color: #fff; }\n.warning { background-color: var(--ds-warning, #f59e0b); color: #fff; }\n.info { background-color: var(--ds-info, #3b82f6); color: #fff; }\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Badge.module.css'\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'danger' | 'success' | 'warning' | 'info'\ntype BadgeSize = 'sm' | 'md' | 'lg'\n\ninterface BadgeProps {\n variant?: BadgeVariant\n size?: BadgeSize\n children: ReactNode\n style?: React.CSSProperties\n}\n\nconst Badge: FC<BadgeProps> = ({ variant = 'default', size = 'md', children, style }) => (\n <span className={`${styles.badge} ${styles[variant]} ${styles[size]}`} style={style}>\n {children}\n </span>\n)\n\nexport default Badge\n\n/*\n * Badge\n *\n * Renders a small inline label used to highlight status, categories, or counts.\n *\n * Props:\n * variant (\"default\" | \"secondary\" | \"outline\" | \"danger\" | \"success\" | \"warning\" | \"info\", optional) — color style; defaults to \"default\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — text and padding size; defaults to \"md\"\n * children (ReactNode, required) — the content shown inside the badge\n * style (React.CSSProperties, optional) — inline styles applied to the badge element\n *\n * Usage:\n * <Badge>New</Badge>\n *\n * // Status badges:\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"danger\" size=\"sm\">Overdue</Badge>\n */\n","import React, { FC } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport styles from './Breadcrumb.module.css'\n\nexport interface BreadcrumbItem {\n label: string\n href?: string\n}\n\ninterface BreadcrumbProps {\n items: BreadcrumbItem[]\n}\n\nconst Breadcrumb: FC<BreadcrumbProps> = ({ items }) => (\n <nav aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n return (\n <li key={item.label} className={styles.item}>\n {i > 0 && <ChevronRight size={14} className={styles.separator} aria-hidden />}\n {isLast || !item.href ? (\n <span className={`${styles.link} ${isLast ? styles.current : ''}`}>\n {item.label}\n </span>\n ) : (\n <a href={item.href} className={styles.link}>\n {item.label}\n </a>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n)\n\nexport default Breadcrumb\n\n/*\n * Breadcrumb\n *\n * Renders a navigation breadcrumb trail with chevron separators; the last item is plain text, earlier items are links when an href is provided.\n *\n * Props:\n * items (BreadcrumbItem[], required) — ordered array of crumbs, each with:\n * label (string) — display text\n * href (string, optional) — link target; if omitted the crumb renders as plain text\n *\n * Usage:\n * <Breadcrumb\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Patients', href: '/patients' },\n * { label: 'Visit summary' },\n * ]}\n * />\n */\n",".list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 0.875rem;\n}\n\n.item {\n display: flex;\n align-items: center;\n}\n\n.separator {\n color: var(--ds-text-secondary, #64748b);\n margin: 0 0.25rem;\n flex-shrink: 0;\n}\n\n.link {\n color: var(--ds-text-secondary, #64748b);\n text-decoration: none;\n transition: color 0.15s;\n}\n\n.link:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: underline;\n}\n\n.current {\n color: var(--ds-text-primary, #0f172a);\n font-weight: 500;\n cursor: default;\n}\n\n.current:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: none;\n}\n","'use client'\n\nimport { LoaderCircle } from \"lucide-react\";\nimport React, { FC, ButtonHTMLAttributes, ReactNode, useEffect, useState } from \"react\";\n\ntype ButtonVariant = \"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\";\ntype ButtonSize = \"sm\" | \"md\" | \"lg\";\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n text?: string;\n loading?: boolean;\n icon?: ReactNode;\n iconPosition?: \"left\" | \"right\";\n // variant shorthand booleans\n outline?: boolean;\n ghost?: boolean;\n danger?: boolean;\n warning?: boolean;\n info?: boolean;\n success?: boolean;\n variant?: ButtonVariant;\n // size shorthand booleans\n small?: boolean;\n large?: boolean;\n size?: ButtonSize;\n}\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { backgroundColor: 'var(--ds-primary, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n outline: { backgroundColor: 'transparent', color: 'var(--ds-primary, #3b82f6)', borderColor: 'var(--ds-primary, #3b82f6)' },\n ghost: { backgroundColor: 'var(--ds-muted, #f1f5f9)', color: 'var(--ds-text-primary, #0f172a)', borderColor: 'transparent' },\n danger: { backgroundColor: 'var(--ds-danger, #ef4444)', color: '#fff', borderColor: 'transparent' },\n warning: { backgroundColor: 'var(--ds-warning, #f59e0b)', color: '#fff', borderColor: 'transparent' },\n info: { backgroundColor: 'var(--ds-info, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n success: { backgroundColor: 'var(--ds-success, #22c55e)', color: '#fff', borderColor: 'transparent' },\n}\n\nconst variantHoverStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { opacity: 0.88 },\n outline: { backgroundColor: 'var(--ds-muted, #f1f5f9)' },\n ghost: { backgroundColor: 'var(--ds-card, #ffffff)' },\n danger: { opacity: 0.88 },\n warning: { opacity: 0.88 },\n info: { opacity: 0.88 },\n success: { opacity: 0.88 },\n}\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: { padding: '0.25rem 0.625rem', fontSize: '0.8rem' },\n md: { padding: '0.5rem 1rem', fontSize: '0.875rem' },\n lg: { padding: '0.75rem 1.5rem', fontSize: '1rem' },\n}\n\nfunction injectSpinKeyframe() {\n if (typeof document === 'undefined') return\n if (document.getElementById('ds-spin-keyframe')) return\n const style = document.createElement('style')\n style.id = 'ds-spin-keyframe'\n style.textContent = '@keyframes ds-spin { to { transform: rotate(360deg); } }'\n document.head.appendChild(style)\n}\n\nconst Button: FC<ButtonProps> = ({\n text,\n children,\n loading = false,\n disabled = false,\n icon,\n iconPosition = \"left\",\n outline = false,\n ghost = false,\n danger = false,\n warning = false,\n info = false,\n success = false,\n variant,\n small = false,\n large = false,\n size,\n style: styleProp,\n ...props\n}) => {\n const [hovered, setHovered] = useState(false)\n\n useEffect(() => { injectSpinKeyframe() }, [])\n\n const resolvedVariant: ButtonVariant =\n variant ??\n (danger ? \"danger\" :\n warning ? \"warning\" :\n info ? \"info\" :\n success ? \"success\" :\n ghost ? \"ghost\" :\n outline ? \"outline\" :\n \"solid\")\n\n const resolvedSize: ButtonSize = size ?? (small ? \"sm\" : large ? \"lg\" : \"md\")\n const isDisabled = disabled || loading\n const content = children ?? text\n const showIcon = icon && !loading\n\n const computedStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n border: '1px solid transparent',\n borderRadius: '0.375rem',\n fontWeight: 500,\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: 'opacity 0.15s, background-color 0.15s',\n opacity: isDisabled ? 0.5 : 1,\n pointerEvents: loading ? 'none' : undefined,\n ...variantStyles[resolvedVariant],\n ...sizeStyles[resolvedSize],\n ...(hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}),\n ...styleProp,\n }\n\n return (\n <button\n disabled={isDisabled}\n style={computedStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n {...props}\n >\n {loading\n ? <LoaderCircle\n aria-hidden\n style={{ width: '1em', height: '1em', animation: 'ds-spin 0.75s linear infinite' }}\n />\n : null}\n {showIcon && iconPosition === \"left\" ? icon : null}\n {content}\n {showIcon && iconPosition === \"right\" ? icon : null}\n </button>\n )\n}\n\nexport default Button\n\n/*\n * Button\n *\n * Renders a styled button with support for variants, sizes, icons, and a loading state.\n *\n * Props:\n * text (string, optional) — button label; can use children instead\n * loading (boolean, optional) — shows a spinner and disables the button while true\n * disabled (boolean, optional) — disables the button\n * icon (ReactNode, optional) — icon to display alongside the label\n * iconPosition (\"left\" | \"right\", optional) — which side the icon appears on; defaults to \"left\"\n * variant (\"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\", optional) — visual style; defaults to \"solid\"\n * outline (boolean, optional) — shorthand for variant=\"outline\"\n * ghost (boolean, optional) — shorthand for variant=\"ghost\"\n * danger (boolean, optional) — shorthand for variant=\"danger\"\n * warning (boolean, optional) — shorthand for variant=\"warning\"\n * info (boolean, optional) — shorthand for variant=\"info\"\n * success (boolean, optional) — shorthand for variant=\"success\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — button size; defaults to \"md\"\n * small (boolean, optional) — shorthand for size=\"sm\"\n * large (boolean, optional) — shorthand for size=\"lg\"\n * ...rest — any valid HTML button attribute (onClick, type, etc.)\n *\n * Usage:\n * <Button text=\"Save\" onClick={handleSave} />\n *\n * // Danger variant with loading state:\n * <Button danger loading={isDeleting} text=\"Delete\" />\n *\n * // Icon on the right, large size:\n * <Button large icon={<ArrowRight />} iconPosition=\"right\">Continue</Button>\n */\n",".card {\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n background-color: var(--ds-card, #ffffff);\n}\n\n.header {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 1.5rem 1.5rem 0;\n}\n\n.title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ds-text-primary, #0f172a);\n margin: 0;\n line-height: 1.4;\n}\n\n.description {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n margin: 0;\n}\n\n.content {\n padding: 1.5rem;\n}\n\n.footer {\n display: flex;\n align-items: center;\n padding: 0 1.5rem 1.5rem;\n}\n","import React, { FC, HTMLAttributes } from 'react'\nimport styles from './Card.module.css'\n\nexport const Card: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.card}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardHeader: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.header}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({ className, ...props }) => (\n <h3 className={`${styles.title}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardDescription: FC<HTMLAttributes<HTMLParagraphElement>> = ({ className, ...props }) => (\n <p className={`${styles.description}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.content}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardFooter: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.footer}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Card / CardHeader / CardTitle / CardDescription / CardContent / CardFooter\n *\n * A set of composable container components for building card-style layouts.\n *\n * Card — outer wrapper with a bordered, rounded container\n * CardHeader — top section, typically holds CardTitle and CardDescription\n * CardTitle — heading rendered as an <h3>\n * CardDescription — muted paragraph below the title\n * CardContent — main body area of the card\n * CardFooter — bottom section, typically holds actions\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML div/h3/p attribute\n *\n * Usage:\n * <Card>\n * <CardHeader>\n * <CardTitle>Patient Summary</CardTitle>\n * <CardDescription>Last visit on 12 May 2026</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Diagnosis: Hypertension</p>\n * </CardContent>\n * <CardFooter>\n * <Button text=\"View full record\" />\n * </CardFooter>\n * </Card>\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Checkbox.module.css'\n\ninterface CheckboxProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Checkbox: FC<CheckboxProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isChecked = checked !== undefined ? checked : internal\n\n const handleChange = () => {\n if (disabled) return\n const next = !isChecked\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isChecked}\n disabled={disabled}\n onChange={handleChange}\n className={styles.input}\n />\n <span className={`${styles.box} ${isChecked ? styles.checked : ''}`}>\n {isChecked && (\n <svg viewBox=\"0 0 12 10\" fill=\"none\" className={styles.checkmark}>\n <path d=\"M1 5l3.5 3.5L11 1\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Checkbox\n\n/*\n * Checkbox\n *\n * Renders a styled checkbox that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the checkbox\n * checked (boolean, optional) — controlled checked state\n * defaultChecked (boolean, optional) — initial checked state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input, useful for pairing with a Label\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each change\n *\n * Usage:\n * <Checkbox label=\"Accept terms\" onChange={val => setAccepted(val)} />\n *\n * // Controlled:\n * <Checkbox checked={isChecked} onChange={setIsChecked} label=\"Remember me\" />\n *\n * // Disabled with a default:\n * <Checkbox label=\"Auto-renew\" defaultChecked disabled />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.box {\n width: 1.125rem;\n height: 1.125rem;\n border: 2px solid var(--ds-border, #e2e8f0);\n border-radius: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: background-color 0.15s, border-color 0.15s;\n background-color: var(--ds-card, #fff);\n}\n\n.checked {\n background-color: var(--ds-primary, #3b82f6);\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.checkmark {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, Copy } from 'lucide-react'\nimport React, { FC, useState } from 'react'\nimport styles from './CopyButton.module.css'\n\ninterface CopyButtonProps {\n text: string\n}\n\nconst CopyButton: FC<CopyButtonProps> = ({ text }) => {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = () => {\n navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n className={styles.copyButton}\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : `Copy ${text}`}\n >\n {copied ? <Check className={styles.icon} /> : <Copy className={styles.icon} />}\n </button>\n )\n}\n\nexport default CopyButton\n\n/*\n * CopyButton\n *\n * Renders an icon button that copies a string to the clipboard; shows a checkmark for 2 seconds after copying.\n *\n * Props:\n * text (string, required) — the string that gets copied to the clipboard when clicked\n *\n * Usage:\n * <CopyButton text=\"npm install react lucide-react\" />\n *\n * // Next to a code snippet:\n * <div className=\"code-block\">\n * <code>{snippet}</code>\n * <CopyButton text={snippet} />\n * </div>\n */\n\n",".copyButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n border: none;\n border-radius: 0.25rem;\n background-color: transparent;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.copyButton:hover {\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.icon {\n width: 1rem;\n height: 1rem;\n}\n","'use client'\n\nimport { Upload } from 'lucide-react'\nimport React, { FC, useRef, useState } from 'react'\nimport styles from './FileUpload.module.css'\n\ninterface FileUploadProps {\n accept?: string\n multiple?: boolean\n disabled?: boolean\n onFileSelect?: (files: FileList) => void\n}\n\nconst FileUpload: FC<FileUploadProps> = ({ accept, multiple, disabled, onFileSelect }) => {\n const [isDragging, setIsDragging] = useState(false)\n const [fileNames, setFileNames] = useState<string[]>([])\n const inputRef = useRef<HTMLInputElement>(null)\n\n const handleFiles = (list: FileList) => {\n setFileNames(Array.from(list).map(f => f.name))\n onFileSelect?.(list)\n }\n\n return (\n <div\n className={`${styles.zone} ${isDragging ? styles.dragging : ''} ${disabled ? styles.disabled : ''}`}\n onClick={() => !disabled && inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault()\n setIsDragging(false)\n if (!disabled && e.dataTransfer.files.length) handleFiles(e.dataTransfer.files)\n }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className={styles.input}\n onChange={(e) => e.target.files && handleFiles(e.target.files)}\n />\n <Upload size={32} className={styles.icon} />\n {fileNames.length > 0\n ? <p className={styles.fileName}>{fileNames.join(', ')}</p>\n : <p className={styles.hint}><strong>Click to upload</strong> or drag and drop</p>\n }\n </div>\n )\n}\n\nexport default FileUpload\n\n/*\n * FileUpload\n *\n * Renders a click-to-browse and drag-and-drop file upload zone; displays selected file names after a pick.\n *\n * Props:\n * accept (string, optional) — file type filter passed to the hidden input (e.g. \"image/*\", \".pdf\")\n * multiple (boolean, optional) — allows selecting more than one file at a time\n * disabled (boolean, optional) — prevents clicking and dropping\n * onFileSelect ((files: FileList) => void, optional) — called with the FileList whenever files are chosen\n *\n * Usage:\n * <FileUpload onFileSelect={files => uploadFiles(files)} />\n *\n * // Images only, multiple files:\n * <FileUpload accept=\"image/*\" multiple onFileSelect={handleImages} />\n */\n",".zone {\n border: 2px dashed var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n background-color: var(--ds-muted, #f1f5f9);\n transition: border-color 0.15s, background-color 0.15s;\n text-align: center;\n}\n\n.zone:hover,\n.dragging {\n border-color: var(--ds-primary, #3b82f6);\n background-color: var(--ds-primary-50, #eff6ff);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.icon {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.hint {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n\n.fileName {\n font-size: 0.875rem;\n color: var(--ds-primary, #3b82f6);\n font-weight: 500;\n}\n",".wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.input::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.input:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n/* --- Error --- */\n.error .input {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error .input:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n\n/* --- Success --- */\n.success .input {\n border-color: var(--ds-success, #22c55e);\n}\n\n.success .input:focus {\n border-color: var(--ds-success, #22c55e);\n box-shadow: 0 0 0 3px rgb(34 197 94 / 0.15);\n}\n\n/* --- Icons --- */\n.hasLeft .input { padding-left: 2.25rem; }\n.hasRight .input { padding-right: 2.25rem; }\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n color: var(--ds-text-secondary, #64748b);\n pointer-events: none;\n}\n\n.leftIcon { left: 0.625rem; }\n.rightIcon { right: 0.625rem; }\n","import React, { FC, InputHTMLAttributes, ReactNode } from 'react'\nimport styles from './Input.module.css'\n\ninterface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n error?: boolean\n success?: boolean\n leftIcon?: ReactNode\n rightIcon?: ReactNode\n}\n\nconst Input: FC<InputProps> = ({\n error,\n success,\n leftIcon,\n rightIcon,\n className,\n ...props\n}) => {\n const wrapperClasses = [\n styles.wrapper,\n error ? styles.error : '',\n success ? styles.success : '',\n leftIcon ? styles.hasLeft : '',\n rightIcon ? styles.hasRight : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return (\n <div className={wrapperClasses}>\n {leftIcon && <span className={styles.leftIcon}>{leftIcon}</span>}\n <input className={styles.input} {...props} />\n {rightIcon && <span className={styles.rightIcon}>{rightIcon}</span>}\n </div>\n )\n}\n\nexport default Input\n\n/*\n * Input\n *\n * Renders a text input with optional left/right icons and error or success border states.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * success (boolean, optional) — applies a success border style\n * leftIcon (ReactNode, optional) — icon displayed inside the left side of the input\n * rightIcon (ReactNode, optional) — icon displayed inside the right side of the input\n * className (string, optional) — extra CSS class names applied to the wrapper div\n * ...rest — any valid HTML input attribute (placeholder, value, onChange, disabled, etc.)\n *\n * Usage:\n * <Input placeholder=\"Search...\" onChange={handleChange} />\n *\n * // With a left icon and error state:\n * <Input leftIcon={<SearchIcon />} error placeholder=\"Not found\" />\n *\n * // Controlled with a success state:\n * <Input value={email} onChange={e => setEmail(e.target.value)} success />\n */\n",".label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--ds-text-primary, #0f172a);\n margin-bottom: 0.375rem;\n}\n\n.required {\n color: var(--ds-danger, #ef4444);\n margin-left: 0.25rem;\n}\n","import React, { FC, LabelHTMLAttributes } from 'react'\nimport styles from './Label.module.css'\n\ninterface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n required?: boolean\n}\n\nconst Label: FC<LabelProps> = ({ children, required, className, ...props }) => {\n return (\n <label className={`${styles.label} ${className ?? ''}`} {...props}>\n {children}\n {required && <span className={styles.required}>*</span>}\n </label>\n )\n}\n\nexport default Label\n\n/*\n * Label\n *\n * Renders a styled form label, optionally appending a red asterisk when the field is required.\n *\n * Props:\n * required (boolean, optional) — appends a \"*\" marker after the label text\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML label attribute (htmlFor, etc.)\n *\n * Usage:\n * <Label htmlFor=\"email\">Email</Label>\n *\n * // Required field:\n * <Label htmlFor=\"name\" required>Full name</Label>\n */\n","'use client'\n\nimport { Eye, EyeOff } from 'lucide-react'\nimport React, { FC, InputHTMLAttributes, useState } from 'react'\nimport Input from '../Input/Input'\n\ntype PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>\n\nconst PasswordInput: FC<PasswordInputProps> = (props) => {\n const [visible, setVisible] = useState(false)\n\n return (\n <Input\n {...props}\n type={visible ? 'text' : 'password'}\n rightIcon={\n <button\n type=\"button\"\n onClick={() => setVisible(v => !v)}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', pointerEvents: 'all' }}\n tabIndex={-1}\n >\n {visible ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n }\n />\n )\n}\n\nexport default PasswordInput\n\n/*\n * PasswordInput\n *\n * Renders a password input with an eye/eye-off toggle button that shows or hides the typed text.\n *\n * Props:\n * ...rest — any valid HTML input attribute except \"type\" (e.g. placeholder, value, onChange, disabled)\n * also accepts Input's error and success props for border states\n *\n * Usage:\n * <PasswordInput placeholder=\"Enter password\" onChange={e => setPassword(e.target.value)} />\n *\n * // With error state:\n * <PasswordInput value={password} onChange={handleChange} error />\n */\n",".track {\n width: 100%;\n height: 0.5rem;\n background-color: var(--ds-border, #e2e8f0);\n border-radius: 9999px;\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n background-color: var(--ds-primary, #3b82f6);\n border-radius: 9999px;\n transition: width 0.3s ease;\n}\n","import React, { FC } from 'react'\nimport styles from './Progress.module.css'\n\ninterface ProgressProps {\n value?: number\n}\n\nconst Progress: FC<ProgressProps> = ({ value = 0 }) => {\n const pct = Math.min(100, Math.max(0, value))\n return (\n <div\n className={styles.track}\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n )\n}\n\nexport default Progress\n\n/*\n * Progress\n *\n * Displays a horizontal progress bar that fills from left to right based on a 0–100 value.\n *\n * Props:\n * value (number, optional) — current progress percentage (0–100); clamped to that range; defaults to 0\n *\n * Usage:\n * <Progress value={60} />\n *\n * // Dynamic upload progress:\n * <Progress value={uploadPercent} />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './RadioGroup.module.css'\n\ninterface RadioOption {\n value: string\n label: string\n}\n\ninterface RadioGroupProps {\n options: RadioOption[]\n name: string\n value?: string\n defaultValue?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst RadioGroup: FC<RadioGroupProps> = ({\n options,\n name,\n value,\n defaultValue = '',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const selected = value !== undefined ? value : internal\n\n const handleChange = (val: string) => {\n if (disabled) return\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={styles.group}>\n {options.map((option) => (\n <label\n key={option.value}\n className={`${styles.item} ${disabled ? styles.disabled : ''}`}\n >\n <input\n type=\"radio\"\n name={name}\n value={option.value}\n checked={selected === option.value}\n disabled={disabled}\n onChange={() => handleChange(option.value)}\n className={styles.input}\n />\n <span className={`${styles.dot} ${selected === option.value ? styles.checked : ''}`}>\n {selected === option.value && <span className={styles.inner} />}\n </span>\n <span className={styles.label}>{option.label}</span>\n </label>\n ))}\n </div>\n )\n}\n\nexport default RadioGroup\n\n/*\n * RadioGroup\n *\n * Renders a group of radio buttons from an array of options, supporting both controlled and uncontrolled use.\n *\n * Props:\n * options (RadioOption[], required) — array of { value: string, label: string } items to render\n * name (string, required) — shared name attribute for the radio inputs (required for HTML form grouping)\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * disabled (boolean, optional) — disables all options\n * onChange ((value: string) => void, optional) — called with the selected option's value on change\n *\n * Usage:\n * <RadioGroup\n * name=\"size\"\n * options={[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]}\n * onChange={val => setSize(val)}\n * />\n *\n * // Controlled:\n * <RadioGroup name=\"plan\" options={planOptions} value={plan} onChange={setPlan} />\n */\n",".group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.item {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.dot {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n border: 2px solid var(--ds-border, #e2e8f0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background-color: var(--ds-card, #fff);\n transition: border-color 0.15s;\n}\n\n.checked {\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.inner {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, ChevronDown } from 'lucide-react'\nimport React, { FC, useEffect, useRef, useState } from 'react'\nimport styles from './Select.module.css'\n\ninterface SelectOption {\n value: string\n label: string\n}\n\ninterface SelectProps {\n options: SelectOption[]\n value?: string\n defaultValue?: string\n placeholder?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst Select: FC<SelectProps> = ({\n options,\n value,\n defaultValue = '',\n placeholder = 'Choose an option',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n\n const selected = value !== undefined ? value : internal\n const selectedLabel = options.find(o => o.value === selected)?.label\n\n const handleSelect = (val: string) => {\n setInternal(val)\n setOpen(false)\n onChange?.(val)\n }\n\n useEffect(() => {\n const handleOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handleOutside)\n return () => document.removeEventListener('mousedown', handleOutside)\n }, [])\n\n return (\n <div ref={ref} className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <button\n type=\"button\"\n className={`${styles.trigger} ${open ? styles.open : ''}`}\n onClick={() => !disabled && setOpen(o => !o)}\n disabled={disabled}\n >\n <span className={selectedLabel ? styles.value : styles.placeholder}>\n {selectedLabel ?? placeholder}\n </span>\n <ChevronDown size={16} className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`} />\n </button>\n {open && (\n <div className={styles.dropdown}>\n {options.map((option) => (\n <div\n key={option.value}\n className={`${styles.option} ${selected === option.value ? styles.selected : ''}`}\n onClick={() => handleSelect(option.value)}\n >\n {selected === option.value\n ? <Check size={14} className={styles.checkIcon} />\n : <span className={styles.checkSpacer} />\n }\n {option.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default Select\n\n/*\n * Select\n *\n * Renders a custom dropdown that lets the user pick one option from a list, supporting controlled and uncontrolled use.\n *\n * Props:\n * options (SelectOption[], required) — array of { value: string, label: string } items to display\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * placeholder (string, optional) — text shown when nothing is selected; defaults to \"Choose an option\"\n * disabled (boolean, optional) — prevents opening the dropdown\n * onChange ((value: string) => void, optional) — called with the selected value when the user picks an option\n *\n * Usage:\n * <Select\n * options={[{ value: 'fr', label: 'French' }, { value: 'en', label: 'English' }]}\n * onChange={val => setLanguage(val)}\n * />\n *\n * // Controlled with placeholder:\n * <Select options={countryOptions} value={country} placeholder=\"Pick a country\" onChange={setCountry} />\n */\n",".wrapper {\n position: relative;\n width: 100%;\n}\n\n.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.trigger {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n transition: border-color 0.15s, box-shadow 0.15s;\n text-align: left;\n font-family: inherit;\n}\n\n.trigger:focus {\n outline: none;\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.open {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.placeholder { color: var(--ds-text-secondary, #64748b); }\n.value { color: var(--ds-text-primary, #0f172a); }\n\n.chevron {\n flex-shrink: 0;\n color: var(--ds-text-secondary, #64748b);\n transition: transform 0.15s;\n}\n\n.chevronOpen {\n transform: rotate(180deg);\n}\n\n.dropdown {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n right: 0;\n z-index: 50;\n background-color: var(--ds-card, #fff);\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);\n overflow: hidden;\n}\n\n.option {\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--ds-text-primary, #0f172a);\n transition: background-color 0.1s;\n}\n\n.option:hover { background-color: var(--ds-muted, #f1f5f9); }\n.selected { background-color: var(--ds-muted, #f1f5f9); font-weight: 500; }\n\n.checkIcon { color: var(--ds-primary, #3b82f6); flex-shrink: 0; }\n.checkSpacer { width: 14px; flex-shrink: 0; }\n",".skeleton {\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.375rem;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.circle {\n border-radius: 9999px;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n","import React, { FC } from 'react'\nimport styles from './Skeleton.module.css'\n\ninterface SkeletonProps {\n height?: string\n width?: string\n circle?: boolean\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ height = '1rem', width = '100%', circle = false }) => (\n <div\n className={`${styles.skeleton} ${circle ? styles.circle : ''}`}\n style={{ height, width }}\n aria-hidden=\"true\"\n />\n)\n\nexport default Skeleton\n\n/*\n * Skeleton\n *\n * Renders an animated placeholder block used to indicate loading content before data arrives.\n *\n * Props:\n * height (string, optional) — CSS height of the block; defaults to \"1rem\"\n * width (string, optional) — CSS width of the block; defaults to \"100%\"\n * circle (boolean, optional) — makes the block fully round (equal height and width) for avatar placeholders\n *\n * Usage:\n * <Skeleton width=\"200px\" height=\"1rem\" />\n *\n * // Avatar placeholder:\n * <Skeleton circle width=\"40px\" height=\"40px\" />\n *\n * // Full-width paragraph lines:\n * <Skeleton height=\"1rem\" />\n * <Skeleton height=\"1rem\" width=\"80%\" />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Slider.module.css'\n\ninterface SliderProps {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n onChange?: (value: number) => void\n}\n\nconst Slider: FC<SliderProps> = ({\n value,\n defaultValue = 50,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const current = value !== undefined ? value : internal\n const fill = `${((current - min) / (max - min)) * 100}%`\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = Number(e.target.value)\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={current}\n disabled={disabled}\n onChange={handleChange}\n className={styles.range}\n style={{ '--fill': fill } as React.CSSProperties}\n />\n </div>\n )\n}\n\nexport default Slider\n\n/*\n * Slider\n *\n * Renders a range slider with a filled track that reflects the current value, supporting controlled and uncontrolled use.\n *\n * Props:\n * value (number, optional) — controlled current value\n * defaultValue (number, optional) — initial value for uncontrolled use; defaults to 50\n * min (number, optional) — minimum value; defaults to 0\n * max (number, optional) — maximum value; defaults to 100\n * step (number, optional) — increment between values; defaults to 1\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * onChange ((value: number) => void, optional) — called with the new numeric value on each change\n *\n * Usage:\n * <Slider onChange={val => setVolume(val)} />\n *\n * // Controlled with custom range and step:\n * <Slider value={opacity} min={0} max={1} step={0.01} onChange={setOpacity} />\n */\n",".wrapper {\n width: 100%;\n padding: 0.25rem 0;\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.range {\n width: 100%;\n height: 0.375rem;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 9999px;\n outline: none;\n cursor: pointer;\n background: linear-gradient(\n to right,\n var(--ds-primary, #3b82f6) 0%,\n var(--ds-primary, #3b82f6) var(--fill, 50%),\n var(--ds-border, #e2e8f0) var(--fill, 50%),\n var(--ds-border, #e2e8f0) 100%\n );\n}\n\n.range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n transition: transform 0.1s;\n}\n\n.range::-webkit-slider-thumb:hover {\n transform: scale(1.2);\n}\n\n.range::-moz-range-thumb {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n}\n\n.disabled .range {\n cursor: not-allowed;\n}\n","import React, { FC } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport styles from './Spinner.module.css'\n\ntype SpinnerSize = 'sm' | 'md' | 'lg'\n\ninterface SpinnerProps {\n size?: SpinnerSize\n}\n\nconst sizePx: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\nconst Spinner: FC<SpinnerProps> = ({ size = 'md' }) => (\n <Loader2 size={sizePx[size]} className={styles.spinner} aria-label=\"Loading\" />\n)\n\nexport default Spinner\n\n/*\n * Spinner\n *\n * Displays an animated loading indicator at one of three sizes.\n *\n * Props:\n * size (\"sm\" | \"md\" | \"lg\", optional) — icon size: sm = 16px, md = 24px, lg = 32px; defaults to \"md\"\n *\n * Usage:\n * <Spinner />\n *\n * // Large spinner while page loads:\n * {isLoading && <Spinner size=\"lg\" />}\n */\n",".spinner {\n color: var(--ds-primary, #3b82f6);\n animation: spin 0.75s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Switch.module.css'\n\ninterface SwitchProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Switch: FC<SwitchProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isOn = checked !== undefined ? checked : internal\n\n const handleToggle = () => {\n if (disabled) return\n const next = !isOn\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isOn}\n disabled={disabled}\n onChange={handleToggle}\n className={styles.input}\n />\n <span className={`${styles.track} ${isOn ? styles.on : ''}`}>\n <span className={`${styles.thumb} ${isOn ? styles.thumbOn : ''}`} />\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Switch\n\n/*\n * Switch\n *\n * Renders a toggle switch that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the switch\n * checked (boolean, optional) — controlled on/off state\n * defaultChecked (boolean, optional) — initial state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each toggle\n *\n * Usage:\n * <Switch label=\"Enable notifications\" onChange={val => setEnabled(val)} />\n *\n * // Controlled:\n * <Switch checked={darkMode} onChange={setDarkMode} label=\"Dark mode\" />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.track {\n width: 2.75rem;\n height: 1.5rem;\n border-radius: 9999px;\n background-color: var(--ds-border, #e2e8f0);\n position: relative;\n transition: background-color 0.2s;\n flex-shrink: 0;\n}\n\n.on {\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.thumb {\n position: absolute;\n top: 0.175rem;\n left: 0.175rem;\n width: 1.15rem;\n height: 1.15rem;\n border-radius: 9999px;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.15);\n transition: transform 0.2s;\n}\n\n.thumbOn {\n transform: translateX(1.25rem);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n",".wrapper {\n width: 100%;\n overflow-x: auto;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n}\n\n.th {\n padding: 0.75rem 1rem;\n text-align: left;\n font-weight: 500;\n color: var(--ds-text-secondary, #64748b);\n background-color: var(--ds-muted, #f1f5f9);\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n white-space: nowrap;\n}\n\n.td {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.row:last-child .td {\n border-bottom: none;\n}\n\n.row:hover .td {\n background-color: var(--ds-muted, #f1f5f9);\n}\n\nthead .row:hover .th {\n background-color: var(--ds-muted, #f1f5f9);\n}\n","import React, { FC, HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react'\nimport styles from './Table.module.css'\n\nexport const Table: FC<HTMLAttributes<HTMLTableElement>> = ({ className, ...props }) => (\n <div className={styles.wrapper}>\n <table className={`${styles.table}${className ? ` ${className}` : ''}`} {...props} />\n </div>\n)\n\nexport const TableHead: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <thead {...props} />\n)\n\nexport const TableBody: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <tbody {...props} />\n)\n\nexport const TableRow: FC<HTMLAttributes<HTMLTableRowElement>> = ({ className, ...props }) => (\n <tr className={`${styles.row}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableHeader: FC<ThHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <th className={`${styles.th}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableCell: FC<TdHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <td className={`${styles.td}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Table / TableHead / TableBody / TableRow / TableHeader / TableCell\n *\n * A set of composable table components that wrap standard HTML table elements with consistent styles.\n *\n * Table — outer wrapper with a scrollable container and a styled <table>\n * TableHead — maps to <thead>\n * TableBody — maps to <tbody>\n * TableRow — styled <tr>\n * TableHeader — styled <th> for column headings\n * TableCell — styled <td> for data cells\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML attribute for the underlying element\n *\n * Usage:\n * <Table>\n * <TableHead>\n * <TableRow>\n * <TableHeader>Name</TableHeader>\n * <TableHeader>Status</TableHeader>\n * </TableRow>\n * </TableHead>\n * <TableBody>\n * <TableRow>\n * <TableCell>Visit 001</TableCell>\n * <TableCell>Completed</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n */\n","'use client'\n\nimport React, { FC, ReactNode, useState } from 'react'\nimport styles from './Tabs.module.css'\n\nexport interface TabItem {\n value: string\n label: string\n content: ReactNode\n icon?: ReactNode\n}\n\ninterface TabsProps {\n tabs: TabItem[]\n defaultValue?: string\n}\n\nconst Tabs: FC<TabsProps> = ({ tabs, defaultValue }) => {\n const [active, setActive] = useState(defaultValue ?? tabs[0]?.value ?? '')\n const activeTab = tabs.find(t => t.value === active)\n\n return (\n <div className={styles.root}>\n <div className={styles.list} role=\"tablist\">\n {tabs.map(tab => (\n <button\n key={tab.value}\n role=\"tab\"\n aria-selected={active === tab.value}\n className={`${styles.trigger} ${active === tab.value ? styles.active : ''}`}\n onClick={() => setActive(tab.value)}\n >\n {tab.icon && <span className={styles['trigger-icon']}>{tab.icon}</span>}\n {tab.label}\n </button>\n ))}\n </div>\n <div className={styles.content} role=\"tabpanel\">\n {activeTab?.content}\n </div>\n </div>\n )\n}\n\nexport default Tabs\n\n/*\n * Tabs\n *\n * Renders a tab bar and displays the content panel of the currently active tab.\n *\n * Props:\n * tabs (TabItem[], required) — array of tab definitions, each with:\n * value (string) — unique identifier for the tab\n * label (string) — text shown on the tab button\n * content (ReactNode) — panel content shown when this tab is active\n * icon (ReactNode, optional) — icon shown before the label in the tab button\n * defaultValue (string, optional) — value of the tab that is active on first render; defaults to the first tab\n *\n * Usage:\n * <Tabs\n * tabs={[\n * { value: 'overview', label: 'Overview', content: <Overview /> },\n * { value: 'settings', label: 'Settings', content: <Settings /> },\n * ]}\n * />\n *\n * // Start on a specific tab:\n * <Tabs tabs={tabs} defaultValue=\"settings\" />\n */\n",".root {\n display: flex;\n flex-direction: column;\n}\n\n.list {\n display: inline-flex;\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.5rem;\n padding: 0.25rem;\n gap: 0.125rem;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 0.375rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ds-text-secondary, #64748b);\n transition: color 0.15s, background-color 0.15s, box-shadow 0.15s;\n white-space: nowrap;\n}\n\n.trigger:hover {\n color: var(--ds-text-primary, #0f172a);\n}\n\n.active {\n background-color: var(--ds-card, #ffffff);\n color: var(--ds-text-primary, #0f172a);\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n}\n\n.trigger-icon {\n display: flex;\n align-items: center;\n}\n\n.content {\n padding-top: 1rem;\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n",".textarea {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n resize: vertical;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n min-height: 6rem;\n}\n\n.textarea::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.textarea:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n.error {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n","import React, { FC, TextareaHTMLAttributes } from 'react'\nimport styles from './Textarea.module.css'\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n error?: boolean\n}\n\nconst Textarea: FC<TextareaProps> = ({ error, className, ...props }) => {\n const classes = [\n styles.textarea,\n error ? styles.error : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return <textarea className={classes} {...props} />\n}\n\nexport default Textarea\n\n/*\n * Textarea\n *\n * Renders a styled multi-line text area with an optional error border state.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML textarea attribute (placeholder, value, onChange, rows, disabled, etc.)\n *\n * Usage:\n * <Textarea placeholder=\"Write your message...\" rows={4} onChange={handleChange} />\n *\n * // With error state:\n * <Textarea error value={notes} onChange={e => setNotes(e.target.value)} />\n */\n",".wrapper {\n position: relative;\n display: inline-flex;\n}\n\n.tooltip {\n position: absolute;\n z-index: 50;\n padding: 0.375rem 0.625rem;\n background-color: var(--ds-tooltip-bg, #0f172a);\n color: var(--ds-tooltip-text, #ffffff);\n font-size: 0.75rem;\n line-height: 1.4;\n border-radius: 0.375rem;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.wrapper:hover .tooltip,\n.wrapper:focus-within .tooltip {\n opacity: 1;\n}\n\n.tooltip::before {\n content: '';\n position: absolute;\n border: 5px solid transparent;\n}\n\n/* Top */\n.top {\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.top::before {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Bottom */\n.bottom {\n top: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.bottom::before {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-bottom-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Left */\n.left {\n right: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.left::before {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Right */\n.right {\n left: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.right::before {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--ds-tooltip-bg, #0f172a);\n}\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Tooltip.module.css'\n\ninterface TooltipProps {\n content: string\n children: ReactNode\n position?: 'top' | 'bottom' | 'left' | 'right'\n}\n\nconst Tooltip: FC<TooltipProps> = ({ content, children, position = 'top' }) => (\n <span className={styles.wrapper}>\n {children}\n <span className={`${styles.tooltip} ${styles[position]}`} role=\"tooltip\">\n {content}\n </span>\n </span>\n)\n\nexport default Tooltip\n\n/*\n * Tooltip\n *\n * Wraps any element and shows a text tooltip on hover in the given direction.\n *\n * Props:\n * content (string, required) — the text shown inside the tooltip\n * children (ReactNode, required) — the element the tooltip is attached to\n * position (\"top\" | \"bottom\" | \"left\" | \"right\", optional) — which side the tooltip appears on; defaults to \"top\"\n *\n * Usage:\n * <Tooltip content=\"Delete this item\">\n * <button>Delete</button>\n * </Tooltip>\n *\n * // Positioned to the right:\n * <Tooltip content=\"More info\" position=\"right\">\n * <InfoIcon />\n * </Tooltip>\n */\n"],"mappings":"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","names":["Alert_default","Avatar_default","Badge_default","Breadcrumb_default","Checkbox_default","CopyButton_default","FileUpload_default","Input_default","Label_default","Progress_default","RadioGroup_default","Select_default","Skeleton_default","Slider_default","Spinner_default","Switch_default","Tabs_default","Textarea_default","Tooltip_default","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","Alert_default","import_jsx_runtime","Avatar_default","import_jsx_runtime","Badge_default","import_lucide_react","import_jsx_runtime","Breadcrumb_default","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","Checkbox_default","import_lucide_react","import_react","import_jsx_runtime","CopyButton_default","import_lucide_react","import_react","import_jsx_runtime","FileUpload_default","import_jsx_runtime","Input_default","import_jsx_runtime","Label_default","import_lucide_react","import_react","import_jsx_runtime","Input_default","import_jsx_runtime","Progress_default","import_react","import_jsx_runtime","RadioGroup_default","import_lucide_react","import_react","import_jsx_runtime","Select_default","import_jsx_runtime","Skeleton_default","import_react","import_jsx_runtime","Slider_default","import_lucide_react","import_jsx_runtime","Spinner_default","import_react","import_jsx_runtime","Switch_default","import_jsx_runtime","import_react","import_jsx_runtime","Tabs_default","import_jsx_runtime","Textarea_default","import_jsx_runtime","Tooltip_default"]}
1
+ {"version":3,"sources":["../src/components/index.ts","../src/components/ThemeProvider.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Alert/Alert.tsx","../src/components/Alert/Alert.module.css","../src/components/Avatar/Avatar.module.css","../src/components/Avatar/Avatar.tsx","../src/components/Badge/Badge.module.css","../src/components/Badge/Badge.tsx","../src/components/Breadcrumb/Breadcrumb.tsx","../src/components/Breadcrumb/Breadcrumb.module.css","../src/components/Button/Button.tsx","../src/components/Card/Card.module.css","../src/components/Card/Card.tsx","../src/components/Checkbox/Checkbox.tsx","../src/components/Checkbox/Checkbox.module.css","../src/components/CopyButton/CopyButton.tsx","../src/components/CopyButton/CopyButton.module.css","../src/components/FileUpload/FileUpload.tsx","../src/components/FileUpload/FileUpload.module.css","../src/components/Input/Input.module.css","../src/components/Input/Input.tsx","../src/components/Label/Label.module.css","../src/components/Label/Label.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/components/Progress/Progress.module.css","../src/components/Progress/Progress.tsx","../src/components/RadioGroup/RadioGroup.tsx","../src/components/RadioGroup/RadioGroup.module.css","../src/components/Select/Select.tsx","../src/components/Select/Select.module.css","../src/components/Skeleton/Skeleton.module.css","../src/components/Skeleton/Skeleton.tsx","../src/components/Slider/Slider.tsx","../src/components/Slider/Slider.module.css","../src/components/Spinner/Spinner.tsx","../src/components/Spinner/Spinner.module.css","../src/components/Switch/Switch.tsx","../src/components/Switch/Switch.module.css","../src/components/Table/Table.module.css","../src/components/Table/Table.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tabs.module.css","../src/components/Textarea/Textarea.module.css","../src/components/Textarea/Textarea.tsx","../src/components/Tooltip/Tooltip.module.css","../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["// Theme\nexport { ThemeProvider, useTheme } from './ThemeProvider'\n\n// Components\nexport { default as Accordion } from './Accordion/Accordion'\nexport { default as Alert } from './Alert/Alert'\nexport { default as Avatar } from './Avatar/Avatar'\nexport { default as Badge } from './Badge/Badge'\nexport { default as Breadcrumb } from './Breadcrumb/Breadcrumb'\nexport { default as Button } from './Button/Button'\nexport { Card, CardContent, CardDescription,\n CardFooter, CardHeader, CardTitle } from './Card/Card'\nexport { default as Checkbox } from './Checkbox/Checkbox'\nexport { default as CopyButton } from './CopyButton/CopyButton'\nexport { default as FileUpload } from './FileUpload/FileUpload'\nexport { default as Input } from './Input/Input'\nexport { default as Label } from './Label/Label'\nexport { default as PasswordInput } from './PasswordInput/PasswordInput'\nexport { default as Progress } from './Progress/Progress'\nexport { default as RadioGroup } from './RadioGroup/RadioGroup'\nexport { default as Select } from './Select/Select'\nexport { default as Skeleton } from './Skeleton/Skeleton'\nexport { default as Slider } from './Slider/Slider'\nexport { default as Spinner } from './Spinner/Spinner'\nexport { default as Switch } from './Switch/Switch'\nexport { Table, TableBody, TableCell,\n TableHead, TableHeader, TableRow } from './Table/Table'\nexport { default as Tabs } from './Tabs/Tabs'\nexport { default as Textarea } from './Textarea/Textarea'\nexport { default as Tooltip } from './Tooltip/Tooltip'\n","'use client'\nimport React, { createContext, useContext, useState } from 'react'\nimport '../styles/globals.css'\n\ntype Theme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n toggle: () => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: {\n children: React.ReactNode\n defaultTheme?: Theme\n}) => {\n const [theme, setTheme] = useState<Theme>(defaultTheme)\n return (\n <ThemeContext.Provider value={{ theme, toggle: () => setTheme(t => t === 'light' ? 'dark' : 'light') }}>\n <div className={theme === 'dark' ? 'ds-theme-dark' : undefined}>\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n\nexport const useTheme = () => {\n const ctx = useContext(ThemeContext)\n if (!ctx) throw new Error('useTheme must be used inside <ThemeProvider>')\n return ctx\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\n\nexport interface AccordionItem {\n value: string\n trigger: string\n content: string\n}\n\ninterface AccordionProps {\n items: AccordionItem[]\n defaultValue?: string | string[]\n multiple?: boolean\n}\n\nconst Accordion: FC<AccordionProps> = ({ items, defaultValue, multiple = false }) => {\n const [open, setOpen] = useState<Set<string>>(() => {\n if (!defaultValue) return new Set()\n if (Array.isArray(defaultValue)) return new Set(defaultValue)\n return new Set([defaultValue])\n })\n const [hovered, setHovered] = useState<string | null>(null)\n\n const toggle = (value: string) => {\n setOpen(prev => {\n const next = new Set(prev)\n if (next.has(value)) {\n next.delete(value)\n } else {\n if (!multiple) next.clear()\n next.add(value)\n }\n return next\n })\n }\n\n return (\n <div style={{\n border: '1px solid var(--ds-border, #e2e8f0)',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n }}>\n {items.map((item, index) => {\n const isOpen = open.has(item.value)\n const isHovered = hovered === item.value\n const isLast = index === items.length - 1\n return (\n <div\n key={item.value}\n style={{\n borderBottom: isLast ? 'none' : '1px solid var(--ds-border, #e2e8f0)',\n }}\n >\n <button\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n background: isHovered ? 'var(--ds-muted, #f1f5f9)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'var(--ds-text-primary, #0f172a)',\n transition: 'background-color 0.15s',\n }}\n onClick={() => toggle(item.value)}\n onMouseEnter={() => setHovered(item.value)}\n onMouseLeave={() => setHovered(null)}\n aria-expanded={isOpen}\n >\n <span>{item.trigger}</span>\n <ChevronDown\n size={16}\n style={{\n flexShrink: 0,\n color: 'var(--ds-text-secondary, #64748b)',\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n <div style={{\n maxHeight: isOpen ? '300px' : '0',\n overflow: 'hidden',\n transition: 'max-height 0.25s ease',\n }}>\n <div style={{\n padding: '0 1rem 1rem',\n fontSize: '0.875rem',\n color: 'var(--ds-text-secondary, #64748b)',\n }}>\n {item.content}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\nexport default Accordion\n\n/*\n * Accordion\n *\n * Renders a list of collapsible sections; by default only one section can be open at a time.\n *\n * Props:\n * items (AccordionItem[], required) — array of sections, each with:\n * value (string) — unique identifier\n * trigger (string) — heading text shown on the clickable row\n * content (string) — body text revealed when the section is open\n * defaultValue (string | string[], optional) — value(s) of sections that start open\n * multiple (boolean, optional) — when true, more than one section can be open simultaneously; defaults to false\n *\n * Usage:\n * <Accordion\n * items={[\n * { value: 'q1', trigger: 'What is eFiche?', content: 'eFiche is a medical records platform.' },\n * { value: 'q2', trigger: 'How do I log in?', content: 'Use your credentials at the login page.' },\n * ]}\n * />\n *\n * // Multiple sections open, first one pre-opened:\n * <Accordion items={faqItems} multiple defaultValue=\"q1\" />\n */\n","import React, { FC, ReactNode } from 'react'\nimport { Info, CheckCircle2, AlertTriangle, AlertCircle } from 'lucide-react'\nimport styles from './Alert.module.css'\n\ntype AlertVariant = 'info' | 'success' | 'warning' | 'danger'\n\ninterface AlertProps {\n variant?: AlertVariant\n title: string\n description: string\n}\n\nconst icons: Record<AlertVariant, ReactNode> = {\n info: <Info size={16} />,\n success: <CheckCircle2 size={16} />,\n warning: <AlertTriangle size={16} />,\n danger: <AlertCircle size={16} />,\n}\n\nconst Alert: FC<AlertProps> = ({ variant = 'info', title, description }) => (\n <div className={`${styles.alert} ${styles[variant]}`} role=\"alert\">\n <span className={styles.icon}>{icons[variant]}</span>\n <div className={styles.content}>\n <p className={styles.title}>{title}</p>\n <p className={styles.description}>{description}</p>\n </div>\n </div>\n)\n\nexport default Alert\n\n/*\n * Alert\n *\n * Displays an inline alert banner with an icon, a bold title, and a description line.\n *\n * Props:\n * title (string, required) — short heading for the alert\n * description (string, required) — supporting detail shown below the title\n * variant (\"info\" | \"success\" | \"warning\" | \"danger\", optional) — color and icon style; defaults to \"info\"\n *\n * Usage:\n * <Alert title=\"Saved\" description=\"Your changes have been saved.\" variant=\"success\" />\n *\n * // Warning:\n * <Alert title=\"Low storage\" description=\"You are using 90% of your quota.\" variant=\"warning\" />\n *\n * // Danger:\n * <Alert title=\"Error\" description=\"Something went wrong. Please try again.\" variant=\"danger\" />\n */\n",".alert {\n display: flex;\n gap: 0.75rem;\n padding: 1rem;\n border-radius: 0.5rem;\n border-left: 4px solid;\n}\n\n.icon {\n flex-shrink: 0;\n margin-top: 0.125rem;\n}\n\n.content {\n flex: 1;\n}\n\n.title {\n font-weight: 600;\n font-size: 0.875rem;\n margin-bottom: 0.25rem;\n margin-top: 0;\n}\n\n.description {\n font-size: 0.875rem;\n margin: 0;\n}\n\n/* Info */\n.info {\n background-color: var(--ds-info-bg, #eff6ff);\n border-left-color: var(--ds-info, #3b82f6);\n}\n.info .icon { color: var(--ds-info, #3b82f6); }\n.info .title { color: var(--ds-info-title, #1e3a8a); }\n.info .description { color: var(--ds-info-desc, #1e40af); }\n\n/* Success */\n.success {\n background-color: var(--ds-success-bg, #f0fdf4);\n border-left-color: var(--ds-success, #22c55e);\n}\n.success .icon { color: var(--ds-success, #22c55e); }\n.success .title { color: var(--ds-success-title, #14532d); }\n.success .description { color: var(--ds-success-desc, #166534); }\n\n/* Warning */\n.warning {\n background-color: var(--ds-warning-bg, #fffbeb);\n border-left-color: var(--ds-warning, #f59e0b);\n}\n.warning .icon { color: var(--ds-warning, #f59e0b); }\n.warning .title { color: var(--ds-warning-title, #78350f); }\n.warning .description { color: var(--ds-warning-desc, #92400e); }\n\n/* Danger */\n.danger {\n background-color: var(--ds-danger-bg, #fef2f2);\n border-left-color: var(--ds-danger, #ef4444);\n}\n.danger .icon { color: var(--ds-danger, #ef4444); }\n.danger .title { color: var(--ds-danger-title, #7f1d1d); }\n.danger .description { color: var(--ds-danger-desc, #991b1b); }\n",".avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n font-weight: 600;\n flex-shrink: 0;\n user-select: none;\n}\n\n.sm { width: 2rem; height: 2rem; font-size: 0.625rem; }\n.md { width: 2.5rem; height: 2.5rem; font-size: 0.875rem; }\n.lg { width: 4rem; height: 4rem; font-size: 1.25rem; }\n","import React, { FC } from 'react'\nimport styles from './Avatar.module.css'\n\ntype AvatarSize = 'sm' | 'md' | 'lg'\n\ninterface AvatarProps {\n fallback: string\n size?: AvatarSize\n style?: React.CSSProperties\n className?: string\n}\n\nconst Avatar: FC<AvatarProps> = ({ fallback, size = 'md', style, className }) => (\n <div\n className={`${styles.avatar} ${styles[size]}${className ? ` ${className}` : ''}`}\n style={style}\n aria-label={fallback}\n >\n {fallback}\n </div>\n)\n\nexport default Avatar\n\n/*\n * Avatar\n *\n * Renders a circular (or rounded) container showing initials or a short text fallback.\n *\n * Props:\n * fallback (string, required) — text displayed inside the avatar, typically initials (e.g. \"AB\")\n * size (\"sm\" | \"md\" | \"lg\", optional) — controls the diameter of the circle; defaults to \"md\"\n * style (React.CSSProperties, optional) — inline styles for custom background color, etc.\n * className (string, optional) — extra CSS class names\n *\n * Usage:\n * <Avatar fallback=\"JD\" />\n *\n * // Large avatar with a custom background:\n * <Avatar fallback=\"MB\" size=\"lg\" style={{ background: '#6366f1' }} />\n */\n",".badge {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n border-radius: 9999px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n/* Sizes */\n.sm { padding: 0.125rem 0.5rem; font-size: 0.625rem; }\n.md { padding: 0.25rem 0.625rem; font-size: 0.75rem; }\n.lg { padding: 0.375rem 0.875rem; font-size: 0.875rem; }\n\n/* Variants */\n.default { background-color: var(--ds-primary, #3b82f6); color: #fff; }\n.secondary { background-color: var(--ds-muted, #f1f5f9); color: var(--ds-text-secondary, #64748b); }\n.outline { background-color: transparent; border: 1px solid var(--ds-border, #e2e8f0); color: var(--ds-text-primary, #0f172a); }\n.danger { background-color: var(--ds-danger, #ef4444); color: #fff; }\n.success { background-color: var(--ds-success, #22c55e); color: #fff; }\n.warning { background-color: var(--ds-warning, #f59e0b); color: #fff; }\n.info { background-color: var(--ds-info, #3b82f6); color: #fff; }\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Badge.module.css'\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'danger' | 'success' | 'warning' | 'info'\ntype BadgeSize = 'sm' | 'md' | 'lg'\n\ninterface BadgeProps {\n variant?: BadgeVariant\n size?: BadgeSize\n children: ReactNode\n style?: React.CSSProperties\n}\n\nconst Badge: FC<BadgeProps> = ({ variant = 'default', size = 'md', children, style }) => (\n <span className={`${styles.badge} ${styles[variant]} ${styles[size]}`} style={style}>\n {children}\n </span>\n)\n\nexport default Badge\n\n/*\n * Badge\n *\n * Renders a small inline label used to highlight status, categories, or counts.\n *\n * Props:\n * variant (\"default\" | \"secondary\" | \"outline\" | \"danger\" | \"success\" | \"warning\" | \"info\", optional) — color style; defaults to \"default\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — text and padding size; defaults to \"md\"\n * children (ReactNode, required) — the content shown inside the badge\n * style (React.CSSProperties, optional) — inline styles applied to the badge element\n *\n * Usage:\n * <Badge>New</Badge>\n *\n * // Status badges:\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"danger\" size=\"sm\">Overdue</Badge>\n */\n","import React, { FC } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport styles from './Breadcrumb.module.css'\n\nexport interface BreadcrumbItem {\n label: string\n href?: string\n}\n\ninterface BreadcrumbProps {\n items: BreadcrumbItem[]\n}\n\nconst Breadcrumb: FC<BreadcrumbProps> = ({ items }) => (\n <nav aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n return (\n <li key={item.label} className={styles.item}>\n {i > 0 && <ChevronRight size={14} className={styles.separator} aria-hidden />}\n {isLast || !item.href ? (\n <span className={`${styles.link} ${isLast ? styles.current : ''}`}>\n {item.label}\n </span>\n ) : (\n <a href={item.href} className={styles.link}>\n {item.label}\n </a>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n)\n\nexport default Breadcrumb\n\n/*\n * Breadcrumb\n *\n * Renders a navigation breadcrumb trail with chevron separators; the last item is plain text, earlier items are links when an href is provided.\n *\n * Props:\n * items (BreadcrumbItem[], required) — ordered array of crumbs, each with:\n * label (string) — display text\n * href (string, optional) — link target; if omitted the crumb renders as plain text\n *\n * Usage:\n * <Breadcrumb\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Patients', href: '/patients' },\n * { label: 'Visit summary' },\n * ]}\n * />\n */\n",".list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 0.875rem;\n}\n\n.item {\n display: flex;\n align-items: center;\n}\n\n.separator {\n color: var(--ds-text-secondary, #64748b);\n margin: 0 0.25rem;\n flex-shrink: 0;\n}\n\n.link {\n color: var(--ds-text-secondary, #64748b);\n text-decoration: none;\n transition: color 0.15s;\n}\n\n.link:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: underline;\n}\n\n.current {\n color: var(--ds-text-primary, #0f172a);\n font-weight: 500;\n cursor: default;\n}\n\n.current:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: none;\n}\n","'use client'\n\nimport { LoaderCircle } from \"lucide-react\";\nimport React, { FC, ButtonHTMLAttributes, ReactNode, useState } from \"react\";\n\ntype ButtonVariant = \"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\";\ntype ButtonSize = \"sm\" | \"md\" | \"lg\";\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n text?: string;\n loading?: boolean;\n icon?: ReactNode;\n iconPosition?: \"left\" | \"right\";\n // variant shorthand booleans\n outline?: boolean;\n ghost?: boolean;\n danger?: boolean;\n warning?: boolean;\n info?: boolean;\n success?: boolean;\n variant?: ButtonVariant;\n // size shorthand booleans\n small?: boolean;\n large?: boolean;\n size?: ButtonSize;\n}\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { backgroundColor: 'var(--ds-primary, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n outline: { backgroundColor: 'transparent', color: 'var(--ds-primary, #3b82f6)', borderColor: 'var(--ds-primary, #3b82f6)' },\n ghost: { backgroundColor: 'var(--ds-muted, #f1f5f9)', color: 'var(--ds-text-primary, #0f172a)', borderColor: 'transparent' },\n danger: { backgroundColor: 'var(--ds-danger, #ef4444)', color: '#fff', borderColor: 'transparent' },\n warning: { backgroundColor: 'var(--ds-warning, #f59e0b)', color: '#fff', borderColor: 'transparent' },\n info: { backgroundColor: 'var(--ds-info, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n success: { backgroundColor: 'var(--ds-success, #22c55e)', color: '#fff', borderColor: 'transparent' },\n}\n\nconst variantHoverStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { opacity: 0.88 },\n outline: { backgroundColor: 'var(--ds-muted, #f1f5f9)' },\n ghost: { backgroundColor: 'var(--ds-card, #ffffff)' },\n danger: { opacity: 0.88 },\n warning: { opacity: 0.88 },\n info: { opacity: 0.88 },\n success: { opacity: 0.88 },\n}\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: { padding: '0.25rem 0.625rem', fontSize: '0.8rem' },\n md: { padding: '0.5rem 1rem', fontSize: '0.875rem' },\n lg: { padding: '0.75rem 1.5rem', fontSize: '1rem' },\n}\n\nconst Button: FC<ButtonProps> = ({\n text,\n children,\n loading = false,\n disabled = false,\n icon,\n iconPosition = \"left\",\n outline = false,\n ghost = false,\n danger = false,\n warning = false,\n info = false,\n success = false,\n variant,\n small = false,\n large = false,\n size,\n style: styleProp,\n ...props\n}) => {\n const [hovered, setHovered] = useState(false)\n\n const resolvedVariant: ButtonVariant =\n variant ??\n (danger ? \"danger\" :\n warning ? \"warning\" :\n info ? \"info\" :\n success ? \"success\" :\n ghost ? \"ghost\" :\n outline ? \"outline\" :\n \"solid\")\n\n const resolvedSize: ButtonSize = size ?? (small ? \"sm\" : large ? \"lg\" : \"md\")\n const isDisabled = disabled || loading\n const content = children ?? text\n const showIcon = icon && !loading\n\n const computedStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n border: '1px solid transparent',\n borderRadius: '0.375rem',\n fontWeight: 500,\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: 'opacity 0.15s, background-color 0.15s',\n opacity: isDisabled ? 0.5 : 1,\n pointerEvents: loading ? 'none' : undefined,\n ...variantStyles[resolvedVariant],\n ...sizeStyles[resolvedSize],\n ...(hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}),\n ...styleProp,\n }\n\n return (\n <>\n {/* React 19 hoists and deduplicates this style tag automatically */}\n <style href=\"ds-spin\" precedence=\"low\">{`@keyframes ds-spin { to { transform: rotate(360deg); } }`}</style>\n <button\n disabled={isDisabled}\n style={computedStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n {...props}\n >\n {loading\n ? <LoaderCircle\n aria-hidden\n style={{ width: '1em', height: '1em', animation: 'ds-spin 0.75s linear infinite' }}\n />\n : null}\n {showIcon && iconPosition === \"left\" ? icon : null}\n {content}\n {showIcon && iconPosition === \"right\" ? icon : null}\n </button>\n </>\n )\n}\n\nexport default Button\n\n/*\n * Button\n *\n * Renders a styled button with support for variants, sizes, icons, and a loading state.\n *\n * Props:\n * text (string, optional) — button label; can use children instead\n * loading (boolean, optional) — shows a spinner and disables the button while true\n * disabled (boolean, optional) — disables the button\n * icon (ReactNode, optional) — icon to display alongside the label\n * iconPosition (\"left\" | \"right\", optional) — which side the icon appears on; defaults to \"left\"\n * variant (\"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\", optional) — visual style; defaults to \"solid\"\n * outline (boolean, optional) — shorthand for variant=\"outline\"\n * ghost (boolean, optional) — shorthand for variant=\"ghost\"\n * danger (boolean, optional) — shorthand for variant=\"danger\"\n * warning (boolean, optional) — shorthand for variant=\"warning\"\n * info (boolean, optional) — shorthand for variant=\"info\"\n * success (boolean, optional) — shorthand for variant=\"success\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — button size; defaults to \"md\"\n * small (boolean, optional) — shorthand for size=\"sm\"\n * large (boolean, optional) — shorthand for size=\"lg\"\n * ...rest — any valid HTML button attribute (onClick, type, etc.)\n *\n * Usage:\n * <Button text=\"Save\" onClick={handleSave} />\n *\n * // Danger variant with loading state:\n * <Button danger loading={isDeleting} text=\"Delete\" />\n *\n * // Icon on the right, large size:\n * <Button large icon={<ArrowRight />} iconPosition=\"right\">Continue</Button>\n */\n",".card {\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n background-color: var(--ds-card, #ffffff);\n}\n\n.header {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 1.5rem 1.5rem 0;\n}\n\n.title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ds-text-primary, #0f172a);\n margin: 0;\n line-height: 1.4;\n}\n\n.description {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n margin: 0;\n}\n\n.content {\n padding: 1.5rem;\n}\n\n.footer {\n display: flex;\n align-items: center;\n padding: 0 1.5rem 1.5rem;\n}\n","import React, { FC, HTMLAttributes } from 'react'\nimport styles from './Card.module.css'\n\nexport const Card: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.card}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardHeader: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.header}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({ className, ...props }) => (\n <h3 className={`${styles.title}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardDescription: FC<HTMLAttributes<HTMLParagraphElement>> = ({ className, ...props }) => (\n <p className={`${styles.description}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.content}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardFooter: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.footer}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Card / CardHeader / CardTitle / CardDescription / CardContent / CardFooter\n *\n * A set of composable container components for building card-style layouts.\n *\n * Card — outer wrapper with a bordered, rounded container\n * CardHeader — top section, typically holds CardTitle and CardDescription\n * CardTitle — heading rendered as an <h3>\n * CardDescription — muted paragraph below the title\n * CardContent — main body area of the card\n * CardFooter — bottom section, typically holds actions\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML div/h3/p attribute\n *\n * Usage:\n * <Card>\n * <CardHeader>\n * <CardTitle>Patient Summary</CardTitle>\n * <CardDescription>Last visit on 12 May 2026</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Diagnosis: Hypertension</p>\n * </CardContent>\n * <CardFooter>\n * <Button text=\"View full record\" />\n * </CardFooter>\n * </Card>\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Checkbox.module.css'\n\ninterface CheckboxProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Checkbox: FC<CheckboxProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isChecked = checked !== undefined ? checked : internal\n\n const handleChange = () => {\n if (disabled) return\n const next = !isChecked\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isChecked}\n disabled={disabled}\n onChange={handleChange}\n className={styles.input}\n />\n <span className={`${styles.box} ${isChecked ? styles.checked : ''}`}>\n {isChecked && (\n <svg viewBox=\"0 0 12 10\" fill=\"none\" className={styles.checkmark}>\n <path d=\"M1 5l3.5 3.5L11 1\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Checkbox\n\n/*\n * Checkbox\n *\n * Renders a styled checkbox that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the checkbox\n * checked (boolean, optional) — controlled checked state\n * defaultChecked (boolean, optional) — initial checked state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input, useful for pairing with a Label\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each change\n *\n * Usage:\n * <Checkbox label=\"Accept terms\" onChange={val => setAccepted(val)} />\n *\n * // Controlled:\n * <Checkbox checked={isChecked} onChange={setIsChecked} label=\"Remember me\" />\n *\n * // Disabled with a default:\n * <Checkbox label=\"Auto-renew\" defaultChecked disabled />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.box {\n width: 1.125rem;\n height: 1.125rem;\n border: 2px solid var(--ds-border, #e2e8f0);\n border-radius: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: background-color 0.15s, border-color 0.15s;\n background-color: var(--ds-card, #fff);\n}\n\n.checked {\n background-color: var(--ds-primary, #3b82f6);\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.checkmark {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, Copy } from 'lucide-react'\nimport React, { FC, useState } from 'react'\nimport styles from './CopyButton.module.css'\n\ninterface CopyButtonProps {\n text: string\n}\n\nconst CopyButton: FC<CopyButtonProps> = ({ text }) => {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = () => {\n navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n className={styles.copyButton}\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : `Copy ${text}`}\n >\n {copied ? <Check className={styles.icon} /> : <Copy className={styles.icon} />}\n </button>\n )\n}\n\nexport default CopyButton\n\n/*\n * CopyButton\n *\n * Renders an icon button that copies a string to the clipboard; shows a checkmark for 2 seconds after copying.\n *\n * Props:\n * text (string, required) — the string that gets copied to the clipboard when clicked\n *\n * Usage:\n * <CopyButton text=\"npm install react lucide-react\" />\n *\n * // Next to a code snippet:\n * <div className=\"code-block\">\n * <code>{snippet}</code>\n * <CopyButton text={snippet} />\n * </div>\n */\n\n",".copyButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n border: none;\n border-radius: 0.25rem;\n background-color: transparent;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.copyButton:hover {\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.icon {\n width: 1rem;\n height: 1rem;\n}\n","'use client'\n\nimport { Upload } from 'lucide-react'\nimport React, { FC, useRef, useState } from 'react'\nimport styles from './FileUpload.module.css'\n\ninterface FileUploadProps {\n accept?: string\n multiple?: boolean\n disabled?: boolean\n onFileSelect?: (files: FileList) => void\n}\n\nconst FileUpload: FC<FileUploadProps> = ({ accept, multiple, disabled, onFileSelect }) => {\n const [isDragging, setIsDragging] = useState(false)\n const [fileNames, setFileNames] = useState<string[]>([])\n const inputRef = useRef<HTMLInputElement>(null)\n\n const handleFiles = (list: FileList) => {\n setFileNames(Array.from(list).map(f => f.name))\n onFileSelect?.(list)\n }\n\n return (\n <div\n className={`${styles.zone} ${isDragging ? styles.dragging : ''} ${disabled ? styles.disabled : ''}`}\n onClick={() => !disabled && inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault()\n setIsDragging(false)\n if (!disabled && e.dataTransfer.files.length) handleFiles(e.dataTransfer.files)\n }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className={styles.input}\n onChange={(e) => e.target.files && handleFiles(e.target.files)}\n />\n <Upload size={32} className={styles.icon} />\n {fileNames.length > 0\n ? <p className={styles.fileName}>{fileNames.join(', ')}</p>\n : <p className={styles.hint}><strong>Click to upload</strong> or drag and drop</p>\n }\n </div>\n )\n}\n\nexport default FileUpload\n\n/*\n * FileUpload\n *\n * Renders a click-to-browse and drag-and-drop file upload zone; displays selected file names after a pick.\n *\n * Props:\n * accept (string, optional) — file type filter passed to the hidden input (e.g. \"image/*\", \".pdf\")\n * multiple (boolean, optional) — allows selecting more than one file at a time\n * disabled (boolean, optional) — prevents clicking and dropping\n * onFileSelect ((files: FileList) => void, optional) — called with the FileList whenever files are chosen\n *\n * Usage:\n * <FileUpload onFileSelect={files => uploadFiles(files)} />\n *\n * // Images only, multiple files:\n * <FileUpload accept=\"image/*\" multiple onFileSelect={handleImages} />\n */\n",".zone {\n border: 2px dashed var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n background-color: var(--ds-muted, #f1f5f9);\n transition: border-color 0.15s, background-color 0.15s;\n text-align: center;\n}\n\n.zone:hover,\n.dragging {\n border-color: var(--ds-primary, #3b82f6);\n background-color: var(--ds-primary-50, #eff6ff);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.icon {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.hint {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n\n.fileName {\n font-size: 0.875rem;\n color: var(--ds-primary, #3b82f6);\n font-weight: 500;\n}\n",".wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.input::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.input:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n/* --- Error --- */\n.error .input {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error .input:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n\n/* --- Success --- */\n.success .input {\n border-color: var(--ds-success, #22c55e);\n}\n\n.success .input:focus {\n border-color: var(--ds-success, #22c55e);\n box-shadow: 0 0 0 3px rgb(34 197 94 / 0.15);\n}\n\n/* --- Icons --- */\n.hasLeft .input { padding-left: 2.25rem; }\n.hasRight .input { padding-right: 2.25rem; }\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n color: var(--ds-text-secondary, #64748b);\n pointer-events: none;\n}\n\n.leftIcon { left: 0.625rem; }\n.rightIcon { right: 0.625rem; }\n","import React, { FC, InputHTMLAttributes, ReactNode } from 'react'\nimport styles from './Input.module.css'\n\ninterface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n error?: boolean\n success?: boolean\n leftIcon?: ReactNode\n rightIcon?: ReactNode\n}\n\nconst Input: FC<InputProps> = ({\n error,\n success,\n leftIcon,\n rightIcon,\n className,\n ...props\n}) => {\n const wrapperClasses = [\n styles.wrapper,\n error ? styles.error : '',\n success ? styles.success : '',\n leftIcon ? styles.hasLeft : '',\n rightIcon ? styles.hasRight : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return (\n <div className={wrapperClasses}>\n {leftIcon && <span className={styles.leftIcon}>{leftIcon}</span>}\n <input className={styles.input} {...props} />\n {rightIcon && <span className={styles.rightIcon}>{rightIcon}</span>}\n </div>\n )\n}\n\nexport default Input\n\n/*\n * Input\n *\n * Renders a text input with optional left/right icons and error or success border states.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * success (boolean, optional) — applies a success border style\n * leftIcon (ReactNode, optional) — icon displayed inside the left side of the input\n * rightIcon (ReactNode, optional) — icon displayed inside the right side of the input\n * className (string, optional) — extra CSS class names applied to the wrapper div\n * ...rest — any valid HTML input attribute (placeholder, value, onChange, disabled, etc.)\n *\n * Usage:\n * <Input placeholder=\"Search...\" onChange={handleChange} />\n *\n * // With a left icon and error state:\n * <Input leftIcon={<SearchIcon />} error placeholder=\"Not found\" />\n *\n * // Controlled with a success state:\n * <Input value={email} onChange={e => setEmail(e.target.value)} success />\n */\n",".label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--ds-text-primary, #0f172a);\n margin-bottom: 0.375rem;\n}\n\n.required {\n color: var(--ds-danger, #ef4444);\n margin-left: 0.25rem;\n}\n","import React, { FC, LabelHTMLAttributes } from 'react'\nimport styles from './Label.module.css'\n\ninterface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n required?: boolean\n}\n\nconst Label: FC<LabelProps> = ({ children, required, className, ...props }) => {\n return (\n <label className={`${styles.label} ${className ?? ''}`} {...props}>\n {children}\n {required && <span className={styles.required}>*</span>}\n </label>\n )\n}\n\nexport default Label\n\n/*\n * Label\n *\n * Renders a styled form label, optionally appending a red asterisk when the field is required.\n *\n * Props:\n * required (boolean, optional) — appends a \"*\" marker after the label text\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML label attribute (htmlFor, etc.)\n *\n * Usage:\n * <Label htmlFor=\"email\">Email</Label>\n *\n * // Required field:\n * <Label htmlFor=\"name\" required>Full name</Label>\n */\n","'use client'\n\nimport { Eye, EyeOff } from 'lucide-react'\nimport React, { FC, InputHTMLAttributes, useState } from 'react'\nimport Input from '../Input/Input'\n\ntype PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>\n\nconst PasswordInput: FC<PasswordInputProps> = (props) => {\n const [visible, setVisible] = useState(false)\n\n return (\n <Input\n {...props}\n type={visible ? 'text' : 'password'}\n rightIcon={\n <button\n type=\"button\"\n onClick={() => setVisible(v => !v)}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', pointerEvents: 'all' }}\n tabIndex={-1}\n >\n {visible ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n }\n />\n )\n}\n\nexport default PasswordInput\n\n/*\n * PasswordInput\n *\n * Renders a password input with an eye/eye-off toggle button that shows or hides the typed text.\n *\n * Props:\n * ...rest — any valid HTML input attribute except \"type\" (e.g. placeholder, value, onChange, disabled)\n * also accepts Input's error and success props for border states\n *\n * Usage:\n * <PasswordInput placeholder=\"Enter password\" onChange={e => setPassword(e.target.value)} />\n *\n * // With error state:\n * <PasswordInput value={password} onChange={handleChange} error />\n */\n",".track {\n width: 100%;\n height: 0.5rem;\n background-color: var(--ds-border, #e2e8f0);\n border-radius: 9999px;\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n background-color: var(--ds-primary, #3b82f6);\n border-radius: 9999px;\n transition: width 0.3s ease;\n}\n","import React, { FC } from 'react'\nimport styles from './Progress.module.css'\n\ninterface ProgressProps {\n value?: number\n}\n\nconst Progress: FC<ProgressProps> = ({ value = 0 }) => {\n const pct = Math.min(100, Math.max(0, value))\n return (\n <div\n className={styles.track}\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n )\n}\n\nexport default Progress\n\n/*\n * Progress\n *\n * Displays a horizontal progress bar that fills from left to right based on a 0–100 value.\n *\n * Props:\n * value (number, optional) — current progress percentage (0–100); clamped to that range; defaults to 0\n *\n * Usage:\n * <Progress value={60} />\n *\n * // Dynamic upload progress:\n * <Progress value={uploadPercent} />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './RadioGroup.module.css'\n\ninterface RadioOption {\n value: string\n label: string\n}\n\ninterface RadioGroupProps {\n options: RadioOption[]\n name: string\n value?: string\n defaultValue?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst RadioGroup: FC<RadioGroupProps> = ({\n options,\n name,\n value,\n defaultValue = '',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const selected = value !== undefined ? value : internal\n\n const handleChange = (val: string) => {\n if (disabled) return\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={styles.group}>\n {options.map((option) => (\n <label\n key={option.value}\n className={`${styles.item} ${disabled ? styles.disabled : ''}`}\n >\n <input\n type=\"radio\"\n name={name}\n value={option.value}\n checked={selected === option.value}\n disabled={disabled}\n onChange={() => handleChange(option.value)}\n className={styles.input}\n />\n <span className={`${styles.dot} ${selected === option.value ? styles.checked : ''}`}>\n {selected === option.value && <span className={styles.inner} />}\n </span>\n <span className={styles.label}>{option.label}</span>\n </label>\n ))}\n </div>\n )\n}\n\nexport default RadioGroup\n\n/*\n * RadioGroup\n *\n * Renders a group of radio buttons from an array of options, supporting both controlled and uncontrolled use.\n *\n * Props:\n * options (RadioOption[], required) — array of { value: string, label: string } items to render\n * name (string, required) — shared name attribute for the radio inputs (required for HTML form grouping)\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * disabled (boolean, optional) — disables all options\n * onChange ((value: string) => void, optional) — called with the selected option's value on change\n *\n * Usage:\n * <RadioGroup\n * name=\"size\"\n * options={[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]}\n * onChange={val => setSize(val)}\n * />\n *\n * // Controlled:\n * <RadioGroup name=\"plan\" options={planOptions} value={plan} onChange={setPlan} />\n */\n",".group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.item {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.dot {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n border: 2px solid var(--ds-border, #e2e8f0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background-color: var(--ds-card, #fff);\n transition: border-color 0.15s;\n}\n\n.checked {\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.inner {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, ChevronDown } from 'lucide-react'\nimport React, { FC, useEffect, useRef, useState } from 'react'\nimport styles from './Select.module.css'\n\ninterface SelectOption {\n value: string\n label: string\n}\n\ninterface SelectProps {\n options: SelectOption[]\n value?: string\n defaultValue?: string\n placeholder?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst Select: FC<SelectProps> = ({\n options,\n value,\n defaultValue = '',\n placeholder = 'Choose an option',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n\n const selected = value !== undefined ? value : internal\n const selectedLabel = options.find(o => o.value === selected)?.label\n\n const handleSelect = (val: string) => {\n setInternal(val)\n setOpen(false)\n onChange?.(val)\n }\n\n useEffect(() => {\n const handleOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handleOutside)\n return () => document.removeEventListener('mousedown', handleOutside)\n }, [])\n\n return (\n <div ref={ref} className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <button\n type=\"button\"\n className={`${styles.trigger} ${open ? styles.open : ''}`}\n onClick={() => !disabled && setOpen(o => !o)}\n disabled={disabled}\n >\n <span className={selectedLabel ? styles.value : styles.placeholder}>\n {selectedLabel ?? placeholder}\n </span>\n <ChevronDown size={16} className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`} />\n </button>\n {open && (\n <div className={styles.dropdown}>\n {options.map((option) => (\n <div\n key={option.value}\n className={`${styles.option} ${selected === option.value ? styles.selected : ''}`}\n onClick={() => handleSelect(option.value)}\n >\n {selected === option.value\n ? <Check size={14} className={styles.checkIcon} />\n : <span className={styles.checkSpacer} />\n }\n {option.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default Select\n\n/*\n * Select\n *\n * Renders a custom dropdown that lets the user pick one option from a list, supporting controlled and uncontrolled use.\n *\n * Props:\n * options (SelectOption[], required) — array of { value: string, label: string } items to display\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * placeholder (string, optional) — text shown when nothing is selected; defaults to \"Choose an option\"\n * disabled (boolean, optional) — prevents opening the dropdown\n * onChange ((value: string) => void, optional) — called with the selected value when the user picks an option\n *\n * Usage:\n * <Select\n * options={[{ value: 'fr', label: 'French' }, { value: 'en', label: 'English' }]}\n * onChange={val => setLanguage(val)}\n * />\n *\n * // Controlled with placeholder:\n * <Select options={countryOptions} value={country} placeholder=\"Pick a country\" onChange={setCountry} />\n */\n",".wrapper {\n position: relative;\n width: 100%;\n}\n\n.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.trigger {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n transition: border-color 0.15s, box-shadow 0.15s;\n text-align: left;\n font-family: inherit;\n}\n\n.trigger:focus {\n outline: none;\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.open {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.placeholder { color: var(--ds-text-secondary, #64748b); }\n.value { color: var(--ds-text-primary, #0f172a); }\n\n.chevron {\n flex-shrink: 0;\n color: var(--ds-text-secondary, #64748b);\n transition: transform 0.15s;\n}\n\n.chevronOpen {\n transform: rotate(180deg);\n}\n\n.dropdown {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n right: 0;\n z-index: 50;\n background-color: var(--ds-card, #fff);\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);\n overflow: hidden;\n}\n\n.option {\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--ds-text-primary, #0f172a);\n transition: background-color 0.1s;\n}\n\n.option:hover { background-color: var(--ds-muted, #f1f5f9); }\n.selected { background-color: var(--ds-muted, #f1f5f9); font-weight: 500; }\n\n.checkIcon { color: var(--ds-primary, #3b82f6); flex-shrink: 0; }\n.checkSpacer { width: 14px; flex-shrink: 0; }\n",".skeleton {\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.375rem;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.circle {\n border-radius: 9999px;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n","import React, { FC } from 'react'\nimport styles from './Skeleton.module.css'\n\ninterface SkeletonProps {\n height?: string\n width?: string\n circle?: boolean\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ height = '1rem', width = '100%', circle = false }) => (\n <div\n className={`${styles.skeleton} ${circle ? styles.circle : ''}`}\n style={{ height, width }}\n aria-hidden=\"true\"\n />\n)\n\nexport default Skeleton\n\n/*\n * Skeleton\n *\n * Renders an animated placeholder block used to indicate loading content before data arrives.\n *\n * Props:\n * height (string, optional) — CSS height of the block; defaults to \"1rem\"\n * width (string, optional) — CSS width of the block; defaults to \"100%\"\n * circle (boolean, optional) — makes the block fully round (equal height and width) for avatar placeholders\n *\n * Usage:\n * <Skeleton width=\"200px\" height=\"1rem\" />\n *\n * // Avatar placeholder:\n * <Skeleton circle width=\"40px\" height=\"40px\" />\n *\n * // Full-width paragraph lines:\n * <Skeleton height=\"1rem\" />\n * <Skeleton height=\"1rem\" width=\"80%\" />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Slider.module.css'\n\ninterface SliderProps {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n onChange?: (value: number) => void\n}\n\nconst Slider: FC<SliderProps> = ({\n value,\n defaultValue = 50,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const current = value !== undefined ? value : internal\n const fill = `${((current - min) / (max - min)) * 100}%`\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = Number(e.target.value)\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={current}\n disabled={disabled}\n onChange={handleChange}\n className={styles.range}\n style={{ '--fill': fill } as React.CSSProperties}\n />\n </div>\n )\n}\n\nexport default Slider\n\n/*\n * Slider\n *\n * Renders a range slider with a filled track that reflects the current value, supporting controlled and uncontrolled use.\n *\n * Props:\n * value (number, optional) — controlled current value\n * defaultValue (number, optional) — initial value for uncontrolled use; defaults to 50\n * min (number, optional) — minimum value; defaults to 0\n * max (number, optional) — maximum value; defaults to 100\n * step (number, optional) — increment between values; defaults to 1\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * onChange ((value: number) => void, optional) — called with the new numeric value on each change\n *\n * Usage:\n * <Slider onChange={val => setVolume(val)} />\n *\n * // Controlled with custom range and step:\n * <Slider value={opacity} min={0} max={1} step={0.01} onChange={setOpacity} />\n */\n",".wrapper {\n width: 100%;\n padding: 0.25rem 0;\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.range {\n width: 100%;\n height: 0.375rem;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 9999px;\n outline: none;\n cursor: pointer;\n background: linear-gradient(\n to right,\n var(--ds-primary, #3b82f6) 0%,\n var(--ds-primary, #3b82f6) var(--fill, 50%),\n var(--ds-border, #e2e8f0) var(--fill, 50%),\n var(--ds-border, #e2e8f0) 100%\n );\n}\n\n.range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n transition: transform 0.1s;\n}\n\n.range::-webkit-slider-thumb:hover {\n transform: scale(1.2);\n}\n\n.range::-moz-range-thumb {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n}\n\n.disabled .range {\n cursor: not-allowed;\n}\n","import React, { FC } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport styles from './Spinner.module.css'\n\ntype SpinnerSize = 'sm' | 'md' | 'lg'\n\ninterface SpinnerProps {\n size?: SpinnerSize\n}\n\nconst sizePx: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\nconst Spinner: FC<SpinnerProps> = ({ size = 'md' }) => (\n <Loader2 size={sizePx[size]} className={styles.spinner} aria-label=\"Loading\" />\n)\n\nexport default Spinner\n\n/*\n * Spinner\n *\n * Displays an animated loading indicator at one of three sizes.\n *\n * Props:\n * size (\"sm\" | \"md\" | \"lg\", optional) — icon size: sm = 16px, md = 24px, lg = 32px; defaults to \"md\"\n *\n * Usage:\n * <Spinner />\n *\n * // Large spinner while page loads:\n * {isLoading && <Spinner size=\"lg\" />}\n */\n",".spinner {\n color: var(--ds-primary, #3b82f6);\n animation: spin 0.75s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Switch.module.css'\n\ninterface SwitchProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Switch: FC<SwitchProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isOn = checked !== undefined ? checked : internal\n\n const handleToggle = () => {\n if (disabled) return\n const next = !isOn\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isOn}\n disabled={disabled}\n onChange={handleToggle}\n className={styles.input}\n />\n <span className={`${styles.track} ${isOn ? styles.on : ''}`}>\n <span className={`${styles.thumb} ${isOn ? styles.thumbOn : ''}`} />\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Switch\n\n/*\n * Switch\n *\n * Renders a toggle switch that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the switch\n * checked (boolean, optional) — controlled on/off state\n * defaultChecked (boolean, optional) — initial state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each toggle\n *\n * Usage:\n * <Switch label=\"Enable notifications\" onChange={val => setEnabled(val)} />\n *\n * // Controlled:\n * <Switch checked={darkMode} onChange={setDarkMode} label=\"Dark mode\" />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.track {\n width: 2.75rem;\n height: 1.5rem;\n border-radius: 9999px;\n background-color: var(--ds-border, #e2e8f0);\n position: relative;\n transition: background-color 0.2s;\n flex-shrink: 0;\n}\n\n.on {\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.thumb {\n position: absolute;\n top: 0.175rem;\n left: 0.175rem;\n width: 1.15rem;\n height: 1.15rem;\n border-radius: 9999px;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.15);\n transition: transform 0.2s;\n}\n\n.thumbOn {\n transform: translateX(1.25rem);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n",".wrapper {\n width: 100%;\n overflow-x: auto;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n}\n\n.th {\n padding: 0.75rem 1rem;\n text-align: left;\n font-weight: 500;\n color: var(--ds-text-secondary, #64748b);\n background-color: var(--ds-muted, #f1f5f9);\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n white-space: nowrap;\n}\n\n.td {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.row:last-child .td {\n border-bottom: none;\n}\n\n.row:hover .td {\n background-color: var(--ds-muted, #f1f5f9);\n}\n\nthead .row:hover .th {\n background-color: var(--ds-muted, #f1f5f9);\n}\n","import React, { FC, HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react'\nimport styles from './Table.module.css'\n\nexport const Table: FC<HTMLAttributes<HTMLTableElement>> = ({ className, ...props }) => (\n <div className={styles.wrapper}>\n <table className={`${styles.table}${className ? ` ${className}` : ''}`} {...props} />\n </div>\n)\n\nexport const TableHead: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <thead {...props} />\n)\n\nexport const TableBody: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <tbody {...props} />\n)\n\nexport const TableRow: FC<HTMLAttributes<HTMLTableRowElement>> = ({ className, ...props }) => (\n <tr className={`${styles.row}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableHeader: FC<ThHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <th className={`${styles.th}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableCell: FC<TdHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <td className={`${styles.td}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Table / TableHead / TableBody / TableRow / TableHeader / TableCell\n *\n * A set of composable table components that wrap standard HTML table elements with consistent styles.\n *\n * Table — outer wrapper with a scrollable container and a styled <table>\n * TableHead — maps to <thead>\n * TableBody — maps to <tbody>\n * TableRow — styled <tr>\n * TableHeader — styled <th> for column headings\n * TableCell — styled <td> for data cells\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML attribute for the underlying element\n *\n * Usage:\n * <Table>\n * <TableHead>\n * <TableRow>\n * <TableHeader>Name</TableHeader>\n * <TableHeader>Status</TableHeader>\n * </TableRow>\n * </TableHead>\n * <TableBody>\n * <TableRow>\n * <TableCell>Visit 001</TableCell>\n * <TableCell>Completed</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n */\n","'use client'\n\nimport React, { FC, ReactNode, useState } from 'react'\nimport styles from './Tabs.module.css'\n\nexport interface TabItem {\n value: string\n label: string\n content: ReactNode\n icon?: ReactNode\n}\n\ninterface TabsProps {\n tabs: TabItem[]\n defaultValue?: string\n}\n\nconst Tabs: FC<TabsProps> = ({ tabs, defaultValue }) => {\n const [active, setActive] = useState(defaultValue ?? tabs[0]?.value ?? '')\n const activeTab = tabs.find(t => t.value === active)\n\n return (\n <div className={styles.root}>\n <div className={styles.list} role=\"tablist\">\n {tabs.map(tab => (\n <button\n key={tab.value}\n role=\"tab\"\n aria-selected={active === tab.value}\n className={`${styles.trigger} ${active === tab.value ? styles.active : ''}`}\n onClick={() => setActive(tab.value)}\n >\n {tab.icon && <span className={styles['trigger-icon']}>{tab.icon}</span>}\n {tab.label}\n </button>\n ))}\n </div>\n <div className={styles.content} role=\"tabpanel\">\n {activeTab?.content}\n </div>\n </div>\n )\n}\n\nexport default Tabs\n\n/*\n * Tabs\n *\n * Renders a tab bar and displays the content panel of the currently active tab.\n *\n * Props:\n * tabs (TabItem[], required) — array of tab definitions, each with:\n * value (string) — unique identifier for the tab\n * label (string) — text shown on the tab button\n * content (ReactNode) — panel content shown when this tab is active\n * icon (ReactNode, optional) — icon shown before the label in the tab button\n * defaultValue (string, optional) — value of the tab that is active on first render; defaults to the first tab\n *\n * Usage:\n * <Tabs\n * tabs={[\n * { value: 'overview', label: 'Overview', content: <Overview /> },\n * { value: 'settings', label: 'Settings', content: <Settings /> },\n * ]}\n * />\n *\n * // Start on a specific tab:\n * <Tabs tabs={tabs} defaultValue=\"settings\" />\n */\n",".root {\n display: flex;\n flex-direction: column;\n}\n\n.list {\n display: inline-flex;\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.5rem;\n padding: 0.25rem;\n gap: 0.125rem;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 0.375rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ds-text-secondary, #64748b);\n transition: color 0.15s, background-color 0.15s, box-shadow 0.15s;\n white-space: nowrap;\n}\n\n.trigger:hover {\n color: var(--ds-text-primary, #0f172a);\n}\n\n.active {\n background-color: var(--ds-card, #ffffff);\n color: var(--ds-text-primary, #0f172a);\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n}\n\n.trigger-icon {\n display: flex;\n align-items: center;\n}\n\n.content {\n padding-top: 1rem;\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n",".textarea {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n resize: vertical;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n min-height: 6rem;\n}\n\n.textarea::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.textarea:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n.error {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n","import React, { FC, TextareaHTMLAttributes } from 'react'\nimport styles from './Textarea.module.css'\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n error?: boolean\n}\n\nconst Textarea: FC<TextareaProps> = ({ error, className, ...props }) => {\n const classes = [\n styles.textarea,\n error ? styles.error : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return <textarea className={classes} {...props} />\n}\n\nexport default Textarea\n\n/*\n * Textarea\n *\n * Renders a styled multi-line text area with an optional error border state.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML textarea attribute (placeholder, value, onChange, rows, disabled, etc.)\n *\n * Usage:\n * <Textarea placeholder=\"Write your message...\" rows={4} onChange={handleChange} />\n *\n * // With error state:\n * <Textarea error value={notes} onChange={e => setNotes(e.target.value)} />\n */\n",".wrapper {\n position: relative;\n display: inline-flex;\n}\n\n.tooltip {\n position: absolute;\n z-index: 50;\n padding: 0.375rem 0.625rem;\n background-color: var(--ds-tooltip-bg, #0f172a);\n color: var(--ds-tooltip-text, #ffffff);\n font-size: 0.75rem;\n line-height: 1.4;\n border-radius: 0.375rem;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.wrapper:hover .tooltip,\n.wrapper:focus-within .tooltip {\n opacity: 1;\n}\n\n.tooltip::before {\n content: '';\n position: absolute;\n border: 5px solid transparent;\n}\n\n/* Top */\n.top {\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.top::before {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Bottom */\n.bottom {\n top: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.bottom::before {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-bottom-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Left */\n.left {\n right: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.left::before {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Right */\n.right {\n left: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.right::before {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--ds-tooltip-bg, #0f172a);\n}\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Tooltip.module.css'\n\ninterface TooltipProps {\n content: string\n children: ReactNode\n position?: 'top' | 'bottom' | 'left' | 'right'\n}\n\nconst Tooltip: FC<TooltipProps> = ({ content, children, position = 'top' }) => (\n <span className={styles.wrapper}>\n {children}\n <span className={`${styles.tooltip} ${styles[position]}`} role=\"tooltip\">\n {content}\n </span>\n </span>\n)\n\nexport default Tooltip\n\n/*\n * Tooltip\n *\n * Wraps any element and shows a text tooltip on hover in the given direction.\n *\n * Props:\n * content (string, required) — the text shown inside the tooltip\n * children (ReactNode, required) — the element the tooltip is attached to\n * position (\"top\" | \"bottom\" | \"left\" | \"right\", optional) — which side the tooltip appears on; defaults to \"top\"\n *\n * Usage:\n * <Tooltip content=\"Delete this item\">\n * <button>Delete</button>\n * </Tooltip>\n *\n * // Positioned to the right:\n * <Tooltip content=\"More info\" position=\"right\">\n * <InfoIcon />\n * </Tooltip>\n */\n"],"mappings":"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","names":["Alert_default","Avatar_default","Badge_default","Breadcrumb_default","Checkbox_default","CopyButton_default","FileUpload_default","Input_default","Label_default","Progress_default","RadioGroup_default","Select_default","Skeleton_default","Slider_default","Spinner_default","Switch_default","Tabs_default","Textarea_default","Tooltip_default","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","Alert_default","import_jsx_runtime","Avatar_default","import_jsx_runtime","Badge_default","import_lucide_react","import_jsx_runtime","Breadcrumb_default","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","Checkbox_default","import_lucide_react","import_react","import_jsx_runtime","CopyButton_default","import_lucide_react","import_react","import_jsx_runtime","FileUpload_default","import_jsx_runtime","Input_default","import_jsx_runtime","Label_default","import_lucide_react","import_react","import_jsx_runtime","Input_default","import_jsx_runtime","Progress_default","import_react","import_jsx_runtime","RadioGroup_default","import_lucide_react","import_react","import_jsx_runtime","Select_default","import_jsx_runtime","Skeleton_default","import_react","import_jsx_runtime","Slider_default","import_lucide_react","import_jsx_runtime","Spinner_default","import_react","import_jsx_runtime","Switch_default","import_jsx_runtime","import_react","import_jsx_runtime","Tabs_default","import_jsx_runtime","Textarea_default","import_jsx_runtime","Tooltip_default"]}
package/dist/index.js CHANGED
@@ -207,8 +207,8 @@ var Breadcrumb_default2 = Breadcrumb;
207
207
 
208
208
  // src/components/Button/Button.tsx
209
209
  import { LoaderCircle } from "lucide-react";
210
- import { useEffect, useState as useState3 } from "react";
211
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
210
+ import { useState as useState3 } from "react";
211
+ import { Fragment, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
212
212
  var variantStyles = {
213
213
  solid: { backgroundColor: "var(--ds-primary, #3b82f6)", color: "#fff", borderColor: "transparent" },
214
214
  outline: { backgroundColor: "transparent", color: "var(--ds-primary, #3b82f6)", borderColor: "var(--ds-primary, #3b82f6)" },
@@ -232,14 +232,6 @@ var sizeStyles = {
232
232
  md: { padding: "0.5rem 1rem", fontSize: "0.875rem" },
233
233
  lg: { padding: "0.75rem 1.5rem", fontSize: "1rem" }
234
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
- }
243
235
  var Button = (_a) => {
244
236
  var _b = _a, {
245
237
  text,
@@ -279,9 +271,6 @@ var Button = (_a) => {
279
271
  "style"
280
272
  ]);
281
273
  const [hovered, setHovered] = useState3(false);
282
- useEffect(() => {
283
- injectSpinKeyframe();
284
- }, []);
285
274
  const resolvedVariant = variant != null ? variant : danger ? "danger" : warning ? "warning" : info ? "info" : success ? "success" : ghost ? "ghost" : outline ? "outline" : "solid";
286
275
  const resolvedSize = size != null ? size : small ? "sm" : large ? "lg" : "md";
287
276
  const isDisabled = disabled || loading;
@@ -299,28 +288,31 @@ var Button = (_a) => {
299
288
  opacity: isDisabled ? 0.5 : 1,
300
289
  pointerEvents: loading ? "none" : void 0
301
290
  }, variantStyles[resolvedVariant]), sizeStyles[resolvedSize]), hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}), styleProp);
302
- return /* @__PURE__ */ jsxs4(
303
- "button",
304
- __spreadProps(__spreadValues({
305
- disabled: isDisabled,
306
- style: computedStyle,
307
- onMouseEnter: () => setHovered(true),
308
- onMouseLeave: () => setHovered(false)
309
- }, props), {
310
- children: [
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,
318
- showIcon && iconPosition === "left" ? icon : null,
319
- content,
320
- showIcon && iconPosition === "right" ? icon : null
321
- ]
322
- })
323
- );
291
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
292
+ /* @__PURE__ */ jsx7("style", { href: "ds-spin", precedence: "low", children: `@keyframes ds-spin { to { transform: rotate(360deg); } }` }),
293
+ /* @__PURE__ */ jsxs4(
294
+ "button",
295
+ __spreadProps(__spreadValues({
296
+ disabled: isDisabled,
297
+ style: computedStyle,
298
+ onMouseEnter: () => setHovered(true),
299
+ onMouseLeave: () => setHovered(false)
300
+ }, props), {
301
+ children: [
302
+ loading ? /* @__PURE__ */ jsx7(
303
+ LoaderCircle,
304
+ {
305
+ "aria-hidden": true,
306
+ style: { width: "1em", height: "1em", animation: "ds-spin 0.75s linear infinite" }
307
+ }
308
+ ) : null,
309
+ showIcon && iconPosition === "left" ? icon : null,
310
+ content,
311
+ showIcon && iconPosition === "right" ? icon : null
312
+ ]
313
+ })
314
+ )
315
+ ] });
324
316
  };
325
317
  var Button_default = Button;
326
318
 
@@ -629,7 +621,7 @@ var RadioGroup_default2 = RadioGroup;
629
621
 
630
622
  // src/components/Select/Select.tsx
631
623
  import { Check as Check2, ChevronDown as ChevronDown2 } from "lucide-react";
632
- import { useEffect as useEffect2, useRef as useRef2, useState as useState9 } from "react";
624
+ import { useEffect, useRef as useRef2, useState as useState9 } from "react";
633
625
 
634
626
  // src/components/Select/Select.module.css
635
627
  var Select_default = {};
@@ -655,7 +647,7 @@ var Select = ({
655
647
  setOpen(false);
656
648
  onChange == null ? void 0 : onChange(val);
657
649
  };
658
- useEffect2(() => {
650
+ useEffect(() => {
659
651
  const handleOutside = (e) => {
660
652
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
661
653
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ThemeProvider.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Alert/Alert.tsx","../src/components/Alert/Alert.module.css","../src/components/Avatar/Avatar.module.css","../src/components/Avatar/Avatar.tsx","../src/components/Badge/Badge.module.css","../src/components/Badge/Badge.tsx","../src/components/Breadcrumb/Breadcrumb.tsx","../src/components/Breadcrumb/Breadcrumb.module.css","../src/components/Button/Button.tsx","../src/components/Card/Card.module.css","../src/components/Card/Card.tsx","../src/components/Checkbox/Checkbox.tsx","../src/components/Checkbox/Checkbox.module.css","../src/components/CopyButton/CopyButton.tsx","../src/components/CopyButton/CopyButton.module.css","../src/components/FileUpload/FileUpload.tsx","../src/components/FileUpload/FileUpload.module.css","../src/components/Input/Input.module.css","../src/components/Input/Input.tsx","../src/components/Label/Label.module.css","../src/components/Label/Label.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/components/Progress/Progress.module.css","../src/components/Progress/Progress.tsx","../src/components/RadioGroup/RadioGroup.tsx","../src/components/RadioGroup/RadioGroup.module.css","../src/components/Select/Select.tsx","../src/components/Select/Select.module.css","../src/components/Skeleton/Skeleton.module.css","../src/components/Skeleton/Skeleton.tsx","../src/components/Slider/Slider.tsx","../src/components/Slider/Slider.module.css","../src/components/Spinner/Spinner.tsx","../src/components/Spinner/Spinner.module.css","../src/components/Switch/Switch.tsx","../src/components/Switch/Switch.module.css","../src/components/Table/Table.module.css","../src/components/Table/Table.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tabs.module.css","../src/components/Textarea/Textarea.module.css","../src/components/Textarea/Textarea.tsx","../src/components/Tooltip/Tooltip.module.css","../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\nimport React, { createContext, useContext, useState } from 'react'\nimport '../styles/globals.css'\n\ntype Theme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n toggle: () => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: {\n children: React.ReactNode\n defaultTheme?: Theme\n}) => {\n const [theme, setTheme] = useState<Theme>(defaultTheme)\n return (\n <ThemeContext.Provider value={{ theme, toggle: () => setTheme(t => t === 'light' ? 'dark' : 'light') }}>\n <div className={theme === 'dark' ? 'ds-theme-dark' : undefined}>\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n\nexport const useTheme = () => {\n const ctx = useContext(ThemeContext)\n if (!ctx) throw new Error('useTheme must be used inside <ThemeProvider>')\n return ctx\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\n\nexport interface AccordionItem {\n value: string\n trigger: string\n content: string\n}\n\ninterface AccordionProps {\n items: AccordionItem[]\n defaultValue?: string | string[]\n multiple?: boolean\n}\n\nconst Accordion: FC<AccordionProps> = ({ items, defaultValue, multiple = false }) => {\n const [open, setOpen] = useState<Set<string>>(() => {\n if (!defaultValue) return new Set()\n if (Array.isArray(defaultValue)) return new Set(defaultValue)\n return new Set([defaultValue])\n })\n const [hovered, setHovered] = useState<string | null>(null)\n\n const toggle = (value: string) => {\n setOpen(prev => {\n const next = new Set(prev)\n if (next.has(value)) {\n next.delete(value)\n } else {\n if (!multiple) next.clear()\n next.add(value)\n }\n return next\n })\n }\n\n return (\n <div style={{\n border: '1px solid var(--ds-border, #e2e8f0)',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n }}>\n {items.map((item, index) => {\n const isOpen = open.has(item.value)\n const isHovered = hovered === item.value\n const isLast = index === items.length - 1\n return (\n <div\n key={item.value}\n style={{\n borderBottom: isLast ? 'none' : '1px solid var(--ds-border, #e2e8f0)',\n }}\n >\n <button\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n background: isHovered ? 'var(--ds-muted, #f1f5f9)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'var(--ds-text-primary, #0f172a)',\n transition: 'background-color 0.15s',\n }}\n onClick={() => toggle(item.value)}\n onMouseEnter={() => setHovered(item.value)}\n onMouseLeave={() => setHovered(null)}\n aria-expanded={isOpen}\n >\n <span>{item.trigger}</span>\n <ChevronDown\n size={16}\n style={{\n flexShrink: 0,\n color: 'var(--ds-text-secondary, #64748b)',\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n <div style={{\n maxHeight: isOpen ? '300px' : '0',\n overflow: 'hidden',\n transition: 'max-height 0.25s ease',\n }}>\n <div style={{\n padding: '0 1rem 1rem',\n fontSize: '0.875rem',\n color: 'var(--ds-text-secondary, #64748b)',\n }}>\n {item.content}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\nexport default Accordion\n\n/*\n * Accordion\n *\n * Renders a list of collapsible sections; by default only one section can be open at a time.\n *\n * Props:\n * items (AccordionItem[], required) — array of sections, each with:\n * value (string) — unique identifier\n * trigger (string) — heading text shown on the clickable row\n * content (string) — body text revealed when the section is open\n * defaultValue (string | string[], optional) — value(s) of sections that start open\n * multiple (boolean, optional) — when true, more than one section can be open simultaneously; defaults to false\n *\n * Usage:\n * <Accordion\n * items={[\n * { value: 'q1', trigger: 'What is eFiche?', content: 'eFiche is a medical records platform.' },\n * { value: 'q2', trigger: 'How do I log in?', content: 'Use your credentials at the login page.' },\n * ]}\n * />\n *\n * // Multiple sections open, first one pre-opened:\n * <Accordion items={faqItems} multiple defaultValue=\"q1\" />\n */\n","import React, { FC, ReactNode } from 'react'\nimport { Info, CheckCircle2, AlertTriangle, AlertCircle } from 'lucide-react'\nimport styles from './Alert.module.css'\n\ntype AlertVariant = 'info' | 'success' | 'warning' | 'danger'\n\ninterface AlertProps {\n variant?: AlertVariant\n title: string\n description: string\n}\n\nconst icons: Record<AlertVariant, ReactNode> = {\n info: <Info size={16} />,\n success: <CheckCircle2 size={16} />,\n warning: <AlertTriangle size={16} />,\n danger: <AlertCircle size={16} />,\n}\n\nconst Alert: FC<AlertProps> = ({ variant = 'info', title, description }) => (\n <div className={`${styles.alert} ${styles[variant]}`} role=\"alert\">\n <span className={styles.icon}>{icons[variant]}</span>\n <div className={styles.content}>\n <p className={styles.title}>{title}</p>\n <p className={styles.description}>{description}</p>\n </div>\n </div>\n)\n\nexport default Alert\n\n/*\n * Alert\n *\n * Displays an inline alert banner with an icon, a bold title, and a description line.\n *\n * Props:\n * title (string, required) — short heading for the alert\n * description (string, required) — supporting detail shown below the title\n * variant (\"info\" | \"success\" | \"warning\" | \"danger\", optional) — color and icon style; defaults to \"info\"\n *\n * Usage:\n * <Alert title=\"Saved\" description=\"Your changes have been saved.\" variant=\"success\" />\n *\n * // Warning:\n * <Alert title=\"Low storage\" description=\"You are using 90% of your quota.\" variant=\"warning\" />\n *\n * // Danger:\n * <Alert title=\"Error\" description=\"Something went wrong. Please try again.\" variant=\"danger\" />\n */\n",".alert {\n display: flex;\n gap: 0.75rem;\n padding: 1rem;\n border-radius: 0.5rem;\n border-left: 4px solid;\n}\n\n.icon {\n flex-shrink: 0;\n margin-top: 0.125rem;\n}\n\n.content {\n flex: 1;\n}\n\n.title {\n font-weight: 600;\n font-size: 0.875rem;\n margin-bottom: 0.25rem;\n margin-top: 0;\n}\n\n.description {\n font-size: 0.875rem;\n margin: 0;\n}\n\n/* Info */\n.info {\n background-color: var(--ds-info-bg, #eff6ff);\n border-left-color: var(--ds-info, #3b82f6);\n}\n.info .icon { color: var(--ds-info, #3b82f6); }\n.info .title { color: var(--ds-info-title, #1e3a8a); }\n.info .description { color: var(--ds-info-desc, #1e40af); }\n\n/* Success */\n.success {\n background-color: var(--ds-success-bg, #f0fdf4);\n border-left-color: var(--ds-success, #22c55e);\n}\n.success .icon { color: var(--ds-success, #22c55e); }\n.success .title { color: var(--ds-success-title, #14532d); }\n.success .description { color: var(--ds-success-desc, #166534); }\n\n/* Warning */\n.warning {\n background-color: var(--ds-warning-bg, #fffbeb);\n border-left-color: var(--ds-warning, #f59e0b);\n}\n.warning .icon { color: var(--ds-warning, #f59e0b); }\n.warning .title { color: var(--ds-warning-title, #78350f); }\n.warning .description { color: var(--ds-warning-desc, #92400e); }\n\n/* Danger */\n.danger {\n background-color: var(--ds-danger-bg, #fef2f2);\n border-left-color: var(--ds-danger, #ef4444);\n}\n.danger .icon { color: var(--ds-danger, #ef4444); }\n.danger .title { color: var(--ds-danger-title, #7f1d1d); }\n.danger .description { color: var(--ds-danger-desc, #991b1b); }\n",".avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n font-weight: 600;\n flex-shrink: 0;\n user-select: none;\n}\n\n.sm { width: 2rem; height: 2rem; font-size: 0.625rem; }\n.md { width: 2.5rem; height: 2.5rem; font-size: 0.875rem; }\n.lg { width: 4rem; height: 4rem; font-size: 1.25rem; }\n","import React, { FC } from 'react'\nimport styles from './Avatar.module.css'\n\ntype AvatarSize = 'sm' | 'md' | 'lg'\n\ninterface AvatarProps {\n fallback: string\n size?: AvatarSize\n style?: React.CSSProperties\n className?: string\n}\n\nconst Avatar: FC<AvatarProps> = ({ fallback, size = 'md', style, className }) => (\n <div\n className={`${styles.avatar} ${styles[size]}${className ? ` ${className}` : ''}`}\n style={style}\n aria-label={fallback}\n >\n {fallback}\n </div>\n)\n\nexport default Avatar\n\n/*\n * Avatar\n *\n * Renders a circular (or rounded) container showing initials or a short text fallback.\n *\n * Props:\n * fallback (string, required) — text displayed inside the avatar, typically initials (e.g. \"AB\")\n * size (\"sm\" | \"md\" | \"lg\", optional) — controls the diameter of the circle; defaults to \"md\"\n * style (React.CSSProperties, optional) — inline styles for custom background color, etc.\n * className (string, optional) — extra CSS class names\n *\n * Usage:\n * <Avatar fallback=\"JD\" />\n *\n * // Large avatar with a custom background:\n * <Avatar fallback=\"MB\" size=\"lg\" style={{ background: '#6366f1' }} />\n */\n",".badge {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n border-radius: 9999px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n/* Sizes */\n.sm { padding: 0.125rem 0.5rem; font-size: 0.625rem; }\n.md { padding: 0.25rem 0.625rem; font-size: 0.75rem; }\n.lg { padding: 0.375rem 0.875rem; font-size: 0.875rem; }\n\n/* Variants */\n.default { background-color: var(--ds-primary, #3b82f6); color: #fff; }\n.secondary { background-color: var(--ds-muted, #f1f5f9); color: var(--ds-text-secondary, #64748b); }\n.outline { background-color: transparent; border: 1px solid var(--ds-border, #e2e8f0); color: var(--ds-text-primary, #0f172a); }\n.danger { background-color: var(--ds-danger, #ef4444); color: #fff; }\n.success { background-color: var(--ds-success, #22c55e); color: #fff; }\n.warning { background-color: var(--ds-warning, #f59e0b); color: #fff; }\n.info { background-color: var(--ds-info, #3b82f6); color: #fff; }\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Badge.module.css'\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'danger' | 'success' | 'warning' | 'info'\ntype BadgeSize = 'sm' | 'md' | 'lg'\n\ninterface BadgeProps {\n variant?: BadgeVariant\n size?: BadgeSize\n children: ReactNode\n style?: React.CSSProperties\n}\n\nconst Badge: FC<BadgeProps> = ({ variant = 'default', size = 'md', children, style }) => (\n <span className={`${styles.badge} ${styles[variant]} ${styles[size]}`} style={style}>\n {children}\n </span>\n)\n\nexport default Badge\n\n/*\n * Badge\n *\n * Renders a small inline label used to highlight status, categories, or counts.\n *\n * Props:\n * variant (\"default\" | \"secondary\" | \"outline\" | \"danger\" | \"success\" | \"warning\" | \"info\", optional) — color style; defaults to \"default\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — text and padding size; defaults to \"md\"\n * children (ReactNode, required) — the content shown inside the badge\n * style (React.CSSProperties, optional) — inline styles applied to the badge element\n *\n * Usage:\n * <Badge>New</Badge>\n *\n * // Status badges:\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"danger\" size=\"sm\">Overdue</Badge>\n */\n","import React, { FC } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport styles from './Breadcrumb.module.css'\n\nexport interface BreadcrumbItem {\n label: string\n href?: string\n}\n\ninterface BreadcrumbProps {\n items: BreadcrumbItem[]\n}\n\nconst Breadcrumb: FC<BreadcrumbProps> = ({ items }) => (\n <nav aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n return (\n <li key={item.label} className={styles.item}>\n {i > 0 && <ChevronRight size={14} className={styles.separator} aria-hidden />}\n {isLast || !item.href ? (\n <span className={`${styles.link} ${isLast ? styles.current : ''}`}>\n {item.label}\n </span>\n ) : (\n <a href={item.href} className={styles.link}>\n {item.label}\n </a>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n)\n\nexport default Breadcrumb\n\n/*\n * Breadcrumb\n *\n * Renders a navigation breadcrumb trail with chevron separators; the last item is plain text, earlier items are links when an href is provided.\n *\n * Props:\n * items (BreadcrumbItem[], required) — ordered array of crumbs, each with:\n * label (string) — display text\n * href (string, optional) — link target; if omitted the crumb renders as plain text\n *\n * Usage:\n * <Breadcrumb\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Patients', href: '/patients' },\n * { label: 'Visit summary' },\n * ]}\n * />\n */\n",".list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 0.875rem;\n}\n\n.item {\n display: flex;\n align-items: center;\n}\n\n.separator {\n color: var(--ds-text-secondary, #64748b);\n margin: 0 0.25rem;\n flex-shrink: 0;\n}\n\n.link {\n color: var(--ds-text-secondary, #64748b);\n text-decoration: none;\n transition: color 0.15s;\n}\n\n.link:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: underline;\n}\n\n.current {\n color: var(--ds-text-primary, #0f172a);\n font-weight: 500;\n cursor: default;\n}\n\n.current:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: none;\n}\n","'use client'\n\nimport { LoaderCircle } from \"lucide-react\";\nimport React, { FC, ButtonHTMLAttributes, ReactNode, useEffect, useState } from \"react\";\n\ntype ButtonVariant = \"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\";\ntype ButtonSize = \"sm\" | \"md\" | \"lg\";\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n text?: string;\n loading?: boolean;\n icon?: ReactNode;\n iconPosition?: \"left\" | \"right\";\n // variant shorthand booleans\n outline?: boolean;\n ghost?: boolean;\n danger?: boolean;\n warning?: boolean;\n info?: boolean;\n success?: boolean;\n variant?: ButtonVariant;\n // size shorthand booleans\n small?: boolean;\n large?: boolean;\n size?: ButtonSize;\n}\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { backgroundColor: 'var(--ds-primary, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n outline: { backgroundColor: 'transparent', color: 'var(--ds-primary, #3b82f6)', borderColor: 'var(--ds-primary, #3b82f6)' },\n ghost: { backgroundColor: 'var(--ds-muted, #f1f5f9)', color: 'var(--ds-text-primary, #0f172a)', borderColor: 'transparent' },\n danger: { backgroundColor: 'var(--ds-danger, #ef4444)', color: '#fff', borderColor: 'transparent' },\n warning: { backgroundColor: 'var(--ds-warning, #f59e0b)', color: '#fff', borderColor: 'transparent' },\n info: { backgroundColor: 'var(--ds-info, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n success: { backgroundColor: 'var(--ds-success, #22c55e)', color: '#fff', borderColor: 'transparent' },\n}\n\nconst variantHoverStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { opacity: 0.88 },\n outline: { backgroundColor: 'var(--ds-muted, #f1f5f9)' },\n ghost: { backgroundColor: 'var(--ds-card, #ffffff)' },\n danger: { opacity: 0.88 },\n warning: { opacity: 0.88 },\n info: { opacity: 0.88 },\n success: { opacity: 0.88 },\n}\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: { padding: '0.25rem 0.625rem', fontSize: '0.8rem' },\n md: { padding: '0.5rem 1rem', fontSize: '0.875rem' },\n lg: { padding: '0.75rem 1.5rem', fontSize: '1rem' },\n}\n\nfunction injectSpinKeyframe() {\n if (typeof document === 'undefined') return\n if (document.getElementById('ds-spin-keyframe')) return\n const style = document.createElement('style')\n style.id = 'ds-spin-keyframe'\n style.textContent = '@keyframes ds-spin { to { transform: rotate(360deg); } }'\n document.head.appendChild(style)\n}\n\nconst Button: FC<ButtonProps> = ({\n text,\n children,\n loading = false,\n disabled = false,\n icon,\n iconPosition = \"left\",\n outline = false,\n ghost = false,\n danger = false,\n warning = false,\n info = false,\n success = false,\n variant,\n small = false,\n large = false,\n size,\n style: styleProp,\n ...props\n}) => {\n const [hovered, setHovered] = useState(false)\n\n useEffect(() => { injectSpinKeyframe() }, [])\n\n const resolvedVariant: ButtonVariant =\n variant ??\n (danger ? \"danger\" :\n warning ? \"warning\" :\n info ? \"info\" :\n success ? \"success\" :\n ghost ? \"ghost\" :\n outline ? \"outline\" :\n \"solid\")\n\n const resolvedSize: ButtonSize = size ?? (small ? \"sm\" : large ? \"lg\" : \"md\")\n const isDisabled = disabled || loading\n const content = children ?? text\n const showIcon = icon && !loading\n\n const computedStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n border: '1px solid transparent',\n borderRadius: '0.375rem',\n fontWeight: 500,\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: 'opacity 0.15s, background-color 0.15s',\n opacity: isDisabled ? 0.5 : 1,\n pointerEvents: loading ? 'none' : undefined,\n ...variantStyles[resolvedVariant],\n ...sizeStyles[resolvedSize],\n ...(hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}),\n ...styleProp,\n }\n\n return (\n <button\n disabled={isDisabled}\n style={computedStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n {...props}\n >\n {loading\n ? <LoaderCircle\n aria-hidden\n style={{ width: '1em', height: '1em', animation: 'ds-spin 0.75s linear infinite' }}\n />\n : null}\n {showIcon && iconPosition === \"left\" ? icon : null}\n {content}\n {showIcon && iconPosition === \"right\" ? icon : null}\n </button>\n )\n}\n\nexport default Button\n\n/*\n * Button\n *\n * Renders a styled button with support for variants, sizes, icons, and a loading state.\n *\n * Props:\n * text (string, optional) — button label; can use children instead\n * loading (boolean, optional) — shows a spinner and disables the button while true\n * disabled (boolean, optional) — disables the button\n * icon (ReactNode, optional) — icon to display alongside the label\n * iconPosition (\"left\" | \"right\", optional) — which side the icon appears on; defaults to \"left\"\n * variant (\"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\", optional) — visual style; defaults to \"solid\"\n * outline (boolean, optional) — shorthand for variant=\"outline\"\n * ghost (boolean, optional) — shorthand for variant=\"ghost\"\n * danger (boolean, optional) — shorthand for variant=\"danger\"\n * warning (boolean, optional) — shorthand for variant=\"warning\"\n * info (boolean, optional) — shorthand for variant=\"info\"\n * success (boolean, optional) — shorthand for variant=\"success\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — button size; defaults to \"md\"\n * small (boolean, optional) — shorthand for size=\"sm\"\n * large (boolean, optional) — shorthand for size=\"lg\"\n * ...rest — any valid HTML button attribute (onClick, type, etc.)\n *\n * Usage:\n * <Button text=\"Save\" onClick={handleSave} />\n *\n * // Danger variant with loading state:\n * <Button danger loading={isDeleting} text=\"Delete\" />\n *\n * // Icon on the right, large size:\n * <Button large icon={<ArrowRight />} iconPosition=\"right\">Continue</Button>\n */\n",".card {\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n background-color: var(--ds-card, #ffffff);\n}\n\n.header {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 1.5rem 1.5rem 0;\n}\n\n.title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ds-text-primary, #0f172a);\n margin: 0;\n line-height: 1.4;\n}\n\n.description {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n margin: 0;\n}\n\n.content {\n padding: 1.5rem;\n}\n\n.footer {\n display: flex;\n align-items: center;\n padding: 0 1.5rem 1.5rem;\n}\n","import React, { FC, HTMLAttributes } from 'react'\nimport styles from './Card.module.css'\n\nexport const Card: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.card}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardHeader: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.header}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({ className, ...props }) => (\n <h3 className={`${styles.title}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardDescription: FC<HTMLAttributes<HTMLParagraphElement>> = ({ className, ...props }) => (\n <p className={`${styles.description}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.content}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardFooter: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.footer}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Card / CardHeader / CardTitle / CardDescription / CardContent / CardFooter\n *\n * A set of composable container components for building card-style layouts.\n *\n * Card — outer wrapper with a bordered, rounded container\n * CardHeader — top section, typically holds CardTitle and CardDescription\n * CardTitle — heading rendered as an <h3>\n * CardDescription — muted paragraph below the title\n * CardContent — main body area of the card\n * CardFooter — bottom section, typically holds actions\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML div/h3/p attribute\n *\n * Usage:\n * <Card>\n * <CardHeader>\n * <CardTitle>Patient Summary</CardTitle>\n * <CardDescription>Last visit on 12 May 2026</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Diagnosis: Hypertension</p>\n * </CardContent>\n * <CardFooter>\n * <Button text=\"View full record\" />\n * </CardFooter>\n * </Card>\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Checkbox.module.css'\n\ninterface CheckboxProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Checkbox: FC<CheckboxProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isChecked = checked !== undefined ? checked : internal\n\n const handleChange = () => {\n if (disabled) return\n const next = !isChecked\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isChecked}\n disabled={disabled}\n onChange={handleChange}\n className={styles.input}\n />\n <span className={`${styles.box} ${isChecked ? styles.checked : ''}`}>\n {isChecked && (\n <svg viewBox=\"0 0 12 10\" fill=\"none\" className={styles.checkmark}>\n <path d=\"M1 5l3.5 3.5L11 1\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Checkbox\n\n/*\n * Checkbox\n *\n * Renders a styled checkbox that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the checkbox\n * checked (boolean, optional) — controlled checked state\n * defaultChecked (boolean, optional) — initial checked state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input, useful for pairing with a Label\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each change\n *\n * Usage:\n * <Checkbox label=\"Accept terms\" onChange={val => setAccepted(val)} />\n *\n * // Controlled:\n * <Checkbox checked={isChecked} onChange={setIsChecked} label=\"Remember me\" />\n *\n * // Disabled with a default:\n * <Checkbox label=\"Auto-renew\" defaultChecked disabled />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.box {\n width: 1.125rem;\n height: 1.125rem;\n border: 2px solid var(--ds-border, #e2e8f0);\n border-radius: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: background-color 0.15s, border-color 0.15s;\n background-color: var(--ds-card, #fff);\n}\n\n.checked {\n background-color: var(--ds-primary, #3b82f6);\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.checkmark {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, Copy } from 'lucide-react'\nimport React, { FC, useState } from 'react'\nimport styles from './CopyButton.module.css'\n\ninterface CopyButtonProps {\n text: string\n}\n\nconst CopyButton: FC<CopyButtonProps> = ({ text }) => {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = () => {\n navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n className={styles.copyButton}\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : `Copy ${text}`}\n >\n {copied ? <Check className={styles.icon} /> : <Copy className={styles.icon} />}\n </button>\n )\n}\n\nexport default CopyButton\n\n/*\n * CopyButton\n *\n * Renders an icon button that copies a string to the clipboard; shows a checkmark for 2 seconds after copying.\n *\n * Props:\n * text (string, required) — the string that gets copied to the clipboard when clicked\n *\n * Usage:\n * <CopyButton text=\"npm install react lucide-react\" />\n *\n * // Next to a code snippet:\n * <div className=\"code-block\">\n * <code>{snippet}</code>\n * <CopyButton text={snippet} />\n * </div>\n */\n\n",".copyButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n border: none;\n border-radius: 0.25rem;\n background-color: transparent;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.copyButton:hover {\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.icon {\n width: 1rem;\n height: 1rem;\n}\n","'use client'\n\nimport { Upload } from 'lucide-react'\nimport React, { FC, useRef, useState } from 'react'\nimport styles from './FileUpload.module.css'\n\ninterface FileUploadProps {\n accept?: string\n multiple?: boolean\n disabled?: boolean\n onFileSelect?: (files: FileList) => void\n}\n\nconst FileUpload: FC<FileUploadProps> = ({ accept, multiple, disabled, onFileSelect }) => {\n const [isDragging, setIsDragging] = useState(false)\n const [fileNames, setFileNames] = useState<string[]>([])\n const inputRef = useRef<HTMLInputElement>(null)\n\n const handleFiles = (list: FileList) => {\n setFileNames(Array.from(list).map(f => f.name))\n onFileSelect?.(list)\n }\n\n return (\n <div\n className={`${styles.zone} ${isDragging ? styles.dragging : ''} ${disabled ? styles.disabled : ''}`}\n onClick={() => !disabled && inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault()\n setIsDragging(false)\n if (!disabled && e.dataTransfer.files.length) handleFiles(e.dataTransfer.files)\n }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className={styles.input}\n onChange={(e) => e.target.files && handleFiles(e.target.files)}\n />\n <Upload size={32} className={styles.icon} />\n {fileNames.length > 0\n ? <p className={styles.fileName}>{fileNames.join(', ')}</p>\n : <p className={styles.hint}><strong>Click to upload</strong> or drag and drop</p>\n }\n </div>\n )\n}\n\nexport default FileUpload\n\n/*\n * FileUpload\n *\n * Renders a click-to-browse and drag-and-drop file upload zone; displays selected file names after a pick.\n *\n * Props:\n * accept (string, optional) — file type filter passed to the hidden input (e.g. \"image/*\", \".pdf\")\n * multiple (boolean, optional) — allows selecting more than one file at a time\n * disabled (boolean, optional) — prevents clicking and dropping\n * onFileSelect ((files: FileList) => void, optional) — called with the FileList whenever files are chosen\n *\n * Usage:\n * <FileUpload onFileSelect={files => uploadFiles(files)} />\n *\n * // Images only, multiple files:\n * <FileUpload accept=\"image/*\" multiple onFileSelect={handleImages} />\n */\n",".zone {\n border: 2px dashed var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n background-color: var(--ds-muted, #f1f5f9);\n transition: border-color 0.15s, background-color 0.15s;\n text-align: center;\n}\n\n.zone:hover,\n.dragging {\n border-color: var(--ds-primary, #3b82f6);\n background-color: var(--ds-primary-50, #eff6ff);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.icon {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.hint {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n\n.fileName {\n font-size: 0.875rem;\n color: var(--ds-primary, #3b82f6);\n font-weight: 500;\n}\n",".wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.input::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.input:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n/* --- Error --- */\n.error .input {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error .input:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n\n/* --- Success --- */\n.success .input {\n border-color: var(--ds-success, #22c55e);\n}\n\n.success .input:focus {\n border-color: var(--ds-success, #22c55e);\n box-shadow: 0 0 0 3px rgb(34 197 94 / 0.15);\n}\n\n/* --- Icons --- */\n.hasLeft .input { padding-left: 2.25rem; }\n.hasRight .input { padding-right: 2.25rem; }\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n color: var(--ds-text-secondary, #64748b);\n pointer-events: none;\n}\n\n.leftIcon { left: 0.625rem; }\n.rightIcon { right: 0.625rem; }\n","import React, { FC, InputHTMLAttributes, ReactNode } from 'react'\nimport styles from './Input.module.css'\n\ninterface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n error?: boolean\n success?: boolean\n leftIcon?: ReactNode\n rightIcon?: ReactNode\n}\n\nconst Input: FC<InputProps> = ({\n error,\n success,\n leftIcon,\n rightIcon,\n className,\n ...props\n}) => {\n const wrapperClasses = [\n styles.wrapper,\n error ? styles.error : '',\n success ? styles.success : '',\n leftIcon ? styles.hasLeft : '',\n rightIcon ? styles.hasRight : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return (\n <div className={wrapperClasses}>\n {leftIcon && <span className={styles.leftIcon}>{leftIcon}</span>}\n <input className={styles.input} {...props} />\n {rightIcon && <span className={styles.rightIcon}>{rightIcon}</span>}\n </div>\n )\n}\n\nexport default Input\n\n/*\n * Input\n *\n * Renders a text input with optional left/right icons and error or success border states.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * success (boolean, optional) — applies a success border style\n * leftIcon (ReactNode, optional) — icon displayed inside the left side of the input\n * rightIcon (ReactNode, optional) — icon displayed inside the right side of the input\n * className (string, optional) — extra CSS class names applied to the wrapper div\n * ...rest — any valid HTML input attribute (placeholder, value, onChange, disabled, etc.)\n *\n * Usage:\n * <Input placeholder=\"Search...\" onChange={handleChange} />\n *\n * // With a left icon and error state:\n * <Input leftIcon={<SearchIcon />} error placeholder=\"Not found\" />\n *\n * // Controlled with a success state:\n * <Input value={email} onChange={e => setEmail(e.target.value)} success />\n */\n",".label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--ds-text-primary, #0f172a);\n margin-bottom: 0.375rem;\n}\n\n.required {\n color: var(--ds-danger, #ef4444);\n margin-left: 0.25rem;\n}\n","import React, { FC, LabelHTMLAttributes } from 'react'\nimport styles from './Label.module.css'\n\ninterface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n required?: boolean\n}\n\nconst Label: FC<LabelProps> = ({ children, required, className, ...props }) => {\n return (\n <label className={`${styles.label} ${className ?? ''}`} {...props}>\n {children}\n {required && <span className={styles.required}>*</span>}\n </label>\n )\n}\n\nexport default Label\n\n/*\n * Label\n *\n * Renders a styled form label, optionally appending a red asterisk when the field is required.\n *\n * Props:\n * required (boolean, optional) — appends a \"*\" marker after the label text\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML label attribute (htmlFor, etc.)\n *\n * Usage:\n * <Label htmlFor=\"email\">Email</Label>\n *\n * // Required field:\n * <Label htmlFor=\"name\" required>Full name</Label>\n */\n","'use client'\n\nimport { Eye, EyeOff } from 'lucide-react'\nimport React, { FC, InputHTMLAttributes, useState } from 'react'\nimport Input from '../Input/Input'\n\ntype PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>\n\nconst PasswordInput: FC<PasswordInputProps> = (props) => {\n const [visible, setVisible] = useState(false)\n\n return (\n <Input\n {...props}\n type={visible ? 'text' : 'password'}\n rightIcon={\n <button\n type=\"button\"\n onClick={() => setVisible(v => !v)}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', pointerEvents: 'all' }}\n tabIndex={-1}\n >\n {visible ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n }\n />\n )\n}\n\nexport default PasswordInput\n\n/*\n * PasswordInput\n *\n * Renders a password input with an eye/eye-off toggle button that shows or hides the typed text.\n *\n * Props:\n * ...rest — any valid HTML input attribute except \"type\" (e.g. placeholder, value, onChange, disabled)\n * also accepts Input's error and success props for border states\n *\n * Usage:\n * <PasswordInput placeholder=\"Enter password\" onChange={e => setPassword(e.target.value)} />\n *\n * // With error state:\n * <PasswordInput value={password} onChange={handleChange} error />\n */\n",".track {\n width: 100%;\n height: 0.5rem;\n background-color: var(--ds-border, #e2e8f0);\n border-radius: 9999px;\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n background-color: var(--ds-primary, #3b82f6);\n border-radius: 9999px;\n transition: width 0.3s ease;\n}\n","import React, { FC } from 'react'\nimport styles from './Progress.module.css'\n\ninterface ProgressProps {\n value?: number\n}\n\nconst Progress: FC<ProgressProps> = ({ value = 0 }) => {\n const pct = Math.min(100, Math.max(0, value))\n return (\n <div\n className={styles.track}\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n )\n}\n\nexport default Progress\n\n/*\n * Progress\n *\n * Displays a horizontal progress bar that fills from left to right based on a 0–100 value.\n *\n * Props:\n * value (number, optional) — current progress percentage (0–100); clamped to that range; defaults to 0\n *\n * Usage:\n * <Progress value={60} />\n *\n * // Dynamic upload progress:\n * <Progress value={uploadPercent} />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './RadioGroup.module.css'\n\ninterface RadioOption {\n value: string\n label: string\n}\n\ninterface RadioGroupProps {\n options: RadioOption[]\n name: string\n value?: string\n defaultValue?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst RadioGroup: FC<RadioGroupProps> = ({\n options,\n name,\n value,\n defaultValue = '',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const selected = value !== undefined ? value : internal\n\n const handleChange = (val: string) => {\n if (disabled) return\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={styles.group}>\n {options.map((option) => (\n <label\n key={option.value}\n className={`${styles.item} ${disabled ? styles.disabled : ''}`}\n >\n <input\n type=\"radio\"\n name={name}\n value={option.value}\n checked={selected === option.value}\n disabled={disabled}\n onChange={() => handleChange(option.value)}\n className={styles.input}\n />\n <span className={`${styles.dot} ${selected === option.value ? styles.checked : ''}`}>\n {selected === option.value && <span className={styles.inner} />}\n </span>\n <span className={styles.label}>{option.label}</span>\n </label>\n ))}\n </div>\n )\n}\n\nexport default RadioGroup\n\n/*\n * RadioGroup\n *\n * Renders a group of radio buttons from an array of options, supporting both controlled and uncontrolled use.\n *\n * Props:\n * options (RadioOption[], required) — array of { value: string, label: string } items to render\n * name (string, required) — shared name attribute for the radio inputs (required for HTML form grouping)\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * disabled (boolean, optional) — disables all options\n * onChange ((value: string) => void, optional) — called with the selected option's value on change\n *\n * Usage:\n * <RadioGroup\n * name=\"size\"\n * options={[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]}\n * onChange={val => setSize(val)}\n * />\n *\n * // Controlled:\n * <RadioGroup name=\"plan\" options={planOptions} value={plan} onChange={setPlan} />\n */\n",".group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.item {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.dot {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n border: 2px solid var(--ds-border, #e2e8f0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background-color: var(--ds-card, #fff);\n transition: border-color 0.15s;\n}\n\n.checked {\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.inner {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, ChevronDown } from 'lucide-react'\nimport React, { FC, useEffect, useRef, useState } from 'react'\nimport styles from './Select.module.css'\n\ninterface SelectOption {\n value: string\n label: string\n}\n\ninterface SelectProps {\n options: SelectOption[]\n value?: string\n defaultValue?: string\n placeholder?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst Select: FC<SelectProps> = ({\n options,\n value,\n defaultValue = '',\n placeholder = 'Choose an option',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n\n const selected = value !== undefined ? value : internal\n const selectedLabel = options.find(o => o.value === selected)?.label\n\n const handleSelect = (val: string) => {\n setInternal(val)\n setOpen(false)\n onChange?.(val)\n }\n\n useEffect(() => {\n const handleOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handleOutside)\n return () => document.removeEventListener('mousedown', handleOutside)\n }, [])\n\n return (\n <div ref={ref} className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <button\n type=\"button\"\n className={`${styles.trigger} ${open ? styles.open : ''}`}\n onClick={() => !disabled && setOpen(o => !o)}\n disabled={disabled}\n >\n <span className={selectedLabel ? styles.value : styles.placeholder}>\n {selectedLabel ?? placeholder}\n </span>\n <ChevronDown size={16} className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`} />\n </button>\n {open && (\n <div className={styles.dropdown}>\n {options.map((option) => (\n <div\n key={option.value}\n className={`${styles.option} ${selected === option.value ? styles.selected : ''}`}\n onClick={() => handleSelect(option.value)}\n >\n {selected === option.value\n ? <Check size={14} className={styles.checkIcon} />\n : <span className={styles.checkSpacer} />\n }\n {option.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default Select\n\n/*\n * Select\n *\n * Renders a custom dropdown that lets the user pick one option from a list, supporting controlled and uncontrolled use.\n *\n * Props:\n * options (SelectOption[], required) — array of { value: string, label: string } items to display\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * placeholder (string, optional) — text shown when nothing is selected; defaults to \"Choose an option\"\n * disabled (boolean, optional) — prevents opening the dropdown\n * onChange ((value: string) => void, optional) — called with the selected value when the user picks an option\n *\n * Usage:\n * <Select\n * options={[{ value: 'fr', label: 'French' }, { value: 'en', label: 'English' }]}\n * onChange={val => setLanguage(val)}\n * />\n *\n * // Controlled with placeholder:\n * <Select options={countryOptions} value={country} placeholder=\"Pick a country\" onChange={setCountry} />\n */\n",".wrapper {\n position: relative;\n width: 100%;\n}\n\n.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.trigger {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n transition: border-color 0.15s, box-shadow 0.15s;\n text-align: left;\n font-family: inherit;\n}\n\n.trigger:focus {\n outline: none;\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.open {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.placeholder { color: var(--ds-text-secondary, #64748b); }\n.value { color: var(--ds-text-primary, #0f172a); }\n\n.chevron {\n flex-shrink: 0;\n color: var(--ds-text-secondary, #64748b);\n transition: transform 0.15s;\n}\n\n.chevronOpen {\n transform: rotate(180deg);\n}\n\n.dropdown {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n right: 0;\n z-index: 50;\n background-color: var(--ds-card, #fff);\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);\n overflow: hidden;\n}\n\n.option {\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--ds-text-primary, #0f172a);\n transition: background-color 0.1s;\n}\n\n.option:hover { background-color: var(--ds-muted, #f1f5f9); }\n.selected { background-color: var(--ds-muted, #f1f5f9); font-weight: 500; }\n\n.checkIcon { color: var(--ds-primary, #3b82f6); flex-shrink: 0; }\n.checkSpacer { width: 14px; flex-shrink: 0; }\n",".skeleton {\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.375rem;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.circle {\n border-radius: 9999px;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n","import React, { FC } from 'react'\nimport styles from './Skeleton.module.css'\n\ninterface SkeletonProps {\n height?: string\n width?: string\n circle?: boolean\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ height = '1rem', width = '100%', circle = false }) => (\n <div\n className={`${styles.skeleton} ${circle ? styles.circle : ''}`}\n style={{ height, width }}\n aria-hidden=\"true\"\n />\n)\n\nexport default Skeleton\n\n/*\n * Skeleton\n *\n * Renders an animated placeholder block used to indicate loading content before data arrives.\n *\n * Props:\n * height (string, optional) — CSS height of the block; defaults to \"1rem\"\n * width (string, optional) — CSS width of the block; defaults to \"100%\"\n * circle (boolean, optional) — makes the block fully round (equal height and width) for avatar placeholders\n *\n * Usage:\n * <Skeleton width=\"200px\" height=\"1rem\" />\n *\n * // Avatar placeholder:\n * <Skeleton circle width=\"40px\" height=\"40px\" />\n *\n * // Full-width paragraph lines:\n * <Skeleton height=\"1rem\" />\n * <Skeleton height=\"1rem\" width=\"80%\" />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Slider.module.css'\n\ninterface SliderProps {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n onChange?: (value: number) => void\n}\n\nconst Slider: FC<SliderProps> = ({\n value,\n defaultValue = 50,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const current = value !== undefined ? value : internal\n const fill = `${((current - min) / (max - min)) * 100}%`\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = Number(e.target.value)\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={current}\n disabled={disabled}\n onChange={handleChange}\n className={styles.range}\n style={{ '--fill': fill } as React.CSSProperties}\n />\n </div>\n )\n}\n\nexport default Slider\n\n/*\n * Slider\n *\n * Renders a range slider with a filled track that reflects the current value, supporting controlled and uncontrolled use.\n *\n * Props:\n * value (number, optional) — controlled current value\n * defaultValue (number, optional) — initial value for uncontrolled use; defaults to 50\n * min (number, optional) — minimum value; defaults to 0\n * max (number, optional) — maximum value; defaults to 100\n * step (number, optional) — increment between values; defaults to 1\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * onChange ((value: number) => void, optional) — called with the new numeric value on each change\n *\n * Usage:\n * <Slider onChange={val => setVolume(val)} />\n *\n * // Controlled with custom range and step:\n * <Slider value={opacity} min={0} max={1} step={0.01} onChange={setOpacity} />\n */\n",".wrapper {\n width: 100%;\n padding: 0.25rem 0;\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.range {\n width: 100%;\n height: 0.375rem;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 9999px;\n outline: none;\n cursor: pointer;\n background: linear-gradient(\n to right,\n var(--ds-primary, #3b82f6) 0%,\n var(--ds-primary, #3b82f6) var(--fill, 50%),\n var(--ds-border, #e2e8f0) var(--fill, 50%),\n var(--ds-border, #e2e8f0) 100%\n );\n}\n\n.range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n transition: transform 0.1s;\n}\n\n.range::-webkit-slider-thumb:hover {\n transform: scale(1.2);\n}\n\n.range::-moz-range-thumb {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n}\n\n.disabled .range {\n cursor: not-allowed;\n}\n","import React, { FC } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport styles from './Spinner.module.css'\n\ntype SpinnerSize = 'sm' | 'md' | 'lg'\n\ninterface SpinnerProps {\n size?: SpinnerSize\n}\n\nconst sizePx: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\nconst Spinner: FC<SpinnerProps> = ({ size = 'md' }) => (\n <Loader2 size={sizePx[size]} className={styles.spinner} aria-label=\"Loading\" />\n)\n\nexport default Spinner\n\n/*\n * Spinner\n *\n * Displays an animated loading indicator at one of three sizes.\n *\n * Props:\n * size (\"sm\" | \"md\" | \"lg\", optional) — icon size: sm = 16px, md = 24px, lg = 32px; defaults to \"md\"\n *\n * Usage:\n * <Spinner />\n *\n * // Large spinner while page loads:\n * {isLoading && <Spinner size=\"lg\" />}\n */\n",".spinner {\n color: var(--ds-primary, #3b82f6);\n animation: spin 0.75s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Switch.module.css'\n\ninterface SwitchProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Switch: FC<SwitchProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isOn = checked !== undefined ? checked : internal\n\n const handleToggle = () => {\n if (disabled) return\n const next = !isOn\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isOn}\n disabled={disabled}\n onChange={handleToggle}\n className={styles.input}\n />\n <span className={`${styles.track} ${isOn ? styles.on : ''}`}>\n <span className={`${styles.thumb} ${isOn ? styles.thumbOn : ''}`} />\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Switch\n\n/*\n * Switch\n *\n * Renders a toggle switch that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the switch\n * checked (boolean, optional) — controlled on/off state\n * defaultChecked (boolean, optional) — initial state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each toggle\n *\n * Usage:\n * <Switch label=\"Enable notifications\" onChange={val => setEnabled(val)} />\n *\n * // Controlled:\n * <Switch checked={darkMode} onChange={setDarkMode} label=\"Dark mode\" />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.track {\n width: 2.75rem;\n height: 1.5rem;\n border-radius: 9999px;\n background-color: var(--ds-border, #e2e8f0);\n position: relative;\n transition: background-color 0.2s;\n flex-shrink: 0;\n}\n\n.on {\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.thumb {\n position: absolute;\n top: 0.175rem;\n left: 0.175rem;\n width: 1.15rem;\n height: 1.15rem;\n border-radius: 9999px;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.15);\n transition: transform 0.2s;\n}\n\n.thumbOn {\n transform: translateX(1.25rem);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n",".wrapper {\n width: 100%;\n overflow-x: auto;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n}\n\n.th {\n padding: 0.75rem 1rem;\n text-align: left;\n font-weight: 500;\n color: var(--ds-text-secondary, #64748b);\n background-color: var(--ds-muted, #f1f5f9);\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n white-space: nowrap;\n}\n\n.td {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.row:last-child .td {\n border-bottom: none;\n}\n\n.row:hover .td {\n background-color: var(--ds-muted, #f1f5f9);\n}\n\nthead .row:hover .th {\n background-color: var(--ds-muted, #f1f5f9);\n}\n","import React, { FC, HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react'\nimport styles from './Table.module.css'\n\nexport const Table: FC<HTMLAttributes<HTMLTableElement>> = ({ className, ...props }) => (\n <div className={styles.wrapper}>\n <table className={`${styles.table}${className ? ` ${className}` : ''}`} {...props} />\n </div>\n)\n\nexport const TableHead: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <thead {...props} />\n)\n\nexport const TableBody: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <tbody {...props} />\n)\n\nexport const TableRow: FC<HTMLAttributes<HTMLTableRowElement>> = ({ className, ...props }) => (\n <tr className={`${styles.row}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableHeader: FC<ThHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <th className={`${styles.th}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableCell: FC<TdHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <td className={`${styles.td}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Table / TableHead / TableBody / TableRow / TableHeader / TableCell\n *\n * A set of composable table components that wrap standard HTML table elements with consistent styles.\n *\n * Table — outer wrapper with a scrollable container and a styled <table>\n * TableHead — maps to <thead>\n * TableBody — maps to <tbody>\n * TableRow — styled <tr>\n * TableHeader — styled <th> for column headings\n * TableCell — styled <td> for data cells\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML attribute for the underlying element\n *\n * Usage:\n * <Table>\n * <TableHead>\n * <TableRow>\n * <TableHeader>Name</TableHeader>\n * <TableHeader>Status</TableHeader>\n * </TableRow>\n * </TableHead>\n * <TableBody>\n * <TableRow>\n * <TableCell>Visit 001</TableCell>\n * <TableCell>Completed</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n */\n","'use client'\n\nimport React, { FC, ReactNode, useState } from 'react'\nimport styles from './Tabs.module.css'\n\nexport interface TabItem {\n value: string\n label: string\n content: ReactNode\n icon?: ReactNode\n}\n\ninterface TabsProps {\n tabs: TabItem[]\n defaultValue?: string\n}\n\nconst Tabs: FC<TabsProps> = ({ tabs, defaultValue }) => {\n const [active, setActive] = useState(defaultValue ?? tabs[0]?.value ?? '')\n const activeTab = tabs.find(t => t.value === active)\n\n return (\n <div className={styles.root}>\n <div className={styles.list} role=\"tablist\">\n {tabs.map(tab => (\n <button\n key={tab.value}\n role=\"tab\"\n aria-selected={active === tab.value}\n className={`${styles.trigger} ${active === tab.value ? styles.active : ''}`}\n onClick={() => setActive(tab.value)}\n >\n {tab.icon && <span className={styles['trigger-icon']}>{tab.icon}</span>}\n {tab.label}\n </button>\n ))}\n </div>\n <div className={styles.content} role=\"tabpanel\">\n {activeTab?.content}\n </div>\n </div>\n )\n}\n\nexport default Tabs\n\n/*\n * Tabs\n *\n * Renders a tab bar and displays the content panel of the currently active tab.\n *\n * Props:\n * tabs (TabItem[], required) — array of tab definitions, each with:\n * value (string) — unique identifier for the tab\n * label (string) — text shown on the tab button\n * content (ReactNode) — panel content shown when this tab is active\n * icon (ReactNode, optional) — icon shown before the label in the tab button\n * defaultValue (string, optional) — value of the tab that is active on first render; defaults to the first tab\n *\n * Usage:\n * <Tabs\n * tabs={[\n * { value: 'overview', label: 'Overview', content: <Overview /> },\n * { value: 'settings', label: 'Settings', content: <Settings /> },\n * ]}\n * />\n *\n * // Start on a specific tab:\n * <Tabs tabs={tabs} defaultValue=\"settings\" />\n */\n",".root {\n display: flex;\n flex-direction: column;\n}\n\n.list {\n display: inline-flex;\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.5rem;\n padding: 0.25rem;\n gap: 0.125rem;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 0.375rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ds-text-secondary, #64748b);\n transition: color 0.15s, background-color 0.15s, box-shadow 0.15s;\n white-space: nowrap;\n}\n\n.trigger:hover {\n color: var(--ds-text-primary, #0f172a);\n}\n\n.active {\n background-color: var(--ds-card, #ffffff);\n color: var(--ds-text-primary, #0f172a);\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n}\n\n.trigger-icon {\n display: flex;\n align-items: center;\n}\n\n.content {\n padding-top: 1rem;\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n",".textarea {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n resize: vertical;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n min-height: 6rem;\n}\n\n.textarea::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.textarea:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n.error {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n","import React, { FC, TextareaHTMLAttributes } from 'react'\nimport styles from './Textarea.module.css'\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n error?: boolean\n}\n\nconst Textarea: FC<TextareaProps> = ({ error, className, ...props }) => {\n const classes = [\n styles.textarea,\n error ? styles.error : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return <textarea className={classes} {...props} />\n}\n\nexport default Textarea\n\n/*\n * Textarea\n *\n * Renders a styled multi-line text area with an optional error border state.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML textarea attribute (placeholder, value, onChange, rows, disabled, etc.)\n *\n * Usage:\n * <Textarea placeholder=\"Write your message...\" rows={4} onChange={handleChange} />\n *\n * // With error state:\n * <Textarea error value={notes} onChange={e => setNotes(e.target.value)} />\n */\n",".wrapper {\n position: relative;\n display: inline-flex;\n}\n\n.tooltip {\n position: absolute;\n z-index: 50;\n padding: 0.375rem 0.625rem;\n background-color: var(--ds-tooltip-bg, #0f172a);\n color: var(--ds-tooltip-text, #ffffff);\n font-size: 0.75rem;\n line-height: 1.4;\n border-radius: 0.375rem;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.wrapper:hover .tooltip,\n.wrapper:focus-within .tooltip {\n opacity: 1;\n}\n\n.tooltip::before {\n content: '';\n position: absolute;\n border: 5px solid transparent;\n}\n\n/* Top */\n.top {\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.top::before {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Bottom */\n.bottom {\n top: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.bottom::before {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-bottom-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Left */\n.left {\n right: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.left::before {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Right */\n.right {\n left: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.right::before {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--ds-tooltip-bg, #0f172a);\n}\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Tooltip.module.css'\n\ninterface TooltipProps {\n content: string\n children: ReactNode\n position?: 'top' | 'bottom' | 'left' | 'right'\n}\n\nconst Tooltip: FC<TooltipProps> = ({ content, children, position = 'top' }) => (\n <span className={styles.wrapper}>\n {children}\n <span className={`${styles.tooltip} ${styles[position]}`} role=\"tooltip\">\n {content}\n </span>\n </span>\n)\n\nexport default Tooltip\n\n/*\n * Tooltip\n *\n * Wraps any element and shows a text tooltip on hover in the given direction.\n *\n * Props:\n * content (string, required) — the text shown inside the tooltip\n * children (ReactNode, required) — the element the tooltip is attached to\n * position (\"top\" | \"bottom\" | \"left\" | \"right\", optional) — which side the tooltip appears on; defaults to \"top\"\n *\n * Usage:\n * <Tooltip content=\"Delete this item\">\n * <button>Delete</button>\n * </Tooltip>\n *\n * // Positioned to the right:\n * <Tooltip content=\"More info\" position=\"right\">\n * <InfoIcon />\n * </Tooltip>\n */\n"],"mappings":"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","names":["useState","jsx","jsx","jsxs","Alert_default","jsx","Avatar_default","jsx","Badge_default","jsx","jsxs","Breadcrumb_default","useState","jsx","jsxs","useState","jsx","useState","jsx","jsxs","useState","Checkbox_default","useState","jsx","useState","CopyButton_default","useState","jsx","jsxs","useState","FileUpload_default","jsx","jsxs","Input_default","jsx","jsxs","Label_default","useState","jsx","useState","Input_default","jsx","Progress_default","useState","jsx","jsxs","useState","RadioGroup_default","Check","ChevronDown","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","ChevronDown","Check","Select_default","jsx","Skeleton_default","useState","jsx","useState","Slider_default","jsx","Spinner_default","useState","jsx","jsxs","useState","Switch_default","jsx","useState","jsx","jsxs","useState","Tabs_default","jsx","Textarea_default","jsx","jsxs","Tooltip_default"]}
1
+ {"version":3,"sources":["../src/components/ThemeProvider.tsx","../src/components/Accordion/Accordion.tsx","../src/components/Alert/Alert.tsx","../src/components/Alert/Alert.module.css","../src/components/Avatar/Avatar.module.css","../src/components/Avatar/Avatar.tsx","../src/components/Badge/Badge.module.css","../src/components/Badge/Badge.tsx","../src/components/Breadcrumb/Breadcrumb.tsx","../src/components/Breadcrumb/Breadcrumb.module.css","../src/components/Button/Button.tsx","../src/components/Card/Card.module.css","../src/components/Card/Card.tsx","../src/components/Checkbox/Checkbox.tsx","../src/components/Checkbox/Checkbox.module.css","../src/components/CopyButton/CopyButton.tsx","../src/components/CopyButton/CopyButton.module.css","../src/components/FileUpload/FileUpload.tsx","../src/components/FileUpload/FileUpload.module.css","../src/components/Input/Input.module.css","../src/components/Input/Input.tsx","../src/components/Label/Label.module.css","../src/components/Label/Label.tsx","../src/components/PasswordInput/PasswordInput.tsx","../src/components/Progress/Progress.module.css","../src/components/Progress/Progress.tsx","../src/components/RadioGroup/RadioGroup.tsx","../src/components/RadioGroup/RadioGroup.module.css","../src/components/Select/Select.tsx","../src/components/Select/Select.module.css","../src/components/Skeleton/Skeleton.module.css","../src/components/Skeleton/Skeleton.tsx","../src/components/Slider/Slider.tsx","../src/components/Slider/Slider.module.css","../src/components/Spinner/Spinner.tsx","../src/components/Spinner/Spinner.module.css","../src/components/Switch/Switch.tsx","../src/components/Switch/Switch.module.css","../src/components/Table/Table.module.css","../src/components/Table/Table.tsx","../src/components/Tabs/Tabs.tsx","../src/components/Tabs/Tabs.module.css","../src/components/Textarea/Textarea.module.css","../src/components/Textarea/Textarea.tsx","../src/components/Tooltip/Tooltip.module.css","../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\nimport React, { createContext, useContext, useState } from 'react'\nimport '../styles/globals.css'\n\ntype Theme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n toggle: () => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: {\n children: React.ReactNode\n defaultTheme?: Theme\n}) => {\n const [theme, setTheme] = useState<Theme>(defaultTheme)\n return (\n <ThemeContext.Provider value={{ theme, toggle: () => setTheme(t => t === 'light' ? 'dark' : 'light') }}>\n <div className={theme === 'dark' ? 'ds-theme-dark' : undefined}>\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n\nexport const useTheme = () => {\n const ctx = useContext(ThemeContext)\n if (!ctx) throw new Error('useTheme must be used inside <ThemeProvider>')\n return ctx\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport { ChevronDown } from 'lucide-react'\n\nexport interface AccordionItem {\n value: string\n trigger: string\n content: string\n}\n\ninterface AccordionProps {\n items: AccordionItem[]\n defaultValue?: string | string[]\n multiple?: boolean\n}\n\nconst Accordion: FC<AccordionProps> = ({ items, defaultValue, multiple = false }) => {\n const [open, setOpen] = useState<Set<string>>(() => {\n if (!defaultValue) return new Set()\n if (Array.isArray(defaultValue)) return new Set(defaultValue)\n return new Set([defaultValue])\n })\n const [hovered, setHovered] = useState<string | null>(null)\n\n const toggle = (value: string) => {\n setOpen(prev => {\n const next = new Set(prev)\n if (next.has(value)) {\n next.delete(value)\n } else {\n if (!multiple) next.clear()\n next.add(value)\n }\n return next\n })\n }\n\n return (\n <div style={{\n border: '1px solid var(--ds-border, #e2e8f0)',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n }}>\n {items.map((item, index) => {\n const isOpen = open.has(item.value)\n const isHovered = hovered === item.value\n const isLast = index === items.length - 1\n return (\n <div\n key={item.value}\n style={{\n borderBottom: isLast ? 'none' : '1px solid var(--ds-border, #e2e8f0)',\n }}\n >\n <button\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '1rem',\n fontSize: '0.875rem',\n fontWeight: 500,\n background: isHovered ? 'var(--ds-muted, #f1f5f9)' : 'transparent',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'var(--ds-text-primary, #0f172a)',\n transition: 'background-color 0.15s',\n }}\n onClick={() => toggle(item.value)}\n onMouseEnter={() => setHovered(item.value)}\n onMouseLeave={() => setHovered(null)}\n aria-expanded={isOpen}\n >\n <span>{item.trigger}</span>\n <ChevronDown\n size={16}\n style={{\n flexShrink: 0,\n color: 'var(--ds-text-secondary, #64748b)',\n transition: 'transform 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n <div style={{\n maxHeight: isOpen ? '300px' : '0',\n overflow: 'hidden',\n transition: 'max-height 0.25s ease',\n }}>\n <div style={{\n padding: '0 1rem 1rem',\n fontSize: '0.875rem',\n color: 'var(--ds-text-secondary, #64748b)',\n }}>\n {item.content}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\nexport default Accordion\n\n/*\n * Accordion\n *\n * Renders a list of collapsible sections; by default only one section can be open at a time.\n *\n * Props:\n * items (AccordionItem[], required) — array of sections, each with:\n * value (string) — unique identifier\n * trigger (string) — heading text shown on the clickable row\n * content (string) — body text revealed when the section is open\n * defaultValue (string | string[], optional) — value(s) of sections that start open\n * multiple (boolean, optional) — when true, more than one section can be open simultaneously; defaults to false\n *\n * Usage:\n * <Accordion\n * items={[\n * { value: 'q1', trigger: 'What is eFiche?', content: 'eFiche is a medical records platform.' },\n * { value: 'q2', trigger: 'How do I log in?', content: 'Use your credentials at the login page.' },\n * ]}\n * />\n *\n * // Multiple sections open, first one pre-opened:\n * <Accordion items={faqItems} multiple defaultValue=\"q1\" />\n */\n","import React, { FC, ReactNode } from 'react'\nimport { Info, CheckCircle2, AlertTriangle, AlertCircle } from 'lucide-react'\nimport styles from './Alert.module.css'\n\ntype AlertVariant = 'info' | 'success' | 'warning' | 'danger'\n\ninterface AlertProps {\n variant?: AlertVariant\n title: string\n description: string\n}\n\nconst icons: Record<AlertVariant, ReactNode> = {\n info: <Info size={16} />,\n success: <CheckCircle2 size={16} />,\n warning: <AlertTriangle size={16} />,\n danger: <AlertCircle size={16} />,\n}\n\nconst Alert: FC<AlertProps> = ({ variant = 'info', title, description }) => (\n <div className={`${styles.alert} ${styles[variant]}`} role=\"alert\">\n <span className={styles.icon}>{icons[variant]}</span>\n <div className={styles.content}>\n <p className={styles.title}>{title}</p>\n <p className={styles.description}>{description}</p>\n </div>\n </div>\n)\n\nexport default Alert\n\n/*\n * Alert\n *\n * Displays an inline alert banner with an icon, a bold title, and a description line.\n *\n * Props:\n * title (string, required) — short heading for the alert\n * description (string, required) — supporting detail shown below the title\n * variant (\"info\" | \"success\" | \"warning\" | \"danger\", optional) — color and icon style; defaults to \"info\"\n *\n * Usage:\n * <Alert title=\"Saved\" description=\"Your changes have been saved.\" variant=\"success\" />\n *\n * // Warning:\n * <Alert title=\"Low storage\" description=\"You are using 90% of your quota.\" variant=\"warning\" />\n *\n * // Danger:\n * <Alert title=\"Error\" description=\"Something went wrong. Please try again.\" variant=\"danger\" />\n */\n",".alert {\n display: flex;\n gap: 0.75rem;\n padding: 1rem;\n border-radius: 0.5rem;\n border-left: 4px solid;\n}\n\n.icon {\n flex-shrink: 0;\n margin-top: 0.125rem;\n}\n\n.content {\n flex: 1;\n}\n\n.title {\n font-weight: 600;\n font-size: 0.875rem;\n margin-bottom: 0.25rem;\n margin-top: 0;\n}\n\n.description {\n font-size: 0.875rem;\n margin: 0;\n}\n\n/* Info */\n.info {\n background-color: var(--ds-info-bg, #eff6ff);\n border-left-color: var(--ds-info, #3b82f6);\n}\n.info .icon { color: var(--ds-info, #3b82f6); }\n.info .title { color: var(--ds-info-title, #1e3a8a); }\n.info .description { color: var(--ds-info-desc, #1e40af); }\n\n/* Success */\n.success {\n background-color: var(--ds-success-bg, #f0fdf4);\n border-left-color: var(--ds-success, #22c55e);\n}\n.success .icon { color: var(--ds-success, #22c55e); }\n.success .title { color: var(--ds-success-title, #14532d); }\n.success .description { color: var(--ds-success-desc, #166534); }\n\n/* Warning */\n.warning {\n background-color: var(--ds-warning-bg, #fffbeb);\n border-left-color: var(--ds-warning, #f59e0b);\n}\n.warning .icon { color: var(--ds-warning, #f59e0b); }\n.warning .title { color: var(--ds-warning-title, #78350f); }\n.warning .description { color: var(--ds-warning-desc, #92400e); }\n\n/* Danger */\n.danger {\n background-color: var(--ds-danger-bg, #fef2f2);\n border-left-color: var(--ds-danger, #ef4444);\n}\n.danger .icon { color: var(--ds-danger, #ef4444); }\n.danger .title { color: var(--ds-danger-title, #7f1d1d); }\n.danger .description { color: var(--ds-danger-desc, #991b1b); }\n",".avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n font-weight: 600;\n flex-shrink: 0;\n user-select: none;\n}\n\n.sm { width: 2rem; height: 2rem; font-size: 0.625rem; }\n.md { width: 2.5rem; height: 2.5rem; font-size: 0.875rem; }\n.lg { width: 4rem; height: 4rem; font-size: 1.25rem; }\n","import React, { FC } from 'react'\nimport styles from './Avatar.module.css'\n\ntype AvatarSize = 'sm' | 'md' | 'lg'\n\ninterface AvatarProps {\n fallback: string\n size?: AvatarSize\n style?: React.CSSProperties\n className?: string\n}\n\nconst Avatar: FC<AvatarProps> = ({ fallback, size = 'md', style, className }) => (\n <div\n className={`${styles.avatar} ${styles[size]}${className ? ` ${className}` : ''}`}\n style={style}\n aria-label={fallback}\n >\n {fallback}\n </div>\n)\n\nexport default Avatar\n\n/*\n * Avatar\n *\n * Renders a circular (or rounded) container showing initials or a short text fallback.\n *\n * Props:\n * fallback (string, required) — text displayed inside the avatar, typically initials (e.g. \"AB\")\n * size (\"sm\" | \"md\" | \"lg\", optional) — controls the diameter of the circle; defaults to \"md\"\n * style (React.CSSProperties, optional) — inline styles for custom background color, etc.\n * className (string, optional) — extra CSS class names\n *\n * Usage:\n * <Avatar fallback=\"JD\" />\n *\n * // Large avatar with a custom background:\n * <Avatar fallback=\"MB\" size=\"lg\" style={{ background: '#6366f1' }} />\n */\n",".badge {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n border-radius: 9999px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n/* Sizes */\n.sm { padding: 0.125rem 0.5rem; font-size: 0.625rem; }\n.md { padding: 0.25rem 0.625rem; font-size: 0.75rem; }\n.lg { padding: 0.375rem 0.875rem; font-size: 0.875rem; }\n\n/* Variants */\n.default { background-color: var(--ds-primary, #3b82f6); color: #fff; }\n.secondary { background-color: var(--ds-muted, #f1f5f9); color: var(--ds-text-secondary, #64748b); }\n.outline { background-color: transparent; border: 1px solid var(--ds-border, #e2e8f0); color: var(--ds-text-primary, #0f172a); }\n.danger { background-color: var(--ds-danger, #ef4444); color: #fff; }\n.success { background-color: var(--ds-success, #22c55e); color: #fff; }\n.warning { background-color: var(--ds-warning, #f59e0b); color: #fff; }\n.info { background-color: var(--ds-info, #3b82f6); color: #fff; }\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Badge.module.css'\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'danger' | 'success' | 'warning' | 'info'\ntype BadgeSize = 'sm' | 'md' | 'lg'\n\ninterface BadgeProps {\n variant?: BadgeVariant\n size?: BadgeSize\n children: ReactNode\n style?: React.CSSProperties\n}\n\nconst Badge: FC<BadgeProps> = ({ variant = 'default', size = 'md', children, style }) => (\n <span className={`${styles.badge} ${styles[variant]} ${styles[size]}`} style={style}>\n {children}\n </span>\n)\n\nexport default Badge\n\n/*\n * Badge\n *\n * Renders a small inline label used to highlight status, categories, or counts.\n *\n * Props:\n * variant (\"default\" | \"secondary\" | \"outline\" | \"danger\" | \"success\" | \"warning\" | \"info\", optional) — color style; defaults to \"default\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — text and padding size; defaults to \"md\"\n * children (ReactNode, required) — the content shown inside the badge\n * style (React.CSSProperties, optional) — inline styles applied to the badge element\n *\n * Usage:\n * <Badge>New</Badge>\n *\n * // Status badges:\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"danger\" size=\"sm\">Overdue</Badge>\n */\n","import React, { FC } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport styles from './Breadcrumb.module.css'\n\nexport interface BreadcrumbItem {\n label: string\n href?: string\n}\n\ninterface BreadcrumbProps {\n items: BreadcrumbItem[]\n}\n\nconst Breadcrumb: FC<BreadcrumbProps> = ({ items }) => (\n <nav aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n return (\n <li key={item.label} className={styles.item}>\n {i > 0 && <ChevronRight size={14} className={styles.separator} aria-hidden />}\n {isLast || !item.href ? (\n <span className={`${styles.link} ${isLast ? styles.current : ''}`}>\n {item.label}\n </span>\n ) : (\n <a href={item.href} className={styles.link}>\n {item.label}\n </a>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n)\n\nexport default Breadcrumb\n\n/*\n * Breadcrumb\n *\n * Renders a navigation breadcrumb trail with chevron separators; the last item is plain text, earlier items are links when an href is provided.\n *\n * Props:\n * items (BreadcrumbItem[], required) — ordered array of crumbs, each with:\n * label (string) — display text\n * href (string, optional) — link target; if omitted the crumb renders as plain text\n *\n * Usage:\n * <Breadcrumb\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Patients', href: '/patients' },\n * { label: 'Visit summary' },\n * ]}\n * />\n */\n",".list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 0.875rem;\n}\n\n.item {\n display: flex;\n align-items: center;\n}\n\n.separator {\n color: var(--ds-text-secondary, #64748b);\n margin: 0 0.25rem;\n flex-shrink: 0;\n}\n\n.link {\n color: var(--ds-text-secondary, #64748b);\n text-decoration: none;\n transition: color 0.15s;\n}\n\n.link:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: underline;\n}\n\n.current {\n color: var(--ds-text-primary, #0f172a);\n font-weight: 500;\n cursor: default;\n}\n\n.current:hover {\n color: var(--ds-text-primary, #0f172a);\n text-decoration: none;\n}\n","'use client'\n\nimport { LoaderCircle } from \"lucide-react\";\nimport React, { FC, ButtonHTMLAttributes, ReactNode, useState } from \"react\";\n\ntype ButtonVariant = \"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\";\ntype ButtonSize = \"sm\" | \"md\" | \"lg\";\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n text?: string;\n loading?: boolean;\n icon?: ReactNode;\n iconPosition?: \"left\" | \"right\";\n // variant shorthand booleans\n outline?: boolean;\n ghost?: boolean;\n danger?: boolean;\n warning?: boolean;\n info?: boolean;\n success?: boolean;\n variant?: ButtonVariant;\n // size shorthand booleans\n small?: boolean;\n large?: boolean;\n size?: ButtonSize;\n}\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { backgroundColor: 'var(--ds-primary, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n outline: { backgroundColor: 'transparent', color: 'var(--ds-primary, #3b82f6)', borderColor: 'var(--ds-primary, #3b82f6)' },\n ghost: { backgroundColor: 'var(--ds-muted, #f1f5f9)', color: 'var(--ds-text-primary, #0f172a)', borderColor: 'transparent' },\n danger: { backgroundColor: 'var(--ds-danger, #ef4444)', color: '#fff', borderColor: 'transparent' },\n warning: { backgroundColor: 'var(--ds-warning, #f59e0b)', color: '#fff', borderColor: 'transparent' },\n info: { backgroundColor: 'var(--ds-info, #3b82f6)', color: '#fff', borderColor: 'transparent' },\n success: { backgroundColor: 'var(--ds-success, #22c55e)', color: '#fff', borderColor: 'transparent' },\n}\n\nconst variantHoverStyles: Record<ButtonVariant, React.CSSProperties> = {\n solid: { opacity: 0.88 },\n outline: { backgroundColor: 'var(--ds-muted, #f1f5f9)' },\n ghost: { backgroundColor: 'var(--ds-card, #ffffff)' },\n danger: { opacity: 0.88 },\n warning: { opacity: 0.88 },\n info: { opacity: 0.88 },\n success: { opacity: 0.88 },\n}\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: { padding: '0.25rem 0.625rem', fontSize: '0.8rem' },\n md: { padding: '0.5rem 1rem', fontSize: '0.875rem' },\n lg: { padding: '0.75rem 1.5rem', fontSize: '1rem' },\n}\n\nconst Button: FC<ButtonProps> = ({\n text,\n children,\n loading = false,\n disabled = false,\n icon,\n iconPosition = \"left\",\n outline = false,\n ghost = false,\n danger = false,\n warning = false,\n info = false,\n success = false,\n variant,\n small = false,\n large = false,\n size,\n style: styleProp,\n ...props\n}) => {\n const [hovered, setHovered] = useState(false)\n\n const resolvedVariant: ButtonVariant =\n variant ??\n (danger ? \"danger\" :\n warning ? \"warning\" :\n info ? \"info\" :\n success ? \"success\" :\n ghost ? \"ghost\" :\n outline ? \"outline\" :\n \"solid\")\n\n const resolvedSize: ButtonSize = size ?? (small ? \"sm\" : large ? \"lg\" : \"md\")\n const isDisabled = disabled || loading\n const content = children ?? text\n const showIcon = icon && !loading\n\n const computedStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n border: '1px solid transparent',\n borderRadius: '0.375rem',\n fontWeight: 500,\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: 'opacity 0.15s, background-color 0.15s',\n opacity: isDisabled ? 0.5 : 1,\n pointerEvents: loading ? 'none' : undefined,\n ...variantStyles[resolvedVariant],\n ...sizeStyles[resolvedSize],\n ...(hovered && !isDisabled ? variantHoverStyles[resolvedVariant] : {}),\n ...styleProp,\n }\n\n return (\n <>\n {/* React 19 hoists and deduplicates this style tag automatically */}\n <style href=\"ds-spin\" precedence=\"low\">{`@keyframes ds-spin { to { transform: rotate(360deg); } }`}</style>\n <button\n disabled={isDisabled}\n style={computedStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n {...props}\n >\n {loading\n ? <LoaderCircle\n aria-hidden\n style={{ width: '1em', height: '1em', animation: 'ds-spin 0.75s linear infinite' }}\n />\n : null}\n {showIcon && iconPosition === \"left\" ? icon : null}\n {content}\n {showIcon && iconPosition === \"right\" ? icon : null}\n </button>\n </>\n )\n}\n\nexport default Button\n\n/*\n * Button\n *\n * Renders a styled button with support for variants, sizes, icons, and a loading state.\n *\n * Props:\n * text (string, optional) — button label; can use children instead\n * loading (boolean, optional) — shows a spinner and disables the button while true\n * disabled (boolean, optional) — disables the button\n * icon (ReactNode, optional) — icon to display alongside the label\n * iconPosition (\"left\" | \"right\", optional) — which side the icon appears on; defaults to \"left\"\n * variant (\"solid\" | \"outline\" | \"ghost\" | \"danger\" | \"warning\" | \"info\" | \"success\", optional) — visual style; defaults to \"solid\"\n * outline (boolean, optional) — shorthand for variant=\"outline\"\n * ghost (boolean, optional) — shorthand for variant=\"ghost\"\n * danger (boolean, optional) — shorthand for variant=\"danger\"\n * warning (boolean, optional) — shorthand for variant=\"warning\"\n * info (boolean, optional) — shorthand for variant=\"info\"\n * success (boolean, optional) — shorthand for variant=\"success\"\n * size (\"sm\" | \"md\" | \"lg\", optional) — button size; defaults to \"md\"\n * small (boolean, optional) — shorthand for size=\"sm\"\n * large (boolean, optional) — shorthand for size=\"lg\"\n * ...rest — any valid HTML button attribute (onClick, type, etc.)\n *\n * Usage:\n * <Button text=\"Save\" onClick={handleSave} />\n *\n * // Danger variant with loading state:\n * <Button danger loading={isDeleting} text=\"Delete\" />\n *\n * // Icon on the right, large size:\n * <Button large icon={<ArrowRight />} iconPosition=\"right\">Continue</Button>\n */\n",".card {\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n background-color: var(--ds-card, #ffffff);\n}\n\n.header {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 1.5rem 1.5rem 0;\n}\n\n.title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ds-text-primary, #0f172a);\n margin: 0;\n line-height: 1.4;\n}\n\n.description {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n margin: 0;\n}\n\n.content {\n padding: 1.5rem;\n}\n\n.footer {\n display: flex;\n align-items: center;\n padding: 0 1.5rem 1.5rem;\n}\n","import React, { FC, HTMLAttributes } from 'react'\nimport styles from './Card.module.css'\n\nexport const Card: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.card}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardHeader: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.header}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({ className, ...props }) => (\n <h3 className={`${styles.title}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardDescription: FC<HTMLAttributes<HTMLParagraphElement>> = ({ className, ...props }) => (\n <p className={`${styles.description}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.content}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const CardFooter: FC<HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={`${styles.footer}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Card / CardHeader / CardTitle / CardDescription / CardContent / CardFooter\n *\n * A set of composable container components for building card-style layouts.\n *\n * Card — outer wrapper with a bordered, rounded container\n * CardHeader — top section, typically holds CardTitle and CardDescription\n * CardTitle — heading rendered as an <h3>\n * CardDescription — muted paragraph below the title\n * CardContent — main body area of the card\n * CardFooter — bottom section, typically holds actions\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML div/h3/p attribute\n *\n * Usage:\n * <Card>\n * <CardHeader>\n * <CardTitle>Patient Summary</CardTitle>\n * <CardDescription>Last visit on 12 May 2026</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Diagnosis: Hypertension</p>\n * </CardContent>\n * <CardFooter>\n * <Button text=\"View full record\" />\n * </CardFooter>\n * </Card>\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Checkbox.module.css'\n\ninterface CheckboxProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Checkbox: FC<CheckboxProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isChecked = checked !== undefined ? checked : internal\n\n const handleChange = () => {\n if (disabled) return\n const next = !isChecked\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isChecked}\n disabled={disabled}\n onChange={handleChange}\n className={styles.input}\n />\n <span className={`${styles.box} ${isChecked ? styles.checked : ''}`}>\n {isChecked && (\n <svg viewBox=\"0 0 12 10\" fill=\"none\" className={styles.checkmark}>\n <path d=\"M1 5l3.5 3.5L11 1\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Checkbox\n\n/*\n * Checkbox\n *\n * Renders a styled checkbox that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the checkbox\n * checked (boolean, optional) — controlled checked state\n * defaultChecked (boolean, optional) — initial checked state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input, useful for pairing with a Label\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each change\n *\n * Usage:\n * <Checkbox label=\"Accept terms\" onChange={val => setAccepted(val)} />\n *\n * // Controlled:\n * <Checkbox checked={isChecked} onChange={setIsChecked} label=\"Remember me\" />\n *\n * // Disabled with a default:\n * <Checkbox label=\"Auto-renew\" defaultChecked disabled />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.box {\n width: 1.125rem;\n height: 1.125rem;\n border: 2px solid var(--ds-border, #e2e8f0);\n border-radius: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: background-color 0.15s, border-color 0.15s;\n background-color: var(--ds-card, #fff);\n}\n\n.checked {\n background-color: var(--ds-primary, #3b82f6);\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.checkmark {\n width: 0.625rem;\n height: 0.625rem;\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, Copy } from 'lucide-react'\nimport React, { FC, useState } from 'react'\nimport styles from './CopyButton.module.css'\n\ninterface CopyButtonProps {\n text: string\n}\n\nconst CopyButton: FC<CopyButtonProps> = ({ text }) => {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = () => {\n navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n className={styles.copyButton}\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : `Copy ${text}`}\n >\n {copied ? <Check className={styles.icon} /> : <Copy className={styles.icon} />}\n </button>\n )\n}\n\nexport default CopyButton\n\n/*\n * CopyButton\n *\n * Renders an icon button that copies a string to the clipboard; shows a checkmark for 2 seconds after copying.\n *\n * Props:\n * text (string, required) — the string that gets copied to the clipboard when clicked\n *\n * Usage:\n * <CopyButton text=\"npm install react lucide-react\" />\n *\n * // Next to a code snippet:\n * <div className=\"code-block\">\n * <code>{snippet}</code>\n * <CopyButton text={snippet} />\n * </div>\n */\n\n",".copyButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n border: none;\n border-radius: 0.25rem;\n background-color: transparent;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.copyButton:hover {\n background-color: var(--ds-accent, #f1f5f9);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.icon {\n width: 1rem;\n height: 1rem;\n}\n","'use client'\n\nimport { Upload } from 'lucide-react'\nimport React, { FC, useRef, useState } from 'react'\nimport styles from './FileUpload.module.css'\n\ninterface FileUploadProps {\n accept?: string\n multiple?: boolean\n disabled?: boolean\n onFileSelect?: (files: FileList) => void\n}\n\nconst FileUpload: FC<FileUploadProps> = ({ accept, multiple, disabled, onFileSelect }) => {\n const [isDragging, setIsDragging] = useState(false)\n const [fileNames, setFileNames] = useState<string[]>([])\n const inputRef = useRef<HTMLInputElement>(null)\n\n const handleFiles = (list: FileList) => {\n setFileNames(Array.from(list).map(f => f.name))\n onFileSelect?.(list)\n }\n\n return (\n <div\n className={`${styles.zone} ${isDragging ? styles.dragging : ''} ${disabled ? styles.disabled : ''}`}\n onClick={() => !disabled && inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault()\n setIsDragging(false)\n if (!disabled && e.dataTransfer.files.length) handleFiles(e.dataTransfer.files)\n }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className={styles.input}\n onChange={(e) => e.target.files && handleFiles(e.target.files)}\n />\n <Upload size={32} className={styles.icon} />\n {fileNames.length > 0\n ? <p className={styles.fileName}>{fileNames.join(', ')}</p>\n : <p className={styles.hint}><strong>Click to upload</strong> or drag and drop</p>\n }\n </div>\n )\n}\n\nexport default FileUpload\n\n/*\n * FileUpload\n *\n * Renders a click-to-browse and drag-and-drop file upload zone; displays selected file names after a pick.\n *\n * Props:\n * accept (string, optional) — file type filter passed to the hidden input (e.g. \"image/*\", \".pdf\")\n * multiple (boolean, optional) — allows selecting more than one file at a time\n * disabled (boolean, optional) — prevents clicking and dropping\n * onFileSelect ((files: FileList) => void, optional) — called with the FileList whenever files are chosen\n *\n * Usage:\n * <FileUpload onFileSelect={files => uploadFiles(files)} />\n *\n * // Images only, multiple files:\n * <FileUpload accept=\"image/*\" multiple onFileSelect={handleImages} />\n */\n",".zone {\n border: 2px dashed var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n background-color: var(--ds-muted, #f1f5f9);\n transition: border-color 0.15s, background-color 0.15s;\n text-align: center;\n}\n\n.zone:hover,\n.dragging {\n border-color: var(--ds-primary, #3b82f6);\n background-color: var(--ds-primary-50, #eff6ff);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.icon {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.hint {\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n\n.fileName {\n font-size: 0.875rem;\n color: var(--ds-primary, #3b82f6);\n font-weight: 500;\n}\n",".wrapper {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.input::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.input:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n/* --- Error --- */\n.error .input {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error .input:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n\n/* --- Success --- */\n.success .input {\n border-color: var(--ds-success, #22c55e);\n}\n\n.success .input:focus {\n border-color: var(--ds-success, #22c55e);\n box-shadow: 0 0 0 3px rgb(34 197 94 / 0.15);\n}\n\n/* --- Icons --- */\n.hasLeft .input { padding-left: 2.25rem; }\n.hasRight .input { padding-right: 2.25rem; }\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n color: var(--ds-text-secondary, #64748b);\n pointer-events: none;\n}\n\n.leftIcon { left: 0.625rem; }\n.rightIcon { right: 0.625rem; }\n","import React, { FC, InputHTMLAttributes, ReactNode } from 'react'\nimport styles from './Input.module.css'\n\ninterface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n error?: boolean\n success?: boolean\n leftIcon?: ReactNode\n rightIcon?: ReactNode\n}\n\nconst Input: FC<InputProps> = ({\n error,\n success,\n leftIcon,\n rightIcon,\n className,\n ...props\n}) => {\n const wrapperClasses = [\n styles.wrapper,\n error ? styles.error : '',\n success ? styles.success : '',\n leftIcon ? styles.hasLeft : '',\n rightIcon ? styles.hasRight : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return (\n <div className={wrapperClasses}>\n {leftIcon && <span className={styles.leftIcon}>{leftIcon}</span>}\n <input className={styles.input} {...props} />\n {rightIcon && <span className={styles.rightIcon}>{rightIcon}</span>}\n </div>\n )\n}\n\nexport default Input\n\n/*\n * Input\n *\n * Renders a text input with optional left/right icons and error or success border states.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * success (boolean, optional) — applies a success border style\n * leftIcon (ReactNode, optional) — icon displayed inside the left side of the input\n * rightIcon (ReactNode, optional) — icon displayed inside the right side of the input\n * className (string, optional) — extra CSS class names applied to the wrapper div\n * ...rest — any valid HTML input attribute (placeholder, value, onChange, disabled, etc.)\n *\n * Usage:\n * <Input placeholder=\"Search...\" onChange={handleChange} />\n *\n * // With a left icon and error state:\n * <Input leftIcon={<SearchIcon />} error placeholder=\"Not found\" />\n *\n * // Controlled with a success state:\n * <Input value={email} onChange={e => setEmail(e.target.value)} success />\n */\n",".label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--ds-text-primary, #0f172a);\n margin-bottom: 0.375rem;\n}\n\n.required {\n color: var(--ds-danger, #ef4444);\n margin-left: 0.25rem;\n}\n","import React, { FC, LabelHTMLAttributes } from 'react'\nimport styles from './Label.module.css'\n\ninterface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n required?: boolean\n}\n\nconst Label: FC<LabelProps> = ({ children, required, className, ...props }) => {\n return (\n <label className={`${styles.label} ${className ?? ''}`} {...props}>\n {children}\n {required && <span className={styles.required}>*</span>}\n </label>\n )\n}\n\nexport default Label\n\n/*\n * Label\n *\n * Renders a styled form label, optionally appending a red asterisk when the field is required.\n *\n * Props:\n * required (boolean, optional) — appends a \"*\" marker after the label text\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML label attribute (htmlFor, etc.)\n *\n * Usage:\n * <Label htmlFor=\"email\">Email</Label>\n *\n * // Required field:\n * <Label htmlFor=\"name\" required>Full name</Label>\n */\n","'use client'\n\nimport { Eye, EyeOff } from 'lucide-react'\nimport React, { FC, InputHTMLAttributes, useState } from 'react'\nimport Input from '../Input/Input'\n\ntype PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>\n\nconst PasswordInput: FC<PasswordInputProps> = (props) => {\n const [visible, setVisible] = useState(false)\n\n return (\n <Input\n {...props}\n type={visible ? 'text' : 'password'}\n rightIcon={\n <button\n type=\"button\"\n onClick={() => setVisible(v => !v)}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'flex', pointerEvents: 'all' }}\n tabIndex={-1}\n >\n {visible ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n }\n />\n )\n}\n\nexport default PasswordInput\n\n/*\n * PasswordInput\n *\n * Renders a password input with an eye/eye-off toggle button that shows or hides the typed text.\n *\n * Props:\n * ...rest — any valid HTML input attribute except \"type\" (e.g. placeholder, value, onChange, disabled)\n * also accepts Input's error and success props for border states\n *\n * Usage:\n * <PasswordInput placeholder=\"Enter password\" onChange={e => setPassword(e.target.value)} />\n *\n * // With error state:\n * <PasswordInput value={password} onChange={handleChange} error />\n */\n",".track {\n width: 100%;\n height: 0.5rem;\n background-color: var(--ds-border, #e2e8f0);\n border-radius: 9999px;\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n background-color: var(--ds-primary, #3b82f6);\n border-radius: 9999px;\n transition: width 0.3s ease;\n}\n","import React, { FC } from 'react'\nimport styles from './Progress.module.css'\n\ninterface ProgressProps {\n value?: number\n}\n\nconst Progress: FC<ProgressProps> = ({ value = 0 }) => {\n const pct = Math.min(100, Math.max(0, value))\n return (\n <div\n className={styles.track}\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n )\n}\n\nexport default Progress\n\n/*\n * Progress\n *\n * Displays a horizontal progress bar that fills from left to right based on a 0–100 value.\n *\n * Props:\n * value (number, optional) — current progress percentage (0–100); clamped to that range; defaults to 0\n *\n * Usage:\n * <Progress value={60} />\n *\n * // Dynamic upload progress:\n * <Progress value={uploadPercent} />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './RadioGroup.module.css'\n\ninterface RadioOption {\n value: string\n label: string\n}\n\ninterface RadioGroupProps {\n options: RadioOption[]\n name: string\n value?: string\n defaultValue?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst RadioGroup: FC<RadioGroupProps> = ({\n options,\n name,\n value,\n defaultValue = '',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const selected = value !== undefined ? value : internal\n\n const handleChange = (val: string) => {\n if (disabled) return\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={styles.group}>\n {options.map((option) => (\n <label\n key={option.value}\n className={`${styles.item} ${disabled ? styles.disabled : ''}`}\n >\n <input\n type=\"radio\"\n name={name}\n value={option.value}\n checked={selected === option.value}\n disabled={disabled}\n onChange={() => handleChange(option.value)}\n className={styles.input}\n />\n <span className={`${styles.dot} ${selected === option.value ? styles.checked : ''}`}>\n {selected === option.value && <span className={styles.inner} />}\n </span>\n <span className={styles.label}>{option.label}</span>\n </label>\n ))}\n </div>\n )\n}\n\nexport default RadioGroup\n\n/*\n * RadioGroup\n *\n * Renders a group of radio buttons from an array of options, supporting both controlled and uncontrolled use.\n *\n * Props:\n * options (RadioOption[], required) — array of { value: string, label: string } items to render\n * name (string, required) — shared name attribute for the radio inputs (required for HTML form grouping)\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * disabled (boolean, optional) — disables all options\n * onChange ((value: string) => void, optional) — called with the selected option's value on change\n *\n * Usage:\n * <RadioGroup\n * name=\"size\"\n * options={[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]}\n * onChange={val => setSize(val)}\n * />\n *\n * // Controlled:\n * <RadioGroup name=\"plan\" options={planOptions} value={plan} onChange={setPlan} />\n */\n",".group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.item {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.dot {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n border: 2px solid var(--ds-border, #e2e8f0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background-color: var(--ds-card, #fff);\n transition: border-color 0.15s;\n}\n\n.checked {\n border-color: var(--ds-primary, #3b82f6);\n}\n\n.inner {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n","'use client'\n\nimport { Check, ChevronDown } from 'lucide-react'\nimport React, { FC, useEffect, useRef, useState } from 'react'\nimport styles from './Select.module.css'\n\ninterface SelectOption {\n value: string\n label: string\n}\n\ninterface SelectProps {\n options: SelectOption[]\n value?: string\n defaultValue?: string\n placeholder?: string\n disabled?: boolean\n onChange?: (value: string) => void\n}\n\nconst Select: FC<SelectProps> = ({\n options,\n value,\n defaultValue = '',\n placeholder = 'Choose an option',\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n\n const selected = value !== undefined ? value : internal\n const selectedLabel = options.find(o => o.value === selected)?.label\n\n const handleSelect = (val: string) => {\n setInternal(val)\n setOpen(false)\n onChange?.(val)\n }\n\n useEffect(() => {\n const handleOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handleOutside)\n return () => document.removeEventListener('mousedown', handleOutside)\n }, [])\n\n return (\n <div ref={ref} className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <button\n type=\"button\"\n className={`${styles.trigger} ${open ? styles.open : ''}`}\n onClick={() => !disabled && setOpen(o => !o)}\n disabled={disabled}\n >\n <span className={selectedLabel ? styles.value : styles.placeholder}>\n {selectedLabel ?? placeholder}\n </span>\n <ChevronDown size={16} className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`} />\n </button>\n {open && (\n <div className={styles.dropdown}>\n {options.map((option) => (\n <div\n key={option.value}\n className={`${styles.option} ${selected === option.value ? styles.selected : ''}`}\n onClick={() => handleSelect(option.value)}\n >\n {selected === option.value\n ? <Check size={14} className={styles.checkIcon} />\n : <span className={styles.checkSpacer} />\n }\n {option.label}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default Select\n\n/*\n * Select\n *\n * Renders a custom dropdown that lets the user pick one option from a list, supporting controlled and uncontrolled use.\n *\n * Props:\n * options (SelectOption[], required) — array of { value: string, label: string } items to display\n * value (string, optional) — controlled selected value\n * defaultValue (string, optional) — initial selected value for uncontrolled use; defaults to \"\"\n * placeholder (string, optional) — text shown when nothing is selected; defaults to \"Choose an option\"\n * disabled (boolean, optional) — prevents opening the dropdown\n * onChange ((value: string) => void, optional) — called with the selected value when the user picks an option\n *\n * Usage:\n * <Select\n * options={[{ value: 'fr', label: 'French' }, { value: 'en', label: 'English' }]}\n * onChange={val => setLanguage(val)}\n * />\n *\n * // Controlled with placeholder:\n * <Select options={countryOptions} value={country} placeholder=\"Pick a country\" onChange={setCountry} />\n */\n",".wrapper {\n position: relative;\n width: 100%;\n}\n\n.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.trigger {\n width: 100%;\n height: 2.25rem;\n padding: 0 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n transition: border-color 0.15s, box-shadow 0.15s;\n text-align: left;\n font-family: inherit;\n}\n\n.trigger:focus {\n outline: none;\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.open {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.placeholder { color: var(--ds-text-secondary, #64748b); }\n.value { color: var(--ds-text-primary, #0f172a); }\n\n.chevron {\n flex-shrink: 0;\n color: var(--ds-text-secondary, #64748b);\n transition: transform 0.15s;\n}\n\n.chevronOpen {\n transform: rotate(180deg);\n}\n\n.dropdown {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n right: 0;\n z-index: 50;\n background-color: var(--ds-card, #fff);\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);\n overflow: hidden;\n}\n\n.option {\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--ds-text-primary, #0f172a);\n transition: background-color 0.1s;\n}\n\n.option:hover { background-color: var(--ds-muted, #f1f5f9); }\n.selected { background-color: var(--ds-muted, #f1f5f9); font-weight: 500; }\n\n.checkIcon { color: var(--ds-primary, #3b82f6); flex-shrink: 0; }\n.checkSpacer { width: 14px; flex-shrink: 0; }\n",".skeleton {\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.375rem;\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.circle {\n border-radius: 9999px;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n","import React, { FC } from 'react'\nimport styles from './Skeleton.module.css'\n\ninterface SkeletonProps {\n height?: string\n width?: string\n circle?: boolean\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ height = '1rem', width = '100%', circle = false }) => (\n <div\n className={`${styles.skeleton} ${circle ? styles.circle : ''}`}\n style={{ height, width }}\n aria-hidden=\"true\"\n />\n)\n\nexport default Skeleton\n\n/*\n * Skeleton\n *\n * Renders an animated placeholder block used to indicate loading content before data arrives.\n *\n * Props:\n * height (string, optional) — CSS height of the block; defaults to \"1rem\"\n * width (string, optional) — CSS width of the block; defaults to \"100%\"\n * circle (boolean, optional) — makes the block fully round (equal height and width) for avatar placeholders\n *\n * Usage:\n * <Skeleton width=\"200px\" height=\"1rem\" />\n *\n * // Avatar placeholder:\n * <Skeleton circle width=\"40px\" height=\"40px\" />\n *\n * // Full-width paragraph lines:\n * <Skeleton height=\"1rem\" />\n * <Skeleton height=\"1rem\" width=\"80%\" />\n */\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Slider.module.css'\n\ninterface SliderProps {\n value?: number\n defaultValue?: number\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n onChange?: (value: number) => void\n}\n\nconst Slider: FC<SliderProps> = ({\n value,\n defaultValue = 50,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultValue)\n const current = value !== undefined ? value : internal\n const fill = `${((current - min) / (max - min)) * 100}%`\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = Number(e.target.value)\n setInternal(val)\n onChange?.(val)\n }\n\n return (\n <div className={`${styles.wrapper} ${disabled ? styles.disabled : ''}`}>\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={current}\n disabled={disabled}\n onChange={handleChange}\n className={styles.range}\n style={{ '--fill': fill } as React.CSSProperties}\n />\n </div>\n )\n}\n\nexport default Slider\n\n/*\n * Slider\n *\n * Renders a range slider with a filled track that reflects the current value, supporting controlled and uncontrolled use.\n *\n * Props:\n * value (number, optional) — controlled current value\n * defaultValue (number, optional) — initial value for uncontrolled use; defaults to 50\n * min (number, optional) — minimum value; defaults to 0\n * max (number, optional) — maximum value; defaults to 100\n * step (number, optional) — increment between values; defaults to 1\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * onChange ((value: number) => void, optional) — called with the new numeric value on each change\n *\n * Usage:\n * <Slider onChange={val => setVolume(val)} />\n *\n * // Controlled with custom range and step:\n * <Slider value={opacity} min={0} max={1} step={0.01} onChange={setOpacity} />\n */\n",".wrapper {\n width: 100%;\n padding: 0.25rem 0;\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.range {\n width: 100%;\n height: 0.375rem;\n -webkit-appearance: none;\n appearance: none;\n border-radius: 9999px;\n outline: none;\n cursor: pointer;\n background: linear-gradient(\n to right,\n var(--ds-primary, #3b82f6) 0%,\n var(--ds-primary, #3b82f6) var(--fill, 50%),\n var(--ds-border, #e2e8f0) var(--fill, 50%),\n var(--ds-border, #e2e8f0) 100%\n );\n}\n\n.range::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n transition: transform 0.1s;\n}\n\n.range::-webkit-slider-thumb:hover {\n transform: scale(1.2);\n}\n\n.range::-moz-range-thumb {\n width: 1.125rem;\n height: 1.125rem;\n border-radius: 9999px;\n background-color: var(--ds-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.2);\n}\n\n.disabled .range {\n cursor: not-allowed;\n}\n","import React, { FC } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport styles from './Spinner.module.css'\n\ntype SpinnerSize = 'sm' | 'md' | 'lg'\n\ninterface SpinnerProps {\n size?: SpinnerSize\n}\n\nconst sizePx: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\nconst Spinner: FC<SpinnerProps> = ({ size = 'md' }) => (\n <Loader2 size={sizePx[size]} className={styles.spinner} aria-label=\"Loading\" />\n)\n\nexport default Spinner\n\n/*\n * Spinner\n *\n * Displays an animated loading indicator at one of three sizes.\n *\n * Props:\n * size (\"sm\" | \"md\" | \"lg\", optional) — icon size: sm = 16px, md = 24px, lg = 32px; defaults to \"md\"\n *\n * Usage:\n * <Spinner />\n *\n * // Large spinner while page loads:\n * {isLoading && <Spinner size=\"lg\" />}\n */\n",".spinner {\n color: var(--ds-primary, #3b82f6);\n animation: spin 0.75s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n","'use client'\n\nimport React, { FC, useState } from 'react'\nimport styles from './Switch.module.css'\n\ninterface SwitchProps {\n label?: string\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n id?: string\n onChange?: (checked: boolean) => void\n}\n\nconst Switch: FC<SwitchProps> = ({\n label,\n checked,\n defaultChecked = false,\n disabled,\n id,\n onChange,\n}) => {\n const [internal, setInternal] = useState(defaultChecked)\n const isOn = checked !== undefined ? checked : internal\n\n const handleToggle = () => {\n if (disabled) return\n const next = !isOn\n setInternal(next)\n onChange?.(next)\n }\n\n return (\n <label className={`${styles.container} ${disabled ? styles.disabled : ''}`} htmlFor={id}>\n <input\n type=\"checkbox\"\n id={id}\n checked={isOn}\n disabled={disabled}\n onChange={handleToggle}\n className={styles.input}\n />\n <span className={`${styles.track} ${isOn ? styles.on : ''}`}>\n <span className={`${styles.thumb} ${isOn ? styles.thumbOn : ''}`} />\n </span>\n {label && <span className={styles.label}>{label}</span>}\n </label>\n )\n}\n\nexport default Switch\n\n/*\n * Switch\n *\n * Renders a toggle switch that can be used as controlled or uncontrolled, with an optional text label.\n *\n * Props:\n * label (string, optional) — text displayed next to the switch\n * checked (boolean, optional) — controlled on/off state\n * defaultChecked (boolean, optional) — initial state for uncontrolled use; defaults to false\n * disabled (boolean, optional) — prevents interaction and applies a disabled style\n * id (string, optional) — HTML id for the underlying input\n * onChange ((checked: boolean) => void, optional) — called with the new boolean value on each toggle\n *\n * Usage:\n * <Switch label=\"Enable notifications\" onChange={val => setEnabled(val)} />\n *\n * // Controlled:\n * <Switch checked={darkMode} onChange={setDarkMode} label=\"Dark mode\" />\n */\n",".container {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n cursor: pointer;\n user-select: none;\n}\n\n.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.track {\n width: 2.75rem;\n height: 1.5rem;\n border-radius: 9999px;\n background-color: var(--ds-border, #e2e8f0);\n position: relative;\n transition: background-color 0.2s;\n flex-shrink: 0;\n}\n\n.on {\n background-color: var(--ds-primary, #3b82f6);\n}\n\n.thumb {\n position: absolute;\n top: 0.175rem;\n left: 0.175rem;\n width: 1.15rem;\n height: 1.15rem;\n border-radius: 9999px;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.15);\n transition: transform 0.2s;\n}\n\n.thumbOn {\n transform: translateX(1.25rem);\n}\n\n.label {\n font-size: 0.875rem;\n color: var(--ds-text-primary, #0f172a);\n}\n",".wrapper {\n width: 100%;\n overflow-x: auto;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.5rem;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n}\n\n.th {\n padding: 0.75rem 1rem;\n text-align: left;\n font-weight: 500;\n color: var(--ds-text-secondary, #64748b);\n background-color: var(--ds-muted, #f1f5f9);\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n white-space: nowrap;\n}\n\n.td {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--ds-border, #e2e8f0);\n color: var(--ds-text-primary, #0f172a);\n}\n\n.row:last-child .td {\n border-bottom: none;\n}\n\n.row:hover .td {\n background-color: var(--ds-muted, #f1f5f9);\n}\n\nthead .row:hover .th {\n background-color: var(--ds-muted, #f1f5f9);\n}\n","import React, { FC, HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react'\nimport styles from './Table.module.css'\n\nexport const Table: FC<HTMLAttributes<HTMLTableElement>> = ({ className, ...props }) => (\n <div className={styles.wrapper}>\n <table className={`${styles.table}${className ? ` ${className}` : ''}`} {...props} />\n </div>\n)\n\nexport const TableHead: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <thead {...props} />\n)\n\nexport const TableBody: FC<HTMLAttributes<HTMLTableSectionElement>> = (props) => (\n <tbody {...props} />\n)\n\nexport const TableRow: FC<HTMLAttributes<HTMLTableRowElement>> = ({ className, ...props }) => (\n <tr className={`${styles.row}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableHeader: FC<ThHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <th className={`${styles.th}${className ? ` ${className}` : ''}`} {...props} />\n)\n\nexport const TableCell: FC<TdHTMLAttributes<HTMLTableCellElement>> = ({ className, ...props }) => (\n <td className={`${styles.td}${className ? ` ${className}` : ''}`} {...props} />\n)\n\n/*\n * Table / TableHead / TableBody / TableRow / TableHeader / TableCell\n *\n * A set of composable table components that wrap standard HTML table elements with consistent styles.\n *\n * Table — outer wrapper with a scrollable container and a styled <table>\n * TableHead — maps to <thead>\n * TableBody — maps to <tbody>\n * TableRow — styled <tr>\n * TableHeader — styled <th> for column headings\n * TableCell — styled <td> for data cells\n *\n * All sub-components accept:\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML attribute for the underlying element\n *\n * Usage:\n * <Table>\n * <TableHead>\n * <TableRow>\n * <TableHeader>Name</TableHeader>\n * <TableHeader>Status</TableHeader>\n * </TableRow>\n * </TableHead>\n * <TableBody>\n * <TableRow>\n * <TableCell>Visit 001</TableCell>\n * <TableCell>Completed</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n */\n","'use client'\n\nimport React, { FC, ReactNode, useState } from 'react'\nimport styles from './Tabs.module.css'\n\nexport interface TabItem {\n value: string\n label: string\n content: ReactNode\n icon?: ReactNode\n}\n\ninterface TabsProps {\n tabs: TabItem[]\n defaultValue?: string\n}\n\nconst Tabs: FC<TabsProps> = ({ tabs, defaultValue }) => {\n const [active, setActive] = useState(defaultValue ?? tabs[0]?.value ?? '')\n const activeTab = tabs.find(t => t.value === active)\n\n return (\n <div className={styles.root}>\n <div className={styles.list} role=\"tablist\">\n {tabs.map(tab => (\n <button\n key={tab.value}\n role=\"tab\"\n aria-selected={active === tab.value}\n className={`${styles.trigger} ${active === tab.value ? styles.active : ''}`}\n onClick={() => setActive(tab.value)}\n >\n {tab.icon && <span className={styles['trigger-icon']}>{tab.icon}</span>}\n {tab.label}\n </button>\n ))}\n </div>\n <div className={styles.content} role=\"tabpanel\">\n {activeTab?.content}\n </div>\n </div>\n )\n}\n\nexport default Tabs\n\n/*\n * Tabs\n *\n * Renders a tab bar and displays the content panel of the currently active tab.\n *\n * Props:\n * tabs (TabItem[], required) — array of tab definitions, each with:\n * value (string) — unique identifier for the tab\n * label (string) — text shown on the tab button\n * content (ReactNode) — panel content shown when this tab is active\n * icon (ReactNode, optional) — icon shown before the label in the tab button\n * defaultValue (string, optional) — value of the tab that is active on first render; defaults to the first tab\n *\n * Usage:\n * <Tabs\n * tabs={[\n * { value: 'overview', label: 'Overview', content: <Overview /> },\n * { value: 'settings', label: 'Settings', content: <Settings /> },\n * ]}\n * />\n *\n * // Start on a specific tab:\n * <Tabs tabs={tabs} defaultValue=\"settings\" />\n */\n",".root {\n display: flex;\n flex-direction: column;\n}\n\n.list {\n display: inline-flex;\n background-color: var(--ds-muted, #f1f5f9);\n border-radius: 0.5rem;\n padding: 0.25rem;\n gap: 0.125rem;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 0.375rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ds-text-secondary, #64748b);\n transition: color 0.15s, background-color 0.15s, box-shadow 0.15s;\n white-space: nowrap;\n}\n\n.trigger:hover {\n color: var(--ds-text-primary, #0f172a);\n}\n\n.active {\n background-color: var(--ds-card, #ffffff);\n color: var(--ds-text-primary, #0f172a);\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n}\n\n.trigger-icon {\n display: flex;\n align-items: center;\n}\n\n.content {\n padding-top: 1rem;\n font-size: 0.875rem;\n color: var(--ds-text-secondary, #64748b);\n}\n",".textarea {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--ds-border, #e2e8f0);\n border-radius: 0.375rem;\n font-size: 0.875rem;\n background-color: var(--ds-card, #fff);\n color: var(--ds-text-primary, #0f172a);\n outline: none;\n resize: vertical;\n transition: border-color 0.15s, box-shadow 0.15s;\n font-family: inherit;\n min-height: 6rem;\n}\n\n.textarea::placeholder {\n color: var(--ds-text-secondary, #64748b);\n}\n\n.textarea:focus {\n border-color: var(--ds-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgb(59 130 246 / 0.15);\n}\n\n.textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--ds-muted, #f1f5f9);\n}\n\n.error {\n border-color: var(--ds-danger, #ef4444);\n}\n\n.error:focus {\n border-color: var(--ds-danger, #ef4444);\n box-shadow: 0 0 0 3px rgb(239 68 68 / 0.15);\n}\n","import React, { FC, TextareaHTMLAttributes } from 'react'\nimport styles from './Textarea.module.css'\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n error?: boolean\n}\n\nconst Textarea: FC<TextareaProps> = ({ error, className, ...props }) => {\n const classes = [\n styles.textarea,\n error ? styles.error : '',\n className ?? '',\n ].filter(Boolean).join(' ')\n\n return <textarea className={classes} {...props} />\n}\n\nexport default Textarea\n\n/*\n * Textarea\n *\n * Renders a styled multi-line text area with an optional error border state.\n *\n * Props:\n * error (boolean, optional) — applies an error border style\n * className (string, optional) — extra CSS class names\n * ...rest — any valid HTML textarea attribute (placeholder, value, onChange, rows, disabled, etc.)\n *\n * Usage:\n * <Textarea placeholder=\"Write your message...\" rows={4} onChange={handleChange} />\n *\n * // With error state:\n * <Textarea error value={notes} onChange={e => setNotes(e.target.value)} />\n */\n",".wrapper {\n position: relative;\n display: inline-flex;\n}\n\n.tooltip {\n position: absolute;\n z-index: 50;\n padding: 0.375rem 0.625rem;\n background-color: var(--ds-tooltip-bg, #0f172a);\n color: var(--ds-tooltip-text, #ffffff);\n font-size: 0.75rem;\n line-height: 1.4;\n border-radius: 0.375rem;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.wrapper:hover .tooltip,\n.wrapper:focus-within .tooltip {\n opacity: 1;\n}\n\n.tooltip::before {\n content: '';\n position: absolute;\n border: 5px solid transparent;\n}\n\n/* Top */\n.top {\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.top::before {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-top-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Bottom */\n.bottom {\n top: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n}\n.bottom::before {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-bottom-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Left */\n.left {\n right: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.left::before {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-left-color: var(--ds-tooltip-bg, #0f172a);\n}\n\n/* Right */\n.right {\n left: calc(100% + 8px);\n top: 50%;\n transform: translateY(-50%);\n}\n.right::before {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-right-color: var(--ds-tooltip-bg, #0f172a);\n}\n","import React, { FC, ReactNode } from 'react'\nimport styles from './Tooltip.module.css'\n\ninterface TooltipProps {\n content: string\n children: ReactNode\n position?: 'top' | 'bottom' | 'left' | 'right'\n}\n\nconst Tooltip: FC<TooltipProps> = ({ content, children, position = 'top' }) => (\n <span className={styles.wrapper}>\n {children}\n <span className={`${styles.tooltip} ${styles[position]}`} role=\"tooltip\">\n {content}\n </span>\n </span>\n)\n\nexport default Tooltip\n\n/*\n * Tooltip\n *\n * Wraps any element and shows a text tooltip on hover in the given direction.\n *\n * Props:\n * content (string, required) — the text shown inside the tooltip\n * children (ReactNode, required) — the element the tooltip is attached to\n * position (\"top\" | \"bottom\" | \"left\" | \"right\", optional) — which side the tooltip appears on; defaults to \"top\"\n *\n * Usage:\n * <Tooltip content=\"Delete this item\">\n * <button>Delete</button>\n * </Tooltip>\n *\n * // Positioned to the right:\n * <Tooltip content=\"More info\" position=\"right\">\n * <InfoIcon />\n * </Tooltip>\n */\n"],"mappings":"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","names":["useState","jsx","jsx","jsxs","Alert_default","jsx","Avatar_default","jsx","Badge_default","jsx","jsxs","Breadcrumb_default","useState","jsx","jsxs","useState","jsx","useState","jsx","jsxs","useState","Checkbox_default","useState","jsx","useState","CopyButton_default","useState","jsx","jsxs","useState","FileUpload_default","jsx","jsxs","Input_default","jsx","jsxs","Label_default","useState","jsx","useState","Input_default","jsx","Progress_default","useState","jsx","jsxs","useState","RadioGroup_default","Check","ChevronDown","useRef","useState","jsx","jsxs","useState","useRef","ChevronDown","Check","Select_default","jsx","Skeleton_default","useState","jsx","useState","Slider_default","jsx","Spinner_default","useState","jsx","jsxs","useState","Switch_default","jsx","useState","jsx","jsxs","useState","Tabs_default","jsx","Textarea_default","jsx","jsxs","Tooltip_default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@efiche/design",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "eFiche UI component library — pre-styled, accessible React components",
5
5
  "license": "MIT",
6
6
  "private": false,