@adamosuiteservices/ui 2.18.6 → 2.19.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/README.md +1 -1
- package/dist/accordion-rounded.cjs +8 -8
- package/dist/accordion-rounded.js +12 -12
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.js +1 -1
- package/dist/alert.cjs +32 -23
- package/dist/alert.js +53 -43
- package/dist/amount-input.cjs +8 -0
- package/dist/amount-input.js +191 -0
- package/dist/avatar.cjs +7 -7
- package/dist/avatar.js +18 -18
- package/dist/badge.cjs +24 -28
- package/dist/badge.js +45 -42
- package/dist/breadcrumb.cjs +3 -4
- package/dist/breadcrumb.js +17 -18
- package/dist/button-CPm4-98H.cjs +87 -0
- package/dist/button-D4ddrxyp.js +156 -0
- package/dist/button-group.cjs +1 -1
- package/dist/button-group.js +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{calendar-Dorq3-wv.cjs → calendar-DXq90PYV.cjs} +20 -22
- package/dist/{calendar-xBaFu2sB.js → calendar-DgfO9zab.js} +239 -240
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/card.cjs +3 -3
- package/dist/card.js +4 -4
- package/dist/checkbox-CIzBdqN7.cjs +24 -0
- package/dist/{checkbox-DL_jFvgl.js → checkbox-DPlUjwLi.js} +54 -52
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/colors.css +1 -1
- package/dist/combobox-DG9u4g84.js +692 -0
- package/dist/combobox-DylTjGrw.cjs +57 -0
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts +2 -1
- package/dist/components/layout/toaster/toaster.d.ts +1 -1
- package/dist/components/ui/alert/alert.d.ts +1 -1
- package/dist/components/ui/amount-input/amount-input.d.ts +32 -0
- package/dist/components/ui/amount-input/index.d.ts +1 -0
- package/dist/components/ui/badge/badge.d.ts +3 -2
- package/dist/components/ui/calendar/calendar.d.ts +1 -1
- package/dist/components/ui/combobox/combobox.d.ts +3 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +3 -1
- package/dist/components/ui/selectable-card/index.d.ts +1 -0
- package/dist/components/ui/selectable-card/selectable-card.d.ts +22 -0
- package/dist/components/ui/timeline/index.d.ts +1 -0
- package/dist/components/ui/timeline/timeline.d.ts +30 -0
- package/dist/components/ui/typography/typography.d.ts +1 -1
- package/dist/context-menu.cjs +18 -19
- package/dist/context-menu.js +37 -38
- package/dist/date-picker-selector.cjs +1 -1
- package/dist/date-picker-selector.js +3 -3
- package/dist/dialog.cjs +7 -9
- package/dist/dialog.js +36 -38
- package/dist/dropdown-menu.cjs +57 -36
- package/dist/dropdown-menu.js +206 -173
- package/dist/field.cjs +12 -7
- package/dist/field.js +51 -45
- package/dist/file-upload-v2.cjs +11 -5
- package/dist/file-upload-v2.js +75 -60
- package/dist/file-upload.cjs +11 -5
- package/dist/file-upload.js +118 -110
- package/dist/full-screen-loader.cjs +1 -1
- package/dist/full-screen-loader.js +1 -1
- package/dist/{icon-B7joBr0A.cjs → icon-C5Q2b1Am.cjs} +1 -1
- package/dist/{icon-BFQz1tQC.js → icon-t4jt1Z2h.js} +1 -1
- package/dist/icon.cjs +1 -1
- package/dist/icon.js +1 -1
- package/dist/index-BBT2EGq8.js +18 -0
- package/dist/index-DCsgSkBj.cjs +1 -0
- package/dist/input-8sEO5zwD.js +44 -0
- package/dist/input-AONeSXcs.cjs +22 -0
- package/dist/input-group-BLffLxyg.cjs +86 -0
- package/dist/input-group-DmevJAqa.js +240 -0
- package/dist/input-group.cjs +1 -84
- package/dist/input-group.js +7 -234
- package/dist/input-otp.cjs +5 -7
- package/dist/input-otp.js +58 -60
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/kbd.cjs +6 -7
- package/dist/kbd.js +14 -15
- package/dist/{label-DqfX9cHc.cjs → label-B7Z1D5-Q.cjs} +5 -4
- package/dist/{label-C6zVnc3d.js → label-_BWRIH7C.js} +14 -13
- package/dist/label.cjs +1 -1
- package/dist/label.js +1 -1
- package/dist/pagination.cjs +5 -5
- package/dist/pagination.js +18 -18
- package/dist/radio-group.cjs +12 -9
- package/dist/radio-group.js +66 -63
- package/dist/select.cjs +18 -16
- package/dist/select.js +18 -16
- package/dist/selectable-card.cjs +29 -0
- package/dist/selectable-card.js +129 -0
- package/dist/separator-DXdc7LcC.cjs +7 -0
- package/dist/{separator-CsaqP20m.js → separator-DZfXXbNt.js} +1 -1
- package/dist/separator.cjs +1 -1
- package/dist/separator.js +1 -1
- package/dist/{sheet-Cnq7TCzu.cjs → sheet-Cp6JGhWC.cjs} +10 -10
- package/dist/{sheet-C9vce0ut.js → sheet-hWerE8S1.js} +9 -6
- package/dist/sheet.cjs +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sidebar.cjs +10 -10
- package/dist/sidebar.js +83 -92
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +1 -1
- package/dist/{spinner-C7q7NthY.cjs → spinner-DUZ2vcus.cjs} +1 -1
- package/dist/{spinner-DQ5JLL3U.js → spinner-_-J3zJ_g.js} +1 -1
- package/dist/spinner.cjs +1 -1
- package/dist/spinner.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch.cjs +2 -4
- package/dist/switch.js +71 -73
- package/dist/table.cjs +14 -14
- package/dist/table.js +12 -12
- package/dist/tabs-underline.cjs +11 -15
- package/dist/tabs-underline.js +20 -24
- package/dist/tabs.cjs +10 -14
- package/dist/tabs.js +20 -24
- package/dist/tailwind-colors.css +1 -1
- package/dist/tailwind-theme.css +1 -1
- package/dist/textarea-BSooGyp-.cjs +18 -0
- package/dist/textarea-D_sj6ivo.js +39 -0
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/themes.css +1 -1
- package/dist/timeline.cjs +4 -0
- package/dist/timeline.js +189 -0
- package/dist/toaster.cjs +5 -4
- package/dist/toaster.js +33 -32
- package/dist/toggle.cjs +4 -4
- package/dist/toggle.js +17 -17
- package/dist/tooltip.cjs +5 -6
- package/dist/tooltip.js +4 -5
- package/docs/components/layout/sidebar.md +81 -53
- package/docs/components/layout/toaster.md +35 -55
- package/docs/components/ui/accordion-rounded.md +12 -11
- package/docs/components/ui/alert.md +66 -36
- package/docs/components/ui/amount-input.md +229 -0
- package/docs/components/ui/avatar.md +28 -32
- package/docs/components/ui/badge.md +85 -32
- package/docs/components/ui/breadcrumb.md +5 -7
- package/docs/components/ui/button-group.md +16 -16
- package/docs/components/ui/button.md +23 -36
- package/docs/components/ui/calendar.md +54 -27
- package/docs/components/ui/card.md +5 -4
- package/docs/components/ui/checkbox.md +3 -3
- package/docs/components/ui/combobox.md +35 -1
- package/docs/components/ui/command.md +7 -7
- package/docs/components/ui/context-menu.md +14 -15
- package/docs/components/ui/date-picker-selector.md +31 -31
- package/docs/components/ui/dialog.md +47 -49
- package/docs/components/ui/dropdown-menu.md +34 -37
- package/docs/components/ui/field.md +25 -31
- package/docs/components/ui/file-upload-v2.md +11 -0
- package/docs/components/ui/file-upload.md +105 -108
- package/docs/components/ui/hover-card.md +28 -6
- package/docs/components/ui/icon.md +10 -9
- package/docs/components/ui/input-group.md +9 -9
- package/docs/components/ui/input.md +30 -33
- package/docs/components/ui/kbd.md +10 -9
- package/docs/components/ui/label.md +6 -6
- package/docs/components/ui/pagination.md +3 -3
- package/docs/components/ui/popover.md +1 -0
- package/docs/components/ui/progress.md +3 -3
- package/docs/components/ui/radio-group.md +18 -6
- package/docs/components/ui/scroll-area.md +4 -4
- package/docs/components/ui/select.md +14 -12
- package/docs/components/ui/selectable-card.md +204 -0
- package/docs/components/ui/separator.md +4 -4
- package/docs/components/ui/sheet.md +21 -3
- package/docs/components/ui/slider.md +3 -3
- package/docs/components/ui/switch.md +7 -7
- package/docs/components/ui/table.md +7 -4
- package/docs/components/ui/tabs-underline.md +36 -36
- package/docs/components/ui/tabs.md +6 -4
- package/docs/components/ui/textarea.md +6 -4
- package/docs/components/ui/timeline.md +214 -0
- package/docs/components/ui/toggle.md +1 -1
- package/docs/components/ui/tooltip.md +3 -3
- package/llm.txt +7 -4
- package/package.json +13 -1
- package/dist/button-BnUlAtuD.js +0 -132
- package/dist/button-CFJs0esR.cjs +0 -63
- package/dist/checkbox-3RIZX2HF.cjs +0 -22
- package/dist/combobox-MkeJiTXj.js +0 -637
- package/dist/combobox-jJRxvUsB.cjs +0 -40
- package/dist/input-BCiOr4Fy.js +0 -44
- package/dist/input-Bz5k4w94.cjs +0 -22
- package/dist/separator-CCGaTo09.cjs +0 -7
- package/dist/textarea-BRCnIxdB.js +0 -33
- package/dist/textarea-DkFUS_oS.cjs +0 -14
|
@@ -6,14 +6,12 @@ Non-intrusive **toast notification system** that appears at the bottom of the sc
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- ✅ 4 visual variants (
|
|
10
|
-
- ✅ Automatic queue system for multiple toasts
|
|
9
|
+
- ✅ 4 visual variants (info, success, warning, destructive)
|
|
11
10
|
- ✅ Configurable auto-close (default 3000ms)
|
|
12
|
-
- ✅ Persistent toasts (no auto-close)
|
|
13
11
|
- ✅ Smooth entry and exit animations
|
|
14
12
|
- ✅ Portal rendering for fixed positioning
|
|
15
13
|
- ✅ Automatic unique IDs
|
|
16
|
-
- ✅
|
|
14
|
+
- ✅ onClose callback support
|
|
17
15
|
|
|
18
16
|
## Import
|
|
19
17
|
|
|
@@ -21,9 +19,9 @@ Non-intrusive **toast notification system** that appears at the bottom of the sc
|
|
|
21
19
|
import { Toaster, ToastManager } from "@adamosuiteservices/ui/toaster";
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
##
|
|
22
|
+
## Initial setup
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Add the `Toaster` component at the top level of your application:
|
|
27
25
|
|
|
28
26
|
```tsx
|
|
29
27
|
import { Toaster } from "@adamosuiteservices/ui/toaster";
|
|
@@ -31,7 +29,7 @@ import { Toaster } from "@adamosuiteservices/ui/toaster";
|
|
|
31
29
|
function App() {
|
|
32
30
|
return (
|
|
33
31
|
<>
|
|
34
|
-
{/*
|
|
32
|
+
{/* Your app here */}
|
|
35
33
|
<Toaster />
|
|
36
34
|
</>
|
|
37
35
|
);
|
|
@@ -64,22 +62,22 @@ function MyComponent() {
|
|
|
64
62
|
|
|
65
63
|
## Variants
|
|
66
64
|
|
|
67
|
-
###
|
|
65
|
+
### info
|
|
68
66
|
|
|
69
|
-
General informational toast with
|
|
67
|
+
General informational toast with neutral gray background.
|
|
70
68
|
|
|
71
69
|
```tsx
|
|
72
70
|
ToastManager.show({
|
|
73
71
|
message: "This is a general informational message",
|
|
74
|
-
variant: "
|
|
72
|
+
variant: "info",
|
|
75
73
|
});
|
|
76
74
|
```
|
|
77
75
|
|
|
78
76
|
**Styles**:
|
|
79
77
|
|
|
80
|
-
- Background: `bg-
|
|
81
|
-
- Text: `text-foreground`
|
|
82
|
-
- Use: General information, neutral confirmations
|
|
78
|
+
- Background: `bg-accent` (light gray)
|
|
79
|
+
- Text: `text-foreground` (dark gray)
|
|
80
|
+
- Use: General information, neutral confirmations, tips
|
|
83
81
|
|
|
84
82
|
### success
|
|
85
83
|
|
|
@@ -95,7 +93,7 @@ ToastManager.show({
|
|
|
95
93
|
**Styles**:
|
|
96
94
|
|
|
97
95
|
- Background: `bg-success-50` (light green)
|
|
98
|
-
- Text: `text-success`
|
|
96
|
+
- Text: `text-success-foreground-subtle` (green)
|
|
99
97
|
- Use: Successful saves, completed operations, confirmations
|
|
100
98
|
|
|
101
99
|
### warning
|
|
@@ -111,8 +109,8 @@ ToastManager.show({
|
|
|
111
109
|
|
|
112
110
|
**Styles**:
|
|
113
111
|
|
|
114
|
-
- Background: `bg-warning-50` (light yellow)
|
|
115
|
-
- Text: `text-warning`
|
|
112
|
+
- Background: `bg-warning-50` (light yellow/orange)
|
|
113
|
+
- Text: `text-warning-foreground-subtle` (orange/brown)
|
|
116
114
|
- Use: Warnings, validations, preventive alerts
|
|
117
115
|
|
|
118
116
|
### destructive
|
|
@@ -129,24 +127,24 @@ ToastManager.show({
|
|
|
129
127
|
**Styles**:
|
|
130
128
|
|
|
131
129
|
- Background: `bg-destructive-50` (light red)
|
|
132
|
-
- Text: `text-destructive`
|
|
130
|
+
- Text: `text-destructive-foreground-subtle` (red)
|
|
133
131
|
- Use: Errors, operation failures, destructive actions
|
|
134
132
|
|
|
135
133
|
## Duration and control
|
|
136
134
|
|
|
137
|
-
###
|
|
135
|
+
### Custom auto-close
|
|
138
136
|
|
|
139
|
-
|
|
137
|
+
By default, toasts close automatically after 3 seconds (3000ms).
|
|
140
138
|
|
|
141
139
|
```tsx
|
|
142
|
-
//
|
|
140
|
+
// Quick toast (1 second)
|
|
143
141
|
ToastManager.show({
|
|
144
142
|
message: "Quick notification",
|
|
145
|
-
variant: "
|
|
143
|
+
variant: "info",
|
|
146
144
|
autoClose: 1000,
|
|
147
145
|
});
|
|
148
146
|
|
|
149
|
-
//
|
|
147
|
+
// Normal toast (3 seconds - default)
|
|
150
148
|
ToastManager.show({
|
|
151
149
|
message: "Normal duration",
|
|
152
150
|
variant: "success",
|
|
@@ -161,22 +159,6 @@ ToastManager.show({
|
|
|
161
159
|
});
|
|
162
160
|
```
|
|
163
161
|
|
|
164
|
-
### Persistent toast
|
|
165
|
-
|
|
166
|
-
For messages that require user confirmation:
|
|
167
|
-
|
|
168
|
-
```tsx
|
|
169
|
-
// Show toast without auto-close
|
|
170
|
-
ToastManager.show({
|
|
171
|
-
message: "This message requires your attention",
|
|
172
|
-
variant: "destructive",
|
|
173
|
-
autoClose: undefined, // Does not close automatically
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// Persistent toasts can be manually closed by the user
|
|
177
|
-
// by clicking on the toast or with specific actions from your app
|
|
178
|
-
```
|
|
179
|
-
|
|
180
162
|
## API
|
|
181
163
|
|
|
182
164
|
### ToastManager.show()
|
|
@@ -197,7 +179,7 @@ ToastManager.show({
|
|
|
197
179
|
type Toast = {
|
|
198
180
|
id?: string;
|
|
199
181
|
message: string;
|
|
200
|
-
variant?: "
|
|
182
|
+
variant?: "info" | "success" | "warning" | "destructive";
|
|
201
183
|
autoClose?: number;
|
|
202
184
|
onClose?: () => void;
|
|
203
185
|
};
|
|
@@ -207,13 +189,13 @@ type Toast = {
|
|
|
207
189
|
|
|
208
190
|
### Toast options
|
|
209
191
|
|
|
210
|
-
| Prop | Type
|
|
211
|
-
| --------- |
|
|
212
|
-
| id | `string`
|
|
213
|
-
| message | `string`
|
|
214
|
-
| variant | `"
|
|
215
|
-
| autoClose | `number \| undefined`
|
|
216
|
-
| onClose | `() => void`
|
|
192
|
+
| Prop | Type | Default | Description |
|
|
193
|
+
| --------- | --------------------------------------------------- | -------------- | --------------------------------------------------------------- |
|
|
194
|
+
| id | `string` | Auto-generated | Unique toast identifier (optional) |
|
|
195
|
+
| message | `string` | - | **Required**. Text to display |
|
|
196
|
+
| variant | `"info" \| "success" \| "warning" \| "destructive"` | `"info"` | Color variant |
|
|
197
|
+
| autoClose | `number \| undefined` | `3000` | Duration in ms before auto-closing. Defaults to 3000 if omitted |
|
|
198
|
+
| onClose | `() => void` | `undefined` | Callback executed when toast closes |
|
|
217
199
|
|
|
218
200
|
### Toaster component
|
|
219
201
|
|
|
@@ -301,13 +283,13 @@ const showMultipleNotifications = () => {
|
|
|
301
283
|
// Toasts will be displayed sequentially
|
|
302
284
|
ToastManager.show({
|
|
303
285
|
message: "Step 1: Processing data...",
|
|
304
|
-
variant: "
|
|
286
|
+
variant: "info",
|
|
305
287
|
autoClose: 2000,
|
|
306
288
|
});
|
|
307
289
|
|
|
308
290
|
ToastManager.show({
|
|
309
291
|
message: "Step 2: Validating information...",
|
|
310
|
-
variant: "
|
|
292
|
+
variant: "info",
|
|
311
293
|
autoClose: 2000,
|
|
312
294
|
});
|
|
313
295
|
|
|
@@ -321,14 +303,13 @@ const showMultipleNotifications = () => {
|
|
|
321
303
|
|
|
322
304
|
## Advanced features
|
|
323
305
|
|
|
324
|
-
###
|
|
306
|
+
### Toast replacement behavior
|
|
325
307
|
|
|
326
|
-
The Toaster
|
|
308
|
+
The Toaster shows one toast at a time. If a new toast is triggered while one is already visible, the new toast immediately replaces the current one:
|
|
327
309
|
|
|
328
|
-
- Multiple toasts are automatically queued
|
|
329
310
|
- Only one toast is shown at a time
|
|
330
|
-
-
|
|
331
|
-
-
|
|
311
|
+
- New toasts replace the current toast immediately
|
|
312
|
+
- Each toast has its own auto-close timer
|
|
332
313
|
|
|
333
314
|
### CSS animations
|
|
334
315
|
|
|
@@ -359,7 +340,7 @@ Execute custom logic when the toast closes:
|
|
|
359
340
|
```tsx
|
|
360
341
|
ToastManager.show({
|
|
361
342
|
message: "Processing...",
|
|
362
|
-
variant: "
|
|
343
|
+
variant: "info",
|
|
363
344
|
onClose: () => {
|
|
364
345
|
console.log("Toast closed");
|
|
365
346
|
// Additional logic after closing
|
|
@@ -423,7 +404,6 @@ ToastManager.show({
|
|
|
423
404
|
- ✅ Adequate color contrast in all variants
|
|
424
405
|
- ✅ Non-intrusive positioning
|
|
425
406
|
- ✅ Configurable auto-close
|
|
426
|
-
- ✅ Manual close by click
|
|
427
407
|
- ⚠️ No `role="alert"` or `aria-live` (future improvement)
|
|
428
408
|
- ⚠️ No keyboard navigation
|
|
429
409
|
|
|
@@ -107,7 +107,7 @@ Individual container for each accordion item.
|
|
|
107
107
|
**Applied styles**:
|
|
108
108
|
|
|
109
109
|
- `rounded-2xl`: Very rounded borders
|
|
110
|
-
- `bg-
|
|
110
|
+
- `bg-accent`: Subtle background
|
|
111
111
|
- `mb-4`: Bottom margin of 1rem
|
|
112
112
|
- `last:mb-0`: No margin on last item
|
|
113
113
|
|
|
@@ -541,16 +541,17 @@ Without badges for minimalist design:
|
|
|
541
541
|
|
|
542
542
|
## Differences with regular accordion
|
|
543
543
|
|
|
544
|
-
| Feature | Regular accordion | Accordion rounded
|
|
545
|
-
| --------------- | ----------------------- |
|
|
546
|
-
| Borders | Square corners | `rounded-2xl` (very rounded)
|
|
547
|
-
| Item background | Transparent with border | `bg-
|
|
548
|
-
| Separation | Border between items | Margin `mb-4` between items
|
|
549
|
-
| Badge support | No (only children) | Yes (dedicated `badge` prop)
|
|
550
|
-
| Title style | Normal | Uppercase, compact
|
|
551
|
-
| Icons | ChevronDown | add/remove
|
|
552
|
-
| Trigger height | Variable | Fixed `h-16` (3.5rem)
|
|
553
|
-
|
|
|
544
|
+
| Feature | Regular accordion | Accordion rounded |
|
|
545
|
+
| --------------- | ----------------------- | ---------------------------- |
|
|
546
|
+
| Borders | Square corners | `rounded-2xl` (very rounded) |
|
|
547
|
+
| Item background | Transparent with border | `bg-accent` (subtle) |
|
|
548
|
+
| Separation | Border between items | Margin `mb-4` between items |
|
|
549
|
+
| Badge support | No (only children) | Yes (dedicated `badge` prop) |
|
|
550
|
+
| Title style | Normal | Uppercase, compact |
|
|
551
|
+
| Icons | ChevronDown | add/remove |
|
|
552
|
+
| Trigger height | Variable | Fixed `h-16` (3.5rem) |
|
|
553
|
+
| Text color | `text-foreground` | `text-accent-foreground` |
|
|
554
|
+
| Main use | General, documentation | Forms, validation, steppers |
|
|
554
555
|
|
|
555
556
|
## Implementation notes
|
|
556
557
|
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Description
|
|
4
4
|
|
|
5
|
-
Versatile component for displaying **important messages** that require user attention. Uses an intelligent grid system for optional icons, supports
|
|
5
|
+
Versatile component for displaying **important messages** that require user attention. Uses an intelligent grid system for optional icons, supports 5 color variants, and allows rich content with buttons, lists, progress bars, and more.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- ✅
|
|
9
|
+
- ✅ 5 visual variants (default, info, destructive, success, warning)
|
|
10
10
|
- ✅ Automatic grid for optional icons
|
|
11
11
|
- ✅ Supports title only, description only, or both
|
|
12
12
|
- ✅ Rich content: buttons, progress, checkboxes, badges
|
|
13
13
|
- ✅ ARIA "alert" role for accessibility
|
|
14
14
|
- ✅ Auto-sized icons (size-4)
|
|
15
|
-
- ✅
|
|
15
|
+
- ✅ Flexible grid layout (works with or without icons)
|
|
16
16
|
- ✅ Slot system for composition
|
|
17
17
|
|
|
18
18
|
## Import
|
|
@@ -91,8 +91,31 @@ For neutral informative messages:
|
|
|
91
91
|
|
|
92
92
|
- Background: `bg-card` (white/light gray depending on theme)
|
|
93
93
|
- Text: `text-card-foreground`
|
|
94
|
+
- Icon: `text-card-foreground` (same as text)
|
|
94
95
|
- Usage: General information, tips, neutral notices
|
|
95
96
|
|
|
97
|
+
### Info (informational messages)
|
|
98
|
+
|
|
99
|
+
For informational messages that need subtle emphasis:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<Alert variant="info">
|
|
103
|
+
<Icon symbol="info" />
|
|
104
|
+
<AlertTitle>Information</AlertTitle>
|
|
105
|
+
<AlertDescription>
|
|
106
|
+
Please review the details carefully before proceeding.
|
|
107
|
+
</AlertDescription>
|
|
108
|
+
</Alert>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Applied styles**:
|
|
112
|
+
|
|
113
|
+
- Background: `bg-accent` (light gray)
|
|
114
|
+
- Text: `text-foreground` (dark gray)
|
|
115
|
+
- Icon: `text-foreground` (same as text)
|
|
116
|
+
- Border: `border-border`
|
|
117
|
+
- Usage: Informational messages, hints, neutral notifications with subtle emphasis
|
|
118
|
+
|
|
96
119
|
### Success (successful operations)
|
|
97
120
|
|
|
98
121
|
For confirmations and positive feedback:
|
|
@@ -110,8 +133,8 @@ For confirmations and positive feedback:
|
|
|
110
133
|
**Applied styles**:
|
|
111
134
|
|
|
112
135
|
- Background: `bg-success-50` (light green)
|
|
113
|
-
-
|
|
114
|
-
-
|
|
136
|
+
- Text: `text-success-foreground-subtle` (green)
|
|
137
|
+
- Icon: `text-success-foreground-subtle` (same as text)
|
|
115
138
|
- Usage: Confirmations, completed operations, successful validations
|
|
116
139
|
|
|
117
140
|
### Warning (warnings)
|
|
@@ -131,8 +154,8 @@ For caution messages requiring attention:
|
|
|
131
154
|
**Applied styles**:
|
|
132
155
|
|
|
133
156
|
- Background: `bg-warning-50` (light orange/yellow)
|
|
134
|
-
-
|
|
135
|
-
-
|
|
157
|
+
- Text: `text-warning-foreground-subtle` (orange/brown)
|
|
158
|
+
- Icon: `text-warning-foreground-subtle` (same as text)
|
|
136
159
|
- Usage: Warnings, approaching limits, recommended actions
|
|
137
160
|
|
|
138
161
|
### Destructive (critical errors)
|
|
@@ -152,8 +175,8 @@ For errors, failures, and critical messages:
|
|
|
152
175
|
**Applied styles**:
|
|
153
176
|
|
|
154
177
|
- Background: `bg-destructive-50` (light red)
|
|
155
|
-
-
|
|
156
|
-
-
|
|
178
|
+
- Text: `text-destructive-foreground-subtle` (red)
|
|
179
|
+
- Icon: `text-destructive-foreground-subtle` (same as text)
|
|
157
180
|
- Usage: Errors, validation failures, blocked actions
|
|
158
181
|
|
|
159
182
|
## Props
|
|
@@ -162,13 +185,13 @@ For errors, failures, and critical messages:
|
|
|
162
185
|
|
|
163
186
|
Main alert container with ARIA role.
|
|
164
187
|
|
|
165
|
-
| Prop | Type
|
|
166
|
-
| --------- |
|
|
167
|
-
| variant | `"default" \| "destructive" \| "success" \| "warning"` | `"default"` | Visual variant of the alert |
|
|
168
|
-
| border | `"default" \| "transparent"`
|
|
169
|
-
| className | `string`
|
|
170
|
-
| children | `ReactNode`
|
|
171
|
-
| ...props | `HTMLAttributes<HTMLDivElement>`
|
|
188
|
+
| Prop | Type | Default | Description |
|
|
189
|
+
| --------- | ---------------------------------------------------------------- | ----------- | ------------------------------------------ |
|
|
190
|
+
| variant | `"default" \| "info" \| "destructive" \| "success" \| "warning"` | `"default"` | Visual variant of the alert |
|
|
191
|
+
| border | `"default" \| "transparent"` | `"default"` | Border style (soft colored or transparent) |
|
|
192
|
+
| className | `string` | - | Additional CSS classes |
|
|
193
|
+
| children | `ReactNode` | - | Content (icon, title, description) |
|
|
194
|
+
| ...props | `HTMLAttributes<HTMLDivElement>` | - | Native div props |
|
|
172
195
|
|
|
173
196
|
**Automatically applied attributes**:
|
|
174
197
|
|
|
@@ -177,7 +200,7 @@ Main alert container with ARIA role.
|
|
|
177
200
|
|
|
178
201
|
### AlertTitle
|
|
179
202
|
|
|
180
|
-
Alert title with
|
|
203
|
+
Alert title with flexible grid positioning.
|
|
181
204
|
|
|
182
205
|
| Prop | Type | Description |
|
|
183
206
|
| --------- | -------------------------------- | ---------------------- |
|
|
@@ -187,11 +210,11 @@ Alert title with automatic line clamp.
|
|
|
187
210
|
|
|
188
211
|
**Features**:
|
|
189
212
|
|
|
190
|
-
- `
|
|
191
|
-
- `font-medium`: Medium font weight
|
|
213
|
+
- `font-semibold`: Semibold font weight
|
|
192
214
|
- `tracking-tight`: Adjusted letter spacing
|
|
193
215
|
- `min-h-4`: Minimum height of 1rem
|
|
194
|
-
- `
|
|
216
|
+
- `row-start-1`: Aligns with icon in first row
|
|
217
|
+
- Automatically positioned in grid (column 1 when no icon, column 2 when icon present)
|
|
195
218
|
|
|
196
219
|
### AlertDescription
|
|
197
220
|
|
|
@@ -205,38 +228,45 @@ Description container with rich content support.
|
|
|
205
228
|
|
|
206
229
|
**Features**:
|
|
207
230
|
|
|
208
|
-
- `text-muted-foreground`: Secondary text color (overridden by variants)
|
|
209
231
|
- `grid`: Internal grid container
|
|
210
232
|
- `justify-items-start`: Aligns items to the left
|
|
211
233
|
- `gap-1`: Spacing of 0.25rem between elements
|
|
212
234
|
- `[&_p]:leading-relaxed`: Relaxed line height for paragraphs
|
|
213
|
-
- `col-start-2`:
|
|
235
|
+
- `col-span-2 row-start-2`: Spans both grid columns in second row
|
|
236
|
+
- Text color inherited from variant
|
|
214
237
|
|
|
215
238
|
## Intelligent grid system
|
|
216
239
|
|
|
217
|
-
The Alert uses CSS Grid with
|
|
240
|
+
The Alert uses a **2-row CSS Grid** with automatic layout and Figma-aligned spacing:
|
|
218
241
|
|
|
219
|
-
|
|
242
|
+
**Base styles**:
|
|
243
|
+
|
|
244
|
+
- Padding: `p-6` (24px on all sides)
|
|
245
|
+
- Border radius: `rounded-3xl` (24px)
|
|
246
|
+
- Gap between title and description: `gap-y-2` (8px)
|
|
247
|
+
- Gap between icon and title: `gap-x-3` (12px)
|
|
248
|
+
|
|
249
|
+
**Grid structure**:
|
|
220
250
|
|
|
221
251
|
```css
|
|
222
|
-
grid-
|
|
252
|
+
grid-template-columns: auto 1fr;
|
|
253
|
+
gap-x: 12px; /* Between icon and content */
|
|
254
|
+
gap-y: 8px; /* Between rows */
|
|
223
255
|
```
|
|
224
256
|
|
|
225
|
-
|
|
226
|
-
- Column 2: All available space
|
|
257
|
+
**Row 1**: Icon (if present) + Title horizontally aligned
|
|
227
258
|
|
|
228
|
-
|
|
259
|
+
- Icon: `col-start-1 row-start-1` (auto-sized)
|
|
260
|
+
- Title: `row-start-1` (auto-positioned in next available column)
|
|
229
261
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```
|
|
262
|
+
**Row 2**: Description spans full width
|
|
263
|
+
|
|
264
|
+
- Description: `col-span-2 row-start-2` (spans both columns)
|
|
234
265
|
|
|
235
|
-
|
|
236
|
-
- Column 2: All remaining space
|
|
237
|
-
- Horizontal gap: 0.75rem (12px)
|
|
266
|
+
**Behavior**:
|
|
238
267
|
|
|
239
|
-
**
|
|
268
|
+
- **With icon**: Title appears in column 2, aligned with icon
|
|
269
|
+
- **Without icon**: Title automatically starts in column 1 (no empty space)
|
|
240
270
|
|
|
241
271
|
### Icon styles
|
|
242
272
|
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Amount input component
|
|
2
|
+
|
|
3
|
+
A composable monetary input with automatic number formatting, regional flag display, and currency symbol derivation from a BCP 47 locale.
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
`AmountInput` is built from four composable sub-components that wrap `InputGroup` internally. The locale drives everything: the regional flag, the currency symbol, and the number formatting. No separate currency code is needed.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Derives the country flag and currency symbol from a single BCP 47 locale tag (e.g. `"es-CO"`)
|
|
12
|
+
- Formats numbers automatically on blur using `Intl.NumberFormat`
|
|
13
|
+
- Supports controlled (`value` + `onValueChange`) and uncontrolled (`defaultValue`) modes
|
|
14
|
+
- Raw number is always available via `onValueChange` — the formatted string stays in the input
|
|
15
|
+
- Composable action slot (`AmountInputAction`) for inline link buttons (e.g. "use all")
|
|
16
|
+
- Disabled state propagates from `<fieldset disabled>` automatically
|
|
17
|
+
- Invalid state via `aria-invalid` triggers a destructive border on the container
|
|
18
|
+
- Eurozone countries each show their own national flag (not the EU flag) for better context in a payment UI
|
|
19
|
+
|
|
20
|
+
## Import
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import {
|
|
24
|
+
AmountInputContainer,
|
|
25
|
+
AmountInputFlag,
|
|
26
|
+
AmountInput,
|
|
27
|
+
AmountInputAction,
|
|
28
|
+
type AmountInputContainerProps,
|
|
29
|
+
type AmountInputFlagProps,
|
|
30
|
+
type AmountInputProps,
|
|
31
|
+
type AmountInputActionProps,
|
|
32
|
+
} from "@adamosuiteservices/ui/amount-input";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Utilities are also exported for custom use:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import {
|
|
39
|
+
REGION_CURRENCY_MAP,
|
|
40
|
+
getRegionFromLocale,
|
|
41
|
+
getCurrencySymbol,
|
|
42
|
+
formatAmount,
|
|
43
|
+
} from "@adamosuiteservices/ui/amount-input";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Basic usage
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<AmountInputContainer>
|
|
50
|
+
<AmountInputFlag locale="en-US" />
|
|
51
|
+
<AmountInput locale="en-US" placeholder="0.00" />
|
|
52
|
+
</AmountInputContainer>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Controlled
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const [value, setValue] = useState<number | undefined>(undefined);
|
|
59
|
+
|
|
60
|
+
<AmountInputContainer>
|
|
61
|
+
<AmountInputFlag locale="es-CO" />
|
|
62
|
+
<AmountInput
|
|
63
|
+
locale="es-CO"
|
|
64
|
+
value={value}
|
|
65
|
+
onValueChange={setValue}
|
|
66
|
+
placeholder="0,00"
|
|
67
|
+
/>
|
|
68
|
+
</AmountInputContainer>;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## With action
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<AmountInputContainer>
|
|
75
|
+
<AmountInputFlag locale="es-CO" />
|
|
76
|
+
<AmountInput
|
|
77
|
+
locale="es-CO"
|
|
78
|
+
value={value}
|
|
79
|
+
onValueChange={setValue}
|
|
80
|
+
placeholder="0,00"
|
|
81
|
+
/>
|
|
82
|
+
<AmountInputAction onClick={handleMax}>Usar todo</AmountInputAction>
|
|
83
|
+
</AmountInputContainer>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Inside a field
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<Field>
|
|
90
|
+
<FieldLabel>Amount</FieldLabel>
|
|
91
|
+
<AmountInputContainer>
|
|
92
|
+
<AmountInputFlag locale="de-DE" />
|
|
93
|
+
<AmountInput locale="de-DE" placeholder="0,00" />
|
|
94
|
+
</AmountInputContainer>
|
|
95
|
+
<FieldDescription>Available balance: €4,200.00</FieldDescription>
|
|
96
|
+
</Field>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Props
|
|
100
|
+
|
|
101
|
+
### AmountInputContainer
|
|
102
|
+
|
|
103
|
+
| Prop | Type | Default | Description |
|
|
104
|
+
| ----------- | --------- | ------- | ----------------------------------------------------------- |
|
|
105
|
+
| `disabled` | `boolean` | — | Propagates disabled styling to flag addon and action button |
|
|
106
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
107
|
+
|
|
108
|
+
Accepts all `<div>` props.
|
|
109
|
+
|
|
110
|
+
### AmountInputFlag
|
|
111
|
+
|
|
112
|
+
| Prop | Type | Default | Description |
|
|
113
|
+
| ---------------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
|
|
114
|
+
| `locale` | `string` | — | BCP 47 locale (e.g. `"es-CO"`, `"de-DE"`). Derives the regional flag and currency symbol |
|
|
115
|
+
| `currencySymbol` | `string` | — | Override the derived currency symbol |
|
|
116
|
+
|
|
117
|
+
### AmountInput
|
|
118
|
+
|
|
119
|
+
| Prop | Type | Default | Description |
|
|
120
|
+
| ----------------------- | -------------------------------------- | --------- | ------------------------------------------------------------ |
|
|
121
|
+
| `value` | `number \| string` | — | Controlled value |
|
|
122
|
+
| `defaultValue` | `number \| string` | — | Uncontrolled initial value |
|
|
123
|
+
| `onValueChange` | `(value: number \| undefined) => void` | — | Called on blur with the parsed numeric value, or `undefined` |
|
|
124
|
+
| `locale` | `string` | `"en-US"` | BCP 47 locale used for `Intl.NumberFormat` formatting |
|
|
125
|
+
| `minimumFractionDigits` | `number` | `2` | Minimum decimal places shown after formatting |
|
|
126
|
+
| `maximumFractionDigits` | `number` | `2` | Maximum decimal places shown after formatting |
|
|
127
|
+
| `disabled` | `boolean` | — | Disables the native input |
|
|
128
|
+
| `placeholder` | `string` | — | Placeholder text |
|
|
129
|
+
| `aria-invalid` | `boolean` | — | Triggers destructive border on the container via `:has()` |
|
|
130
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
131
|
+
|
|
132
|
+
Accepts all `<input>` props except `type`, `value` (native), `defaultValue` (native), and `onChange`.
|
|
133
|
+
|
|
134
|
+
### AmountInputAction
|
|
135
|
+
|
|
136
|
+
| Prop | Type | Default | Description |
|
|
137
|
+
| ----------- | -------- | ---------- | ---------------------- |
|
|
138
|
+
| `type` | `string` | `"button"` | HTML button type |
|
|
139
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
140
|
+
|
|
141
|
+
Accepts all `InputGroupButton` props except `variant` (locked to `"link"`).
|
|
142
|
+
|
|
143
|
+
## Utilities
|
|
144
|
+
|
|
145
|
+
### `REGION_CURRENCY_MAP`
|
|
146
|
+
|
|
147
|
+
`Record<string, string>` — maps ISO 3166-1 alpha-2 region codes (lowercase) to ISO 4217 currency codes. Covers 40+ regions. Eurozone countries all map to `"EUR"`.
|
|
148
|
+
|
|
149
|
+
### `getRegionFromLocale(locale: string): string | null`
|
|
150
|
+
|
|
151
|
+
Extracts the lowercase region code from a BCP 47 locale tag using `Intl.Locale`. Returns `null` if the locale is invalid or has no region subtag.
|
|
152
|
+
|
|
153
|
+
### `getCurrencySymbol(currencyCode: string): string`
|
|
154
|
+
|
|
155
|
+
Returns the currency symbol (`$`, `€`, `£`, etc.) for an ISO 4217 code using `Intl.NumberFormat`. Falls back to the code itself if derivation fails.
|
|
156
|
+
|
|
157
|
+
### `formatAmount(raw, locale, minimumFractionDigits, maximumFractionDigits): string`
|
|
158
|
+
|
|
159
|
+
Formats a raw numeric string using `Intl.NumberFormat`. Returns the original string if it cannot be parsed as a number.
|
|
160
|
+
|
|
161
|
+
## Examples
|
|
162
|
+
|
|
163
|
+
### Disabled state
|
|
164
|
+
|
|
165
|
+
Pass `disabled` to both `AmountInputContainer` (for addon styling) and `AmountInput` (for the native input):
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<AmountInputContainer disabled>
|
|
169
|
+
<AmountInputFlag locale="es-CO" />
|
|
170
|
+
<AmountInput locale="es-CO" defaultValue={9500000} disabled />
|
|
171
|
+
</AmountInputContainer>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Invalid state
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<AmountInputContainer>
|
|
178
|
+
<AmountInputFlag locale="en-GB" />
|
|
179
|
+
<AmountInput locale="en-GB" placeholder="0.00" aria-invalid />
|
|
180
|
+
</AmountInputContainer>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Inside a disabled fieldset
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<FieldSet disabled>
|
|
187
|
+
<FieldLegend>Payment details</FieldLegend>
|
|
188
|
+
<AmountInputContainer>
|
|
189
|
+
<AmountInputFlag locale="en-US" />
|
|
190
|
+
<AmountInput locale="en-US" defaultValue={250} />
|
|
191
|
+
</AmountInputContainer>
|
|
192
|
+
</FieldSet>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Multiple currencies
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
const locales = ["en-US", "de-DE", "es-CO", "en-GB", "pt-BR", "es-MX"];
|
|
199
|
+
|
|
200
|
+
{
|
|
201
|
+
locales.map((locale) => (
|
|
202
|
+
<AmountInputContainer key={locale}>
|
|
203
|
+
<AmountInputFlag locale={locale} />
|
|
204
|
+
<AmountInput locale={locale} placeholder="0.00" />
|
|
205
|
+
</AmountInputContainer>
|
|
206
|
+
));
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Implementation notes
|
|
211
|
+
|
|
212
|
+
- `AmountInputFlag` resolves: locale → region code → `REGION_CURRENCY_MAP` → currency code → `getCurrencySymbol`
|
|
213
|
+
- `AmountInput` uses a dual-state strategy: `displayValue` (formatted string shown in the input) and a raw number via `onValueChange`. On focus, formatting is stripped so the user types a plain number. On blur, formatting is re-applied.
|
|
214
|
+
- `AmountInputContainer` passes `data-disabled` to `InputGroup`, which propagates opacity to addons via `group-data-[disabled=true]` selectors.
|
|
215
|
+
- `data-slot="input-group-control"` on the inner `<input>` allows `InputGroup`'s `:has()` selectors to activate the focus ring and error border.
|
|
216
|
+
|
|
217
|
+
## Accessibility
|
|
218
|
+
|
|
219
|
+
- `aria-invalid` on `AmountInput` switches the container border to the destructive color automatically.
|
|
220
|
+
- `inputMode="decimal"` on the inner `<input>` opens the numeric keyboard on mobile.
|
|
221
|
+
- `disabled` on `AmountInput` maps to native HTML disabled, which prevents interaction and announces the state to screen readers.
|
|
222
|
+
- Cards inside a `<fieldset disabled>` inherit the disabled state natively.
|
|
223
|
+
|
|
224
|
+
## References
|
|
225
|
+
|
|
226
|
+
- [MDN: Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat)
|
|
227
|
+
- [MDN: Intl.Locale](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale)
|
|
228
|
+
- [flagcdn.com](https://flagcdn.com) — flag images by region code
|
|
229
|
+
- [BCP 47 language tags](https://www.rfc-editor.org/rfc/rfc5646)
|