@yuva-devlab/ui 1.4.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +117 -33
  2. package/dist/components/accordion/accordion.mdx +18 -0
  3. package/dist/components/alert/alert.css +2 -2
  4. package/dist/components/alert-dialog/alert-dialog.mdx +18 -0
  5. package/dist/components/aspect-ratio/aspect-ratio.mdx +22 -0
  6. package/dist/components/breadcrumb/breadcrumb.mdx +18 -0
  7. package/dist/components/calendar/calendar-nav.css +111 -0
  8. package/dist/components/calendar/calendar.css +27 -82
  9. package/dist/components/calendar/calendar.mdx +18 -0
  10. package/dist/components/card/card.css +4 -4
  11. package/dist/components/carousel/carousel.css +4 -4
  12. package/dist/components/carousel/carousel.mdx +18 -0
  13. package/dist/components/chart/chart.css +86 -0
  14. package/dist/components/chart/chart.mdx +18 -0
  15. package/dist/components/checkbox/checkbox.css +11 -0
  16. package/dist/components/collapsible/collapsible.mdx +18 -0
  17. package/dist/components/command/command.css +3 -3
  18. package/dist/components/command/command.mdx +18 -0
  19. package/dist/components/confirm-dialog/confirm-dialog.mdx +18 -0
  20. package/dist/components/context-menu/context-menu.mdx +18 -0
  21. package/dist/components/copy-button/copy-button.mdx +18 -0
  22. package/dist/components/date-picker/date-picker.css +2 -2
  23. package/dist/components/date-picker/date-picker.mdx +18 -0
  24. package/dist/components/dialog/dialog.css +6 -6
  25. package/dist/components/drawer/drawer.mdx +18 -0
  26. package/dist/components/dropdown-menu/dropdown-menu.css +18 -0
  27. package/dist/components/dropdown-menu/dropdown-menu.mdx +18 -0
  28. package/dist/components/empty-state/empty-state.css +67 -0
  29. package/dist/components/empty-state/empty-state.mdx +18 -0
  30. package/dist/components/form/form.mdx +18 -0
  31. package/dist/components/hover-card/hover-card.mdx +18 -0
  32. package/dist/components/input-otp/input-otp.mdx +18 -0
  33. package/dist/components/label/label.mdx +18 -0
  34. package/dist/components/layout/layout.css +158 -0
  35. package/dist/components/layout/layout.mdx +30 -0
  36. package/dist/components/loading-state/loading-state.css +11 -0
  37. package/dist/components/loading-state/loading-state.mdx +18 -0
  38. package/dist/components/menubar/menubar.css +4 -4
  39. package/dist/components/menubar/menubar.mdx +18 -0
  40. package/dist/components/metric-card/metric-card.mdx +18 -0
  41. package/dist/components/navigation-menu/navigation-menu.css +2 -2
  42. package/dist/components/navigation-menu/navigation-menu.mdx +18 -0
  43. package/dist/components/pagination/pagination.css +8 -2
  44. package/dist/components/pagination/pagination.mdx +18 -0
  45. package/dist/components/panel/panel.mdx +18 -0
  46. package/dist/components/popover/popover.css +2 -2
  47. package/dist/components/popover/popover.mdx +18 -0
  48. package/dist/components/radio-group/radio-group.mdx +18 -0
  49. package/dist/components/resizable/resizable.mdx +18 -0
  50. package/dist/components/scroll-area/scroll-area.mdx +18 -0
  51. package/dist/components/searchable-select/searchable-select.css +26 -3
  52. package/dist/components/searchable-select/searchable-select.mdx +18 -0
  53. package/dist/components/secret-reveal-card/secret-reveal-card.css +6 -0
  54. package/dist/components/secret-reveal-card/secret-reveal-card.mdx +18 -0
  55. package/dist/components/select/select.css +16 -1
  56. package/dist/components/separator/separator.mdx +18 -0
  57. package/dist/components/sheet/sheet.css +5 -1
  58. package/dist/components/sheet/sheet.mdx +18 -0
  59. package/dist/components/sidebar/sidebar-menu.css +183 -0
  60. package/dist/components/sidebar/sidebar-submenu.css +69 -0
  61. package/dist/components/sidebar/sidebar.css +171 -4
  62. package/dist/components/sidebar/sidebar.mdx +18 -0
  63. package/dist/components/slider/slider.mdx +18 -0
  64. package/dist/components/status-chip/status-chip.mdx +18 -0
  65. package/dist/components/table/table.css +5 -3
  66. package/dist/components/tabs/tabs.css +3 -3
  67. package/dist/components/textarea/textarea.css +3 -3
  68. package/dist/components/textarea/textarea.mdx +18 -0
  69. package/dist/components/toggle/toggle.css +9 -9
  70. package/dist/components/toggle/toggle.mdx +18 -0
  71. package/dist/components/toggle-group/toggle-group.mdx +18 -0
  72. package/dist/components/tooltip/tooltip.mdx +18 -0
  73. package/dist/components/typography/heading.mdx +36 -0
  74. package/dist/components/typography/text.mdx +34 -0
  75. package/dist/components/typography/typography.css +98 -0
  76. package/dist/components.css +1156 -164
  77. package/dist/index.cjs +1206 -958
  78. package/dist/index.cjs.map +1 -1
  79. package/dist/index.d.cts +657 -196
  80. package/dist/index.d.ts +657 -196
  81. package/dist/index.js +1174 -948
  82. package/dist/index.js.map +1 -1
  83. package/dist/preset.css +2 -4
  84. package/dist/styles/components.css +1156 -164
  85. package/dist/styles/preset.css +2 -4
  86. package/dist/styles/styles.css +7 -4
  87. package/dist/styles/utilities.css +137 -0
  88. package/dist/styles.css +7 -4
  89. package/dist/utilities.css +137 -0
  90. package/package.json +5 -6
