@yuva-devlab/ui 1.4.3 → 1.4.4

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/README.md CHANGED
@@ -1,202 +1,162 @@
1
1
  # 📦 @yuva-devlab/ui
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@yuva-devlab/ui.svg)](https://www.npmjs.com/package/@yuva-devlab/ui)
4
- [![npm downloads](https://img.shields.io/npm/dm/@yuva-devlab/ui.svg)](https://www.npmjs.com/package/@yuva-devlab/ui)
5
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
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
7
 
7
- > A production-ready, fully-typed React component library built with Vanilla
8
- > Extract, featuring a natural design system and comprehensive accessibility
9
- > support.
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
+
10
+ ---
10
11
 
11
12
  ## Features
12
13
 
13
- - 🎨 **Natural Design System** - Organic color palettes inspired by Material
14
- Design 3
15
- - 🔒 **Type-Safe** - Full TypeScript support with comprehensive type definitions
16
- - 🎭 **Zero-Runtime CSS** - Vanilla Extract compiles styles at build time
17
- - ♿ **Accessible** - Built on Radix UI primitives with ARIA compliance
18
- - 🧩 **Polymorphic** - Components support `as` prop for semantic flexibility
19
- - 🎯 **Tree-Shakeable** - Import only what you need
20
- - 📦 **Monorepo Architecture** - Clean separation of tokens, primitives, and
21
- components
14
+ - 🎨 **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.
16
+ - ♿ **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.
20
+
21
+ ---
22
22
 
23
23
  ## Installation
24
24
 
25
25
  ```bash
26
+ # pnpm (recommended)
27
+ pnpm add @yuva-devlab/ui @yuva-devlab/tokens lucide-react
28
+
26
29
  # npm
27
- npm install @yuva-devlab/ui
30
+ npm install @yuva-devlab/ui @yuva-devlab/tokens lucide-react
28
31
 
29
32
  # yarn
30
- yarn add @yuva-devlab/ui
31
-
32
- # pnpm
33
- pnpm add @yuva-devlab/ui
33
+ yarn add @yuva-devlab/ui @yuva-devlab/tokens lucide-react
34
34
  ```
35
35
 
36
36
  ### Peer Dependencies
37
37
 
38
+ Ensure your project has the required peer dependencies installed:
39
+
38
40
  ```bash
39
- # npm
40
- npm install react@^19.2.0 react-dom@^19.2.0
41
+ pnpm add react@^19.0.0 react-dom@^19.0.0 sonner@^2.0.0
42
+ ```
41
43
 
42
- # yarn
43
- yarn add react@^19.2.0 react-dom@^19.2.0
44
+ ---
45
+
46
+ ## Quick Start
47
+
48
+ ### 1. Configure Styles
49
+
50
+ In your application's root stylesheet (e.g. `globals.css` or `app.css`), import the token preset, desired brand theme, and component styles:
44
51
 
45
- # pnpm
46
- pnpm add react@^19.2.0 react-dom@^19.2.0
52
+ ```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";
47
57
  ```
48
58
 
49
- ## Quick Start
59
+ > **Tip:** You can import any theme preset from `@yuva-devlab/tokens/themes/*` (`orchestrai`, `vitalai`, `finai`, `logs`, `portal`).
60
+
61
+ ### 2. Render Components
50
62
 
51
63
  ```tsx
52
- import { Button, Input, Stack, Container } from "@yuva-devlab/ui";
53
- import "@yuva-devlab/ui/styles.css";
64
+ import { Button, Card, DatePicker, Badge } from "@yuva-devlab/ui";
65
+ import { Sparkles } from "lucide-react";
54
66
 
55
- function App() {
67
+ export default function DashboardCard() {
56
68
  return (
57
- <Container size="lg">
58
- <Stack gap="md">
59
- <Input label="Email" placeholder="you@example.com" type="email" />
60
- <Button variant="primary" size="md">
61
- Sign In
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
62
80
  </Button>
63
- </Stack>
64
- </Container>
81
+ </div>
82
+ </Card>
65
83
  );
66
84
  }
67
85
  ```
68
86
 
69
- ## Available Components
70
-
71
- ### Form Components
72
-
73
- - **Button** - Primary, secondary, tertiary variants with loading states
74
- - **Input** - Text input with label, error states, and helper text
75
-
76
- ### Typography
77
-
78
- - **Typography** - Polymorphic text component supporting h1-h6, p, span, etc.
79
-
80
- ### Layout Components
87
+ ---
81
88
 
82
- - **Box** - Polymorphic container with spacing utilities
83
- - **Flex** - Flexbox layout with alignment and gap props
84
- - **Grid** - CSS Grid layout with responsive columns
85
- - **Stack** - Vertical/horizontal stacking with consistent spacing
86
- - **Container** - Responsive max-width wrapper (sm, md, lg, xl, 2xl)
89
+ ## Multi-Brand Theming
87
90
 
88
- ### Coming Soon
91
+ DevLab UI supports multi-brand switching at runtime using `data-brand` and `data-theme` HTML attributes:
89
92
 
90
- - Select (Radix UI based)
91
- - Switch (Radix UI based)
92
- - Checkbox (Radix UI based)
93
- - Radio (Radix UI based)
94
- - InputNumber
93
+ ```html
94
+ <!-- Switch to VitalAI Athletic Theme with Dark Mode -->
95
+ <html data-brand="vitalai" class="dark">
96
+ ...
97
+ </html>
98
+ ```
95
99
 
96
- ## Component Examples
100
+ ### Supported Brand Themes
97
101
 
98
- ### Button
102
+ | Brand Key | Theme Name | Primary Aesthetic | Token Import |
103
+ | :----------- | :---------------- | :------------------------ | :------------------------------------------ |
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
+ | `finai` | **FinAI** | High-Finance Emerald | `@yuva-devlab/tokens/themes/finai.css` |
107
+ | `logs` | **DevLab Logs** | High-Density Matrix Amber | `@yuva-devlab/tokens/themes/logs.css` |
108
+ | `portal` | **DevLab Portal** | Enterprise Modern Indigo | `@yuva-devlab/tokens/themes/portal.css` |
99
109
 
100
- ```tsx
101
- import { Button } from "@yuva-devlab/ui";
110
+ ---
102
111
 
103
- // Variants
104
- <Button variant="primary">Primary Action</Button>
105
- <Button variant="secondary">Secondary Action</Button>
106
- <Button variant="tertiary">Tertiary Action</Button>
112
+ ## Component Catalog (56 Components)
107
113
 
108
- // Sizes
109
- <Button size="sm">Small</Button>
110
- <Button size="md">Medium</Button>
111
- <Button size="lg">Large</Button>
114
+ ### General & Layout
112
115
 
113
- // States
114
- <Button loading>Loading...</Button>
115
- <Button disabled>Disabled</Button>
116
+ - **Button**, **CopyButton**, **Card**, **MetricCard**, **SecretRevealCard**, **Badge**, **StatusBadge**, **StatusChip**, **Separator**, **Skeleton**, **LoadingState**, **AspectRatio**, **ScrollArea**, **Resizable**
116
117
 
117
- // Polymorphic
118
- <Button as="a" href="/home">Link Button</Button>
119
- ```
118
+ ### Form & Data Entry
120
119
 
121
- ### Layout System
120
+ - **Input**, **Textarea**, **Checkbox**, **Switch**, **Slider**, **RadioGroup**, **Select**, **SearchableSelect**, **DatePicker**, **Calendar**, **InputOTP**, **Toggle**, **ToggleGroup**, **Form**
122
121
 
123
- ```tsx
124
- import { Container, Stack, Flex, Box } from "@yuva-devlab/ui";
125
-
126
- <Container size="xl">
127
- <Stack gap="lg">
128
- <Flex align="center" justify="between">
129
- <Box p="md">Logo</Box>
130
- <Box>Navigation</Box>
131
- </Flex>
132
-
133
- <Grid cols={{ base: 1, md: 2, lg: 3 }} gap="md">
134
- <Box p="lg">Card 1</Box>
135
- <Box p="lg">Card 2</Box>
136
- <Box p="lg">Card 3</Box>
137
- </Grid>
138
- </Stack>
139
- </Container>;
140
- ```
122
+ ### Navigation
141
123
 
142
- ## Styling & Brand Theming
124
+ - **Sidebar**, **NavigationMenu**, **Menubar**, **Breadcrumb**, **Tabs**, **Pagination**
143
125
 
144
- ### 1. Global Styles Setup
126
+ ### Overlays & Dialogs
145
127
 
146
- Import the UI stylesheet in your root layout:
128
+ - **Dialog**, **AlertDialog**, **ConfirmDialog**, **Drawer**, **Sheet**, **Popover**, **Tooltip**, **HoverCard**, **DropdownMenu**, **ContextMenu**
147
129
 
148
- ```tsx
149
- import "@yuva-devlab/ui/styles.css";
150
- ```
130
+ ### Feedback & Display
151
131
 
152
- Or import specific brand themes directly:
132
+ - **Alert**, **Progress**, **Toaster** (Sonner integration), **Avatar**, **Table**, **Accordion**, **Collapsible**, **Carousel**, **Chart**, **Command**
153
133
 
154
- ```css
155
- @import "@yuva-devlab/ui/styles.css";
156
- @import "@yuva-devlab/ui/themes/finai.css";
157
- ```
134
+ ---
158
135
 
159
- ### 2. Brand & Theme Provider (`ConfigProvider`)
136
+ ## TypeScript & Polymorphic Support
160
137
 
161
- Wrap your application with `ConfigProvider` (or `ThemeProvider`) and pass your `brand`:
138
+ All components export full TypeScript definitions and support polymorphic composition via the `asChild` prop:
162
139
 
163
140
  ```tsx
164
- import { ConfigProvider } from "@yuva-devlab/ui";
141
+ import Link from "next/link";
142
+ import { Button } from "@yuva-devlab/ui";
165
143
 
166
- export function RootLayout({ children }: { children: React.ReactNode }) {
167
- return (
168
- <ConfigProvider brand="finai" defaultTheme="system">
169
- {children}
170
- </ConfigProvider>
171
- );
172
- }
144
+ <Button asChild variant="secondary">
145
+ <Link href="/dashboard">Navigate to Dashboard</Link>
146
+ </Button>;
173
147
  ```
174
148
 
175
- The provider sets the appropriate `data-brand` and `data-theme` attributes on `<html>`, instantly activating the scoped design tokens for that brand without loading or exposing styles of other brands!
176
-
177
149
  ---
178
150
 
179
- ## Development
151
+ ## Documentation & Live Previews
180
152
 
181
- ```bash
182
- # Install dependencies
183
- pnpm install
153
+ Explore the interactive component playground, live documentation, and API references at:
184
154
 
185
- # Build the library
186
- pnpm --filter @yuva-devlab/ui build
155
+ - **Documentation**: [https://github.com/yuvadevlab/devlab-shared](https://github.com/yuvadevlab/devlab-shared)
156
+ - **Repository**: [https://github.com/yuvadevlab/devlab-shared](https://github.com/yuvadevlab/devlab-shared)
187
157
 
188
- # Run tests
189
- pnpm --filter @yuva-devlab/ui test
190
-
191
- # Type check
192
- pnpm --filter @yuva-devlab/ui typecheck
193
- ```
194
-
195
- ## Documentation
196
-
197
- - **Storybook**: Run `pnpm dev:docs` to view interactive component documentation
198
- - **Playground**: Run `pnpm dev:playground` to test components in a live
158
+ ---
199
159
 
200
160
  ## License
201
161
 
202
- MIT © Yuva Devlab
162
+ MIT © [Yuva DevLab](https://github.com/yuvadevlab)
@@ -0,0 +1,238 @@
1
+ .dl-calendar {
2
+ --cell-size: 2rem;
3
+ display: inline-block;
4
+ width: fit-content;
5
+ max-width: 100%;
6
+ padding: 0.75rem;
7
+ box-sizing: border-box;
8
+ color: var(--foreground);
9
+ }
10
+
11
+ .dl-calendar .rdp-root {
12
+ width: fit-content;
13
+ margin: 0 auto;
14
+ }
15
+
16
+ .dl-calendar .rdp-months {
17
+ position: relative;
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 1rem;
21
+ width: calc(var(--cell-size, 2rem) * 7);
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ .dl-calendar .rdp-month {
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: 0.75rem;
29
+ width: 100%;
30
+ }
31
+
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
+ .dl-calendar table.rdp-month_grid,
100
+ .dl-calendar table {
101
+ width: 100%;
102
+ border-collapse: collapse;
103
+ table-layout: fixed;
104
+ margin: 0;
105
+ }
106
+
107
+ /* Weekday header cells */
108
+ .dl-calendar th.rdp-weekday,
109
+ .dl-calendar th {
110
+ width: calc(100% / 7);
111
+ height: var(--cell-size, 2rem);
112
+ text-align: center;
113
+ vertical-align: middle;
114
+ font-size: 0.75rem;
115
+ font-weight: 500;
116
+ color: var(--muted-foreground);
117
+ padding: 0;
118
+ margin: 0;
119
+ box-sizing: border-box;
120
+ }
121
+
122
+ /* Day table cells */
123
+ .dl-calendar td.rdp-day,
124
+ .dl-calendar td {
125
+ width: calc(100% / 7);
126
+ height: var(--cell-size, 2rem);
127
+ padding: 2px !important;
128
+ margin: 0;
129
+ text-align: center;
130
+ vertical-align: middle;
131
+ background: transparent !important;
132
+ background-color: transparent !important;
133
+ border: none !important;
134
+ box-sizing: border-box;
135
+ }
136
+
137
+ /* Day Button inside td */
138
+ .dl-calendar button.rdp-day_button,
139
+ .dl-calendar .dl-calendar__day-button {
140
+ width: 100% !important;
141
+ height: 100% !important;
142
+ min-width: 0 !important;
143
+ min-height: 0 !important;
144
+ margin: 0 auto !important;
145
+ padding: 0 !important;
146
+ display: inline-flex !important;
147
+ align-items: center;
148
+ justify-content: center;
149
+ border-radius: var(--radius-md, 0.375rem) !important;
150
+ border: none !important;
151
+ font-size: 0.875rem;
152
+ font-weight: 400;
153
+ color: var(--foreground);
154
+ background: transparent;
155
+ cursor: pointer;
156
+ box-sizing: border-box;
157
+ transition: all 0.15s ease;
158
+ }
159
+
160
+ .dl-calendar button.rdp-day_button:hover:not(:disabled) {
161
+ background-color: var(--accent) !important;
162
+ color: var(--accent-foreground) !important;
163
+ }
164
+
165
+ /* Selected Date Highlight */
166
+ .dl-calendar td[aria-selected="true"] button.rdp-day_button,
167
+ .dl-calendar td.rdp-selected button.rdp-day_button,
168
+ .dl-calendar button.rdp-day_button[data-selected="true"],
169
+ .dl-calendar button.rdp-day_button[data-selected-single="true"] {
170
+ background-color: var(--primary) !important;
171
+ color: var(--primary-foreground) !important;
172
+ border-radius: var(--radius-md, 0.375rem) !important;
173
+ font-weight: 600;
174
+ box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
175
+ }
176
+
177
+ .dl-calendar td[aria-selected="true"] button.rdp-day_button:hover,
178
+ .dl-calendar td.rdp-selected button.rdp-day_button:hover,
179
+ .dl-calendar button.rdp-day_button[data-selected="true"]:hover,
180
+ .dl-calendar button.rdp-day_button[data-selected-single="true"]:hover {
181
+ background-color: color-mix(in oklch, var(--primary) 88%, black) !important;
182
+ color: var(--primary-foreground) !important;
183
+ }
184
+
185
+ /* Today indicator (when not selected) */
186
+ .dl-calendar
187
+ td.rdp-today:not([aria-selected="true"]):not(.rdp-selected)
188
+ button.rdp-day_button {
189
+ background-color: color-mix(
190
+ in oklch,
191
+ var(--secondary) 60%,
192
+ transparent
193
+ ) !important;
194
+ color: var(--foreground) !important;
195
+ font-weight: 600;
196
+ border: 1px solid var(--border) !important;
197
+ }
198
+
199
+ /* Range selection styles */
200
+ .dl-calendar td.rdp-range_start {
201
+ 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;
204
+ }
205
+
206
+ .dl-calendar td.rdp-range_middle {
207
+ background-color: var(--accent) !important;
208
+ border-radius: 0 !important;
209
+ }
210
+
211
+ .dl-calendar td.rdp-range_middle button.rdp-day_button {
212
+ background: transparent !important;
213
+ color: var(--accent-foreground) !important;
214
+ border-radius: 0 !important;
215
+ }
216
+
217
+ .dl-calendar td.rdp-range_end {
218
+ 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;
221
+ }
222
+
223
+ .dl-calendar td.rdp-outside button.rdp-day_button {
224
+ color: var(--muted-foreground) !important;
225
+ opacity: 0.35;
226
+ }
227
+
228
+ .dl-calendar button.rdp-day_button:disabled {
229
+ color: var(--muted-foreground) !important;
230
+ opacity: 0.25;
231
+ cursor: not-allowed;
232
+ pointer-events: none;
233
+ }
234
+
235
+ .dl-calendar td.rdp-hidden {
236
+ visibility: hidden;
237
+ pointer-events: none;
238
+ }
@@ -13,6 +13,8 @@
13
13
  cursor: pointer;
14
14
  transition: all 0.15s ease;
15
15
  user-select: none;
16
+ white-space: nowrap;
17
+ flex-shrink: 0;
16
18
  }
17
19
 
18
20
  .dl-copy-button:hover {
@@ -24,7 +24,13 @@
24
24
  flex-shrink: 0;
25
25
  }
26
26
 
27
- .dl-date-picker-content {
28
- width: auto;
29
- padding: 0;
27
+ .dl-date-picker-content,
28
+ .dl-popover.dl-date-picker-content {
29
+ width: fit-content !important;
30
+ max-width: fit-content !important;
31
+ padding: 0 !important;
32
+ box-shadow: 0 4px 20px rgb(0 0 0 / 0.15);
33
+ border-radius: var(--radius-lg, 0.5rem);
34
+ border: 1px solid var(--border);
35
+ background-color: var(--popover);
30
36
  }
@@ -15,3 +15,8 @@
15
15
  .dl-popover[data-state="closed"] {
16
16
  animation: dl-fade-out 150ms ease;
17
17
  }
18
+
19
+ .dl-popover.dl-date-picker-content {
20
+ width: auto;
21
+ padding: 0;
22
+ }
@@ -26,6 +26,7 @@
26
26
  border: 1px solid var(--border);
27
27
  border-radius: calc(var(--radius, 0.5rem) - 2px);
28
28
  padding: 0.5rem 0.75rem;
29
+ flex-wrap: nowrap;
29
30
  }
30
31
 
31
32
  .dl-secret-reveal__code {
@@ -34,4 +35,6 @@
34
35
  color: var(--primary);
35
36
  word-break: break-all;
36
37
  user-select: all;
38
+ min-width: 0;
39
+ flex: 1;
37
40
  }