@scalably/ui 0.1.0 → 0.2.1
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/LICENSE +21 -0
- package/README.md +41 -34
- package/dist/index.d.cts +39 -7
- package/dist/index.d.ts +39 -7
- package/dist/index.esm.js +3 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +11 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Scalably
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Scalably UI Component Library
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
3
6
|
A modern, accessible, and fully isolated React component library built with TypeScript and Tailwind CSS. Designed to work seamlessly across multiple projects without style conflicts.
|
|
4
7
|
|
|
5
8
|
## 🚀 Features
|
|
@@ -20,19 +23,11 @@ npm install @scalably/ui
|
|
|
20
23
|
|
|
21
24
|
## 🎨 Usage
|
|
22
25
|
|
|
23
|
-
### 1.
|
|
26
|
+
### 1. Use Components (Styles Auto-Injected)
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
The `ScalablyUIProvider` automatically injects styles into `document.head`, so you don't need to manually import CSS. This ensures styles work correctly in portals (modals, tooltips, etc.). No wrapper or scope class is required—just wrap your app once.
|
|
26
29
|
|
|
27
30
|
```tsx
|
|
28
|
-
// In your main.tsx, App.tsx, or index.tsx
|
|
29
|
-
import "@scalably/ui/styles";
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### 2. Use Components
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import "@scalably/ui/styles";
|
|
36
31
|
import { ScalablyUIProvider, Form, FormField, Input, Button, ToastContainer, Toast } from "@scalably/ui";
|
|
37
32
|
|
|
38
33
|
export default function App() {
|
|
@@ -55,28 +50,40 @@ export default function App() {
|
|
|
55
50
|
}
|
|
56
51
|
```
|
|
57
52
|
|
|
58
|
-
###
|
|
53
|
+
### 2. Optional: Manual CSS Import
|
|
59
54
|
|
|
60
|
-
|
|
55
|
+
If you prefer to import CSS manually (e.g., for better control or SSR optimization), you can disable automatic injection:
|
|
61
56
|
|
|
62
57
|
```tsx
|
|
58
|
+
// In your main.tsx, App.tsx, or index.tsx
|
|
63
59
|
import "@scalably/ui/styles";
|
|
64
60
|
import { ScalablyUIProvider } from "@scalably/ui";
|
|
65
61
|
|
|
66
62
|
export default function App() {
|
|
67
|
-
return
|
|
63
|
+
return (
|
|
64
|
+
<ScalablyUIProvider injectStyles={false}>
|
|
65
|
+
{/* your app */}
|
|
66
|
+
</ScalablyUIProvider>
|
|
67
|
+
);
|
|
68
68
|
}
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
### 3. Portal Support
|
|
72
|
+
|
|
73
|
+
Styles automatically work in portaled components (modals, tooltips, popovers, etc.) because:
|
|
74
|
+
- Styles are injected globally into `document.head`
|
|
75
|
+
- CSS variables propagate to all elements
|
|
76
|
+
- No parent selector dependencies
|
|
72
77
|
|
|
73
78
|
```tsx
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
</
|
|
79
|
+
// Tooltips, modals, and other portaled components work automatically
|
|
80
|
+
<Tooltip content="This works in portals!" portal>
|
|
81
|
+
<Button>Hover me</Button>
|
|
82
|
+
</Tooltip>
|
|
78
83
|
```
|
|
79
84
|
|
|
85
|
+
Note: Toasts in this library are intentionally declarative. Render a `Toast` inside a `ToastContainer` when you want it visible (e.g., based on component state). This avoids hidden globals and keeps UI state predictable. If you prefer an imperative API, you can wrap your own tiny helper around local state to toggle a `Toast` component.
|
|
86
|
+
|
|
80
87
|
### 4. React import guidance
|
|
81
88
|
|
|
82
89
|
If you reference the React namespace (e.g., `React.useState`, `React.forwardRef`, `React.SVGProps`) add an explicit import to avoid UMD global errors:
|
|
@@ -145,13 +152,11 @@ All components use prefixed Tailwind classes (`sui-*`) to ensure complete style
|
|
|
145
152
|
|
|
146
153
|
```tsx
|
|
147
154
|
// ✅ Correct - components are properly isolated
|
|
148
|
-
<
|
|
149
|
-
<Button>Isolated Button</Button>
|
|
150
|
-
</div>
|
|
155
|
+
<Button>Isolated Button</Button>
|
|
151
156
|
|
|
152
|
-
//
|
|
153
|
-
<div className="p-4">
|
|
154
|
-
<Button>Button
|
|
157
|
+
// ✅ Your global styles won't break the components
|
|
158
|
+
<div className="p-4 bg-red-500">
|
|
159
|
+
<Button>Isolated Button</Button>
|
|
155
160
|
</div>
|
|
156
161
|
```
|
|
157
162
|
|
|
@@ -222,14 +227,14 @@ Visit our Storybook documentation for:
|
|
|
222
227
|
|
|
223
228
|
### Colors
|
|
224
229
|
|
|
225
|
-
- **Primary**: `#36499B`
|
|
226
|
-
- **Secondary**: `#F2F6FC`
|
|
227
|
-
- **Success**: `#22BC4D`
|
|
228
|
-
- **Warning**: `#FF7A00`
|
|
229
|
-
- **Info**: `#2772F0`
|
|
230
|
-
- **Error**: `#EA3540`
|
|
231
|
-
- **Inactive**: `#777E90`
|
|
232
|
-
- **Disabled**: `#B2BBC7`
|
|
230
|
+
- **Primary**: `#36499B` – Main brand color for primary actions (`sui-bg-primary`, `sui-text-primary`)
|
|
231
|
+
- **Secondary**: `#F2F6FC` – Light background colors (`sui-bg-secondary`, `sui-text-secondary`)
|
|
232
|
+
- **Success**: `#22BC4D` – Positive actions and success states (`sui-bg-success`, `sui-text-success`)
|
|
233
|
+
- **Warning**: `#FF7A00` – Caution and in-progress states (`sui-bg-warning`, `sui-text-warning`)
|
|
234
|
+
- **Info**: `#2772F0` – Informational content (`sui-bg-info`, `sui-text-info`)
|
|
235
|
+
- **Error**: `#EA3540` – Destructive actions and errors (`sui-bg-error`, `sui-text-error`)
|
|
236
|
+
- **Inactive**: `#777E90` – Inactive or completed states (`sui-text-inactive`, `sui-border-inactive`)
|
|
237
|
+
- **Disabled**: `#B2BBC7` – Disabled elements (`sui-text-disabled`, `sui-border-disabled`)
|
|
233
238
|
|
|
234
239
|
### Typography
|
|
235
240
|
|
|
@@ -243,10 +248,12 @@ Visit our Storybook documentation for:
|
|
|
243
248
|
|
|
244
249
|
The library uses a custom Tailwind configuration with:
|
|
245
250
|
|
|
246
|
-
- **Prefix**: `sui-` for all utility classes
|
|
247
|
-
- **
|
|
251
|
+
- **Prefix**: `sui-` for all utility classes (provides style isolation)
|
|
252
|
+
- **Global Styles**: Automatically injected via `ScalablyUIProvider`
|
|
253
|
+
- **CSS Variables**: Design tokens available globally for theming
|
|
248
254
|
- **Custom Colors**: Brand-specific color palette
|
|
249
255
|
- **Custom Shadows**: Soft, medium, and strong shadow variants
|
|
256
|
+
- **Portal Support**: Styles work in portaled components (modals, tooltips, etc.)
|
|
250
257
|
|
|
251
258
|
### Build Configuration
|
|
252
259
|
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,6 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
-
import { ClassValue } from 'clsx';
|
|
7
6
|
import * as date_fns from 'date-fns';
|
|
8
7
|
export { addMonths, endOfMonth, isSameDay, startOfMonth } from 'date-fns';
|
|
9
8
|
|
|
@@ -142,7 +141,7 @@ interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "
|
|
|
142
141
|
declare const StatusBadge: react.ForwardRefExoticComponent<StatusBadgeProps & react.RefAttributes<HTMLSpanElement>>;
|
|
143
142
|
|
|
144
143
|
declare const buttonVariants: (props?: ({
|
|
145
|
-
variant?: "
|
|
144
|
+
variant?: "link" | "text" | "outline" | "default" | "destructive" | "secondary" | null | undefined;
|
|
146
145
|
size?: "icon" | "md" | "lg" | null | undefined;
|
|
147
146
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
148
147
|
type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
|
@@ -750,6 +749,13 @@ interface FileUploadProps {
|
|
|
750
749
|
* This runs after internal type/size validation.
|
|
751
750
|
*/
|
|
752
751
|
onValidateFile?: (file: File) => FileUploadError | null | undefined;
|
|
752
|
+
/** Enable video thumbnail capture UI via modal when a video file is selected. */
|
|
753
|
+
enableVideoThumbnail?: boolean;
|
|
754
|
+
/**
|
|
755
|
+
* Called when a thumbnail is captured from the selected video's current frame.
|
|
756
|
+
* Provides the Blob (image/jpeg) and a data URL for immediate preview.
|
|
757
|
+
*/
|
|
758
|
+
onThumbnailCapture?: (thumbnail: Blob, dataUrl: string, file: FileUploadFile) => void;
|
|
753
759
|
}
|
|
754
760
|
/**
|
|
755
761
|
* File upload component with drag-and-drop, validation, previews, and accessibility support.
|
|
@@ -1569,29 +1575,55 @@ declare const ViewToggle: React.FC<ViewToggleProps>;
|
|
|
1569
1575
|
|
|
1570
1576
|
interface ScalablyUIProviderProps {
|
|
1571
1577
|
children: React.ReactNode;
|
|
1578
|
+
/**
|
|
1579
|
+
* @deprecated `className` is no longer needed. Styles are applied globally.
|
|
1580
|
+
*/
|
|
1572
1581
|
className?: string;
|
|
1573
1582
|
/**
|
|
1574
|
-
*
|
|
1583
|
+
* @deprecated `asChild` is no longer needed. Styles are applied globally.
|
|
1575
1584
|
*/
|
|
1576
1585
|
asChild?: boolean;
|
|
1586
|
+
/**
|
|
1587
|
+
* When true, automatically injects the component library styles into document.head.
|
|
1588
|
+
* This ensures styles work in portals (modals, tooltips, etc.) without requiring
|
|
1589
|
+
* manual CSS imports. Defaults to true.
|
|
1590
|
+
*/
|
|
1591
|
+
injectStyles?: boolean;
|
|
1577
1592
|
}
|
|
1578
1593
|
/**
|
|
1579
1594
|
* ScalablyUIProvider
|
|
1580
1595
|
*
|
|
1581
|
-
*
|
|
1596
|
+
* Provides the Scalably UI component library context and automatically injects styles.
|
|
1597
|
+
* All classes are globally prefixed (`sui-*`), so no wrapper element is required.
|
|
1598
|
+
*
|
|
1599
|
+
* Features:
|
|
1600
|
+
* - Automatically injects CSS into document.head (prevents double-injection)
|
|
1601
|
+
* - Works with SSR (only injects on client-side)
|
|
1602
|
+
* - Ensures styles are available for portaled components
|
|
1603
|
+
* - Maintains style isolation via 'sui-' prefix
|
|
1582
1604
|
*
|
|
1583
1605
|
* Usage:
|
|
1606
|
+
* ```tsx
|
|
1584
1607
|
* <ScalablyUIProvider>
|
|
1585
1608
|
* <App />
|
|
1586
1609
|
* </ScalablyUIProvider>
|
|
1610
|
+
* ```
|
|
1587
1611
|
*
|
|
1588
|
-
*
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1612
|
+
* To disable automatic style injection (if you import CSS manually):
|
|
1613
|
+
* ```tsx
|
|
1614
|
+
* <ScalablyUIProvider injectStyles={false}>
|
|
1615
|
+
* <App />
|
|
1591
1616
|
* </ScalablyUIProvider>
|
|
1617
|
+
* ```
|
|
1592
1618
|
*/
|
|
1593
1619
|
declare const ScalablyUIProvider: React.FC<ScalablyUIProviderProps>;
|
|
1594
1620
|
|
|
1621
|
+
/**
|
|
1622
|
+
* Type for class values accepted by clsx
|
|
1623
|
+
*/
|
|
1624
|
+
type ClassValue = ClassArray | ClassDictionary | string | number | bigint | null | boolean | undefined;
|
|
1625
|
+
type ClassDictionary = Record<string, unknown>;
|
|
1626
|
+
type ClassArray = ClassValue[];
|
|
1595
1627
|
/**
|
|
1596
1628
|
* Utility function to merge Tailwind CSS classes intelligently
|
|
1597
1629
|
* Combines clsx for conditional classes and tailwind-merge for conflict resolution
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
-
import { ClassValue } from 'clsx';
|
|
7
6
|
import * as date_fns from 'date-fns';
|
|
8
7
|
export { addMonths, endOfMonth, isSameDay, startOfMonth } from 'date-fns';
|
|
9
8
|
|
|
@@ -142,7 +141,7 @@ interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "
|
|
|
142
141
|
declare const StatusBadge: react.ForwardRefExoticComponent<StatusBadgeProps & react.RefAttributes<HTMLSpanElement>>;
|
|
143
142
|
|
|
144
143
|
declare const buttonVariants: (props?: ({
|
|
145
|
-
variant?: "
|
|
144
|
+
variant?: "link" | "text" | "outline" | "default" | "destructive" | "secondary" | null | undefined;
|
|
146
145
|
size?: "icon" | "md" | "lg" | null | undefined;
|
|
147
146
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
148
147
|
type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
|
@@ -750,6 +749,13 @@ interface FileUploadProps {
|
|
|
750
749
|
* This runs after internal type/size validation.
|
|
751
750
|
*/
|
|
752
751
|
onValidateFile?: (file: File) => FileUploadError | null | undefined;
|
|
752
|
+
/** Enable video thumbnail capture UI via modal when a video file is selected. */
|
|
753
|
+
enableVideoThumbnail?: boolean;
|
|
754
|
+
/**
|
|
755
|
+
* Called when a thumbnail is captured from the selected video's current frame.
|
|
756
|
+
* Provides the Blob (image/jpeg) and a data URL for immediate preview.
|
|
757
|
+
*/
|
|
758
|
+
onThumbnailCapture?: (thumbnail: Blob, dataUrl: string, file: FileUploadFile) => void;
|
|
753
759
|
}
|
|
754
760
|
/**
|
|
755
761
|
* File upload component with drag-and-drop, validation, previews, and accessibility support.
|
|
@@ -1569,29 +1575,55 @@ declare const ViewToggle: React.FC<ViewToggleProps>;
|
|
|
1569
1575
|
|
|
1570
1576
|
interface ScalablyUIProviderProps {
|
|
1571
1577
|
children: React.ReactNode;
|
|
1578
|
+
/**
|
|
1579
|
+
* @deprecated `className` is no longer needed. Styles are applied globally.
|
|
1580
|
+
*/
|
|
1572
1581
|
className?: string;
|
|
1573
1582
|
/**
|
|
1574
|
-
*
|
|
1583
|
+
* @deprecated `asChild` is no longer needed. Styles are applied globally.
|
|
1575
1584
|
*/
|
|
1576
1585
|
asChild?: boolean;
|
|
1586
|
+
/**
|
|
1587
|
+
* When true, automatically injects the component library styles into document.head.
|
|
1588
|
+
* This ensures styles work in portals (modals, tooltips, etc.) without requiring
|
|
1589
|
+
* manual CSS imports. Defaults to true.
|
|
1590
|
+
*/
|
|
1591
|
+
injectStyles?: boolean;
|
|
1577
1592
|
}
|
|
1578
1593
|
/**
|
|
1579
1594
|
* ScalablyUIProvider
|
|
1580
1595
|
*
|
|
1581
|
-
*
|
|
1596
|
+
* Provides the Scalably UI component library context and automatically injects styles.
|
|
1597
|
+
* All classes are globally prefixed (`sui-*`), so no wrapper element is required.
|
|
1598
|
+
*
|
|
1599
|
+
* Features:
|
|
1600
|
+
* - Automatically injects CSS into document.head (prevents double-injection)
|
|
1601
|
+
* - Works with SSR (only injects on client-side)
|
|
1602
|
+
* - Ensures styles are available for portaled components
|
|
1603
|
+
* - Maintains style isolation via 'sui-' prefix
|
|
1582
1604
|
*
|
|
1583
1605
|
* Usage:
|
|
1606
|
+
* ```tsx
|
|
1584
1607
|
* <ScalablyUIProvider>
|
|
1585
1608
|
* <App />
|
|
1586
1609
|
* </ScalablyUIProvider>
|
|
1610
|
+
* ```
|
|
1587
1611
|
*
|
|
1588
|
-
*
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1612
|
+
* To disable automatic style injection (if you import CSS manually):
|
|
1613
|
+
* ```tsx
|
|
1614
|
+
* <ScalablyUIProvider injectStyles={false}>
|
|
1615
|
+
* <App />
|
|
1591
1616
|
* </ScalablyUIProvider>
|
|
1617
|
+
* ```
|
|
1592
1618
|
*/
|
|
1593
1619
|
declare const ScalablyUIProvider: React.FC<ScalablyUIProviderProps>;
|
|
1594
1620
|
|
|
1621
|
+
/**
|
|
1622
|
+
* Type for class values accepted by clsx
|
|
1623
|
+
*/
|
|
1624
|
+
type ClassValue = ClassArray | ClassDictionary | string | number | bigint | null | boolean | undefined;
|
|
1625
|
+
type ClassDictionary = Record<string, unknown>;
|
|
1626
|
+
type ClassArray = ClassValue[];
|
|
1595
1627
|
/**
|
|
1596
1628
|
* Utility function to merge Tailwind CSS classes intelligently
|
|
1597
1629
|
* Combines clsx for conditional classes and tailwind-merge for conflict resolution
|