@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.
Files changed (194) hide show
  1. package/README.md +1 -1
  2. package/dist/accordion-rounded.cjs +8 -8
  3. package/dist/accordion-rounded.js +12 -12
  4. package/dist/accordion.cjs +1 -1
  5. package/dist/accordion.js +1 -1
  6. package/dist/alert.cjs +32 -23
  7. package/dist/alert.js +53 -43
  8. package/dist/amount-input.cjs +8 -0
  9. package/dist/amount-input.js +191 -0
  10. package/dist/avatar.cjs +7 -7
  11. package/dist/avatar.js +18 -18
  12. package/dist/badge.cjs +24 -28
  13. package/dist/badge.js +45 -42
  14. package/dist/breadcrumb.cjs +3 -4
  15. package/dist/breadcrumb.js +17 -18
  16. package/dist/button-CPm4-98H.cjs +87 -0
  17. package/dist/button-D4ddrxyp.js +156 -0
  18. package/dist/button-group.cjs +1 -1
  19. package/dist/button-group.js +1 -1
  20. package/dist/button.cjs +1 -1
  21. package/dist/button.js +1 -1
  22. package/dist/{calendar-Dorq3-wv.cjs → calendar-DXq90PYV.cjs} +20 -22
  23. package/dist/{calendar-xBaFu2sB.js → calendar-DgfO9zab.js} +239 -240
  24. package/dist/calendar.cjs +1 -1
  25. package/dist/calendar.js +1 -1
  26. package/dist/card.cjs +3 -3
  27. package/dist/card.js +4 -4
  28. package/dist/checkbox-CIzBdqN7.cjs +24 -0
  29. package/dist/{checkbox-DL_jFvgl.js → checkbox-DPlUjwLi.js} +54 -52
  30. package/dist/checkbox.cjs +1 -1
  31. package/dist/checkbox.js +1 -1
  32. package/dist/colors.css +1 -1
  33. package/dist/combobox-DG9u4g84.js +692 -0
  34. package/dist/combobox-DylTjGrw.cjs +57 -0
  35. package/dist/combobox.cjs +1 -1
  36. package/dist/combobox.js +1 -1
  37. package/dist/components/layout/sidebar/sidebar.d.ts +2 -1
  38. package/dist/components/layout/toaster/toaster.d.ts +1 -1
  39. package/dist/components/ui/alert/alert.d.ts +1 -1
  40. package/dist/components/ui/amount-input/amount-input.d.ts +32 -0
  41. package/dist/components/ui/amount-input/index.d.ts +1 -0
  42. package/dist/components/ui/badge/badge.d.ts +3 -2
  43. package/dist/components/ui/calendar/calendar.d.ts +1 -1
  44. package/dist/components/ui/combobox/combobox.d.ts +3 -1
  45. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +3 -1
  46. package/dist/components/ui/selectable-card/index.d.ts +1 -0
  47. package/dist/components/ui/selectable-card/selectable-card.d.ts +22 -0
  48. package/dist/components/ui/timeline/index.d.ts +1 -0
  49. package/dist/components/ui/timeline/timeline.d.ts +30 -0
  50. package/dist/components/ui/typography/typography.d.ts +1 -1
  51. package/dist/context-menu.cjs +18 -19
  52. package/dist/context-menu.js +37 -38
  53. package/dist/date-picker-selector.cjs +1 -1
  54. package/dist/date-picker-selector.js +3 -3
  55. package/dist/dialog.cjs +7 -9
  56. package/dist/dialog.js +36 -38
  57. package/dist/dropdown-menu.cjs +57 -36
  58. package/dist/dropdown-menu.js +206 -173
  59. package/dist/field.cjs +12 -7
  60. package/dist/field.js +51 -45
  61. package/dist/file-upload-v2.cjs +11 -5
  62. package/dist/file-upload-v2.js +75 -60
  63. package/dist/file-upload.cjs +11 -5
  64. package/dist/file-upload.js +118 -110
  65. package/dist/full-screen-loader.cjs +1 -1
  66. package/dist/full-screen-loader.js +1 -1
  67. package/dist/{icon-B7joBr0A.cjs → icon-C5Q2b1Am.cjs} +1 -1
  68. package/dist/{icon-BFQz1tQC.js → icon-t4jt1Z2h.js} +1 -1
  69. package/dist/icon.cjs +1 -1
  70. package/dist/icon.js +1 -1
  71. package/dist/index-BBT2EGq8.js +18 -0
  72. package/dist/index-DCsgSkBj.cjs +1 -0
  73. package/dist/input-8sEO5zwD.js +44 -0
  74. package/dist/input-AONeSXcs.cjs +22 -0
  75. package/dist/input-group-BLffLxyg.cjs +86 -0
  76. package/dist/input-group-DmevJAqa.js +240 -0
  77. package/dist/input-group.cjs +1 -84
  78. package/dist/input-group.js +7 -234
  79. package/dist/input-otp.cjs +5 -7
  80. package/dist/input-otp.js +58 -60
  81. package/dist/input.cjs +1 -1
  82. package/dist/input.js +1 -1
  83. package/dist/kbd.cjs +6 -7
  84. package/dist/kbd.js +14 -15
  85. package/dist/{label-DqfX9cHc.cjs → label-B7Z1D5-Q.cjs} +5 -4
  86. package/dist/{label-C6zVnc3d.js → label-_BWRIH7C.js} +14 -13
  87. package/dist/label.cjs +1 -1
  88. package/dist/label.js +1 -1
  89. package/dist/pagination.cjs +5 -5
  90. package/dist/pagination.js +18 -18
  91. package/dist/radio-group.cjs +12 -9
  92. package/dist/radio-group.js +66 -63
  93. package/dist/select.cjs +18 -16
  94. package/dist/select.js +18 -16
  95. package/dist/selectable-card.cjs +29 -0
  96. package/dist/selectable-card.js +129 -0
  97. package/dist/separator-DXdc7LcC.cjs +7 -0
  98. package/dist/{separator-CsaqP20m.js → separator-DZfXXbNt.js} +1 -1
  99. package/dist/separator.cjs +1 -1
  100. package/dist/separator.js +1 -1
  101. package/dist/{sheet-Cnq7TCzu.cjs → sheet-Cp6JGhWC.cjs} +10 -10
  102. package/dist/{sheet-C9vce0ut.js → sheet-hWerE8S1.js} +9 -6
  103. package/dist/sheet.cjs +1 -1
  104. package/dist/sheet.js +1 -1
  105. package/dist/sidebar.cjs +10 -10
  106. package/dist/sidebar.js +83 -92
  107. package/dist/slider.cjs +1 -1
  108. package/dist/slider.js +1 -1
  109. package/dist/{spinner-C7q7NthY.cjs → spinner-DUZ2vcus.cjs} +1 -1
  110. package/dist/{spinner-DQ5JLL3U.js → spinner-_-J3zJ_g.js} +1 -1
  111. package/dist/spinner.cjs +1 -1
  112. package/dist/spinner.js +1 -1
  113. package/dist/styles.css +1 -1
  114. package/dist/switch.cjs +2 -4
  115. package/dist/switch.js +71 -73
  116. package/dist/table.cjs +14 -14
  117. package/dist/table.js +12 -12
  118. package/dist/tabs-underline.cjs +11 -15
  119. package/dist/tabs-underline.js +20 -24
  120. package/dist/tabs.cjs +10 -14
  121. package/dist/tabs.js +20 -24
  122. package/dist/tailwind-colors.css +1 -1
  123. package/dist/tailwind-theme.css +1 -1
  124. package/dist/textarea-BSooGyp-.cjs +18 -0
  125. package/dist/textarea-D_sj6ivo.js +39 -0
  126. package/dist/textarea.cjs +1 -1
  127. package/dist/textarea.js +1 -1
  128. package/dist/themes.css +1 -1
  129. package/dist/timeline.cjs +4 -0
  130. package/dist/timeline.js +189 -0
  131. package/dist/toaster.cjs +5 -4
  132. package/dist/toaster.js +33 -32
  133. package/dist/toggle.cjs +4 -4
  134. package/dist/toggle.js +17 -17
  135. package/dist/tooltip.cjs +5 -6
  136. package/dist/tooltip.js +4 -5
  137. package/docs/components/layout/sidebar.md +81 -53
  138. package/docs/components/layout/toaster.md +35 -55
  139. package/docs/components/ui/accordion-rounded.md +12 -11
  140. package/docs/components/ui/alert.md +66 -36
  141. package/docs/components/ui/amount-input.md +229 -0
  142. package/docs/components/ui/avatar.md +28 -32
  143. package/docs/components/ui/badge.md +85 -32
  144. package/docs/components/ui/breadcrumb.md +5 -7
  145. package/docs/components/ui/button-group.md +16 -16
  146. package/docs/components/ui/button.md +23 -36
  147. package/docs/components/ui/calendar.md +54 -27
  148. package/docs/components/ui/card.md +5 -4
  149. package/docs/components/ui/checkbox.md +3 -3
  150. package/docs/components/ui/combobox.md +35 -1
  151. package/docs/components/ui/command.md +7 -7
  152. package/docs/components/ui/context-menu.md +14 -15
  153. package/docs/components/ui/date-picker-selector.md +31 -31
  154. package/docs/components/ui/dialog.md +47 -49
  155. package/docs/components/ui/dropdown-menu.md +34 -37
  156. package/docs/components/ui/field.md +25 -31
  157. package/docs/components/ui/file-upload-v2.md +11 -0
  158. package/docs/components/ui/file-upload.md +105 -108
  159. package/docs/components/ui/hover-card.md +28 -6
  160. package/docs/components/ui/icon.md +10 -9
  161. package/docs/components/ui/input-group.md +9 -9
  162. package/docs/components/ui/input.md +30 -33
  163. package/docs/components/ui/kbd.md +10 -9
  164. package/docs/components/ui/label.md +6 -6
  165. package/docs/components/ui/pagination.md +3 -3
  166. package/docs/components/ui/popover.md +1 -0
  167. package/docs/components/ui/progress.md +3 -3
  168. package/docs/components/ui/radio-group.md +18 -6
  169. package/docs/components/ui/scroll-area.md +4 -4
  170. package/docs/components/ui/select.md +14 -12
  171. package/docs/components/ui/selectable-card.md +204 -0
  172. package/docs/components/ui/separator.md +4 -4
  173. package/docs/components/ui/sheet.md +21 -3
  174. package/docs/components/ui/slider.md +3 -3
  175. package/docs/components/ui/switch.md +7 -7
  176. package/docs/components/ui/table.md +7 -4
  177. package/docs/components/ui/tabs-underline.md +36 -36
  178. package/docs/components/ui/tabs.md +6 -4
  179. package/docs/components/ui/textarea.md +6 -4
  180. package/docs/components/ui/timeline.md +214 -0
  181. package/docs/components/ui/toggle.md +1 -1
  182. package/docs/components/ui/tooltip.md +3 -3
  183. package/llm.txt +7 -4
  184. package/package.json +13 -1
  185. package/dist/button-BnUlAtuD.js +0 -132
  186. package/dist/button-CFJs0esR.cjs +0 -63
  187. package/dist/checkbox-3RIZX2HF.cjs +0 -22
  188. package/dist/combobox-MkeJiTXj.js +0 -637
  189. package/dist/combobox-jJRxvUsB.cjs +0 -40
  190. package/dist/input-BCiOr4Fy.js +0 -44
  191. package/dist/input-Bz5k4w94.cjs +0 -22
  192. package/dist/separator-CCGaTo09.cjs +0 -7
  193. package/dist/textarea-BRCnIxdB.js +0 -33
  194. package/dist/textarea-DkFUS_oS.cjs +0 -14
