@sypra-ui/ui 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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 ADDED
@@ -0,0 +1,84 @@
1
+ # @sypra-ui/ui
2
+
3
+ React primitives for React 18+ applications. They use Tailwind utility classes
4
+ and semantic CSS variables, so the library has no runtime styling dependency.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ pnpm add @sypra-ui/ui
10
+ ```
11
+
12
+ Import the theme tokens once in your global stylesheet:
13
+
14
+ ```css
15
+ @import '@sypra-ui/ui/styles.css';
16
+ @tailwind base;
17
+ @tailwind components;
18
+ @tailwind utilities;
19
+ ```
20
+
21
+ Tell Tailwind to scan the installed package so it emits the utilities used by
22
+ the components:
23
+
24
+ ```ts
25
+ // tailwind.config.ts
26
+ export default {
27
+ content: [
28
+ './src/**/*.{ts,tsx}',
29
+ './node_modules/@sypra-ui/ui/dist/**/*.{js,mjs}',
30
+ ],
31
+ };
32
+ ```
33
+
34
+ ## Customize the theme
35
+
36
+ Set the semantic tokens on `:root` for an application-wide theme, or on a
37
+ wrapper to scope a theme to one part of the page.
38
+
39
+ ```css
40
+ .brand-theme {
41
+ --rui-background: 224 30% 8%;
42
+ --rui-foreground: 210 40% 98%;
43
+ --rui-card: 224 25% 12%;
44
+ --rui-primary: 270 85% 62%;
45
+ --rui-primary-foreground: 0 0% 100%;
46
+ --rui-secondary: 224 20% 18%;
47
+ --rui-border: 224 18% 24%;
48
+ --rui-success: 142 71% 45%;
49
+ --rui-success-background: 142 45% 14%;
50
+ --rui-success-foreground: 142 70% 82%;
51
+ --rui-warning: 38 92% 50%;
52
+ --rui-warning-background: 36 45% 16%;
53
+ --rui-warning-foreground: 45 93% 81%;
54
+ --rui-ring: 270 85% 68%;
55
+ --rui-radius: 1rem;
56
+ }
57
+ ```
58
+
59
+ `--rui-radius` changes the default shape: use `0` for sharp controls, a small
60
+ value for subtle rounding, or `9999px` for pills. The full token set is in
61
+ `src/styles.css`.
62
+
63
+ ## Customize one component
64
+
65
+ Most visual primitives accept `className`, and `Button` provides `variant` and
66
+ `size` (`sm`, `md`, `lg`). Use regular Tailwind utilities for local sizing or
67
+ shape changes. Prefix an override with `!` when it replaces a library utility
68
+ for the same CSS property. Wrap a page composition in a themed element to
69
+ scope token changes to that page.
70
+
71
+ ```tsx
72
+ import { Button, Card } from '@sypra-ui/ui';
73
+
74
+ <Button size="lg" className="!rounded-full !px-8 !text-base">
75
+ Upgrade
76
+ </Button>
77
+
78
+ <Card className="!rounded-none !border-violet-500 !bg-violet-50">
79
+ Custom card
80
+ </Card>
81
+ ```
82
+
83
+ The package is ESM-only. Import `@sypra-ui/ui/styles.css` exactly once per
84
+ application.
@@ -0,0 +1,286 @@
1
+ import * as react from 'react';
2
+ import { ButtonHTMLAttributes, InputHTMLAttributes, ComponentPropsWithoutRef, SelectHTMLAttributes, ReactNode, CSSProperties, TableHTMLAttributes } from 'react';
3
+
4
+ declare const cn: (...values: Array<string | false | null | undefined>) => string;
5
+
6
+ declare const buttonStyles: {
7
+ readonly primary: "bg-[hsl(var(--rui-primary))] text-[hsl(var(--rui-primary-foreground))] hover:opacity-90";
8
+ readonly secondary: "bg-[hsl(var(--rui-secondary))] text-[hsl(var(--rui-secondary-foreground))] hover:opacity-80";
9
+ readonly outline: "border border-[hsl(var(--rui-border))] bg-transparent hover:bg-[hsl(var(--rui-accent))]";
10
+ readonly ghost: "bg-transparent hover:bg-[hsl(var(--rui-accent))]";
11
+ readonly destructive: "bg-[hsl(var(--rui-destructive))] text-[hsl(var(--rui-destructive-foreground))] hover:opacity-90";
12
+ };
13
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
14
+ variant?: keyof typeof buttonStyles;
15
+ size?: 'sm' | 'md' | 'lg';
16
+ loading?: boolean;
17
+ }
18
+ declare function Button({ variant, size, loading, className, children, disabled, ...props }: ButtonProps): react.JSX.Element;
19
+ declare function IconButton({ children, 'aria-label': label, className, ...props }: ButtonProps): react.JSX.Element;
20
+ declare const Input: ({ className, ...props }: InputHTMLAttributes<HTMLInputElement>) => react.JSX.Element;
21
+ declare const Textarea: ({ className, ...props }: ComponentPropsWithoutRef<"textarea">) => react.JSX.Element;
22
+ declare const Label: ({ className, ...props }: ComponentPropsWithoutRef<"label">) => react.JSX.Element;
23
+ declare const Checkbox: ({ className, ...props }: InputHTMLAttributes<HTMLInputElement>) => react.JSX.Element;
24
+ declare const Radio: ({ className, ...props }: InputHTMLAttributes<HTMLInputElement>) => react.JSX.Element;
25
+ declare const Switch: ({ checked, onChange, disabled, className, ...props }: Omit<InputHTMLAttributes<HTMLInputElement>, "type">) => react.JSX.Element;
26
+ declare const Select: ({ className, children, ...props }: SelectHTMLAttributes<HTMLSelectElement>) => react.JSX.Element;
27
+
28
+ type ChildrenProps$3 = {
29
+ children?: ReactNode;
30
+ className?: string;
31
+ };
32
+ declare function Card({ className, ...props }: ComponentPropsWithoutRef<'section'>): react.JSX.Element;
33
+ declare function CardHeader({ className, ...props }: ComponentPropsWithoutRef<'div'>): react.JSX.Element;
34
+ declare function CardTitle({ className, ...props }: ComponentPropsWithoutRef<'h3'>): react.JSX.Element;
35
+ declare function CardDescription({ className, ...props }: ComponentPropsWithoutRef<'p'>): react.JSX.Element;
36
+ declare function Badge({ className, variant, ...props }: ChildrenProps$3 & {
37
+ variant?: 'default' | 'success' | 'warning' | 'destructive' | 'outline';
38
+ }): react.JSX.Element;
39
+ declare function Avatar({ src, alt, fallback, className, }: {
40
+ src?: string;
41
+ alt?: string;
42
+ fallback?: ReactNode;
43
+ className?: string;
44
+ }): react.JSX.Element;
45
+ declare const Separator: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
46
+ declare const Skeleton: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
47
+ declare function Progress({ value, max, label, className, }: {
48
+ value: number;
49
+ max?: number;
50
+ label?: string;
51
+ className?: string;
52
+ }): react.JSX.Element;
53
+
54
+ type ChildrenProps$2 = {
55
+ children?: ReactNode;
56
+ className?: string;
57
+ };
58
+ declare function Dialog({ open: controlled, defaultOpen, onOpenChange, children, }: {
59
+ open?: boolean;
60
+ defaultOpen?: boolean;
61
+ onOpenChange?: (open: boolean) => void;
62
+ children: ReactNode;
63
+ }): react.JSX.Element;
64
+ declare function DialogTrigger({ children, asChild, }: {
65
+ children: ReactNode;
66
+ asChild?: boolean;
67
+ }): react.JSX.Element;
68
+ declare function DialogClose({ children, asChild, }: {
69
+ children: ReactNode;
70
+ asChild?: boolean;
71
+ }): react.JSX.Element;
72
+ declare function DialogContent({ children, className, movable, constrainToViewport, style, ...props }: ChildrenProps$2 & {
73
+ movable?: boolean;
74
+ constrainToViewport?: boolean;
75
+ style?: CSSProperties;
76
+ }): react.ReactPortal | null;
77
+ declare const DialogHeader: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
78
+ declare const DialogTitle: ({ className, ...props }: ComponentPropsWithoutRef<"h2">) => react.JSX.Element;
79
+ declare const DialogDescription: ({ className, ...props }: ComponentPropsWithoutRef<"p">) => react.JSX.Element;
80
+ declare const DialogBody: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
81
+ declare const DialogFooter: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
82
+ declare const AlertDialog: typeof Dialog;
83
+ declare const AlertDialogTrigger: typeof DialogTrigger;
84
+ declare const AlertDialogContent: typeof DialogContent;
85
+ declare const AlertDialogHeader: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
86
+ declare const AlertDialogTitle: ({ className, ...props }: ComponentPropsWithoutRef<"h2">) => react.JSX.Element;
87
+ declare const AlertDialogDescription: ({ className, ...props }: ComponentPropsWithoutRef<"p">) => react.JSX.Element;
88
+ declare const AlertDialogFooter: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
89
+ declare const AlertDialogClose: typeof DialogClose;
90
+ declare function Sheet({ children, ...props }: ComponentPropsWithoutRef<typeof Dialog>): react.JSX.Element;
91
+ declare const SheetTrigger: typeof DialogTrigger;
92
+ declare const SheetClose: typeof DialogClose;
93
+ declare function SheetContent({ className, ...props }: ComponentPropsWithoutRef<typeof DialogContent>): react.JSX.Element;
94
+ declare const Drawer: typeof Sheet;
95
+ declare const DrawerTrigger: typeof DialogTrigger;
96
+ declare const DrawerContent: typeof SheetContent;
97
+
98
+ declare function Popover({ trigger, children, className, open: controlledOpen, defaultOpen, onOpenChange, }: {
99
+ trigger: ReactNode;
100
+ children: ReactNode;
101
+ className?: string;
102
+ open?: boolean;
103
+ defaultOpen?: boolean;
104
+ onOpenChange?: (open: boolean) => void;
105
+ }): react.JSX.Element;
106
+ declare const Tooltip: ({ content, children, className, }: {
107
+ content: string;
108
+ children: ReactNode;
109
+ className?: string;
110
+ }) => react.JSX.Element;
111
+ declare function DropdownMenu({ trigger, children, }: {
112
+ trigger: ReactNode;
113
+ children: ReactNode;
114
+ }): react.JSX.Element;
115
+ declare const DropdownMenuItem: ({ className, ...props }: ComponentPropsWithoutRef<"button">) => react.JSX.Element;
116
+
117
+ type ChildrenProps$1 = {
118
+ children?: ReactNode;
119
+ className?: string;
120
+ };
121
+ declare function Navbar({ brand, children, className, label, }: {
122
+ brand?: ReactNode;
123
+ children?: ReactNode;
124
+ className?: string;
125
+ label?: string;
126
+ }): react.JSX.Element;
127
+ declare function Sidebar({ children, className, label, }: ChildrenProps$1 & {
128
+ label?: string;
129
+ }): react.JSX.Element;
130
+ declare function MobileNav({ children, className, label, }: ChildrenProps$1 & {
131
+ label?: string;
132
+ }): react.JSX.Element;
133
+ declare function Breadcrumb({ items, }: {
134
+ items: Array<{
135
+ label: string;
136
+ href?: string;
137
+ }>;
138
+ }): react.JSX.Element;
139
+ declare function Tabs({ tabs, value, defaultValue, onValueChange, className, }: {
140
+ tabs: Array<{
141
+ value: string;
142
+ label: ReactNode;
143
+ content: ReactNode;
144
+ disabled?: boolean;
145
+ }>;
146
+ value?: string;
147
+ defaultValue?: string;
148
+ onValueChange?: (value: string) => void;
149
+ className?: string;
150
+ }): react.JSX.Element;
151
+ declare function Accordion({ items, type, }: {
152
+ items: Array<{
153
+ value: string;
154
+ title: ReactNode;
155
+ content: ReactNode;
156
+ }>;
157
+ type?: 'single' | 'multiple';
158
+ }): react.JSX.Element;
159
+ declare function Pagination({ page, pageSize, total, onPageChange, onPageSizeChange, pageSizeOptions, ariaLabel, className, }: {
160
+ page: number;
161
+ pageSize: number;
162
+ total: number;
163
+ onPageChange: (page: number) => void;
164
+ onPageSizeChange?: (size: number) => void;
165
+ pageSizeOptions?: number[];
166
+ ariaLabel?: string;
167
+ className?: string;
168
+ }): react.JSX.Element;
169
+
170
+ declare function Alert({ title, children, variant, className, }: {
171
+ title?: ReactNode;
172
+ children?: ReactNode;
173
+ variant?: 'default' | 'destructive' | 'success';
174
+ className?: string;
175
+ }): react.JSX.Element;
176
+ declare function Toast({ title, description, action, className, }: {
177
+ title: ReactNode;
178
+ description?: ReactNode;
179
+ action?: ReactNode;
180
+ className?: string;
181
+ }): react.JSX.Element;
182
+ declare const EmptyState: ({ title, description, action, className, }: {
183
+ title?: ReactNode;
184
+ description?: ReactNode;
185
+ action?: ReactNode;
186
+ className?: string;
187
+ }) => react.JSX.Element;
188
+ declare const ErrorState: ({ title, onRetry, className, }: {
189
+ title?: ReactNode;
190
+ onRetry?: () => void;
191
+ className?: string;
192
+ }) => react.JSX.Element;
193
+ declare const LoadingState: ({ label, className, }: {
194
+ label?: string;
195
+ className?: string;
196
+ }) => react.JSX.Element;
197
+
198
+ type ChildrenProps = {
199
+ children?: ReactNode;
200
+ className?: string;
201
+ };
202
+ declare const PageShell: ({ as: Component, className, ...props }: ComponentPropsWithoutRef<"main"> & {
203
+ as?: "main" | "div";
204
+ }) => react.JSX.Element;
205
+ declare const PageHeader: ({ as: Heading, title, description, actions, className, }: {
206
+ title: ReactNode;
207
+ as?: "h1" | "h2" | "h3";
208
+ description?: ReactNode;
209
+ actions?: ReactNode;
210
+ className?: string;
211
+ }) => react.JSX.Element;
212
+ declare const PageContent: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
213
+ declare const Section: ({ title, description, children, className, }: ChildrenProps & {
214
+ title?: ReactNode;
215
+ description?: ReactNode;
216
+ }) => react.JSX.Element;
217
+ declare const Stack: ({ gap, className, ...props }: ComponentPropsWithoutRef<"div"> & {
218
+ gap?: 1 | 2 | 3 | 4 | 6 | 8;
219
+ }) => react.JSX.Element;
220
+ declare const Container: ({ className, ...props }: ComponentPropsWithoutRef<"div">) => react.JSX.Element;
221
+
222
+ declare const Table: ({ className, ...props }: TableHTMLAttributes<HTMLTableElement>) => react.JSX.Element;
223
+ declare const TableHeader: ({ className, ...props }: ComponentPropsWithoutRef<"thead">) => react.JSX.Element;
224
+ declare const TableBody: ({ className, ...props }: ComponentPropsWithoutRef<"tbody">) => react.JSX.Element;
225
+ declare const TableFooter: ({ className, ...props }: ComponentPropsWithoutRef<"tfoot">) => react.JSX.Element;
226
+ declare const TableRow: ({ className, ...props }: ComponentPropsWithoutRef<"tr">) => react.JSX.Element;
227
+ declare const TableHead: ({ className, ...props }: ComponentPropsWithoutRef<"th">) => react.JSX.Element;
228
+ declare const TableCell: ({ className, ...props }: ComponentPropsWithoutRef<"td">) => react.JSX.Element;
229
+ declare const TableCaption: ({ className, ...props }: ComponentPropsWithoutRef<"caption">) => react.JSX.Element;
230
+ type DataColumn<T> = {
231
+ key: keyof T | string;
232
+ header: ReactNode;
233
+ cell?: (row: T) => ReactNode;
234
+ sortable?: boolean;
235
+ className?: string;
236
+ };
237
+ type DataTablePagination = {
238
+ page: number;
239
+ pageSize: number;
240
+ total: number;
241
+ };
242
+ declare function DataTable<T extends Record<string, unknown>>({ data, columns, loading, error, pagination, onPageChange, onRowClick, emptyMessage, className, }: {
243
+ data: T[];
244
+ columns: DataColumn<T>[];
245
+ loading?: boolean;
246
+ error?: ReactNode;
247
+ pagination?: DataTablePagination;
248
+ onPageChange?: (page: number) => void;
249
+ onRowClick?: (row: T) => void;
250
+ emptyMessage?: ReactNode;
251
+ className?: string;
252
+ }): react.JSX.Element;
253
+ declare function SearchableTable<T extends Record<string, unknown>>({ data, columns, searchKeys, ...props }: Omit<ComponentPropsWithoutRef<typeof DataTable<T>>, 'data'> & {
254
+ data: T[];
255
+ columns: DataColumn<T>[];
256
+ searchKeys: Array<keyof T>;
257
+ }): react.JSX.Element;
258
+ declare const PaginatedTable: typeof DataTable;
259
+
260
+ declare function Command({ open, onOpenChange, items, }: {
261
+ open: boolean;
262
+ onOpenChange: (open: boolean) => void;
263
+ items: Array<{
264
+ label: string;
265
+ onSelect: () => void;
266
+ keywords?: string[];
267
+ }>;
268
+ }): react.JSX.Element;
269
+ declare function ContextMenu({ children, menu, }: {
270
+ children: ReactNode;
271
+ menu: ReactNode;
272
+ }): react.JSX.Element;
273
+ declare function CopyButton({ value, children, onCopy, }: {
274
+ value: string;
275
+ children?: ReactNode;
276
+ onCopy?: () => void;
277
+ }): react.JSX.Element;
278
+ declare function PasswordInput({ className, ...props }: InputHTMLAttributes<HTMLInputElement>): react.JSX.Element;
279
+ declare function FileUpload({ accept, multiple, onFiles, label, }: {
280
+ accept?: string;
281
+ multiple?: boolean;
282
+ onFiles: (files: File[]) => void;
283
+ label?: string;
284
+ }): react.JSX.Element;
285
+
286
+ export { Accordion, Alert, AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Avatar, Badge, Breadcrumb, Button, type ButtonProps, Card, CardDescription, CardHeader, CardTitle, Checkbox, Command, Container, ContextMenu, CopyButton, type DataColumn, DataTable, type DataTablePagination, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerContent, DrawerTrigger, DropdownMenu, DropdownMenuItem, EmptyState, ErrorState, FileUpload, IconButton, Input, Label, LoadingState, MobileNav, Navbar, PageContent, PageHeader, PageShell, PaginatedTable, Pagination, PasswordInput, Popover, Progress, Radio, SearchableTable, Section, Select, Separator, Sheet, SheetClose, SheetContent, SheetTrigger, Sidebar, Skeleton, Stack, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Textarea, Toast, Tooltip, cn };