@suribef/suri-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 +21 -0
- package/README.md +329 -0
- package/dist/components/Badge/Badge.d.ts +10 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Button/Button.d.ts +10 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Card/Card.d.ts +34 -0
- package/dist/components/Card/index.d.ts +2 -0
- package/dist/components/Divider/Divider.d.ts +10 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Input/Input.d.ts +8 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Select/Select.d.ts +20 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Spinner/Spinner.d.ts +10 -0
- package/dist/components/Spinner/index.d.ts +2 -0
- package/dist/components/Stack/Stack.d.ts +15 -0
- package/dist/components/Stack/index.d.ts +2 -0
- package/dist/components/Textarea/Textarea.d.ts +10 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/index.d.ts +19 -0
- package/dist/suri-ui.cjs +6 -0
- package/dist/suri-ui.css +2 -0
- package/dist/suri-ui.js +612 -0
- package/dist/utils/cn.d.ts +1 -0
- package/dist/utils/useCombinedRef.d.ts +2 -0
- package/package.json +107 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sergio Uribe
|
|
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,329 @@
|
|
|
1
|
+
# SuriUI
|
|
2
|
+
|
|
3
|
+
React component library built with TypeScript, CSS Modules, and
|
|
4
|
+
zero runtime dependencies.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@suribef/suri-ui)
|
|
7
|
+
[](https://github.com/Suribef/suri-ui/actions)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @suribef/suri-ui
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Peer dependencies** — install if not already present:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react react-dom
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
Import the design tokens once at your app's entry point:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// main.tsx or App.tsx
|
|
31
|
+
import '@suribef/suri-ui/dist/suri-ui.css'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This registers the CSS custom properties (colors, spacing, radius,
|
|
35
|
+
typography) that all components depend on. Without this import,
|
|
36
|
+
components render without styles.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Components
|
|
41
|
+
|
|
42
|
+
### Button
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { Button } from '@suribef/suri-ui'
|
|
46
|
+
|
|
47
|
+
<Button variant="primary" size="md" onClick={handleClick}>
|
|
48
|
+
Save changes
|
|
49
|
+
</Button>
|
|
50
|
+
|
|
51
|
+
<Button loading>Saving...</Button>
|
|
52
|
+
|
|
53
|
+
<Button variant="danger" disabled>Delete</Button>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Default | Description |
|
|
57
|
+
|------|------|---------|-------------|
|
|
58
|
+
| variant | `primary \| secondary \| ghost \| danger` | `primary` | Visual style |
|
|
59
|
+
| size | `sm \| md \| lg` | `md` | Height and padding scale |
|
|
60
|
+
| loading | `boolean` | `false` | Shows spinner, blocks clicks, keeps focus |
|
|
61
|
+
| disabled | `boolean` | `false` | Native disabled, removes from tab order |
|
|
62
|
+
| fullWidth | `boolean` | `false` | 100% container width |
|
|
63
|
+
| leftIcon | `ReactNode` | — | Icon before label |
|
|
64
|
+
| rightIcon | `ReactNode` | — | Icon after label |
|
|
65
|
+
|
|
66
|
+
> **Accessibility note:** `loading` uses `aria-disabled` (not native
|
|
67
|
+
> `disabled`) so the button stays focusable while the operation runs.
|
|
68
|
+
> Screen readers announce "busy" to communicate the active state.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Badge
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { Badge } from '@suribef/suri-ui'
|
|
76
|
+
|
|
77
|
+
<Badge variant="success">Active</Badge>
|
|
78
|
+
|
|
79
|
+
{/* Dot mode — aria-label required */}
|
|
80
|
+
<Badge dot variant="danger" aria-label="3 unread notifications" />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| Prop | Type | Default | Description |
|
|
84
|
+
|------|------|---------|-------------|
|
|
85
|
+
| variant | `default \| success \| warning \| danger \| info` | `default` | Semantic color |
|
|
86
|
+
| size | `sm \| md` | `md` | Height scale |
|
|
87
|
+
| dot | `boolean` | `false` | Visual indicator mode, no text rendered |
|
|
88
|
+
|
|
89
|
+
> **Accessibility note:** Dot mode without `aria-label` logs a
|
|
90
|
+
> development warning. The label is required for screen reader users.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Spinner
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { Spinner } from '@suribef/suri-ui'
|
|
98
|
+
|
|
99
|
+
<Spinner />
|
|
100
|
+
<Spinner size="lg" label="Loading dashboard..." />
|
|
101
|
+
|
|
102
|
+
{/* For critical operations that need immediate announcement */}
|
|
103
|
+
<Spinner aria-live="assertive" label="Processing payment..." />
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| Prop | Type | Default | Description |
|
|
107
|
+
|------|------|---------|-------------|
|
|
108
|
+
| size | `sm \| md \| lg` | `md` | Visual size |
|
|
109
|
+
| label | `string` | `Cargando...` | Screen reader text |
|
|
110
|
+
| aria-live | `polite \| assertive` | `polite` | Announcement urgency |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Input
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { Input } from '@suribef/suri-ui'
|
|
118
|
+
|
|
119
|
+
<Input
|
|
120
|
+
label="Email"
|
|
121
|
+
placeholder="you@example.com"
|
|
122
|
+
helperText="We'll never share your email"
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
<Input
|
|
126
|
+
label="Email"
|
|
127
|
+
value={email}
|
|
128
|
+
error={errors.email}
|
|
129
|
+
onChange={e => setEmail(e.target.value)}
|
|
130
|
+
required
|
|
131
|
+
/>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
| Prop | Type | Default | Description |
|
|
135
|
+
|------|------|---------|-------------|
|
|
136
|
+
| label | `string` | — | Visible label, auto-associated via `useId()` |
|
|
137
|
+
| helperText | `string` | — | Hint text below the input |
|
|
138
|
+
| error | `string` | — | Error message, replaces helperText |
|
|
139
|
+
| fullWidth | `boolean` | `false` | 100% container width |
|
|
140
|
+
|
|
141
|
+
Extends all native `<input>` props. Compatible with React Hook Form
|
|
142
|
+
and other form libraries via `forwardRef`.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Textarea
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { Textarea } from '@suribef/suri-ui'
|
|
150
|
+
|
|
151
|
+
<Textarea label="Message" rows={4} />
|
|
152
|
+
|
|
153
|
+
<Textarea
|
|
154
|
+
label="Notes"
|
|
155
|
+
autoResize
|
|
156
|
+
placeholder="Grows as you type..."
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Prop | Type | Default | Description |
|
|
161
|
+
|------|------|---------|-------------|
|
|
162
|
+
| label | `string` | — | Visible label |
|
|
163
|
+
| helperText | `string` | — | Hint text |
|
|
164
|
+
| error | `string` | — | Error message |
|
|
165
|
+
| rows | `number` | `3` | Initial visible lines |
|
|
166
|
+
| resize | `none \| vertical \| horizontal \| both` | `vertical` | Resize handle |
|
|
167
|
+
| autoResize | `boolean` | `false` | Grows with content via scrollHeight |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### Select
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { Select } from '@suribef/suri-ui'
|
|
175
|
+
import type { SelectItem } from '@suribef/suri-ui'
|
|
176
|
+
|
|
177
|
+
const options: SelectItem[] = [
|
|
178
|
+
{ value: 'mx', label: 'Mexico' },
|
|
179
|
+
{ value: 'us', label: 'United States' },
|
|
180
|
+
{ value: 'ca', label: 'Canada', disabled: true }
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
<Select
|
|
184
|
+
label="Country"
|
|
185
|
+
options={options}
|
|
186
|
+
placeholder="Select a country"
|
|
187
|
+
/>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Grouped options:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
const grouped: SelectItem[] = [
|
|
194
|
+
{
|
|
195
|
+
group: 'North America',
|
|
196
|
+
options: [
|
|
197
|
+
{ value: 'mx', label: 'Mexico' },
|
|
198
|
+
{ value: 'us', label: 'United States' }
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
group: 'Europe',
|
|
203
|
+
options: [{ value: 'es', label: 'Spain' }]
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> **Implementation note:** Select uses the native `<select>` element
|
|
209
|
+
> with a CSS reset and custom chevron. This gives mobile users the
|
|
210
|
+
> native picker (optimal UX on iOS/Android) and guaranteed keyboard
|
|
211
|
+
> accessibility. A fully custom listbox is planned for v2.0.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Card
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import { Card } from '@suribef/suri-ui'
|
|
219
|
+
|
|
220
|
+
<Card>
|
|
221
|
+
<Card.Header divided>
|
|
222
|
+
<strong>Card title</strong>
|
|
223
|
+
</Card.Header>
|
|
224
|
+
<Card.Body>Content goes here.</Card.Body>
|
|
225
|
+
<Card.Footer divided>
|
|
226
|
+
<Button size="sm">Action</Button>
|
|
227
|
+
</Card.Footer>
|
|
228
|
+
</Card>
|
|
229
|
+
|
|
230
|
+
{/* Semantic element */}
|
|
231
|
+
<Card as="article" shadow="md">
|
|
232
|
+
<Card.Body>Blog post content</Card.Body>
|
|
233
|
+
</Card>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
| Prop | Type | Default | Description |
|
|
237
|
+
|------|------|---------|-------------|
|
|
238
|
+
| as | `div \| article \| section \| main` | `div` | Semantic element |
|
|
239
|
+
| shadow | `none \| sm \| md \| lg` | `sm` | Elevation level |
|
|
240
|
+
| bordered | `boolean` | `true` | Border visibility |
|
|
241
|
+
| fullWidth | `boolean` | `false` | 100% container width |
|
|
242
|
+
|
|
243
|
+
> **Layout note:** Card has no padding — subcomponents (Header, Body,
|
|
244
|
+
> Footer) own their padding. This allows full-bleed images and colored
|
|
245
|
+
> headers without consumer overrides.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### Stack
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
import { Stack } from '@suribef/suri-ui'
|
|
253
|
+
|
|
254
|
+
{/* Vertical stack */}
|
|
255
|
+
<Stack gap={4}>
|
|
256
|
+
<Input label="First name" />
|
|
257
|
+
<Input label="Last name" />
|
|
258
|
+
<Button>Submit</Button>
|
|
259
|
+
</Stack>
|
|
260
|
+
|
|
261
|
+
{/* Horizontal with alignment */}
|
|
262
|
+
<Stack direction="row" align="center" justify="between">
|
|
263
|
+
<span>Label</span>
|
|
264
|
+
<Button size="sm">Action</Button>
|
|
265
|
+
</Stack>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
| Prop | Type | Default | Description |
|
|
269
|
+
|------|------|---------|-------------|
|
|
270
|
+
| as | `div \| ul \| ol \| nav \| section \| main` | `div` | Semantic element |
|
|
271
|
+
| direction | `row \| column \| row-reverse \| column-reverse` | `column` | Flex direction |
|
|
272
|
+
| gap | `1–12` | `4` | Spacing scale token |
|
|
273
|
+
| align | `start \| center \| end \| stretch \| baseline` | — | align-items |
|
|
274
|
+
| justify | `start \| center \| end \| between \| around \| evenly` | — | justify-content |
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### Divider
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
import { Divider } from '@suribef/suri-ui'
|
|
282
|
+
|
|
283
|
+
{/* Semantic — screen readers announce "separator" */}
|
|
284
|
+
<Divider />
|
|
285
|
+
|
|
286
|
+
{/* Decorative — invisible to assistive technology */}
|
|
287
|
+
<Divider decorative />
|
|
288
|
+
|
|
289
|
+
{/* Vertical — for toolbars and navbars */}
|
|
290
|
+
<Divider orientation="vertical" />
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Theming
|
|
296
|
+
|
|
297
|
+
Override any token in your CSS to customize globally:
|
|
298
|
+
|
|
299
|
+
```css
|
|
300
|
+
:root {
|
|
301
|
+
--sui-color-primary: #0070f3;
|
|
302
|
+
--sui-color-primary-hover: #0060df;
|
|
303
|
+
--sui-radius-md: 4px;
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Full token list in
|
|
308
|
+
[src/tokens/index.css](./src/tokens/index.css).
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Contributing
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
git clone https://github.com/Suribef/suri-ui
|
|
316
|
+
npm install
|
|
317
|
+
npm test # 118 tests
|
|
318
|
+
npm run storybook # Component explorer on localhost:6006
|
|
319
|
+
npm run build # Verify dist output
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Architecture decisions are documented in
|
|
323
|
+
[docs/decisions/](./docs/decisions/).
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## License
|
|
328
|
+
|
|
329
|
+
MIT © [Sergio Uribe](https://github.com/Suribef)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
|
|
3
|
+
variant?: 'default' | 'success' | 'warning' | 'danger' | 'info';
|
|
4
|
+
size?: 'sm' | 'md';
|
|
5
|
+
dot?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function Badge({ variant, size, dot, children, className, ...props }: BadgeProps): import("react").JSX.Element;
|
|
8
|
+
export declare namespace Badge {
|
|
9
|
+
var displayName: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
3
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
loading?: boolean;
|
|
6
|
+
leftIcon?: ReactNode;
|
|
7
|
+
rightIcon?: ReactNode;
|
|
8
|
+
fullWidth?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const Button: import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { forwardRef, HTMLAttributes } from 'react';
|
|
2
|
+
type CardElement = 'div' | 'article' | 'section' | 'main';
|
|
3
|
+
export interface CardProps extends HTMLAttributes<HTMLElement> {
|
|
4
|
+
as?: CardElement;
|
|
5
|
+
shadow?: 'none' | 'sm' | 'md' | 'lg';
|
|
6
|
+
bordered?: boolean;
|
|
7
|
+
fullWidth?: boolean;
|
|
8
|
+
}
|
|
9
|
+
type CardType = ReturnType<typeof forwardRef<HTMLElement, CardProps>> & {
|
|
10
|
+
Header: typeof CardHeader;
|
|
11
|
+
Body: typeof CardBody;
|
|
12
|
+
Footer: typeof CardFooter;
|
|
13
|
+
};
|
|
14
|
+
export interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
|
|
15
|
+
divided?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function CardHeader({ divided, className, children, ...props }: CardHeaderProps): import("react").JSX.Element;
|
|
18
|
+
export declare namespace CardHeader {
|
|
19
|
+
var displayName: string;
|
|
20
|
+
}
|
|
21
|
+
export type CardBodyProps = HTMLAttributes<HTMLDivElement>;
|
|
22
|
+
export declare function CardBody({ className, children, ...props }: CardBodyProps): import("react").JSX.Element;
|
|
23
|
+
export declare namespace CardBody {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
|
|
27
|
+
divided?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function CardFooter({ divided, className, children, ...props }: CardFooterProps): import("react").JSX.Element;
|
|
30
|
+
export declare namespace CardFooter {
|
|
31
|
+
var displayName: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const Card: CardType;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface DividerProps extends HTMLAttributes<HTMLElement> {
|
|
3
|
+
decorative?: boolean;
|
|
4
|
+
orientation?: 'horizontal' | 'vertical';
|
|
5
|
+
label?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function Divider({ decorative, orientation, label, className, ...props }: DividerProps): import("react").JSX.Element;
|
|
8
|
+
export declare namespace Divider {
|
|
9
|
+
var displayName: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
|
+
label?: string;
|
|
4
|
+
helperText?: string;
|
|
5
|
+
error?: string;
|
|
6
|
+
fullWidth?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const Input: import('react').ForwardRefExoticComponent<InputProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SelectHTMLAttributes } from 'react';
|
|
2
|
+
export type SelectOption = {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type SelectOptionGroup = {
|
|
8
|
+
group: string;
|
|
9
|
+
options: SelectOption[];
|
|
10
|
+
};
|
|
11
|
+
export type SelectItem = SelectOption | SelectOptionGroup;
|
|
12
|
+
export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'children'> {
|
|
13
|
+
options: SelectItem[];
|
|
14
|
+
label?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
helperText?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
fullWidth?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const Select: import('react').ForwardRefExoticComponent<SelectProps & import('react').RefAttributes<HTMLSelectElement>>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {
|
|
3
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
|
+
label?: string;
|
|
5
|
+
'aria-live'?: 'polite' | 'assertive';
|
|
6
|
+
}
|
|
7
|
+
export declare function Spinner({ size, label, 'aria-live': ariaLive, className, ...props }: SpinnerProps): import("react").JSX.Element;
|
|
8
|
+
export declare namespace Spinner {
|
|
9
|
+
var displayName: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
type StackElement = 'div' | 'ul' | 'ol' | 'nav' | 'section' | 'main';
|
|
3
|
+
type GapScale = 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
|
|
4
|
+
export interface StackProps extends HTMLAttributes<HTMLElement> {
|
|
5
|
+
as?: StackElement;
|
|
6
|
+
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
7
|
+
gap?: GapScale;
|
|
8
|
+
align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';
|
|
9
|
+
justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
|
|
10
|
+
wrap?: boolean;
|
|
11
|
+
fullWidth?: boolean;
|
|
12
|
+
fullHeight?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const Stack: import('react').ForwardRefExoticComponent<StackProps & import('react').RefAttributes<HTMLElement>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TextareaHTMLAttributes } from 'react';
|
|
2
|
+
export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
label?: string;
|
|
4
|
+
helperText?: string;
|
|
5
|
+
error?: string;
|
|
6
|
+
fullWidth?: boolean;
|
|
7
|
+
resize?: 'none' | 'vertical' | 'horizontal' | 'both';
|
|
8
|
+
autoResize?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const Textarea: import('react').ForwardRefExoticComponent<TextareaProps & import('react').RefAttributes<HTMLTextAreaElement>>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { Button } from './components/Button';
|
|
2
|
+
export type { ButtonProps } from './components/Button';
|
|
3
|
+
export { Badge } from './components/Badge';
|
|
4
|
+
export type { BadgeProps } from './components/Badge';
|
|
5
|
+
export { Spinner } from './components/Spinner';
|
|
6
|
+
export type { SpinnerProps } from './components/Spinner';
|
|
7
|
+
export { Input } from './components/Input';
|
|
8
|
+
export type { InputProps } from './components/Input';
|
|
9
|
+
export { Card, CardHeader, CardBody, CardFooter } from './components/Card';
|
|
10
|
+
export type { CardProps, CardHeaderProps, CardBodyProps, CardFooterProps } from './components/Card';
|
|
11
|
+
export { Stack } from './components/Stack';
|
|
12
|
+
export type { StackProps } from './components/Stack';
|
|
13
|
+
export { Divider } from './components/Divider';
|
|
14
|
+
export type { DividerProps } from './components/Divider';
|
|
15
|
+
export { Textarea } from './components/Textarea';
|
|
16
|
+
export type { TextareaProps } from './components/Textarea';
|
|
17
|
+
export { useCombinedRef } from './utils/useCombinedRef';
|
|
18
|
+
export { Select } from './components/Select';
|
|
19
|
+
export type { SelectProps, SelectItem, SelectOption, SelectOptionGroup } from './components/Select';
|
package/dist/suri-ui.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);let t=require("react");function n(...e){return e.filter(Boolean).join(` `)}var r={button:`_button_1cyfq_1`,primary:`_primary_1cyfq_27`,secondary:`_secondary_1cyfq_28`,ghost:`_ghost_1cyfq_29`,danger:`_danger_1cyfq_30`,sm:`_sm_1cyfq_37`,md:`_md_1cyfq_38`,lg:`_lg_1cyfq_39`,fullWidth:`_fullWidth_1cyfq_41`,loading:`_loading_1cyfq_42`,spinner:`_spinner_1cyfq_44`,spin:`_spin_1cyfq_44`,icon:`_icon_1cyfq_56`},i=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),a=e((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){N||(N=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return P[e]||(P[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(j(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,L[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
2
|
+
let props = %s;
|
|
3
|
+
<%s {...props} />
|
|
4
|
+
React keys must be passed directly to JSX without using spread:
|
|
5
|
+
let props = %s;
|
|
6
|
+
<%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),o=e(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=i():t.exports=a()}))(),s=(0,t.forwardRef)(({variant:e=`primary`,size:t=`md`,loading:i=!1,leftIcon:a,rightIcon:s,fullWidth:c=!1,disabled:l,children:u,className:d,onClick:f,tabIndex:p,...m},h)=>(0,o.jsxs)(`button`,{ref:h,className:n(r.button,r[e],r[t],c&&r.fullWidth,i&&r.loading,d),disabled:l,"aria-disabled":i||void 0,"aria-busy":i||void 0,tabIndex:i?-1:p,"data-fullwidth":c||void 0,"data-loading":i||void 0,onClick:e=>{if(i){e.preventDefault();return}f?.(e)},...m,children:[i&&(0,o.jsx)(`span`,{className:r.spinner,"aria-hidden":`true`}),!i&&a&&(0,o.jsx)(`span`,{className:r.icon,children:a}),(0,o.jsx)(`span`,{children:u}),!i&&s&&(0,o.jsx)(`span`,{className:r.icon,children:s})]}));s.displayName=`Button`;var c={badge:`_badge_1di7z_1`,sm:`_sm_1di7z_13`,md:`_md_1di7z_14`,dot:`_dot_1di7z_17`,default:`_default_1di7z_26`,success:`_success_1di7z_27`,warning:`_warning_1di7z_28`,danger:`_danger_1di7z_29`,info:`_info_1di7z_30`};function l({variant:e=`default`,size:t=`md`,dot:r=!1,children:i,className:a,...s}){return process.env.NODE_ENV!==`production`&&r&&!s[`aria-label`]&&console.warn(`[SuriUI Badge] El modo dot requiere aria-label para accesibilidad. Ejemplo: <Badge dot aria-label="3 notificaciones" />`),(0,o.jsx)(`span`,{className:n(c.badge,c[e],c[t],r&&c.dot,a),"data-dot":r||void 0,...s,children:!r&&i})}l.displayName=`Badge`;var u={spinner:`_spinner_b9met_1`,sm:`_sm_b9met_10`,md:`_md_b9met_11`,lg:`_lg_b9met_12`,svg:`_svg_b9met_15`,spin:`_spin_b9met_1`,track:`_track_b9met_22`,head:`_head_b9met_28`};function d({size:e=`md`,label:t=`Cargando...`,"aria-live":r=`polite`,className:i,...a}){return(0,o.jsxs)(`span`,{role:`status`,"aria-live":r,className:n(u.spinner,u[e],i),...a,children:[(0,o.jsxs)(`svg`,{className:u.svg,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,focusable:`false`,children:[(0,o.jsx)(`circle`,{className:u.track,cx:`12`,cy:`12`,r:`10`,strokeWidth:`3`}),(0,o.jsx)(`path`,{className:u.head,d:`M12 2a10 10 0 0 1 10 10`,strokeWidth:`3`,strokeLinecap:`round`})]}),(0,o.jsx)(`span`,{className:`sui-sr-only`,children:t})]})}d.displayName=`Spinner`;var f={wrapper:`_wrapper_1cd3d_1`,fullWidth:`_fullWidth_1cd3d_7`,label:`_label_1cd3d_12`,required:`_required_1cd3d_20`,input:`_input_1cd3d_25`,inputError:`_inputError_1cd3d_51`,disabled:`_disabled_1cd3d_68`,description:`_description_1cd3d_74`,descriptionHelper:`_descriptionHelper_1cd3d_80`,descriptionError:`_descriptionError_1cd3d_84`},p=(0,t.forwardRef)(({label:e,helperText:r,error:i,fullWidth:a=!1,disabled:s,required:c,id:l,className:u,...d},p)=>{let m=(0,t.useId)(),h=l??m,g=`${h}-description`,_=i||r||void 0;return(0,o.jsxs)(`div`,{className:n(f.wrapper,a&&f.fullWidth,s&&f.disabled),"data-fullwidth":a||void 0,"data-error":!!i||void 0,"data-disabled":s||void 0,children:[e&&(0,o.jsxs)(`label`,{htmlFor:h,className:f.label,children:[e,c&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:f.required,children:[` `,`*`]})]}),(0,o.jsx)(`input`,{ref:p,id:h,className:n(f.input,i&&f.inputError,u),disabled:s,required:c,"aria-required":c||void 0,"aria-invalid":!!i||void 0,"aria-describedby":g,...d}),(0,o.jsx)(`span`,{id:g,className:n(f.description,i?f.descriptionError:f.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:_})]})});p.displayName=`Input`;var m={card:`_card_l6w6d_4`,bordered:`_bordered_l6w6d_15`,fullWidth:`_fullWidth_l6w6d_19`,"shadow-sm":`_shadow-sm_l6w6d_24`,"shadow-md":`_shadow-md_l6w6d_25`,"shadow-lg":`_shadow-lg_l6w6d_26`,header:`_header_l6w6d_29`,headerDivided:`_headerDivided_l6w6d_33`,body:`_body_l6w6d_37`,footer:`_footer_l6w6d_41`,footerDivided:`_footerDivided_l6w6d_45`},h=(0,t.forwardRef)(({as:e=`div`,shadow:t=`sm`,bordered:r=!0,fullWidth:i=!1,className:a,children:s,...c},l)=>(0,o.jsx)(e,{ref:l,className:n(m.card,t!==`none`&&m[`shadow-${t}`],r&&m.bordered,i&&m.fullWidth,a),"data-shadow":t,"data-bordered":r||void 0,"data-fullwidth":i||void 0,...c,children:s}));h.displayName=`Card`;function g({divided:e=!1,className:t,children:r,...i}){return(0,o.jsx)(`div`,{className:n(m.header,e&&m.headerDivided,t),"data-divided":e||void 0,...i,children:r})}g.displayName=`Card.Header`;function _({className:e,children:t,...r}){return(0,o.jsx)(`div`,{className:n(m.body,e),...r,children:t})}_.displayName=`Card.Body`;function v({divided:e=!1,className:t,children:r,...i}){return(0,o.jsx)(`div`,{className:n(m.footer,e&&m.footerDivided,t),"data-divided":e||void 0,...i,children:r})}v.displayName=`Card.Footer`;var y=h;y.Header=g,y.Body=_,y.Footer=v;var b={stack:`_stack_2ervp_1`,"direction-column":`_direction-column_2ervp_8`,"direction-row":`_direction-row_2ervp_9`,"direction-row-reverse":`_direction-row-reverse_2ervp_10`,"direction-column-reverse":`_direction-column-reverse_2ervp_11`,"align-start":`_align-start_2ervp_14`,"align-center":`_align-center_2ervp_15`,"align-end":`_align-end_2ervp_16`,"align-stretch":`_align-stretch_2ervp_17`,"align-baseline":`_align-baseline_2ervp_18`,"justify-start":`_justify-start_2ervp_21`,"justify-center":`_justify-center_2ervp_22`,"justify-end":`_justify-end_2ervp_23`,"justify-between":`_justify-between_2ervp_24`,"justify-around":`_justify-around_2ervp_25`,"justify-evenly":`_justify-evenly_2ervp_26`,wrap:`_wrap_2ervp_29`,fullWidth:`_fullWidth_2ervp_30`,fullHeight:`_fullHeight_2ervp_31`},x=(0,t.forwardRef)(({as:e=`div`,direction:t=`column`,gap:r=4,align:i,justify:a,wrap:s=!1,fullWidth:c=!1,fullHeight:l=!1,className:u,style:d,children:f,...p},m)=>{let h=e,g=`var(--sui-space-${r})`;return(0,o.jsx)(h,{ref:m,className:n(b.stack,b[`direction-${t}`],i&&b[`align-${i}`],a&&b[`justify-${a}`],s&&b.wrap,c&&b.fullWidth,l&&b.fullHeight,u),style:{"--sui-stack-gap":g,...d},"data-direction":t,"data-fullwidth":c||void 0,"data-fullheight":l||void 0,...p,children:f})});x.displayName=`Stack`;var S={divider:`_divider_a98c6_1`,horizontal:`_horizontal_a98c6_7`,vertical:`_vertical_a98c6_13`};function C({decorative:e=!1,orientation:t=`horizontal`,label:r,className:i,...a}){let s=t===`vertical`;return e?(0,o.jsx)(`div`,{"aria-hidden":`true`,className:n(S.divider,s?S.vertical:S.horizontal,i),"data-orientation":t,"data-decorative":`true`,...a}):(0,o.jsx)(`hr`,{role:s?`separator`:void 0,"aria-orientation":s?`vertical`:void 0,"aria-label":r,className:n(S.divider,s?S.vertical:S.horizontal,i),"data-orientation":t,...a})}C.displayName=`Divider`;function w(...e){return(0,t.useCallback)(t=>{e.forEach(e=>{e&&(typeof e==`function`?e(t):e.current=t)})},e)}var T={wrapper:`_wrapper_48l1v_1`,fullWidth:`_fullWidth_48l1v_7`,label:`_label_48l1v_10`,required:`_required_48l1v_18`,textarea:`_textarea_48l1v_21`,"resize-none":`_resize-none_48l1v_47`,"resize-vertical":`_resize-vertical_48l1v_48`,"resize-horizontal":`_resize-horizontal_48l1v_49`,"resize-both":`_resize-both_48l1v_50`,autoResize:`_autoResize_48l1v_54`,textareaError:`_textareaError_48l1v_60`,disabled:`_disabled_48l1v_77`,description:`_description_48l1v_83`,descriptionHelper:`_descriptionHelper_48l1v_91`,descriptionError:`_descriptionError_48l1v_92`},E=(0,t.forwardRef)(({label:e,helperText:r,error:i,fullWidth:a=!1,resize:s=`vertical`,autoResize:c=!1,disabled:l,required:u,id:d,rows:f=3,value:p,className:m,onChange:h,...g},_)=>{let v=(0,t.useId)(),y=d??v,b=`${y}-description`,x=i||r||void 0,S=(0,t.useRef)(null),C=w(S,_);return(0,t.useEffect)(()=>{if(!c||!S.current)return;let e=S.current;e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`},[c,p]),(0,o.jsxs)(`div`,{className:n(T.wrapper,a&&T.fullWidth,l&&T.disabled),"data-fullwidth":a||void 0,"data-error":!!i||void 0,"data-disabled":l||void 0,children:[e&&(0,o.jsxs)(`label`,{htmlFor:y,className:T.label,children:[e,u&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:T.required,children:[` `,`*`]})]}),(0,o.jsx)(`textarea`,{ref:C,id:y,rows:f,value:p,className:n(T.textarea,T[`resize-${s}`],c&&T.autoResize,i&&T.textareaError,m),disabled:l,required:u,"aria-required":u||void 0,"aria-invalid":!!i||void 0,"aria-describedby":b,onChange:h,...g}),(0,o.jsx)(`span`,{id:b,className:n(T.description,i?T.descriptionError:T.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:x})]})});E.displayName=`Textarea`;var D={wrapper:`_wrapper_1ny9q_1`,fullWidth:`_fullWidth_1ny9q_7`,label:`_label_1ny9q_10`,required:`_required_1ny9q_18`,selectWrapper:`_selectWrapper_1ny9q_21`,select:`_select_1ny9q_21`,selectError:`_selectError_1ny9q_57`,disabled:`_disabled_1ny9q_74`,description:`_description_1ny9q_80`,descriptionHelper:`_descriptionHelper_1ny9q_88`,descriptionError:`_descriptionError_1ny9q_89`};function O(e){return`group`in e}var k=(0,t.forwardRef)(({options:e,label:r,placeholder:i,helperText:a,error:s,fullWidth:c=!1,disabled:l,required:u,id:d,className:f,...p},m)=>{let h=(0,t.useId)(),g=d??h,_=`${g}-description`,v=s||a||void 0;return(0,o.jsxs)(`div`,{className:n(D.wrapper,c&&D.fullWidth,l&&D.disabled),"data-fullwidth":c||void 0,"data-error":!!s||void 0,"data-disabled":l||void 0,children:[r&&(0,o.jsxs)(`label`,{htmlFor:g,className:D.label,children:[r,u&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:D.required,children:[` `,`*`]})]}),(0,o.jsx)(`div`,{className:D.selectWrapper,children:(0,o.jsxs)(`select`,{ref:m,id:g,className:n(D.select,s&&D.selectError,f),disabled:l,required:u,"aria-required":u||void 0,"aria-invalid":!!s||void 0,"aria-describedby":_,...p,children:[i&&(0,o.jsx)(`option`,{value:``,disabled:!0,hidden:!0,children:i}),e.map(e=>O(e)?(0,o.jsx)(`optgroup`,{label:e.group,children:e.options.map(e=>(0,o.jsx)(`option`,{value:e.value,disabled:e.disabled,children:e.label},e.value))},e.group):(0,o.jsx)(`option`,{value:e.value,disabled:e.disabled,children:e.label},e.value))]})}),(0,o.jsx)(`span`,{id:_,className:n(D.description,s?D.descriptionError:D.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:v})]})});k.displayName=`Select`,exports.Badge=l,exports.Button=s,exports.Card=y,exports.CardBody=_,exports.CardFooter=v,exports.CardHeader=g,exports.Divider=C,exports.Input=p,exports.Select=k,exports.Spinner=d,exports.Stack=x,exports.Textarea=E,exports.useCombinedRef=w;
|
package/dist/suri-ui.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
:root{--sui-color-primary:#6366f1;--sui-color-primary-hover:#4f46e5;--sui-color-primary-foreground:#fff;--sui-color-secondary:#f4f4f5;--sui-color-secondary-hover:#e4e4e7;--sui-color-secondary-foreground:#18181b;--sui-color-danger:#ef4444;--sui-color-danger-hover:#dc2626;--sui-color-danger-foreground:#fff;--sui-color-ghost-hover:#0000000f;--sui-font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--sui-font-size-sm:.875rem;--sui-font-size-md:1rem;--sui-font-size-lg:1.125rem;--sui-font-weight-medium:500;--sui-space-2:.5rem;--sui-space-3:.75rem;--sui-space-4:1rem;--sui-space-6:1.5rem;--sui-radius-md:8px;--sui-radius-lg:12px;--sui-radius-full:9999px;--sui-transition-fast:.12s ease;--sui-color-success:#dcfce7;--sui-color-success-foreground:#166534;--sui-color-warning:#fef9c3;--sui-color-warning-foreground:#854d0e;--sui-color-info:#dbeafe;--sui-color-info-foreground:#1e40af;--sui-color-border:#d1d5db;--sui-color-border-focus:var(--sui-color-primary);--sui-color-border-error:var(--sui-color-danger);--sui-color-input-bg:#fff;--sui-color-input-bg-disabled:#f9fafb;--sui-color-text-primary:#111827;--sui-color-text-secondary:#6b7280;--sui-color-text-placeholder:#9ca3af;--sui-color-text-error:var(--sui-color-danger);--sui-color-text-disabled:#9ca3af;--sui-focus-ring:0 0 0 3px #6366f140;--sui-space-5:1.25rem;--sui-space-8:2rem;--sui-space-10:2.5rem;--sui-space-12:3rem;--sui-color-divider:#e5e7eb;--sui-shadow-sm:0 1px 3px #00000014, 0 1px 2px #0000000a;--sui-shadow-md:0 4px 6px #00000012, 0 2px 4px #0000000d;--sui-shadow-lg:0 10px 15px #00000014, 0 4px 6px #0000000a;--sui-color-card-bg:#fff;--sui-color-card-border:#e5e7eb;--sui-textarea-min-height:80px;--sui-textarea-max-height:400px;--sui-select-chevron-size:16px}.sui-sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._button_1cyfq_1{justify-content:center;align-items:center;gap:var(--sui-space-2);font-family:var(--sui-font-sans);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-md);cursor:pointer;transition:background-color var(--sui-transition-fast), opacity var(--sui-transition-fast), transform var(--sui-transition-fast);white-space:nowrap;-webkit-user-select:none;user-select:none;border:none;display:inline-flex}._button_1cyfq_1:disabled,._button_1cyfq_1[aria-disabled=true]{opacity:.5;cursor:not-allowed}._button_1cyfq_1:active:not(:disabled):not([aria-disabled=true]){transform:scale(.98)}._primary_1cyfq_27{background-color:var(--sui-color-primary);color:var(--sui-color-primary-foreground)}._secondary_1cyfq_28{background-color:var(--sui-color-secondary);color:var(--sui-color-secondary-foreground)}._ghost_1cyfq_29{color:var(--sui-color-secondary-foreground);background-color:#0000}._danger_1cyfq_30{background-color:var(--sui-color-danger);color:var(--sui-color-danger-foreground)}._primary_1cyfq_27:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-primary-hover)}._secondary_1cyfq_28:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-secondary-hover)}._ghost_1cyfq_29:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-ghost-hover)}._danger_1cyfq_30:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-danger-hover)}._sm_1cyfq_37{height:32px;padding:0 var(--sui-space-3);font-size:var(--sui-font-size-sm)}._md_1cyfq_38{height:40px;padding:0 var(--sui-space-4);font-size:var(--sui-font-size-md)}._lg_1cyfq_39{height:48px;padding:0 var(--sui-space-6);font-size:var(--sui-font-size-lg)}._fullWidth_1cyfq_41{width:100%}._loading_1cyfq_42{cursor:wait}._spinner_1cyfq_44{border:2px solid;border-top-color:#0000;border-radius:50%;flex-shrink:0;width:14px;height:14px;animation:.6s linear infinite _spin_1cyfq_44;display:inline-block}@keyframes _spin_1cyfq_44{to{transform:rotate(360deg)}}._icon_1cyfq_56{flex-shrink:0;align-items:center;display:inline-flex}._badge_1di7z_1{font-family:var(--sui-font-sans);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-full);white-space:nowrap;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}._sm_1di7z_13{height:20px;padding:0 var(--sui-space-2);font-size:.75rem}._md_1di7z_14{height:24px;padding:0 var(--sui-space-3);font-size:var(--sui-font-size-sm)}._dot_1di7z_17{border-radius:50%;flex-shrink:0;padding:0}._dot_1di7z_17._sm_1di7z_13{width:6px;height:6px}._dot_1di7z_17._md_1di7z_14{width:8px;height:8px}._default_1di7z_26{background-color:var(--sui-color-secondary);color:var(--sui-color-secondary-foreground)}._success_1di7z_27{background-color:var(--sui-color-success);color:var(--sui-color-success-foreground)}._warning_1di7z_28{background-color:var(--sui-color-warning);color:var(--sui-color-warning-foreground)}._danger_1di7z_29{background-color:var(--sui-color-danger);color:var(--sui-color-danger-foreground)}._info_1di7z_30{background-color:var(--sui-color-info);color:var(--sui-color-info-foreground)}._spinner_b9met_1{color:var(--sui-color-primary);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}._sm_b9met_10{width:16px;height:16px}._md_b9met_11{width:24px;height:24px}._lg_b9met_12{width:40px;height:40px}._svg_b9met_15{width:100%;height:100%;animation:.75s linear infinite _spin_b9met_1}._track_b9met_22{stroke:currentColor;opacity:.2}._head_b9met_28{stroke:currentColor}@keyframes _spin_b9met_1{to{transform:rotate(360deg)}}._wrapper_1cd3d_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_1cd3d_7{width:100%}._label_1cd3d_12{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_1cd3d_20{color:var(--sui-color-text-error)}._input_1cd3d_25{width:100%;height:40px;padding:0 var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none}._input_1cd3d_25::placeholder{color:var(--sui-color-text-placeholder)}._input_1cd3d_25:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._inputError_1cd3d_51{border-color:var(--sui-color-border-error)}._inputError_1cd3d_51:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._input_1cd3d_25:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_1cd3d_1._disabled_1cd3d_68 ._label_1cd3d_12{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_1cd3d_74{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._descriptionHelper_1cd3d_80{color:var(--sui-color-text-secondary)}._descriptionError_1cd3d_84{color:var(--sui-color-text-error)}._description_1cd3d_74:empty{display:none}._card_l6w6d_4{background-color:var(--sui-color-card-bg);border-radius:var(--sui-radius-lg);box-sizing:border-box;position:relative;overflow:hidden}._bordered_l6w6d_15{border:1px solid var(--sui-color-card-border)}._fullWidth_l6w6d_19{width:100%}._shadow-sm_l6w6d_24{box-shadow:var(--sui-shadow-sm)}._shadow-md_l6w6d_25{box-shadow:var(--sui-shadow-md)}._shadow-lg_l6w6d_26{box-shadow:var(--sui-shadow-lg)}._header_l6w6d_29{padding:var(--sui-space-4) var(--sui-space-4) var(--sui-space-3)}._headerDivided_l6w6d_33{border-bottom:1px solid var(--sui-color-card-border)}._body_l6w6d_37{padding:var(--sui-space-4)}._footer_l6w6d_41{padding:var(--sui-space-3) var(--sui-space-4) var(--sui-space-4)}._footerDivided_l6w6d_45{border-top:1px solid var(--sui-color-card-border)}._stack_2ervp_1{gap:var(--sui-stack-gap,var(--sui-space-4));box-sizing:border-box;display:flex}._direction-column_2ervp_8{flex-direction:column}._direction-row_2ervp_9{flex-direction:row}._direction-row-reverse_2ervp_10{flex-direction:row-reverse}._direction-column-reverse_2ervp_11{flex-direction:column-reverse}._align-start_2ervp_14{align-items:flex-start}._align-center_2ervp_15{align-items:center}._align-end_2ervp_16{align-items:flex-end}._align-stretch_2ervp_17{align-items:stretch}._align-baseline_2ervp_18{align-items:baseline}._justify-start_2ervp_21{justify-content:flex-start}._justify-center_2ervp_22{justify-content:center}._justify-end_2ervp_23{justify-content:flex-end}._justify-between_2ervp_24{justify-content:space-between}._justify-around_2ervp_25{justify-content:space-around}._justify-evenly_2ervp_26{justify-content:space-evenly}._wrap_2ervp_29{flex-wrap:wrap}._fullWidth_2ervp_30{width:100%}._fullHeight_2ervp_31{height:100%}._divider_a98c6_1{background-color:var(--sui-color-divider);border:none;flex-shrink:0}._horizontal_a98c6_7{width:100%;height:1px;margin:0}._vertical_a98c6_13{align-self:stretch;width:1px;height:100%}._wrapper_48l1v_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_48l1v_7{width:100%}._label_48l1v_10{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_48l1v_18{color:var(--sui-color-text-error)}._textarea_48l1v_21{width:100%;min-height:var(--sui-textarea-min-height);max-height:var(--sui-textarea-max-height);padding:var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none;line-height:1.5}._textarea_48l1v_21::placeholder{color:var(--sui-color-text-placeholder)}._textarea_48l1v_21:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._resize-none_48l1v_47{resize:none}._resize-vertical_48l1v_48{resize:vertical}._resize-horizontal_48l1v_49{resize:horizontal}._resize-both_48l1v_50{resize:both}._autoResize_48l1v_54{resize:none;overflow:hidden}._textareaError_48l1v_60{border-color:var(--sui-color-border-error)}._textareaError_48l1v_60:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._textarea_48l1v_21:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_48l1v_1._disabled_48l1v_77 ._label_48l1v_10{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_48l1v_83{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._description_48l1v_83:empty{display:none}._descriptionHelper_48l1v_91{color:var(--sui-color-text-secondary)}._descriptionError_48l1v_92{color:var(--sui-color-text-error)}._wrapper_1ny9q_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_1ny9q_7{width:100%}._label_1ny9q_10{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_1ny9q_18{color:var(--sui-color-text-error)}._selectWrapper_1ny9q_21{display:flex;position:relative}._select_1ny9q_21{width:100%;height:40px;padding:0 var(--sui-space-8) 0 var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--sui-space-3) center;background-size:var(--sui-select-chevron-size);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);cursor:pointer;appearance:none;transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none}._select_1ny9q_21:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._selectError_1ny9q_57{border-color:var(--sui-color-border-error)}._selectError_1ny9q_57:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._select_1ny9q_21:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_1ny9q_1._disabled_1ny9q_74 ._label_1ny9q_10{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_1ny9q_80{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._description_1ny9q_80:empty{display:none}._descriptionHelper_1ny9q_88{color:var(--sui-color-text-secondary)}._descriptionError_1ny9q_89{color:var(--sui-color-text-error)}
|
|
2
|
+
/*$vite$:1*/
|