@@ -50,18 +50,7 @@ function MyForm() {
50
50
  }
51
51
  ```
52
52
 
53
- ### Múltiples Archivos
54
-
55
- ```tsx
56
- import { useState } from "react";
57
- import { FileUpload } from "@adamosuiteservices/ui/file-upload";
58
-
59
- function MyForm() {
60
- const [files, setFiles] = useState<File[]>([]);
61
-
62
- return <FileUpload selectedFiles={files} onFilesSelect={setFiles} multiple />;
63
- }
64
- ```
53
+ ### Multiple files
65
54
 
66
55
  **Default configuration**:
67
56
 
@@ -448,75 +437,55 @@ Position where selected files appear in multiple mode:
448
437
  ### With Field components
449
438
 
450
439
  ```tsx
451
- acceptedExtensions?: string[]
452
- ```
453
-
454
- Array of allowed file extensions. Default: `[".xls", ".xlsx", ".numbers"]`
455
-
456
- **Example**:
457
-
458
- ```tsx
459
- <FileUpload
460
- selectedFile={file}
461
- onFileSelect={setFile}
462
- acceptedExtensions={[".pdf", ".doc", ".docx"]}
463
- />
464
- ```
465
-
466
- ### maxSizeInMB
467
-
468
- ```tsx
469
- maxSizeInMB?: number
470
- ```
471
-
472
- Maximum file size in megabytes. Default: `50`
473
-
474
- **Example**:
475
-
476
- ```tsx
477
- <FileUpload selectedFile={file} onFileSelect={setFile} maxSizeInMB={10} />
478
- ```
479
-
480
- ## Examples
440
+ import { useState } from "react";
441
+ import { FileUpload } from "@adamosuiteservices/ui/file-upload";
442
+ import {
443
+ Field,
444
+ FieldLabel,
445
+ FieldDescription,
446
+ FieldError,
447
+ FieldGroup,
448
+ } from "@adamosuiteservices/ui/field";
481
449
 
482
- const handleInvalidFile = (file: File, reason: "extension" | "size") => {
483
- if (reason === "extension") {
484
- setError(`File "${file.name}" has an invalid extension.`);
485
- } else if (reason === "size") {
486
- setError(`File "${file.name}" exceeds the maximum size limit.`);
487
- }
488
- };
450
+ function DocumentUpload() {
451
+ const [file, setFile] = useState<File | null>(null);
452
+ const [error, setError] = useState("");
453
+
454
+ const handleInvalidFile = (f: File, reason: "extension" | "size") => {
455
+ setError(
456
+ reason === "extension"
457
+ ? `File "${f.name}" has an invalid extension.`
458
+ : `File "${f.name}" exceeds the maximum size limit.`,
459
+ );
460
+ };
489
461
 
490
- return (
491
- <FieldGroup className="adm:max-w-xl">
492
- <Field>
493
- <FieldLabel>Upload document (PDF or DOCX only, max 2MB)</FieldLabel>
494
- <FileUpload
495
- selectedFile={file}
496
- onFileSelect={(newFile) => {
497
- setFile(newFile);
498
- if (newFile) setError("");
499
- }}
500
- onInvalidFile={handleInvalidFile}
501
- aria-invalid={!!error}
502
- acceptedExtensions={[".pdf", ".docx"]}
503
- maxSizeInMB={2}
504
- />
505
- {error ? (
506
- <FieldError>{error}</FieldError>
507
- ) : (
508
- <FieldDescription>
509
- Supported formats: PDF, DOCX. Maximum 2MB.
510
- </FieldDescription>
511
- )}
512
- </Field>
513
- </FieldGroup>
514
- );
462
+ return (
463
+ <FieldGroup className="adm:max-w-xl">
464
+ <Field data-invalid={!!error}>
465
+ <FieldLabel>Upload document (PDF or DOCX only, max 2 MB)</FieldLabel>
466
+ <FileUpload
467
+ selectedFile={file}
468
+ onFileSelect={(newFile) => {
469
+ setFile(newFile);
470
+ if (newFile) setError("");
471
+ }}
472
+ onInvalidFile={handleInvalidFile}
473
+ aria-invalid={!!error}
474
+ acceptedExtensions={[".pdf", ".docx"]}
475
+ maxSizeInMB={2}
476
+ />
477
+ {error ? (
478
+ <FieldError>{error}</FieldError>
479
+ ) : (
480
+ <FieldDescription>
481
+ Supported formats: PDF, DOCX. Maximum 2 MB.
482
+ </FieldDescription>
483
+ )}
484
+ </Field>
485
+ </FieldGroup>
486
+ );
515
487
  }
516
-
517
- ````
518
-
519
- ### Estado Deshabilitado
488
+ ```
520
489
 
