@yuva-devlab/ui 1.0.0 → 1.1.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.
- package/README.md +29 -14
- package/dist/index.cjs +53 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -6
- package/dist/index.d.ts +18 -6
- package/dist/index.js +51 -19
- package/dist/index.js.map +1 -1
- package/dist/preset.css +159 -0
- package/dist/styles/preset.css +159 -0
- package/dist/styles/styles.css +6 -0
- package/dist/styles/themes/finai.css +114 -0
- package/dist/styles/themes/orchestrai.css +75 -0
- package/dist/styles.css +6 -0
- package/dist/themes/finai.css +114 -0
- package/dist/themes/orchestrai.css +75 -0
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -139,22 +139,42 @@ import { Container, Stack, Flex, Box } from "@yuva-devlab/ui";
|
|
|
139
139
|
</Container>;
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
## Styling
|
|
142
|
+
## Styling & Brand Theming
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
are compiled at build time.
|
|
144
|
+
### 1. Global Styles Setup
|
|
146
145
|
|
|
147
|
-
|
|
146
|
+
Import the UI stylesheet in your root layout:
|
|
148
147
|
|
|
149
148
|
```tsx
|
|
150
|
-
// Import global styles once in your app entry point
|
|
151
149
|
import "@yuva-devlab/ui/styles.css";
|
|
152
150
|
```
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
Or import specific brand themes directly:
|
|
155
153
|
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
```css
|
|
155
|
+
@import "@yuva-devlab/ui/styles.css";
|
|
156
|
+
@import "@yuva-devlab/ui/themes/finai.css";
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 2. Brand & Theme Provider (`ConfigProvider`)
|
|
160
|
+
|
|
161
|
+
Wrap your application with `ConfigProvider` (or `ThemeProvider`) and pass your `brand`:
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import { ConfigProvider } from "@yuva-devlab/ui";
|
|
165
|
+
|
|
166
|
+
export function RootLayout({ children }: { children: React.ReactNode }) {
|
|
167
|
+
return (
|
|
168
|
+
<ConfigProvider brand="finai" defaultTheme="system">
|
|
169
|
+
{children}
|
|
170
|
+
</ConfigProvider>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
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
|
+
---
|
|
158
178
|
|
|
159
179
|
## Development
|
|
160
180
|
|
|
@@ -169,18 +189,13 @@ pnpm --filter @yuva-devlab/ui build
|
|
|
169
189
|
pnpm --filter @yuva-devlab/ui test
|
|
170
190
|
|
|
171
191
|
# Type check
|
|
172
|
-
pnpm --filter @yuva-devlab/ui
|
|
192
|
+
pnpm --filter @yuva-devlab/ui typecheck
|
|
173
193
|
```
|
|
174
194
|
|
|
175
195
|
## Documentation
|
|
176
196
|
|
|
177
197
|
- **Storybook**: Run `pnpm dev:docs` to view interactive component documentation
|
|
178
198
|
- **Playground**: Run `pnpm dev:playground` to test components in a live
|
|
179
|
-
environment
|
|
180
|
-
|
|
181
|
-
## Related Packages
|
|
182
|
-
|
|
183
|
-
- [@yuva-devlab/tokens](../tokens) - Tailwind CSS 4 preset and design token theme bridge
|
|
184
199
|
|
|
185
200
|
## License
|
|
186
201
|
|
package/dist/index.cjs
CHANGED
|
@@ -94,6 +94,7 @@ __export(index_exports, {
|
|
|
94
94
|
CommandList: () => CommandList,
|
|
95
95
|
CommandSeparator: () => CommandSeparator,
|
|
96
96
|
CommandShortcut: () => CommandShortcut,
|
|
97
|
+
ConfigProvider: () => ConfigProvider,
|
|
97
98
|
ConfirmDialog: () => ConfirmDialog,
|
|
98
99
|
ContextMenu: () => ContextMenu,
|
|
99
100
|
ContextMenuCheckboxItem: () => ContextMenuCheckboxItem,
|
|
@@ -284,6 +285,7 @@ __export(index_exports, {
|
|
|
284
285
|
navigationMenuTriggerStyle: () => navigationMenuTriggerStyle,
|
|
285
286
|
toast: () => import_sonner.toast,
|
|
286
287
|
toggleVariants: () => toggleVariants,
|
|
288
|
+
useConfig: () => useConfig,
|
|
287
289
|
useFormField: () => useFormField,
|
|
288
290
|
useIsMobile: () => useIsMobile,
|
|
289
291
|
useSidebar: () => useSidebar,
|
|
@@ -303,15 +305,20 @@ var import_react = require("react");
|
|
|
303
305
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
304
306
|
var initialState = {
|
|
305
307
|
theme: "system",
|
|
308
|
+
brand: "finai",
|
|
306
309
|
setTheme: () => null,
|
|
310
|
+
setBrand: () => null,
|
|
307
311
|
resolvedTheme: "dark"
|
|
308
312
|
};
|
|
309
313
|
var ThemeProviderContext = (0, import_react.createContext)(initialState);
|
|
310
314
|
function ThemeProvider({
|
|
311
315
|
children,
|
|
316
|
+
brand: initialBrand = "finai",
|
|
312
317
|
defaultTheme = "system",
|
|
313
318
|
storageKey = "yd-theme",
|
|
319
|
+
brandStorageKey = "yd-brand",
|
|
314
320
|
attribute = "data-theme",
|
|
321
|
+
brandAttribute = "data-brand",
|
|
315
322
|
enableSystem = true,
|
|
316
323
|
...props
|
|
317
324
|
}) {
|
|
@@ -322,6 +329,13 @@ function ThemeProvider({
|
|
|
322
329
|
}
|
|
323
330
|
return defaultTheme;
|
|
324
331
|
});
|
|
332
|
+
const [brand, setBrandState] = (0, import_react.useState)(() => {
|
|
333
|
+
if (typeof window !== "undefined") {
|
|
334
|
+
const stored = localStorage.getItem(brandStorageKey);
|
|
335
|
+
if (stored) return stored;
|
|
336
|
+
}
|
|
337
|
+
return initialBrand;
|
|
338
|
+
});
|
|
325
339
|
const [resolvedTheme, setResolvedTheme] = (0, import_react.useState)("dark");
|
|
326
340
|
(0, import_react.useEffect)(() => {
|
|
327
341
|
const root = window.document.documentElement;
|
|
@@ -331,20 +345,33 @@ function ThemeProvider({
|
|
|
331
345
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
332
346
|
activeTheme = systemTheme;
|
|
333
347
|
}
|
|
334
|
-
const isDark = activeTheme.includes("dark") || activeTheme === "orchestrai";
|
|
348
|
+
const isDark = activeTheme.includes("dark") || activeTheme === "orchestrai" || brand === "orchestrai" && activeTheme !== "light";
|
|
335
349
|
const resolved = isDark ? "dark" : "light";
|
|
336
350
|
setResolvedTheme(resolved);
|
|
337
351
|
root.classList.add(resolved);
|
|
352
|
+
if (brandAttribute && brand) {
|
|
353
|
+
root.setAttribute(brandAttribute, brand);
|
|
354
|
+
}
|
|
338
355
|
if (attribute) {
|
|
339
|
-
|
|
356
|
+
const combinedTheme = theme === "system" ? `${brand}-${resolved}` : theme.startsWith(brand) ? theme : `${brand}-${theme}`;
|
|
357
|
+
root.setAttribute(attribute, combinedTheme);
|
|
340
358
|
}
|
|
341
|
-
}, [theme, enableSystem, attribute]);
|
|
359
|
+
}, [theme, brand, enableSystem, attribute, brandAttribute]);
|
|
342
360
|
const value = {
|
|
343
361
|
theme,
|
|
362
|
+
brand,
|
|
344
363
|
setTheme: (newTheme) => {
|
|
345
|
-
|
|
364
|
+
if (typeof window !== "undefined") {
|
|
365
|
+
localStorage.setItem(storageKey, newTheme);
|
|
366
|
+
}
|
|
346
367
|
setThemeState(newTheme);
|
|
347
368
|
},
|
|
369
|
+
setBrand: (newBrand) => {
|
|
370
|
+
if (typeof window !== "undefined") {
|
|
371
|
+
localStorage.setItem(brandStorageKey, newBrand);
|
|
372
|
+
}
|
|
373
|
+
setBrandState(newBrand);
|
|
374
|
+
},
|
|
348
375
|
resolvedTheme
|
|
349
376
|
};
|
|
350
377
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
|
|
@@ -356,6 +383,8 @@ var useTheme = () => {
|
|
|
356
383
|
}
|
|
357
384
|
return context;
|
|
358
385
|
};
|
|
386
|
+
var ConfigProvider = ThemeProvider;
|
|
387
|
+
var useConfig = useTheme;
|
|
359
388
|
|
|
360
389
|
// src/hooks/use-mobile.ts
|
|
361
390
|
var React2 = __toESM(require("react"), 1);
|
|
@@ -428,7 +457,7 @@ var import_react_slot = require("@radix-ui/react-slot");
|
|
|
428
457
|
var import_class_variance_authority = require("class-variance-authority");
|
|
429
458
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
430
459
|
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
431
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-
|
|
460
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
432
461
|
{
|
|
433
462
|
variants: {
|
|
434
463
|
variant: {
|
|
@@ -714,7 +743,10 @@ var BreadcrumbLink = React8.forwardRef(({ asChild, className, ...props }, ref) =
|
|
|
714
743
|
Comp,
|
|
715
744
|
{
|
|
716
745
|
ref,
|
|
717
|
-
className: cn(
|
|
746
|
+
className: cn(
|
|
747
|
+
"cursor-pointer transition-colors hover:text-foreground",
|
|
748
|
+
className
|
|
749
|
+
),
|
|
718
750
|
...props
|
|
719
751
|
}
|
|
720
752
|
);
|
|
@@ -1430,7 +1462,7 @@ var Checkbox = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
1430
1462
|
{
|
|
1431
1463
|
ref,
|
|
1432
1464
|
className: cn(
|
|
1433
|
-
"grid place-content-center peer shrink-0 rounded-sm border border-primary shadow cursor-pointer focus-visible:outline-none focus-visible:ring-
|
|
1465
|
+
"grid place-content-center peer shrink-0 rounded-sm border border-primary shadow cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground size-4",
|
|
1434
1466
|
className
|
|
1435
1467
|
),
|
|
1436
1468
|
...props,
|
|
@@ -1490,7 +1522,7 @@ var DialogContent = React14.forwardRef(({ className, children, ...props }, ref)
|
|
|
1490
1522
|
...props,
|
|
1491
1523
|
children: [
|
|
1492
1524
|
children,
|
|
1493
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background cursor-pointer transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background cursor-pointer transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
1494
1526
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.X, { className: "size-4" }),
|
|
1495
1527
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sr-only", children: "Close" })
|
|
1496
1528
|
] })
|
|
@@ -1891,7 +1923,7 @@ var DropdownMenuSubTrigger = React18.forwardRef(({ className, inset, children, .
|
|
|
1891
1923
|
{
|
|
1892
1924
|
ref,
|
|
1893
1925
|
className: cn(
|
|
1894
|
-
"flex cursor-
|
|
1926
|
+
"flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1895
1927
|
inset && "pl-8",
|
|
1896
1928
|
className
|
|
1897
1929
|
),
|
|
@@ -1934,7 +1966,7 @@ var DropdownMenuItem = React18.forwardRef(({ className, inset, ...props }, ref)
|
|
|
1934
1966
|
{
|
|
1935
1967
|
ref,
|
|
1936
1968
|
className: cn(
|
|
1937
|
-
"relative flex cursor-
|
|
1969
|
+
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
1938
1970
|
inset && "pl-8",
|
|
1939
1971
|
className
|
|
1940
1972
|
),
|
|
@@ -1947,7 +1979,7 @@ var DropdownMenuCheckboxItem = React18.forwardRef(({ className, children, ...pro
|
|
|
1947
1979
|
{
|
|
1948
1980
|
ref,
|
|
1949
1981
|
className: cn(
|
|
1950
|
-
"relative flex cursor-
|
|
1982
|
+
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
1951
1983
|
className
|
|
1952
1984
|
),
|
|
1953
1985
|
...props,
|
|
@@ -1963,7 +1995,7 @@ var DropdownMenuRadioItem = React18.forwardRef(({ className, children, ...props
|
|
|
1963
1995
|
{
|
|
1964
1996
|
ref,
|
|
1965
1997
|
className: cn(
|
|
1966
|
-
"relative flex cursor-
|
|
1998
|
+
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
1967
1999
|
className
|
|
1968
2000
|
),
|
|
1969
2001
|
...props,
|
|
@@ -2209,7 +2241,7 @@ var Input = React23.forwardRef(
|
|
|
2209
2241
|
{
|
|
2210
2242
|
type,
|
|
2211
2243
|
className: cn(
|
|
2212
|
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:
|
|
2244
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:font-medium file:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
2213
2245
|
className
|
|
2214
2246
|
),
|
|
2215
2247
|
ref,
|
|
@@ -2757,7 +2789,7 @@ var SelectTrigger = React31.forwardRef(({ className, children, ...props }, ref)
|
|
|
2757
2789
|
{
|
|
2758
2790
|
ref,
|
|
2759
2791
|
className: cn(
|
|
2760
|
-
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background cursor-pointer data-placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
2792
|
+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background cursor-pointer data-placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:opacity-50 [&>span]:line-clamp-1",
|
|
2761
2793
|
className
|
|
2762
2794
|
),
|
|
2763
2795
|
...props,
|
|
@@ -2800,7 +2832,7 @@ var SelectContent = React31.forwardRef(({ className, children, position = "poppe
|
|
|
2800
2832
|
ref,
|
|
2801
2833
|
className: cn(
|
|
2802
2834
|
"relative z-50 max-h-(--radix-select-content-available-height) min-w-32 overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-select-content-transform-origin)",
|
|
2803
|
-
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1
|
|
2835
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1",
|
|
2804
2836
|
className
|
|
2805
2837
|
),
|
|
2806
2838
|
position,
|
|
@@ -2836,7 +2868,7 @@ var SelectItem = React31.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
2836
2868
|
{
|
|
2837
2869
|
ref,
|
|
2838
2870
|
className: cn(
|
|
2839
|
-
"relative flex w-full cursor-
|
|
2871
|
+
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
2840
2872
|
className
|
|
2841
2873
|
),
|
|
2842
2874
|
...props,
|
|
@@ -3771,7 +3803,7 @@ var TabsTrigger = React39.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
3771
3803
|
{
|
|
3772
3804
|
ref,
|
|
3773
3805
|
className: cn(
|
|
3774
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background cursor-pointer transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
3806
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background cursor-pointer transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
|
|
3775
3807
|
className
|
|
3776
3808
|
),
|
|
3777
3809
|
...props
|
|
@@ -3783,7 +3815,7 @@ var TabsContent = React39.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
3783
3815
|
{
|
|
3784
3816
|
ref,
|
|
3785
3817
|
className: cn(
|
|
3786
|
-
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
3818
|
+
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
|
|
3787
3819
|
className
|
|
3788
3820
|
),
|
|
3789
3821
|
...props
|
|
@@ -3799,7 +3831,7 @@ var Textarea = React40.forwardRef(({ className, ...props }, ref) => {
|
|
|
3799
3831
|
"textarea",
|
|
3800
3832
|
{
|
|
3801
3833
|
className: cn(
|
|
3802
|
-
"flex min-h-15 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-
|
|
3834
|
+
"flex min-h-15 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
3803
3835
|
className
|
|
3804
3836
|
),
|
|
3805
3837
|
ref,
|
|
@@ -4320,6 +4352,7 @@ function LoadingState({
|
|
|
4320
4352
|
CommandList,
|
|
4321
4353
|
CommandSeparator,
|
|
4322
4354
|
CommandShortcut,
|
|
4355
|
+
ConfigProvider,
|
|
4323
4356
|
ConfirmDialog,
|
|
4324
4357
|
ContextMenu,
|
|
4325
4358
|
ContextMenuCheckboxItem,
|
|
@@ -4510,6 +4543,7 @@ function LoadingState({
|
|
|
4510
4543
|
navigationMenuTriggerStyle,
|
|
4511
4544
|
toast,
|
|
4512
4545
|
toggleVariants,
|
|
4546
|
+
useConfig,
|
|
4513
4547
|
useFormField,
|
|
4514
4548
|
useIsMobile,
|
|
4515
4549
|
useSidebar,
|