package/README.md CHANGED
@@ -3,20 +3,33 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@yuva-devlab/ui.svg)](https://www.npmjs.com/package/@yuva-devlab/ui)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
5
  [![React 19](https://img.shields.io/badge/React-19.x-61dafb.svg)](https://react.dev)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.x%20%7C%206.x-3178c6.svg)](https://www.typescriptlang.org)
6
+ [![TypeScript 6](https://img.shields.io/badge/TypeScript-6.x-3178c6.svg)](https://www.typescriptlang.org)
7
+ [![W3C Cascade Layers](https://img.shields.io/badge/CSS-W3C%20Cascade%20Layers-22c55e.svg)](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer)
7
8
 
8
- > Production-ready, fully-typed React component library engineered for the DevLab ecosystem. Built on accessible Radix UI primitives, powered by OKLCH CSS design tokens (`@yuva-devlab/tokens`), and fully compatible with Tailwind CSS 4.
9
+ > Production-ready, fully-typed React component library engineered for the DevLab ecosystem. Built on accessible Radix UI primitives, powered by OKLCH CSS design tokens (`@yuva-devlab/tokens`), and modular W3C Cascade Layers (`@layer dl-*`).
10
+
11
+ ---
12
+
13
+ ## What's New in v2.0.0
14
+
15
+ - **Pure Platform CSS Architecture**: Completely eliminated Tailwind CSS runtime and utility dependencies from components. Component styling is strictly governed by W3C Cascade Layers (`@layer dl-base, dl-tokens, dl-components, dl-utilities`), eliminating CSS specificity conflicts and removing build-step plugin overhead.
16
+ - **First-Class Typography Primitives**: Added `<Heading>` and `<Text>` primitives with decoupled semantic HTML tags (`as="h1"`..`as="h6"`, `span`, `div`) and visual scales (`size="display" | "h1".."h6"` and `variant="body-lg" | "body" | "body-sm" | "caption" | "code" | "metric"`).
17
+ - **64+ Accessible UI Primitives**: Expanded catalog with Radix UI accessibility compliance and multi-brand responsiveness.
18
+ - **Upgraded Design Tokens Peer**: Upgraded to `@yuva-devlab/tokens@^2.0.0` with isolated brand extensions and native VS Code autocomplete.
9
19
 
10
20
  ---
11
21
 
12
22
  ## Features
13
23
 
14
24
  - 🎨 **Multi-Brand Theme Architecture** - Seamless brand isolation across OrchestrAI, VitalAI, FinAI, Logs, and Portal.
15
- - ⚡ **Zero-Runtime Overhead** - Driven by standard CSS custom properties and modern OKLCH color spaces.
25
+ - 📐 **Dynamic Theme-Driven Sizing** - Automatic adaptation across brand densities (compact telemetry logs, precision finance tables, athletic kinetic scaling).
26
+ - ⚡ **Pure Platform CSS** - Scoped W3C Cascade Layers (`@layer dl-components, dl-layout, dl-utilities`) and semantic design tokens.
27
+ - 🔤 **Typography Primitives** - First-class `<Heading>` and `<Text>` primitives with semantic decoupling.
28
+ - 📐 **Layout & Composition Primitives** - First-class `<Box>`, `<Flex>`, `<Stack>`, `<Grid>`, and `<Container>` primitives.
16
29
  - ♿ **Accessible by Default** - Built on Radix UI primitives with complete WAI-ARIA and keyboard navigation compliance.
17
- - 🧩 **56+ Core UI Components** - Buttons, Calendars, DatePickers, Drawers, Sheets, Sidebars, Menus, Modals, and more.
18
- - 🔒 **End-to-End Type Safety** - First-class TypeScript definitions with full polymorphic `asChild` composition support.
19
- - 📦 **Tree-Shakeable ESM & CJS** - Optimized builds producing clean dual artifacts.
30
+ - 🧩 **64+ Core UI & Layout Primitives** - Buttons, Calendars, DatePickers, Drawers, Sheets, Sidebars, Menus, Modals, EmptyStates, Layouts, and more.
31
+ - 🔒 **End-to-End Type Safety** - First-class TypeScript definitions with full polymorphic `asChild` and `as` composition support.
32
+ - 📦 **Tree-Shakeable ESM & CJS** - Highly optimized builds producing clean dual artifacts.
20
33
 
21
34
  ---
22
35
 
@@ -47,38 +60,56 @@ pnpm add react@^19.0.0 react-dom@^19.0.0 sonner@^2.0.0
47
60
 
48
61
  ### 1. Configure Styles
49
62
 
50
- In your application's root stylesheet (e.g. `globals.css` or `app.css`), import the token preset, desired brand theme, and component styles:
63
+ In your application's root stylesheet (e.g. `globals.css` or `app.css`), establish the W3C Cascade Layer order and import your desired tokens and styles:
51
64
 
52
65
  ```css
53
- @import "tailwindcss";
54
- @import "@yuva-devlab/tokens/preset.css";
55
- @import "@yuva-devlab/tokens/themes/orchestrai.css";
56
- @import "@yuva-devlab/ui/components.css";
66
+ /* 1. Establish W3C Cascade Layer hierarchy */
67
+ @layer dl-base, dl-tokens, dl-components, dl-layout, dl-utilities, dl-app;
68
+
69
+ /* 2. Import design tokens & brand theme */
70
+ @import "@yuva-devlab/tokens/styles.css";
71
+ @import "@yuva-devlab/tokens/themes/finai.css";
72
+
73
+ /* 3. Import UI components and layout styles */
74
+ @import "@yuva-devlab/ui/styles.css";
57
75
  ```
58
76
 
59
- > **Tip:** You can import any theme preset from `@yuva-devlab/tokens/themes/*` (`orchestrai`, `vitalai`, `finai`, `logs`, `portal`).
77
+ > **Tip:** You can import any theme preset from `@yuva-devlab/tokens/themes/*` (`finai`, `vitalai`, `logs`, `orchestrai`, `portal`).
60
78
 
61
- ### 2. Render Components
79
+ ### 2. Render Components & Typography Primitives
62
80
 
63
81
  ```tsx
64
- import { Button, Card, DatePicker, Badge } from "@yuva-devlab/ui";
82
+ import {
83
+ Heading,
84
+ Text,
85
+ Button,
86
+ Card,
87
+ Badge,
88
+ Stack,
89
+ Flex,
90
+ } from "@yuva-devlab/ui";
65
91
  import { Sparkles } from "lucide-react";
66
92
 
67
93
  export default function DashboardCard() {
68
94
  return (
69
- <Card className="p-6 max-w-md shadow-md">
70
- <div className="flex items-center justify-between mb-4">
71
- <h2 className="text-xl font-bold">DevLab Project</h2>
72
- <Badge variant="default">Production</Badge>
73
- </div>
74
-
75
- <div className="space-y-4">
76
- <DatePicker />
77
- <Button variant="primary" className="w-full">
78
- <Sparkles className="w-4 h-4 mr-2" />
79
- Deploy Pipeline
95
+ <Card>
96
+ <Stack gap={4}>
97
+ <Flex justify="between" align="center">
98
+ {/* Decoupled semantic level and visual scale */}
99
+ <Heading as="h2" size="h3">
100
+ DevLab Portfolio
101
+ </Heading>
102
+ <Badge variant="default">Active</Badge>
103
+ </Flex>
104
+
105
+ <Text variant="caption">Last updated 5m ago</Text>
106
+ <Text variant="metric">$1,248,390.50</Text>
107
+
108
+ <Button variant="primary">
109
+ <Sparkles />
110
+ Execute Transaction
80
111
  </Button>
81
- </div>
112
+ </Stack>
82
113
  </Card>
83
114
  );
84
115
  }
@@ -86,13 +117,52 @@ export default function DashboardCard() {
86
117
 
87
118
  ---
88
119
 
120
+ ## Typography Primitives
121
+
122
+ ### Heading Component
123
+
124
+ The `<Heading>` primitive decouples semantic HTML structure (`as`) from visual appearance (`size`):
125
+
126
+ ```tsx
127
+ import { Heading } from "@yuva-devlab/ui";
128
+
129
+ // Semantic H1 rendered with compact H3 visual appearance
130
+ <Heading as="h1" size="h3">Compact Header</Heading>
131
+
132
+ // Display heading for landing pages
133
+ <Heading as="h1" size="display">DevLab Cloud</Heading>
134
+ ```
135
+
136
+ | Prop | Type | Default | Description |
137
+ | :------ | :-------------------------------------------------------------------------------------- | :----------- | :------------------------------------------------------- |
138
+ | `as` | `"h1"` \| `"h2"` \| `"h3"` \| `"h4"` \| `"h5"` \| `"h6"` \| `"span"` \| `"div"` | `"h2"` | The semantic HTML element rendered to the DOM. |
139
+ | `size` | `"display"` \| `"h1"` \| `"h2"` \| `"h3"` \| `"h4"` \| `"h5"` \| `"h6"` | Matches `as` | The visual typographic scale applied via Cascade Layers. |
140
+ | `color` | `"default"` \| `"muted"` \| `"primary"` \| `"accent"` \| `"destructive"` \| `"success"` | `"default"` | Semantic text color token. |
141
+
142
+ ### Text Component
143
+
144
+ The `<Text>` primitive handles body text, captions, inline code, and tabular metric numerals:
145
+
146
+ ```tsx
147
+ import { Text } from "@yuva-devlab/ui";
148
+
149
+ <Text variant="body-lg">Large intro body copy</Text>
150
+ <Text variant="body">Standard UI body text</Text>
151
+ <Text variant="body-sm">Small helper description</Text>
152
+ <Text variant="caption">Footnotes and timestamps</Text>
153
+ <Text variant="code">const token = useToken();</Text>
154
+ <Text variant="metric">3,492 req/s</Text>
155
+ ```
156
+
157
+ ---
158
+
89
159
  ## Multi-Brand Theming
90
160
 
91
161
  DevLab UI supports multi-brand switching at runtime using `data-brand` and `data-theme` HTML attributes:
92
162
 
93
163
  ```html
94
- <!-- Switch to VitalAI Athletic Theme with Dark Mode -->
95
- <html data-brand="vitalai" class="dark">
164
+ <!-- Switch to FinAI Spacious Theme with Dark Mode -->
165
+ <html data-brand="finai" class="dark">
96
166
  ...
97
167
  </html>
98
168
  ```
@@ -101,19 +171,33 @@ DevLab UI supports multi-brand switching at runtime using `data-brand` and `data
101
171
 
102
172
  | Brand Key | Theme Name | Primary Aesthetic | Token Import |
103
173
  | :----------- | :---------------- | :------------------------ | :------------------------------------------ |
104
- | `orchestrai` | **OrchestrAI** | Midnight Neon Violet | `@yuva-devlab/tokens/themes/orchestrai.css` |
105
- | `vitalai` | **VitalAI** | Athletic Volt Kinetic | `@yuva-devlab/tokens/themes/vitalai.css` |
106
174
  | `finai` | **FinAI** | High-Finance Emerald | `@yuva-devlab/tokens/themes/finai.css` |
175
+ | `vitalai` | **VitalAI** | Athletic Volt Kinetic | `@yuva-devlab/tokens/themes/vitalai.css` |
107
176
  | `logs` | **DevLab Logs** | High-Density Matrix Amber | `@yuva-devlab/tokens/themes/logs.css` |
177
+ | `orchestrai` | **OrchestrAI** | Midnight Neon Violet | `@yuva-devlab/tokens/themes/orchestrai.css` |
108
178
  | `portal` | **DevLab Portal** | Enterprise Modern Indigo | `@yuva-devlab/tokens/themes/portal.css` |
109
179
 
110
180
  ---
111
181
 
112
- ## Component Catalog (56 Components)
182
+ ## Component Catalog (64 Components)
183
+
184
+ ### Typography Primitives
185
+
186
+ - **Heading** - Semantic heading with decoupled visual scale (`display`, `h1`..`h6`).
187
+ - **Text** - Multi-variant typography primitive (`body-lg`, `body`, `body-sm`, `caption`, `code`, `metric`).
188
+
189
+ ### Layout & Composition Primitives
190
+
191
+ - **Box** - Fundamental container with padding, border, radius, shadow, and surface backgrounds.
192
+ - **Flex** - 1D flexbox container (`direction`, `justify`, `align`, `wrap`, `gap`, `inline`).
193
+ - **Stack** - Vertical or horizontal layout flow with token-governed spacing.
194
+ - **Grid** - Responsive 2D grid (`cols`, `gap`, minItemWidth auto-fit).
195
+ - **Container** - Responsive centered layout container with max-width boundaries (`sm` to `2xl`).
196
+ - **AspectRatio**, **Panel**, **Resizable**, **ScrollArea**, **Separator**
113
197
 
114
- ### General & Layout
198
+ ### General & Display
115
199
 
116
- - **Button**, **CopyButton**, **Card**, **MetricCard**, **SecretRevealCard**, **Badge**, **StatusBadge**, **StatusChip**, **Separator**, **Skeleton**, **LoadingState**, **AspectRatio**, **ScrollArea**, **Resizable**
200
+ - **Button**, **CopyButton**, **Card**, **MetricCard**, **SecretRevealCard**, **Badge**, **StatusBadge**, **StatusChip**, **Skeleton**, **LoadingState**, **EmptyState**
117
201
 
118
202
  ### Form & Data Entry
119
203
 
@@ -0,0 +1,18 @@
1
+ import { Meta, Title, Description, Canvas, Controls } from "@storybook/blocks";
2
+ import * as AccordionStories from "./accordion.stories";
3
+
4
+ <Meta of={AccordionStories} />
5
+
6
+ <Title />
7
+
8
+ # Accordion
9
+
10
+ Vertically stacked set of interactive headings that each reveal a section of content.
11
+
12
+ ## Default
13
+
14
+ <Canvas of={AccordionStories.Default} />
15
+
16
+ ## Component Properties
17
+
18
+ <Controls />
@@ -1,9 +1,9 @@
1
1
  .dl-alert {
2
2
  position: relative;
3
3
  width: 100%;
4
- border-radius: var(--radius-lg, 0.5rem);
4
+ border-radius: var(--radius, 0.5rem);
5
5
  border: 1px solid var(--border);
6
- padding: 0.875rem 1rem;
6
+ padding: var(--space-4, 0.875rem) var(--space-5, 1rem);
7
7
  font-size: 0.875rem;
8
8
  display: grid;
9
9
  grid-template-columns: 1fr;
@@ -0,0 +1,18 @@
1
+ import { Meta, Title, Description, Canvas, Controls } from "@storybook/blocks";
2
+ import * as AlertDialogStories from "./alert-dialog.stories";
3
+
4
+ <Meta of={AlertDialogStories} />
5
+
6
+ <Title />
7
+
8
+ # Alert Dialog
9
+
10
+ Modal dialog that interrupts the user with important content and expects a confirmation or cancellation action.
11
+
12
+ ## Default
13
+
14
+ <Canvas of={AlertDialogStories.Default} />
15
+
16
+ ## Component Properties
17
+
18
+ <Controls />
@@ -0,0 +1,22 @@
1
+ import { Meta, Title, Description, Canvas, Controls } from "@storybook/blocks";
2
+ import * as AspectRatioStories from "./aspect-ratio.stories";
3
+
4
+ <Meta of={AspectRatioStories} />
5
+
6
+ <Title />
7
+
8
+ # Aspect Ratio
9
+
10
+ Displays content within a desired ratio, preventing layout shifts during asset loading.
11
+
12
+ ## Default (16:9)
13
+
14
+ <Canvas of={AspectRatioStories.Default} />
15
+
16
+ ## Square (1:1)
17
+
18
+ <Canvas of={AspectRatioStories.Square} />
19
+
20
+ ## Component Properties
21
+
22
+ <Controls />
@@ -0,0 +1,18 @@
1
+ import { Meta, Title, Description, Canvas, Controls } from "@storybook/blocks";
2
+ import * as BreadcrumbStories from "./breadcrumb.stories";
3
+
4
+ <Meta of={BreadcrumbStories} />
5
+
6
+ <Title />
7
+
8
+ # Breadcrumb
9
+
10
+ Hierarchical navigation trail indicating the current page location within a navigational hierarchy.
11
+
12
+ ## Default
13
+
14
+ <Canvas of={BreadcrumbStories.Default} />
15
+
16
+ ## Component Properties
17
+
18
+ <Controls />
@@ -0,0 +1,111 @@
1
+ .dl-calendar .rdp-month_caption,
2
+ .dl-calendar .dl-calendar__month-caption {
3
+ position: relative;
4
+ display: flex;
5
+ height: var(--cell-size, 2rem);
6
+ width: 100%;
7
+ align-items: center;
8
+ justify-content: center;
9
+ padding: 0 var(--cell-size, 2rem);
10
+ font-size: 0.875rem;
11
+ font-weight: 600;
12
+ color: var(--foreground);
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ .dl-calendar .rdp-caption_label,
17
+ .dl-calendar .dl-calendar__caption-label {
18
+ font-size: 0.875rem;
19
+ font-weight: 600;
20
+ color: var(--foreground);
21
+ line-height: 1;
22
+ user-select: none;
23
+ }
24
+
25
+ .dl-calendar .dl-calendar__caption-label--interactive {
26
+ display: flex;
27
+ height: var(--control-height-sm, 2rem);
28
+ align-items: center;
29
+ gap: 0.25rem;
30
+ border-radius: var(--radius-md, 0.375rem);
31
+ padding-inline: 0.5rem 0.25rem;
32
+ }
33
+
34
+ .dl-calendar .dl-calendar__dropdowns {
35
+ display: flex;
36
+ width: 100%;
37
+ align-items: center;
38
+ justify-content: center;
39
+ gap: 0.375rem;
40
+ font-size: 0.875rem;
41
+ font-weight: 500;
42
+ }
43
+
44
+ .dl-calendar .dl-calendar__dropdown-root {
45
+ position: relative;
46
+ border-radius: var(--radius-md, 0.375rem);
47
+ border: 1px solid var(--border);
48
+ box-shadow: var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05));
49
+ }
50
+
51
+ .dl-calendar .dl-calendar__dropdown {
52
+ position: absolute;
53
+ inset: 0;
54
+ opacity: 0;
55
+ background: var(--popover);
56
+ cursor: pointer;
57
+ }
58
+
59
+ .dl-calendar .rdp-nav,
60
+ .dl-calendar .dl-calendar__nav {
61
+ position: absolute;
62
+ top: 0;
63
+ inset-inline: 0;
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ width: 100%;
68
+ height: var(--cell-size, 2rem);
69
+ pointer-events: none;
70
+ }
71
+
72
+ .dl-calendar .rdp-button_previous,
73
+ .dl-calendar .rdp-button_next,
74
+ .dl-calendar .dl-calendar__nav-button {
75
+ pointer-events: auto;
76
+ width: var(--cell-size, 2rem) !important;
77
+ height: var(--cell-size, 2rem) !important;
78
+ min-width: var(--cell-size, 2rem) !important;
79
+ padding: 0 !important;
80
+ display: inline-flex !important;
81
+ align-items: center;
82
+ justify-content: center;
83
+ border-radius: var(--radius-md, 0.375rem) !important;
84
+ border: 1px solid var(--border);
85
+ background: var(--background);
86
+ color: var(--muted-foreground);
87
+ cursor: pointer;
88
+ user-select: none;
89
+ transition: all 0.15s ease;
90
+ }
91
+
92
+ .dl-calendar .rdp-button_previous:hover,
93
+ .dl-calendar .rdp-button_next:hover,
94
+ .dl-calendar .dl-calendar__nav-button:hover {
95
+ background-color: var(--accent);
96
+ color: var(--accent-foreground);
97
+ }
98
+
99
+ .dl-calendar .rdp-button_previous[aria-disabled="true"],
100
+ .dl-calendar .rdp-button_next[aria-disabled="true"] {
101
+ opacity: 0.5;
102
+ pointer-events: none;
103
+ }
104
+
105
+ .dl-calendar .rdp-button_previous svg,
106
+ .dl-calendar .rdp-button_next svg,
107
+ .dl-calendar .dl-calendar__chevron {
108
+ width: 1rem;
109
+ height: 1rem;
110
+ flex-shrink: 0;
111
+ }
@@ -1,9 +1,9 @@
1
1
  .dl-calendar {
2
- --cell-size: 2rem;
2
+ --cell-size: var(--control-height-sm, 2rem);
3
3
  display: inline-block;
4
4
  width: fit-content;
5
5
  max-width: 100%;
6
- padding: 0.75rem;
6
+ padding: var(--space-3, 0.75rem);
7
7
  box-sizing: border-box;
8
8
  color: var(--foreground);
9
9
  }
@@ -13,7 +13,8 @@
13
13
  margin: 0 auto;
14
14
  }
15
15
 
16
- .dl-calendar .rdp-months {
16
+ .dl-calendar .rdp-months,
17
+ .dl-calendar .dl-calendar__months {
17
18
  position: relative;
18
19
  display: flex;
19
20
  flex-direction: column;
@@ -22,81 +23,23 @@
22
23
  box-sizing: border-box;
23
24
  }
24
25
 
25
- .dl-calendar .rdp-month {
26
+ @media (min-width: 768px) {
27
+ .dl-calendar .rdp-months,
28
+ .dl-calendar .dl-calendar__months {
29
+ flex-direction: row;
30
+ }
31
+ }
32
+
33
+ .dl-calendar .rdp-month,
34
+ .dl-calendar .dl-calendar__month {
26
35
  display: flex;
27
36
  flex-direction: column;
28
37
  gap: 0.75rem;
29
38
  width: 100%;
30
39
  }
31
40
 
32
- .dl-calendar .rdp-month_caption {
33
- position: relative;
34
- display: flex;
35
- height: var(--cell-size, 2rem);
36
- width: 100%;
37
- align-items: center;
38
- justify-content: center;
39
- padding: 0 var(--cell-size, 2rem);
40
- font-size: 0.875rem;
41
- font-weight: 600;
42
- color: var(--foreground);
43
- box-sizing: border-box;
44
- }
45
-
46
- .dl-calendar .rdp-caption_label {
47
- font-size: 0.875rem;
48
- font-weight: 600;
49
- color: var(--foreground);
50
- line-height: 1;
51
- }
52
-
53
- /* Navigation prev / next arrows */
54
- .dl-calendar .rdp-nav {
55
- position: absolute;
56
- top: 0;
57
- left: 0;
58
- right: 0;
59
- display: flex;
60
- align-items: center;
61
- justify-content: space-between;
62
- width: 100%;
63
- height: var(--cell-size, 2rem);
64
- pointer-events: none;
65
- }
66
-
67
- .dl-calendar .rdp-button_previous,
68
- .dl-calendar .rdp-button_next {
69
- pointer-events: auto;
70
- width: var(--cell-size, 2rem) !important;
71
- height: var(--cell-size, 2rem) !important;
72
- min-width: var(--cell-size, 2rem) !important;
73
- padding: 0 !important;
74
- display: inline-flex !important;
75
- align-items: center;
76
- justify-content: center;
77
- border-radius: var(--radius-md, 0.375rem) !important;
78
- border: 1px solid var(--border);
79
- background: var(--background);
80
- color: var(--muted-foreground);
81
- cursor: pointer;
82
- transition: all 0.15s ease;
83
- }
84
-
85
- .dl-calendar .rdp-button_previous:hover,
86
- .dl-calendar .rdp-button_next:hover {
87
- background-color: var(--accent);
88
- color: var(--accent-foreground);
89
- }
90
-
91
- .dl-calendar .rdp-button_previous svg,
92
- .dl-calendar .rdp-button_next svg {
93
- width: 1rem;
94
- height: 1rem;
95
- flex-shrink: 0;
96
- }
97
-
98
- /* Grid Table */
99
41
  .dl-calendar table.rdp-month_grid,
42
+ .dl-calendar table.dl-calendar__table,
100
43
  .dl-calendar table {
101
44
  width: 100%;
102
45
  border-collapse: collapse;
@@ -104,7 +47,6 @@
104
47
  margin: 0;
105
48
  }
106
49
 
107
- /* Weekday header cells */
108
50
  .dl-calendar th.rdp-weekday,
109
51
  .dl-calendar th {
110
52
  width: calc(100% / 7);
@@ -119,7 +61,6 @@
119
61
  box-sizing: border-box;
120
62
  }
121
63
 
122
- /* Day table cells */
123
64
  .dl-calendar td.rdp-day,
124
65
  .dl-calendar td {
125
66
  width: calc(100% / 7);
@@ -129,12 +70,19 @@
129
70
  text-align: center;
130
71
  vertical-align: middle;
131
72
  background: transparent !important;
132
- background-color: transparent !important;
133
73
  border: none !important;
134
74
  box-sizing: border-box;
135
75
  }
136
76
 
137
- /* Day Button inside td */
77
+ .dl-calendar .dl-calendar__week-number {
78
+ display: flex;
79
+ width: var(--cell-size, 2rem);
80
+ height: var(--cell-size, 2rem);
81
+ align-items: center;
82
+ justify-content: center;
83
+ text-align: center;
84
+ }
85
+
138
86
  .dl-calendar button.rdp-day_button,
139
87
  .dl-calendar .dl-calendar__day-button {
140
88
  width: 100% !important;
@@ -146,10 +94,12 @@
146
94
  display: inline-flex !important;
147
95
  align-items: center;
148
96
  justify-content: center;
97
+ aspect-ratio: 1 / 1;
149
98
  border-radius: var(--radius-md, 0.375rem) !important;
150
99
  border: none !important;
151
100
  font-size: 0.875rem;
152
101
  font-weight: 400;
102
+ line-height: 1;
153
103
  color: var(--foreground);
154
104
  background: transparent;
155
105
  cursor: pointer;
@@ -162,7 +112,6 @@
162
112
  color: var(--accent-foreground) !important;
163
113
  }
164
114
 
165
- /* Selected Date Highlight */
166
115
  .dl-calendar td[aria-selected="true"] button.rdp-day_button,
167
116
  .dl-calendar td.rdp-selected button.rdp-day_button,
168
117
  .dl-calendar button.rdp-day_button[data-selected="true"],
@@ -182,7 +131,6 @@
182
131
  color: var(--primary-foreground) !important;
183
132
  }
184
133
 
185
- /* Today indicator (when not selected) */
186
134
  .dl-calendar
187
135
  td.rdp-today:not([aria-selected="true"]):not(.rdp-selected)
188
136
  button.rdp-day_button {
@@ -196,11 +144,9 @@
196
144
  border: 1px solid var(--border) !important;
197
145
  }
198
146
 
199
- /* Range selection styles */
200
147
  .dl-calendar td.rdp-range_start {
201
148
  background-color: var(--accent) !important;
202
- border-top-left-radius: var(--radius-md, 0.375rem) !important;
203
- border-bottom-left-radius: var(--radius-md, 0.375rem) !important;
149
+ border-radius: var(--radius-md, 0.375rem) 0 0 var(--radius-md, 0.375rem) !important;
204
150
  }
205
151
 
206
152
  .dl-calendar td.rdp-range_middle {
@@ -216,8 +162,7 @@
216
162
 
217
163
  .dl-calendar td.rdp-range_end {
218
164
  background-color: var(--accent) !important;
219
- border-top-right-radius: var(--radius-md, 0.375rem) !important;
220
- border-bottom-right-radius: var(--radius-md, 0.375rem) !important;
165
+ border-radius: 0 var(--radius-md, 0.375rem) var(--radius-md, 0.375rem) !important;
221
166
  }
222
167
 
223
168
  .dl-calendar td.rdp-outside button.rdp-day_button {
@@ -0,0 +1,18 @@
1
+ import { Meta, Title, Description, Canvas, Controls } from "@storybook/blocks";
2
+ import * as CalendarStories from "./calendar.stories";
3
+
4
+ <Meta of={CalendarStories} />
5
+
6
+ <Title />
7
+
8
+ # Calendar
9
+
10
+ Interactive calendar date selection component supporting day, month, and year navigation.
11
+
12
+ ## Default
13
+
14
+ <Canvas of={CalendarStories.Default} />
15
+
16
+ ## Component Properties
17
+
18
+ <Controls />
@@ -1,5 +1,5 @@
1
1
  .dl-card {
2
- border-radius: var(--radius-lg, 0.5rem);
2
+ border-radius: var(--radius, 0.75rem);
3
3
  border: 1px solid var(--border);
4
4
  background-color: var(--card);
5
5
  color: var(--card-foreground);
@@ -9,7 +9,7 @@
9
9
  display: flex;
10
10
  flex-direction: column;
11
11
  gap: 0.375rem;
12
- padding: 1.5rem;
12
+ padding: var(--card-padding, 1.5rem);
13
13
  }
14
14
  .dl-card__title {
15
15
  font-weight: 600;
@@ -21,10 +21,10 @@
21
21
  color: var(--muted-foreground);
22
22
  }
23
23
  .dl-card__content {
24
- padding: 1.5rem;
24
+ padding: var(--card-padding, 1.5rem);
25
25
  }
26
26
  .dl-card__footer {
27
27
  display: flex;
28
28
  align-items: center;
29
- padding: 1.5rem;
29
+ padding: var(--card-padding, 1.5rem);
30
30
  }
@@ -27,18 +27,18 @@
27
27
  }
28
28
 
29
29
  .dl-carousel-item--horizontal {
30
- padding-left: 1rem;
30
+ padding-left: var(--space-4, 1rem);
31
31
  }
32
32
 
33
33
  .dl-carousel-item--vertical {
34
- padding-top: 1rem;
34
+ padding-top: var(--space-4, 1rem);
35
35
  }
36
36
 
37
37
  .dl-carousel-btn {
38
38
  position: absolute;
39
39
  border-radius: 9999px;
40
- width: 2rem;
41
- height: 2rem;
40
+ width: var(--control-height-sm, 2rem);
41
+ height: var(--control-height-sm, 2rem);
42
42
  padding: 0;
43
43
  }
44
44