521
490
  ```tsx
522
491
  import {
@@ -559,7 +528,7 @@ function DisabledWithFileExample() {
559
528
  </FieldGroup>
560
529
  );
561
530
  }
562
- ````
531
+ ```
563
532
 
564
533
  ### Inside fieldset disabled
565
534
 
@@ -733,12 +702,17 @@ function MultipleFilesWithCallbacks() {
733
702
 
734
703
  ### Excel files (default)
735
704
 
736
- ````tsx
705
+ ```tsx
737
706
  const [file, setFile] = useState<File | null>(null);
738
707
 
739
708
  <FileUpload
740
709
  selectedFile={file}
741
- ### Múltiples Archivos
710
+ onFileSelect={setFile}
711
+ // Default: .xls, .xlsx, .numbers; max 50 MB
712
+ />;
713
+ ```
714
+
715
+ ### Multiple files with labels
742
716
 
743
717
  ```tsx
744
718
  const [files, setFiles] = useState<File[]>([]);
@@ -750,10 +724,10 @@ const [files, setFiles] = useState<File[]>([]);
750
724
  maxFiles={5}
751
725
  labels={{
752
726
  dragDrop: "Drag and drop your files here or",
753
- selectFile: "Select files"
727
+ selectFile: "Select files",
754
728
  }}
755
- />
756
- ````
729
+ />;
730
+ ```
757
731
 
758
732
  ### Multiple images
759
733
 
@@ -793,13 +767,24 @@ const [files, setFiles] = useState<File[]>([]);
793
767
  />;
794
768
  ```
795
769
 
796
- />
797
-
798
770
  ### Images
799
771
 
800
- ````tsx
772
+ ```tsx
801
773
  const [image, setImage] = useState<File | null>(null);
802
774
 
775
+ <FileUpload
776
+ selectedFile={image}
777
+ onFileSelect={setImage}
778
+ acceptedExtensions={[".jpg", ".jpeg", ".png", ".gif", ".webp"]}
779
+ maxSizeInMB={5}
780
+ labels={{
781
+ dragDrop: "Drag and drop your image here or",
782
+ selectFile: "Select image",
783
+ fileRequirements: "Supported: JPG, PNG, GIF, WebP. Max 5 MB.",
784
+ }}
785
+ />;
786
+ ```
787
+
803
788
  ## Visual states
804
789
 
805
790
  ### Simple mode
@@ -807,6 +792,7 @@ const [image, setImage] = useState<File | null>(null);
807
792
  #### Without selected file
808
793
 
809
794
  The component shows:
795
+
810
796
  - Drag & drop area with dashed border
811
797
  - Document icon on light blue background
812
798
  - Instructional text and link to select file
@@ -815,6 +801,7 @@ The component shows:
815
801
  #### With selected file
816
802
 
817
803
  The drag & drop area is hidden and shows:
804
+
818
805
  - Card with `bg-muted` background and border
819
806
  - Document icon on `bg-primary-50` background
820
807
  - File name (with truncate if long)
@@ -830,12 +817,15 @@ Only the drag & drop area is shown.
830
817
  ### During drag over
831
818
 
832
819
  When the user drags files over the area:
833
- - Border changes to `border-primary`
820
+
821
+ - Border changes to `border-strong-border`
822
+ - Background changes to `bg-muted`
834
823
  - Smooth transition with `transition-colors`
835
824
 
836
825
  ### Invalid state
837
826
 
838
827
  When `invalid={true}` or `aria-invalid={true}`:
828
+
839
829
  - Border: `border-destructive`
840
830
  - Background: `bg-destructive/5`
841
831
  - Document icon: `text-destructive` with `bg-destructive/10` background
@@ -848,11 +838,13 @@ When `invalid={true}` or `aria-invalid={true}`:
848
838
  When `disabled={true}` or inside `<fieldset disabled>`:
849
839
 
850
840
  **Drag & drop area**:
841
+
851
842
  - Opacity: `opacity-50`
852
843
  - Cursor: `cursor-not-allowed`
853
844
  - Visual error states are not applied
854
845
 
855
846
  **Selected files**:
847
+
856
848
  - Opacity: `opacity-50`
857
849
  - Cursor: `cursor-not-allowed`
858
850
  - Remove button disabled
@@ -868,6 +860,7 @@ The component automatically validates:
868
860
  3. **Count** (multiple mode): Limits to `maxFiles` number of files
869
861
 
870
862
  If a file does not meet these validations:
863
+
871
864
  - It is not selected
872
865
  - The `onFileSelect`/`onFilesSelect` callbacks are not invoked
873
866
  - The `onInvalidFile` callback is invoked (if defined) with the file and reason
@@ -898,16 +891,18 @@ const handleInvalidFile = (file: File, reason: "extension" | "size") => {
898
891
  invalid={!!error}
899
892
  acceptedExtensions={[".pdf", ".docx"]}
900
893
  maxSizeInMB={2}
901
- />
894
+ />;
902
895
 
903
- {error && (
904
- <div className="adm:rounded-lg adm:border adm:border-destructive adm:bg-destructive/5 adm:p-4">
905
- <Typography color="destructive" className="adm:text-sm adm:font-medium">
906
- {error}
907
- </Typography>
908
- </div>
909
- )}
910
- ````
896
+ {
897
+ error && (
898
+ <div className="adm:rounded-lg adm:border adm:border-destructive adm:bg-destructive/5 adm:p-4">
899
+ <Typography color="destructive" className="adm:text-sm adm:font-medium">
900
+ {error}
901
+ </Typography>
902
+ </div>
903
+ );
904
+ }
905
+ ```
911
906
 
912
907
  ## Behavior by mode
913
908
 
@@ -930,26 +925,28 @@ const handleInvalidFile = (file: File, reason: "extension" | "size") => {
930
925
  **Drag & drop area:**
931
926
 
932
927
  - Padding: `p-6` (24px)
933
- - Border radius: `rounded-2xl` (16px)
934
- - Border: `border-2 border-dashed`
928
+ - Border radius: `rounded-3xl` (24px)
929
+ - Border: `border border-dashed`
935
930
  - Normal state: `border-input bg-background`
936
- - Dragging: `border-primary`
931
+ - Hover: `border-strong-border bg-muted`
932
+ - Dragging: `border-strong-border`
937
933
  - Transitions: `transition-colors`
934
+ - Drop icon: `upload` from Material Symbols on `bg-primary-50` background (`rounded-full size-11`)
938
935
 
939
936
  **Selected file card:**
940
937
 
941
- - Padding: `p-6` (24px)
942
- - Border radius: `rounded-2xl` (16px)
938
+ - Padding: `p-4` (16px)
939
+ - Border radius: `rounded-3xl` (24px)
943
940
  - Background: `bg-muted`
944
- - Border: `border-input`
945
- - Horizontal gap: `gap-4` (16px)
946
- - Icon: `text-primary` on `bg-primary/15` background
941
+ - No border
942
+ - Horizontal gap: `gap-6` (24px)
943
+ - Icon: `article` from Material Symbols on `bg-background` background (`rounded-full size-11`)
947
944
 
948
945
  **Remove button:**
949
946
 
950
- - Variant: `destructive-medium`
951
- - Icon: `delete` from Material Symbols
952
- - Icon color: `text-destructive`
947
+ - Variant: `ghost`, size: `icon`
948
+ - Icon: `cancel` from Material Symbols
949
+ - Icon color: `text-destructive` (automatically inherits `text-disabled-foreground` when disabled)
953
950
 
954
951
  **Clear all button (multiple mode):**
955
952
 
@@ -60,10 +60,32 @@ import {
60
60
 
61
61
  ## Props
62
62
 
63
- | Prop | Type | Default | Description |
64
- | ---------- | -------- | ------- | ------------------------- |
65
- | openDelay | `number` | `200` | Delay before opening (ms) |
66
- | closeDelay | `number` | `300` | Delay before closing (ms) |
63
+ ### HoverCard (root)
64
+
65
+ | Prop | Type | Default | Description |
66
+ | -------------- | ------------------------- | ------- | --------------------------- |
67
+ | `open` | `boolean` | - | Controlled open state |
68
+ | `onOpenChange` | `(open: boolean) => void` | - | Callback when state changes |
69
+ | `openDelay` | `number` | `200` | Delay before opening (ms) |
70
+ | `closeDelay` | `number` | `300` | Delay before closing (ms) |
71
+
72
+ ### HoverCardTrigger
73
+
74
+ | Prop | Type | Description |
75
+ | --------- | --------- | ---------------------------------------- |
76
+ | `asChild` | `boolean` | Pass props to child instead of a wrapper |
77
+
78
+ ### HoverCardContent
79
+
80
+ | Prop | Type | Default | Description |
81
+ | ------------- | ---------------------------------------- | ---------- | ---------------------------------------- |
82
+ | `align` | `"start" \| "center" \| "end"` | `"center"` | Horizontal alignment relative to trigger |
83
+ | `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Side where the card appears |
84
+ | `sideOffset` | `number` | `4` | Distance from trigger (px) |
85
+ | `alignOffset` | `number` | `0` | Alignment offset |
86
+ | `className` | `string` | - | Additional CSS classes |
87
+
88
+ **Default styles**: `w-64`, `p-4`, `rounded-md`, `shadow-xs`, `bg-popover`, `z-50`
67
89
 
68
90
  ## References
69
91
 
@@ -90,7 +112,7 @@ import {
90
112
  </HoverCard>
91
113
  ```
92
114
 
93
- ### Con Avatar (User Preview)
115
+ ### With avatar (user preview)
94
116
 
95
117
  ```tsx
96
118
  import {
@@ -152,7 +174,7 @@ import { Icon } from "@adamosuiteservices/ui/icon";
152
174
  <p className="text-sm">Building design systems and web apps.</p>
153
175
  <div className="flex items-center gap-4 text-sm text-muted-foreground">
154
176
  <div className="flex items-center gap-1">
155
- <UsersIcon className="h-4 w-4" />
177
+ <Icon symbol="group" className="text-lg" />
156
178
  <span>2.1k followers</span>
157
179
  </div>
158
180
  <div>Following 180</div>
@@ -31,7 +31,7 @@ import { Icon, type IconProps } from "@adamosuiteservices/ui/icon";
31
31
  ```tsx
32
32
  import { type IconProps } from "@adamosuiteservices/ui/icon";
33
33
 
34
- // Para crear componentes custom
34
+ // To create custom components
35
35
  function CustomIcon(props: IconProps) {
36
36
  return <Icon {...props} className="custom-icon-styles" />;
37
37
  }
@@ -386,21 +386,21 @@ const commonIcons = [
386
386
  <Icon symbol="star" className="adm:text-5xl" /> {/* ~48px */}
387
387
  ```
388
388
 
389
- ### Peso Apropiado por Contexto
389
+ ### Appropriate weight by context
390
390
 
391
391
  ```tsx
392
392
  {
393
- /* ✅ Correcto - Peso ligero para interfaces modernas */
393
+ /* ✅ Correct - Light weight for modern interfaces */
394
394
  }
395
395
  <Icon symbol="menu" weight={300} />;
396
396
 
397
397
  {
398
- /* ✅ Correcto - Peso mayor para énfasis */
398
+ /* ✅ Correct - Heavier weight for emphasis */
399
399
  }
400
400
  <Icon symbol="warning" weight={500} fill={1} className="adm:text-warning" />;
401
401
 
402
402
  {
403
- /* ❌ Evitar - Peso muy pesado sin propósito */
403
+ /* ❌ Avoid - Too heavy without purpose */
404
404
  }
405
405
  <Icon symbol="home" weight={700} />;
406
406
  ```
@@ -417,18 +417,18 @@ const commonIcons = [
417
417
  <Icon symbol="favorite" fill={liked ? 1 : 0} />
418
418
  ```
419
419
 
420
- ### Accesibilidad
420
+ ### Accessibility
421
421
 
422
422
  ```tsx
423
423
  {
424
- /* ✅ Correcto - Botones con labels */
424
+ /* ✅ Correct - Buttons with labels */
425
425
  }
426
426
  <Button variant="ghost" size="icon" aria-label="Close dialog">
427
427
  <Icon symbol="close" className="adm:text-2xl" />
428
428
  </Button>;
429
429
 
430
430
  {
431
- /* ✅ Correcto - Iconos decorativos */
431
+ /* ✅ Correct - Decorative icons */
432
432
  }
433
433
  <div className="adm:flex adm:items-center adm:gap-2">
434
434
  <Icon symbol="folder" className="adm:text-xl" aria-hidden="true" />
@@ -513,8 +513,9 @@ The component renders a `<span>` with the following characteristics:
513
513
 
514
514
  ```tsx
515
515
  <span
516
+ translate="no"
516
517
  data-slot="icon"
517
- className="material-symbols-outlined adm:inline-block adm:text-2xl"
518
+ className="material-symbols-outlined adm:inline-block adm:text-2xl adm:select-none"
518
519
  style={{ fontVariationSettings: "..." }}
519
520
  >
520
521
  {symbol}
@@ -79,12 +79,12 @@ import {
79
79
 
80
80
  ### InputGroupButton
81
81
 
82
- | Prop | Type | Default | Description |
83
- | --------- | ---------------------------------------- | ----------------- | ------------------------------ |
84
- | `size` | `"xs" \| "sm" \| "icon-xs" \| "icon-sm"` | `"xs"` | Button size |
85
- | `variant` | Button variants | `"ghost-neutral"` | Button variant |
86
- | `type` | `string` | `"button"` | HTML button type |
87
- | ...rest | - | - | All Button props except `size` |
82
+ | Prop | Type | Default | Description |
83
+ | --------- | ---------------------------------------- | ---------------- | ------------------------------ |
84
+ | `size` | `"xs" \| "sm" \| "icon-xs" \| "icon-sm"` | `"xs"` | Button size |
85
+ | `variant` | Button variants | `"link-neutral"` | Button variant |
86
+ | `type` | `string` | `"button"` | HTML button type |
87
+ | ...rest | - | - | All Button props except `size` |
88
88
 
89
89
  **Sizes**:
90
90
 
@@ -448,9 +448,9 @@ function App() {
448
448
 
449
449
  ### InputGroup States
450
450
 
451
- - **Disabled**: `data-disabled` → `opacity-50` en addons
452
- - **Focus**: `has-[input:focus-visible]` → ring y border aplicados al grupo
453
- - **Invalid**: `has-[input[aria-invalid=true]]` → ring destructive y border
451
+ - **Disabled**: `data-disabled` → `opacity-50` on addons
452
+ - **Focus**: `has-[input:focus-visible]` → ring and border applied to the group
453
+ - **Invalid**: `has-[input[aria-invalid=true]]` → destructive ring and border
454
454
 
455
455
  ### Focus behavior
456
456
 
@@ -128,20 +128,20 @@ import { Input } from "@adamosuiteservices/ui/input";
128
128
 
129
129
  ```tsx
130
130
  {
131
- /* Pequeño */
131
+ /* Small */
132
132
  }
133
133
  <Input type="text" placeholder="Small input" className="h-9 text-sm" />;
134
134
 
135
135
  {
136
- /* Por defecto */
136
+ /* Default */
137
137
  }
138
138
  <Input type="text" placeholder="Default input" />;
139
139
  {
140
- /* h-10 por defecto */
140
+ /* h-10 by default */
141
141
  }
142
142
 
143
143
  {
144
- /* Grande */
144
+ /* Large */
145
145
  }
146
146
  <Input type="text" placeholder="Large input" className="h-11" />;
147
147
  ```
@@ -179,32 +179,28 @@ import { Input } from "@adamosuiteservices/ui/input";
179
179
 
180
180
  ### Focus
181
181
 
182
- El input tiene un anillo de enfoque visible:
182
+ The input has a visible focus ring:
183
183
 
184
184
  ```css
185
- focus-visible:ring-ring/50
186
- focus-visible:ring-[3px]
185
+ focus-visible:border-primary-300
186
+ focus-visible:ring-4
187
+ focus-visible:ring-primary/10
187
188
  ```
188
189
 
189
190
  ### Validation states
190
191
 
191
192
  - Normal border: `border-input`
192
- - Invalid: `aria-invalid:border-destructive` with red ring
193
-
194
- ### Dark mode
195
-
196
- ```css
197
- dark: bg-input/30;
198
- ```
193
+ - Invalid: `aria-invalid:border-destructive` + red ring on focus `ring-4 ring-destructive/10`
199
194
 
200
195
  ### File input
201
196
 
202
197
  File inputs have special styles for the button:
203
198
 
204
199
  ```css
205
- file:h-7
200
+ file:h-full
206
201
  file:text-sm
207
202
  file:font-medium
203
+ file:text-foreground
208
204
  ```
209
205
 
210
206
  ## Common use cases
@@ -265,7 +261,7 @@ const maxLength = 100;
265
261
 
266
262
  ## Implementation notes
267
263
 
268
- - Uses the `` prefix in all styles
264
+ - Uses the `adm:` prefix in all styles
269
265
  - Based on the native HTML `<input>` element
270
266
  - Supports all native HTML input props
271
267
  - Internal SVG icons are automatically resized
@@ -273,32 +269,32 @@ const maxLength = 100;
273
269
 
274
270
  ## References
275
271
 
276
- - Documentación de shadcn/ui: <https://ui.shadcn.com/docs/components/input>
272
+ - shadcn/ui documentation: <https://ui.shadcn.com/docs/components/input>
277
273
  - MDN Input: <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>
278
274
 
279
275
  ## Advanced features
280
276
 
281
- **Forms**: Inputs en formularios de registro, login, contacto
282
- **Search**: Barras de búsqueda con `type="search"`
283
- **File upload**: Selección de archivos con `type="file"`
284
- **Numbers**: Cantidades, precios, edades con `type="number"`
285
- **Dates**: Selección de fechas con `type="date"`
286
- **Validation**: Campos con validación visual via `aria-invalid`
277
+ **Forms**: Inputs in registration, login, and contact forms
278
+ **Search**: Search bars with `type="search"`
279
+ **File upload**: File selection with `type="file"`
280
+ **Numbers**: Quantities, prices, ages with `type="number"`
281
+ **Dates**: Date selection with `type="date"`
282
+ **Validation**: Fields with visual validation via `aria-invalid`
287
283
 
288
284
  ## States and data attributes
289
285
 
290
286
  ### Focus
291
287
 
292
- - **Focused**: `focus-visible:ring-ring/50`, `focus-visible:ring-[3px]`, `focus-visible:border-ring`
288
+ - **Focused**: `focus-visible:border-primary-300`, `focus-visible:ring-4`, `focus-visible:ring-primary/10`
293
289
 
294
290
  ### Validation
295
291
 
296
- - **Invalid**: `aria-invalid:border-destructive`, `aria-invalid:ring-destructive/20`
292
+ - **Invalid**: `aria-invalid:border-destructive`, `aria-invalid:focus-visible:border-destructive`, `aria-invalid:focus-visible:ring-destructive/10`
297
293
  - **Valid**: Border normal `border-input`
298
294
 
299
295
  ### Disabled state
300
296
 
301
- - **Disabled**: `opacity-50`, `pointer-events-none`, `cursor-not-allowed`
297
+ - **Disabled**: `disabled:opacity-100`, `disabled:pointer-events-none`, `disabled:cursor-not-allowed`, `disabled:bg-input-disabled`, `disabled:text-input-foreground-disabled`, `disabled:placeholder:text-disabled-foreground`
302
298
 
303
299
  ### File input styles
304
300
 
@@ -309,9 +305,10 @@ const maxLength = 100;
309
305
  - **Height**: `h-10` (~40px) default
310
306
  - **Border**: `border`, `border-input`, `rounded-md`
311
307
  - **Padding**: `px-3` (no vertical padding, height defines the height)
312
- - **Font**: `text-base md:text-sm`
308
+ - **Font**: `text-sm`
313
309
  - **Shadow**: `shadow-xs`
314
- - **Background**: `bg-transparent`, `dark:bg-input/30`
310
+ - **Background**: `bg-background`
311
+ - **Hover**: `hover:bg-muted`
315
312
  - **Transitions**: `transition-[color,box-shadow]`
316
313
  - **Selection**: `selection:bg-primary selection:text-primary-foreground`
317
314
 
@@ -332,17 +329,17 @@ const maxLength = 100;
332
329
  - **Props forwarding**: Accepts all native HTML props
333
330
  - **Validation**: Uses native attributes (`required`, `pattern`, `min`, `max`) + `aria-invalid`
334
331
  - **File input**: Special styles for "Choose file" button
335
- - **Focus ring**: 3px with 50% opacity for visibility without being invasive
332
+ - **Focus ring**: `ring-4` with `ring-primary/10` for visibility without being invasive
336
333
  - **Shadow**: Subtle `shadow-xs` for depth
337
- - **Responsive**: `text-base` on mobile, `text-sm` on desktop (`md:`)
338
- - **Dark mode**: Semi-transparent background `dark:bg-input/30`
334
+ - **Font size**: `text-sm` on all screen sizes
335
+ - **Background**: Solid `bg-background`, `hover:bg-muted`
339
336
 
340
337
  ## Differences with Textarea
341
338
 
342
339
  | Aspect | Input | Textarea |
343
340
  | ---------- | -------------------------------- | ------------------------- |
344
341
  | **Lines** | Single-line | Multi-line |
345
- | **Height** | Fixed (h-9) | Variable (min-h-20) |
342
+ | **Height** | Fixed (h-10) | Variable (min-h-20) |
346
343
  | **Resize** | No | Yes (vertical by default) |
347
344
  | **Types** | Multiple (email, password, etc.) | Text only |
348
345
  | **Usage** | Short data | Long text |
@@ -354,7 +351,7 @@ const maxLength = 100;
354
351
  **Styles don't apply**: Verify you're using `className` with valid Tailwind
355
352
  **File input doesn't look good**: Use `file:*` classes to style button
356
353
  **Invalid state doesn't work**: Make sure to use `aria-invalid` not just `invalid`
357
- **Inconsistent height**: Input has `h-9` default, use `className` to override
354
+ **Inconsistent height**: Input has `h-10` default, use `className` to override
358
355
  **Dark mode doesn't work**: Verify theme configured and `dark:` class applying
359
356
  **Number input allows text**: Browser validates, but use additional JS validation
360
357