@ojiepermana/angular-component 22.0.27

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 (244) hide show
  1. package/README.md +82 -0
  2. package/accordion/README.md +193 -0
  3. package/alert/README.md +180 -0
  4. package/alert-dialog/README.md +239 -0
  5. package/aspect-ratio/README.md +112 -0
  6. package/avatar/README.md +176 -0
  7. package/badge/README.md +133 -0
  8. package/breadcrumb/README.md +216 -0
  9. package/button/README.md +139 -0
  10. package/button-group/README.md +208 -0
  11. package/calendar/README.md +135 -0
  12. package/card/README.md +220 -0
  13. package/carousel/README.md +276 -0
  14. package/checkbox/README.md +149 -0
  15. package/collapsible/README.md +195 -0
  16. package/combobox/README.md +198 -0
  17. package/command/README.md +275 -0
  18. package/composer/README.md +235 -0
  19. package/context-menu/README.md +267 -0
  20. package/date-picker/README.md +179 -0
  21. package/dialog/README.md +235 -0
  22. package/drawer/README.md +145 -0
  23. package/dropdown-menu/README.md +311 -0
  24. package/editor/README.md +136 -0
  25. package/empty/README.md +183 -0
  26. package/fesm2022/ojiepermana-angular-component-accordion.mjs +186 -0
  27. package/fesm2022/ojiepermana-angular-component-accordion.mjs.map +1 -0
  28. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +276 -0
  29. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs.map +1 -0
  30. package/fesm2022/ojiepermana-angular-component-alert.mjs +99 -0
  31. package/fesm2022/ojiepermana-angular-component-alert.mjs.map +1 -0
  32. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +37 -0
  33. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs.map +1 -0
  34. package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -0
  35. package/fesm2022/ojiepermana-angular-component-avatar.mjs.map +1 -0
  36. package/fesm2022/ojiepermana-angular-component-badge.mjs +50 -0
  37. package/fesm2022/ojiepermana-angular-component-badge.mjs.map +1 -0
  38. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +200 -0
  39. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs.map +1 -0
  40. package/fesm2022/ojiepermana-angular-component-button-group.mjs +103 -0
  41. package/fesm2022/ojiepermana-angular-component-button-group.mjs.map +1 -0
  42. package/fesm2022/ojiepermana-angular-component-button.mjs +68 -0
  43. package/fesm2022/ojiepermana-angular-component-button.mjs.map +1 -0
  44. package/fesm2022/ojiepermana-angular-component-calendar.mjs +103 -0
  45. package/fesm2022/ojiepermana-angular-component-calendar.mjs.map +1 -0
  46. package/fesm2022/ojiepermana-angular-component-card.mjs +152 -0
  47. package/fesm2022/ojiepermana-angular-component-card.mjs.map +1 -0
  48. package/fesm2022/ojiepermana-angular-component-carousel.mjs +334 -0
  49. package/fesm2022/ojiepermana-angular-component-carousel.mjs.map +1 -0
  50. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +165 -0
  51. package/fesm2022/ojiepermana-angular-component-checkbox.mjs.map +1 -0
  52. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +121 -0
  53. package/fesm2022/ojiepermana-angular-component-collapsible.mjs.map +1 -0
  54. package/fesm2022/ojiepermana-angular-component-combobox.mjs +274 -0
  55. package/fesm2022/ojiepermana-angular-component-combobox.mjs.map +1 -0
  56. package/fesm2022/ojiepermana-angular-component-command.mjs +297 -0
  57. package/fesm2022/ojiepermana-angular-component-command.mjs.map +1 -0
  58. package/fesm2022/ojiepermana-angular-component-composer.mjs +352 -0
  59. package/fesm2022/ojiepermana-angular-component-composer.mjs.map +1 -0
  60. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +108 -0
  61. package/fesm2022/ojiepermana-angular-component-context-menu.mjs.map +1 -0
  62. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +186 -0
  63. package/fesm2022/ojiepermana-angular-component-date-picker.mjs.map +1 -0
  64. package/fesm2022/ojiepermana-angular-component-dialog.mjs +283 -0
  65. package/fesm2022/ojiepermana-angular-component-dialog.mjs.map +1 -0
  66. package/fesm2022/ojiepermana-angular-component-drawer.mjs +6 -0
  67. package/fesm2022/ojiepermana-angular-component-drawer.mjs.map +1 -0
  68. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +494 -0
  69. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs.map +1 -0
  70. package/fesm2022/ojiepermana-angular-component-editor.mjs +680 -0
  71. package/fesm2022/ojiepermana-angular-component-editor.mjs.map +1 -0
  72. package/fesm2022/ojiepermana-angular-component-empty.mjs +145 -0
  73. package/fesm2022/ojiepermana-angular-component-empty.mjs.map +1 -0
  74. package/fesm2022/ojiepermana-angular-component-form.mjs +364 -0
  75. package/fesm2022/ojiepermana-angular-component-form.mjs.map +1 -0
  76. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +275 -0
  77. package/fesm2022/ojiepermana-angular-component-hover-card.mjs.map +1 -0
  78. package/fesm2022/ojiepermana-angular-component-icon.mjs +86 -0
  79. package/fesm2022/ojiepermana-angular-component-icon.mjs.map +1 -0
  80. package/fesm2022/ojiepermana-angular-component-input-group.mjs +179 -0
  81. package/fesm2022/ojiepermana-angular-component-input-group.mjs.map +1 -0
  82. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +517 -0
  83. package/fesm2022/ojiepermana-angular-component-input-otp.mjs.map +1 -0
  84. package/fesm2022/ojiepermana-angular-component-input.mjs +45 -0
  85. package/fesm2022/ojiepermana-angular-component-input.mjs.map +1 -0
  86. package/fesm2022/ojiepermana-angular-component-item.mjs +264 -0
  87. package/fesm2022/ojiepermana-angular-component-item.mjs.map +1 -0
  88. package/fesm2022/ojiepermana-angular-component-kanban.mjs +314 -0
  89. package/fesm2022/ojiepermana-angular-component-kanban.mjs.map +1 -0
  90. package/fesm2022/ojiepermana-angular-component-kbd.mjs +55 -0
  91. package/fesm2022/ojiepermana-angular-component-kbd.mjs.map +1 -0
  92. package/fesm2022/ojiepermana-angular-component-label.mjs +33 -0
  93. package/fesm2022/ojiepermana-angular-component-label.mjs.map +1 -0
  94. package/fesm2022/ojiepermana-angular-component-menubar.mjs +311 -0
  95. package/fesm2022/ojiepermana-angular-component-menubar.mjs.map +1 -0
  96. package/fesm2022/ojiepermana-angular-component-native-select.mjs +67 -0
  97. package/fesm2022/ojiepermana-angular-component-native-select.mjs.map +1 -0
  98. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +408 -0
  99. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs.map +1 -0
  100. package/fesm2022/ojiepermana-angular-component-pagination.mjs +226 -0
  101. package/fesm2022/ojiepermana-angular-component-pagination.mjs.map +1 -0
  102. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +810 -0
  103. package/fesm2022/ojiepermana-angular-component-pillbox.mjs.map +1 -0
  104. package/fesm2022/ojiepermana-angular-component-popover.mjs +145 -0
  105. package/fesm2022/ojiepermana-angular-component-popover.mjs.map +1 -0
  106. package/fesm2022/ojiepermana-angular-component-progress.mjs +60 -0
  107. package/fesm2022/ojiepermana-angular-component-progress.mjs.map +1 -0
  108. package/fesm2022/ojiepermana-angular-component-radio.mjs +173 -0
  109. package/fesm2022/ojiepermana-angular-component-radio.mjs.map +1 -0
  110. package/fesm2022/ojiepermana-angular-component-resizable.mjs +478 -0
  111. package/fesm2022/ojiepermana-angular-component-resizable.mjs.map +1 -0
  112. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +54 -0
  113. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs.map +1 -0
  114. package/fesm2022/ojiepermana-angular-component-select.mjs +297 -0
  115. package/fesm2022/ojiepermana-angular-component-select.mjs.map +1 -0
  116. package/fesm2022/ojiepermana-angular-component-separator.mjs +37 -0
  117. package/fesm2022/ojiepermana-angular-component-separator.mjs.map +1 -0
  118. package/fesm2022/ojiepermana-angular-component-sheet.mjs +297 -0
  119. package/fesm2022/ojiepermana-angular-component-sheet.mjs.map +1 -0
  120. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +31 -0
  121. package/fesm2022/ojiepermana-angular-component-skeleton.mjs.map +1 -0
  122. package/fesm2022/ojiepermana-angular-component-slider.mjs +423 -0
  123. package/fesm2022/ojiepermana-angular-component-slider.mjs.map +1 -0
  124. package/fesm2022/ojiepermana-angular-component-spinner.mjs +60 -0
  125. package/fesm2022/ojiepermana-angular-component-spinner.mjs.map +1 -0
  126. package/fesm2022/ojiepermana-angular-component-switch.mjs +140 -0
  127. package/fesm2022/ojiepermana-angular-component-switch.mjs.map +1 -0
  128. package/fesm2022/ojiepermana-angular-component-table.mjs +155 -0
  129. package/fesm2022/ojiepermana-angular-component-table.mjs.map +1 -0
  130. package/fesm2022/ojiepermana-angular-component-tabs.mjs +271 -0
  131. package/fesm2022/ojiepermana-angular-component-tabs.mjs.map +1 -0
  132. package/fesm2022/ojiepermana-angular-component-textarea.mjs +39 -0
  133. package/fesm2022/ojiepermana-angular-component-textarea.mjs.map +1 -0
  134. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -0
  135. package/fesm2022/ojiepermana-angular-component-timeline.mjs.map +1 -0
  136. package/fesm2022/ojiepermana-angular-component-toast.mjs +161 -0
  137. package/fesm2022/ojiepermana-angular-component-toast.mjs.map +1 -0
  138. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +289 -0
  139. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs.map +1 -0
  140. package/fesm2022/ojiepermana-angular-component-toggle.mjs +82 -0
  141. package/fesm2022/ojiepermana-angular-component-toggle.mjs.map +1 -0
  142. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +410 -0
  143. package/fesm2022/ojiepermana-angular-component-tooltip.mjs.map +1 -0
  144. package/fesm2022/ojiepermana-angular-component-utils.mjs +81 -0
  145. package/fesm2022/ojiepermana-angular-component-utils.mjs.map +1 -0
  146. package/fesm2022/ojiepermana-angular-component.mjs +11 -0
  147. package/fesm2022/ojiepermana-angular-component.mjs.map +1 -0
  148. package/form/README.md +210 -0
  149. package/hover-card/README.md +142 -0
  150. package/icon/README.md +25 -0
  151. package/input/README.md +159 -0
  152. package/input-group/README.md +237 -0
  153. package/input-otp/README.md +278 -0
  154. package/item/README.md +247 -0
  155. package/kanban/README.md +81 -0
  156. package/kbd/README.md +139 -0
  157. package/label/README.md +135 -0
  158. package/menubar/README.md +269 -0
  159. package/native-select/README.md +176 -0
  160. package/navigation-menu/README.md +160 -0
  161. package/package.json +291 -0
  162. package/pagination/README.md +144 -0
  163. package/pillbox/README.md +67 -0
  164. package/popover/README.md +43 -0
  165. package/progress/README.md +160 -0
  166. package/radio/README.md +209 -0
  167. package/resizable/README.md +168 -0
  168. package/scroll-area/README.md +143 -0
  169. package/select/README.md +174 -0
  170. package/separator/README.md +170 -0
  171. package/sheet/README.md +183 -0
  172. package/skeleton/README.md +158 -0
  173. package/slider/README.md +207 -0
  174. package/spinner/README.md +160 -0
  175. package/switch/README.md +166 -0
  176. package/table/README.md +291 -0
  177. package/tabs/README.md +214 -0
  178. package/textarea/README.md +153 -0
  179. package/timeline/README.md +94 -0
  180. package/toast/README.md +321 -0
  181. package/toggle/README.md +131 -0
  182. package/toggle-group/README.md +206 -0
  183. package/tooltip/README.md +207 -0
  184. package/types/ojiepermana-angular-component-accordion.d.ts +51 -0
  185. package/types/ojiepermana-angular-component-alert-dialog.d.ts +93 -0
  186. package/types/ojiepermana-angular-component-alert.d.ts +37 -0
  187. package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -0
  188. package/types/ojiepermana-angular-component-avatar.d.ts +51 -0
  189. package/types/ojiepermana-angular-component-badge.d.ts +19 -0
  190. package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -0
  191. package/types/ojiepermana-angular-component-button-group.d.ts +26 -0
  192. package/types/ojiepermana-angular-component-button.d.ts +22 -0
  193. package/types/ojiepermana-angular-component-calendar.d.ts +39 -0
  194. package/types/ojiepermana-angular-component-card.d.ts +60 -0
  195. package/types/ojiepermana-angular-component-carousel.d.ts +86 -0
  196. package/types/ojiepermana-angular-component-checkbox.d.ts +42 -0
  197. package/types/ojiepermana-angular-component-collapsible.d.ts +42 -0
  198. package/types/ojiepermana-angular-component-combobox.d.ts +53 -0
  199. package/types/ojiepermana-angular-component-command.d.ts +102 -0
  200. package/types/ojiepermana-angular-component-composer.d.ts +90 -0
  201. package/types/ojiepermana-angular-component-context-menu.d.ts +36 -0
  202. package/types/ojiepermana-angular-component-date-picker.d.ts +48 -0
  203. package/types/ojiepermana-angular-component-dialog.d.ts +87 -0
  204. package/types/ojiepermana-angular-component-drawer.d.ts +1 -0
  205. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +140 -0
  206. package/types/ojiepermana-angular-component-editor.d.ts +126 -0
  207. package/types/ojiepermana-angular-component-empty.d.ts +50 -0
  208. package/types/ojiepermana-angular-component-form.d.ts +140 -0
  209. package/types/ojiepermana-angular-component-hover-card.d.ts +75 -0
  210. package/types/ojiepermana-angular-component-icon.d.ts +31 -0
  211. package/types/ojiepermana-angular-component-input-group.d.ts +51 -0
  212. package/types/ojiepermana-angular-component-input-otp.d.ts +142 -0
  213. package/types/ojiepermana-angular-component-input.d.ts +16 -0
  214. package/types/ojiepermana-angular-component-item.d.ts +88 -0
  215. package/types/ojiepermana-angular-component-kanban.d.ts +70 -0
  216. package/types/ojiepermana-angular-component-kbd.d.ts +16 -0
  217. package/types/ojiepermana-angular-component-label.d.ts +11 -0
  218. package/types/ojiepermana-angular-component-menubar.d.ts +69 -0
  219. package/types/ojiepermana-angular-component-native-select.d.ts +26 -0
  220. package/types/ojiepermana-angular-component-navigation-menu.d.ts +98 -0
  221. package/types/ojiepermana-angular-component-pagination.d.ts +33 -0
  222. package/types/ojiepermana-angular-component-pillbox.d.ts +156 -0
  223. package/types/ojiepermana-angular-component-popover.d.ts +50 -0
  224. package/types/ojiepermana-angular-component-progress.d.ts +17 -0
  225. package/types/ojiepermana-angular-component-radio.d.ts +57 -0
  226. package/types/ojiepermana-angular-component-resizable.d.ts +99 -0
  227. package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -0
  228. package/types/ojiepermana-angular-component-select.d.ts +56 -0
  229. package/types/ojiepermana-angular-component-separator.d.ts +14 -0
  230. package/types/ojiepermana-angular-component-sheet.d.ts +78 -0
  231. package/types/ojiepermana-angular-component-skeleton.d.ts +10 -0
  232. package/types/ojiepermana-angular-component-slider.d.ts +74 -0
  233. package/types/ojiepermana-angular-component-spinner.d.ts +13 -0
  234. package/types/ojiepermana-angular-component-switch.d.ts +44 -0
  235. package/types/ojiepermana-angular-component-table.d.ts +52 -0
  236. package/types/ojiepermana-angular-component-tabs.d.ts +92 -0
  237. package/types/ojiepermana-angular-component-textarea.d.ts +12 -0
  238. package/types/ojiepermana-angular-component-timeline.d.ts +63 -0
  239. package/types/ojiepermana-angular-component-toast.d.ts +51 -0
  240. package/types/ojiepermana-angular-component-toggle-group.d.ts +89 -0
  241. package/types/ojiepermana-angular-component-toggle.d.ts +25 -0
  242. package/types/ojiepermana-angular-component-tooltip.d.ts +101 -0
  243. package/types/ojiepermana-angular-component-utils.d.ts +30 -0
  244. package/types/ojiepermana-angular-component.d.ts +2 -0
@@ -0,0 +1,174 @@
1
+ # Select
2
+
3
+ Material-backed custom select with shadcn styling for overlay-driven single or multiple choice.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { FormsModule } from '@angular/forms';
9
+ import { OptionComponent, SelectComponent } from '@ojiepermana/angular-component/select';
10
+ ```
11
+
12
+ ## Composition
13
+
14
+ `SelectField` owns the trigger, overlay, disabled state, and common ARIA passthrough.
15
+ Project `SelectItem` children into it for the actual choices.
16
+
17
+ For grouped menus, the current Angular mapping uses `MatOptgroup` from
18
+ `@angular/material/core` inside `SelectField` rather than publishing separate
19
+ `SelectGroup`, `SelectLabel`, or `SelectSeparator` wrappers.
20
+
21
+ ```text
22
+ SelectField
23
+ ├── SelectItem
24
+ ├── SelectItem
25
+ └── mat-optgroup (optional grouping bridge)
26
+ ├── SelectItem
27
+ └── SelectItem
28
+ ```
29
+
30
+ ## Basic Usage
31
+
32
+ ```html
33
+ <SelectField class="block w-full max-w-xs" placeholder="Select a plan" [(ngModel)]="plan" aria-label="Plan">
34
+ <SelectItem value="free">Free</SelectItem>
35
+ <SelectItem value="pro">Pro</SelectItem>
36
+ <SelectItem value="enterprise">Enterprise</SelectItem>
37
+ </SelectField>
38
+ ```
39
+
40
+ ## Common Patterns
41
+
42
+ ### Grouped options
43
+
44
+ ```ts
45
+ import { MatOptgroup } from '@angular/material/core';
46
+ ```
47
+
48
+ ```html
49
+ <SelectField class="block w-full max-w-sm" placeholder="Select produce" [(ngModel)]="produce" aria-label="Produce">
50
+ <mat-optgroup label="Fruits">
51
+ <SelectItem value="apple">Apple</SelectItem>
52
+ <SelectItem value="banana">Banana</SelectItem>
53
+ <SelectItem value="blueberry">Blueberry</SelectItem>
54
+ </mat-optgroup>
55
+
56
+ <mat-optgroup label="Vegetables">
57
+ <SelectItem value="carrot">Carrot</SelectItem>
58
+ <SelectItem value="broccoli">Broccoli</SelectItem>
59
+ <SelectItem value="spinach">Spinach</SelectItem>
60
+ </mat-optgroup>
61
+ </SelectField>
62
+ ```
63
+
64
+ ### Disabled trigger
65
+
66
+ ```html
67
+ <SelectField placeholder="Disabled" disabled aria-label="Disabled plan">
68
+ <SelectItem value="free">Free</SelectItem>
69
+ <SelectItem value="pro">Pro</SelectItem>
70
+ <SelectItem value="enterprise">Enterprise</SelectItem>
71
+ </SelectField>
72
+ ```
73
+
74
+ ### Scrollable overlay
75
+
76
+ Long lists scroll automatically inside the Material overlay. You do not need a
77
+ separate input for that behavior.
78
+
79
+ ```html
80
+ <SelectField class="block w-full max-w-md" placeholder="Select a timezone" [(ngModel)]="timezone" aria-label="Timezone">
81
+ <mat-optgroup label="North America">
82
+ <SelectItem value="est">Eastern Standard Time</SelectItem>
83
+ <SelectItem value="cst">Central Standard Time</SelectItem>
84
+ <SelectItem value="mst">Mountain Standard Time</SelectItem>
85
+ <SelectItem value="pst">Pacific Standard Time</SelectItem>
86
+ </mat-optgroup>
87
+
88
+ <mat-optgroup label="Europe & Africa">
89
+ <SelectItem value="gmt">Greenwich Mean Time</SelectItem>
90
+ <SelectItem value="cet">Central European Time</SelectItem>
91
+ <SelectItem value="eet">Eastern European Time</SelectItem>
92
+ </mat-optgroup>
93
+ </SelectField>
94
+ ```
95
+
96
+ ### Helper and error text
97
+
98
+ The wrapper accepts `aria-describedby`, so helper or error text can live next to
99
+ the trigger instead of inside it.
100
+
101
+ ```html
102
+ <SelectField
103
+ class="block w-full max-w-sm"
104
+ placeholder="Select department"
105
+ aria-label="Department"
106
+ aria-describedby="department-error"
107
+ [formControl]="departmentControl"
108
+ required>
109
+ <SelectItem value="engineering">Engineering</SelectItem>
110
+ <SelectItem value="sales">Sales</SelectItem>
111
+ <SelectItem value="operations">Operations</SelectItem>
112
+ </SelectField>
113
+
114
+ <p id="department-error" class="text-sm font-medium text-destructive">Select a department before continuing.</p>
115
+ ```
116
+
117
+ ### Multiple selection
118
+
119
+ ```html
120
+ <SelectField multiple [(ngModel)]="interests" aria-label="Interests">
121
+ @for (i of all; track i) {
122
+ <SelectItem [value]="i">{{ i }}</SelectItem>
123
+ }
124
+ </SelectField>
125
+ ```
126
+
127
+ ## API Reference
128
+
129
+ | Primitive | Selector | Inputs | Outputs |
130
+ | --------------------- | -------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------- |
131
+ | `SelectComponent` | `SelectField` | `placeholder`, `disabled`, `multiple`, `required`, `aria-label`, `aria-labelledby`, `aria-describedby`, `class` | `valueChange`, `openedChange` |
132
+ | `OptionComponent` | `SelectItem` | `value`, `disabled`, `class` | none |
133
+ | `MatOptgroup` mapping | `mat-optgroup` | `label`, `disabled` | none |
134
+
135
+ Public methods on `SelectComponent`: `open()`, `close()`, `focus()`.
136
+
137
+ ## Styling and Theming
138
+
139
+ The component inherits Angular Material overlay behavior but applies the local
140
+ shadcn-style bridge tokens through `select.component.css`.
141
+
142
+ - The trigger uses the local input, ring, radius, and muted-foreground tokens.
143
+ - The overlay panel keeps `panelClass="select-panel"` so the shared Material
144
+ bridge layer can restyle the menu surface and options.
145
+ - Group labels come from Angular Material `mat-optgroup`, so grouped menus inherit
146
+ Material spacing while still picking up the surrounding theme tokens.
147
+
148
+ ## Accessibility
149
+
150
+ Built on `mat-select`, which exposes the listbox/combobox interaction contract.
151
+
152
+ - Provide an accessible name with surrounding copy or `aria-label`/`aria-labelledby`.
153
+ - Use `aria-describedby` when helper or validation text is rendered next to the trigger.
154
+ - Group options only when the categories make the list easier to scan.
155
+
156
+ ## Keyboard Interactions
157
+
158
+ - `Enter`, `Space`, or `Alt+ArrowDown` opens the trigger.
159
+ - Arrow keys move through the open option list, and Material typeahead jumps to matching labels.
160
+ - `Enter` or `Space` confirms the active option, and `Escape` closes the panel.
161
+
162
+ ## Angular Notes
163
+
164
+ - `SelectField` is intentionally a thin Angular wrapper over `mat-select` rather than a one-to-one Radix port.
165
+ - Grouped menus currently rely on `MatOptgroup` from `@angular/material/core`.
166
+ - If you want browser-native pickers, semantic `optgroup` nodes, or mobile-first behavior, use `select[NativeSelect]` instead.
167
+
168
+ ## Source Parity
169
+
170
+ This Angular slice follows the shadcn Select information architecture while staying honest about the local API.
171
+
172
+ - The public entrypoint exposes `SelectField` and `SelectItem` instead of separate `SelectTrigger`, `SelectContent`, `SelectGroup`, and `SelectItem` components.
173
+ - Group labels map to Angular Material `mat-optgroup`; there is no published `SelectSeparator` wrapper today.
174
+ - Overlay positioning follows Angular Material, so the wrapper does not currently expose the shadcn/Radix `position="item-aligned" | "popper"` switch.
@@ -0,0 +1,170 @@
1
+ # Separator
2
+
3
+ Visually or semantically separates content. Use Separator for subtle section
4
+ breaks, split navigation rows, compact menu metadata, and stacked definition
5
+ lists.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { SeparatorComponent } from '@ojiepermana/angular-component/separator';
11
+ ```
12
+
13
+ ## Basic usage
14
+
15
+ Use the default separator for purely visual breaks. When the divider carries
16
+ structure that assistive technology should announce, set
17
+ `[decorative]="false"`.
18
+
19
+ ```html
20
+ <Separator class="my-4" /> <Separator [decorative]="false" class="my-4" />
21
+ ```
22
+
23
+ ## Common patterns
24
+
25
+ ### Preview card
26
+
27
+ This mirrors the upstream shadcn hero example: title block, separator, then the
28
+ supporting description.
29
+
30
+ ```html
31
+ <div class="flex w-full max-w-sm flex-col gap-4 rounded-xl border border-border bg-card/40 p-5 text-sm">
32
+ <div class="flex flex-col gap-1.5">
33
+ <div class="leading-none font-medium">shadcn/ui</div>
34
+ <div class="text-muted-foreground">The Foundation for your Design System</div>
35
+ </div>
36
+ <Separator />
37
+ <div class="text-muted-foreground">
38
+ A set of beautifully designed components that you can customize, extend, and build on.
39
+ </div>
40
+ </div>
41
+ ```
42
+
43
+ ### Vertical row
44
+
45
+ Use `orientation="vertical"` when the separator sits inside a horizontal flex
46
+ row. Give the host an explicit height, or inherit it from a parent with defined
47
+ cross-axis size.
48
+
49
+ ```html
50
+ <div class="flex h-5 items-center gap-4 text-sm">
51
+ <div>Blog</div>
52
+ <Separator orientation="vertical" class="h-5" />
53
+ <div>Docs</div>
54
+ <Separator orientation="vertical" class="h-5" />
55
+ <div>Source</div>
56
+ </div>
57
+ ```
58
+
59
+ ### Menu metadata
60
+
61
+ Vertical separators work well between compact description groups.
62
+
63
+ ```html
64
+ <div class="flex w-full max-w-2xl items-center gap-2 text-sm md:gap-4">
65
+ <div class="flex flex-col gap-1">
66
+ <span class="font-medium">Settings</span>
67
+ <span class="text-xs text-muted-foreground">Manage preferences</span>
68
+ </div>
69
+ <Separator orientation="vertical" class="h-10" />
70
+ <div class="flex flex-col gap-1">
71
+ <span class="font-medium">Account</span>
72
+ <span class="text-xs text-muted-foreground">Profile &amp; security</span>
73
+ </div>
74
+ <Separator orientation="vertical" class="hidden h-10 md:block" />
75
+ <div class="hidden flex-col gap-1 md:flex">
76
+ <span class="font-medium">Help</span>
77
+ <span class="text-xs text-muted-foreground">Support &amp; docs</span>
78
+ </div>
79
+ </div>
80
+ ```
81
+
82
+ ### List rows
83
+
84
+ Horizontal separators are the lightest-weight way to split dense stacked rows.
85
+
86
+ ```html
87
+ <div class="flex w-full max-w-sm flex-col gap-2 text-sm">
88
+ <dl class="flex items-center justify-between gap-4">
89
+ <dt class="font-medium">Item 1</dt>
90
+ <dd class="text-muted-foreground">Value 1</dd>
91
+ </dl>
92
+ <Separator />
93
+ <dl class="flex items-center justify-between gap-4">
94
+ <dt class="font-medium">Item 2</dt>
95
+ <dd class="text-muted-foreground">Value 2</dd>
96
+ </dl>
97
+ <Separator />
98
+ <dl class="flex items-center justify-between gap-4">
99
+ <dt class="font-medium">Item 3</dt>
100
+ <dd class="text-muted-foreground">Value 3</dd>
101
+ </dl>
102
+ </div>
103
+ ```
104
+
105
+ ### RTL
106
+
107
+ The separator itself does not need an RTL-specific API. Set `dir="rtl"` on the
108
+ surrounding container and translate neighboring content.
109
+
110
+ ```html
111
+ <section
112
+ dir="rtl"
113
+ lang="ar"
114
+ class="flex w-full max-w-sm flex-col gap-4 rounded-xl border border-border bg-card/40 p-5 text-right text-sm">
115
+ <div class="flex flex-col gap-1.5">
116
+ <div class="leading-none font-medium">shadcn/ui</div>
117
+ <div class="text-muted-foreground">الأساس لنظام التصميم الخاص بك</div>
118
+ </div>
119
+ <Separator />
120
+ <div class="text-muted-foreground">مجموعة من المكونات المصممة بشكل جميل يمكنك تخصيصها وتوسيعها والبناء عليها.</div>
121
+ </section>
122
+ ```
123
+
124
+ ## API reference
125
+
126
+ | Input | Type | Default | Description |
127
+ | ------------- | ---------------------------- | -------------- | -------------------------------------------------------------- |
128
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Axis of the divider. |
129
+ | `decorative` | `boolean` | `true` | When `false`, sets `role="separator"` plus `aria-orientation`. |
130
+ | `class` | `string` | `''` | Width, height, spacing, and visibility utilities. |
131
+
132
+ Native host attributes such as `dir`, `data-*`, and `id` still pass through to
133
+ the custom element host.
134
+
135
+ ## Styling and theming
136
+
137
+ Tokens consumed:
138
+
139
+ - `bg-border` for the rule itself.
140
+
141
+ Horizontal mode applies `h-px w-full`. Vertical mode applies `h-full w-px`.
142
+ The host renders as a block-level custom element so width and height utilities
143
+ behave predictably on the separator itself.
144
+
145
+ ## Accessibility
146
+
147
+ - Separators are decorative by default and render with `role="none"`.
148
+ - When the divider carries structure, set `[decorative]="false"` so assistive
149
+ technology sees a real `separator` with the correct `aria-orientation`.
150
+ - Keep accessible names on the surrounding content; separators themselves do not
151
+ require labels.
152
+
153
+ ## Keyboard interactions
154
+
155
+ Separator is not interactive and has no keyboard behavior of its own.
156
+
157
+ ## Angular notes
158
+
159
+ - Because `Separator` is a custom element, vertical examples need a height
160
+ source from the parent or the host `class` input.
161
+ - The block-level host class is intentional. It ensures horizontal separators
162
+ honor `w-full` and other layout utilities that would otherwise be unreliable
163
+ on an inline custom element.
164
+
165
+ ## Source parity
166
+
167
+ This Angular implementation follows the shadcn separator preview plus the
168
+ vertical, menu, list, and RTL examples. It adds Angular-specific guidance for
169
+ semantic separators and for the custom-element host layout behavior needed to
170
+ match the upstream visuals.
@@ -0,0 +1,183 @@
1
+ # Sheet
2
+
3
+ Edge-anchored overlay surface that extends Dialog into a side panel. The Sheet slides in from the top, right, bottom, or left edge of the viewport and is backed by CDK Overlay plus FocusTrap.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import {
9
+ SheetCloseDirective,
10
+ SheetComponent,
11
+ SheetContentComponent,
12
+ SheetDescriptionComponent,
13
+ SheetFooterComponent,
14
+ SheetHeaderComponent,
15
+ SheetTitleComponent,
16
+ } from '@ojiepermana/angular-component/sheet';
17
+ ```
18
+
19
+ ## Composition
20
+
21
+ ```text
22
+ button[Button] (external trigger; sets the open signal)
23
+ Sheet
24
+ ├── built-in close button (optional)
25
+ ├── SheetHeader
26
+ │ ├── SheetTitle
27
+ │ └── SheetDescription
28
+ ├── SheetContent (optional body / scroll region)
29
+ └── SheetFooter
30
+ └── button[SheetClose] (optional custom close action)
31
+ ```
32
+
33
+ The Angular surface intentionally keeps the trigger outside the overlay component. Instead of a JSX-style `SheetTrigger`, you open the sheet by setting the bound `open` signal from a regular button or link.
34
+
35
+ ## Basic Usage
36
+
37
+ ```ts
38
+ import { signal } from '@angular/core';
39
+ ```
40
+
41
+ ```html
42
+ <button type="button" Button variant="outline" (click)="open.set(true)">Edit profile</button>
43
+
44
+ <Sheet [(open)]="open" aria-labelledby="sheet-title" aria-describedby="sheet-description" class="sm:max-w-md">
45
+ <SheetHeader>
46
+ <SheetTitle id="sheet-title">Edit profile</SheetTitle>
47
+ <SheetDescription id="sheet-description">
48
+ Make changes to your profile here. Click save when you are done.
49
+ </SheetDescription>
50
+ </SheetHeader>
51
+
52
+ <SheetContent class="grid gap-4 py-4">
53
+ <div class="grid gap-2">
54
+ <label Label for="sheet-name">Name</label>
55
+ <input Input id="sheet-name" value="Pedro Duarte" />
56
+ </div>
57
+ <div class="grid gap-2">
58
+ <label Label for="sheet-username">Username</label>
59
+ <input Input id="sheet-username" value="@peduarte" />
60
+ </div>
61
+ </SheetContent>
62
+
63
+ <SheetFooter>
64
+ <button type="button" Button variant="outline" SheetClose>Cancel</button>
65
+ <button type="button" Button (click)="open.set(false)">Save changes</button>
66
+ </SheetFooter>
67
+ </Sheet>
68
+ ```
69
+
70
+ ## Common Patterns
71
+
72
+ ### Side selection
73
+
74
+ Use `side` to choose where the surface enters from. Right is the default for `Sheet`, while the `Drawer` alias defaults to bottom.
75
+
76
+ ```html
77
+ <button type="button" Button variant="outline" (click)="rightOpen.set(true)">Right</button>
78
+ <button type="button" Button variant="outline" (click)="leftOpen.set(true)">Left</button>
79
+
80
+ <Sheet [(open)]="rightOpen" side="right" class="sm:max-w-md">...</Sheet>
81
+ <Sheet [(open)]="leftOpen" side="left" class="sm:max-w-md">...</Sheet>
82
+ ```
83
+
84
+ For `top` and `bottom`, add a height constraint such as `class="max-h-[55vh]"` when the body content can grow on shorter screens.
85
+
86
+ ### No close button
87
+
88
+ Hide the default corner close affordance with `[showCloseButton]="false"` and own dismissal explicitly through the footer or body.
89
+
90
+ ```html
91
+ <Sheet [(open)]="noCloseOpen" [showCloseButton]="false" class="sm:max-w-sm">
92
+ <SheetHeader>
93
+ <SheetTitle>No Close Button</SheetTitle>
94
+ <SheetDescription> Hide the top-right control when dismissal should stay in the footer. </SheetDescription>
95
+ </SheetHeader>
96
+
97
+ <SheetFooter class="sm:justify-start">
98
+ <button type="button" Button variant="outline" SheetClose>Close</button>
99
+ </SheetFooter>
100
+ </Sheet>
101
+ ```
102
+
103
+ ### RTL
104
+
105
+ Because the overlay surface renders through CDK Overlay, set `dir="rtl"` on projected content inside the sheet when the direction should be scoped to the open panel.
106
+
107
+ ```html
108
+ <Sheet [(open)]="rtlOpen" [showCloseButton]="false" side="left" class="sm:max-w-md">
109
+ <div dir="rtl" lang="ar" class="flex flex-1 flex-col gap-4 text-right">
110
+ <SheetHeader>
111
+ <SheetTitle>تعديل الملف الشخصي</SheetTitle>
112
+ <SheetDescription>قم بإجراء تغييرات على ملفك الشخصي هنا ثم احفظها.</SheetDescription>
113
+ </SheetHeader>
114
+
115
+ <SheetContent class="grid gap-4 py-4">
116
+ <div class="grid gap-2">
117
+ <label Label for="sheet-rtl-name">الاسم</label>
118
+ <input Input id="sheet-rtl-name" value="بيدرو دوارتي" />
119
+ </div>
120
+ </SheetContent>
121
+
122
+ <SheetFooter class="sm:justify-start">
123
+ <button type="button" Button variant="outline" SheetClose>إغلاق</button>
124
+ <button type="button" Button (click)="rtlOpen.set(false)">حفظ التغييرات</button>
125
+ </SheetFooter>
126
+ </div>
127
+ </Sheet>
128
+ ```
129
+
130
+ ## API Reference
131
+
132
+ | Input | Type | Default |
133
+ | ---------------------- | --------------- | ---------- | ----------- | ------- | ---------------------------------------------- |
134
+ | `open` | `boolean` model | `false` |
135
+ | `side` | `'top' \\ | 'right' \\ | 'bottom' \\ | 'left'` | `'right'` for `Sheet`, `'bottom'` for `Drawer` |
136
+ | `closeOnEscape` | `boolean` | `true` |
137
+ | `closeOnBackdropClick` | `boolean` | `true` |
138
+ | `showCloseButton` | `boolean` | `true` |
139
+ | `closeButtonLabel` | `string` | `'Close'` |
140
+ | `aria-labelledby` | `string \\ | null` | `null` |
141
+ | `aria-describedby` | `string \\ | null` | `null` |
142
+ | `class` | `string` | `''` |
143
+
144
+ | Part | Purpose |
145
+ | -------------------- | -------------------------------------------------------------- |
146
+ | `SheetHeader` | Title and supporting description wrapper |
147
+ | `SheetTitle` | Visible, accessible sheet title |
148
+ | `SheetDescription` | Supporting copy that can be referenced from `aria-describedby` |
149
+ | `SheetContent` | Optional body wrapper for forms, spacing, and scroll regions |
150
+ | `SheetFooter` | Action row for primary and secondary controls |
151
+ | `button[SheetClose]` | Angular-friendly equivalent of shadcn `SheetClose` |
152
+
153
+ ## Styling And Theming
154
+
155
+ - The surface uses theme border tokens such as `border-border` on its edge divider so it stays aligned with the current theme.
156
+ - Left and right sheets default to `w-3/4 sm:max-w-sm`; add width utilities through the `class` input when a broader side panel is needed.
157
+ - Top and bottom sheets stretch across the viewport edge. Use `max-h-*` or spacing utilities on the root `class` input when the body can grow.
158
+ - `SheetContent` is the best place for internal scroll handling. Keep footer actions outside that overflow region when they must stay visible.
159
+ - Entry animation comes from `--sheet-from` and automatically collapses to zero duration under `prefers-reduced-motion`.
160
+
161
+ ## Accessibility
162
+
163
+ - The surface renders with `role="dialog"` and `aria-modal="true"`.
164
+ - Focus is trapped with `FocusTrap` and restored to the previously focused element on close.
165
+ - `Escape` and backdrop click close the sheet by default and can be disabled independently.
166
+ - Use stable IDs for the visible title and description when the sheet contains forms or longer instructional copy.
167
+
168
+ ## Keyboard Interactions
169
+
170
+ - `Tab` and `Shift+Tab` move focus within the trapped overlay.
171
+ - `Escape` closes the sheet unless `closeOnEscape` is disabled.
172
+ - `Enter` and `Space` activate the trigger, footer actions, and custom `SheetClose` controls through native button behavior.
173
+
174
+ ## Angular Notes
175
+
176
+ - `Sheet` combines the upstream `Sheet` root and `SheetContent` overlay surface into a single Angular component.
177
+ - `SheetContent` remains available as an internal body wrapper for layout, padding, and scroll regions.
178
+ - `Drawer` is exported as a bottom-first alias over the same primitive when the interaction reads more naturally as a drawer.
179
+ - `button[SheetClose]` and `a[SheetClose]` are the Angular-friendly equivalents of shadcn `SheetClose` for internal dismissal actions.
180
+
181
+ ## Source Parity
182
+
183
+ The local Sheet follows the shadcn component information architecture and behavior, but translates trigger ownership to an external signal instead of a `SheetTrigger` child component. Lower-level dialog semantics and API expectations still map closely to the Radix Dialog reference at https://www.radix-ui.com/primitives/docs/components/dialog#api-reference.
@@ -0,0 +1,158 @@
1
+ # Skeleton
2
+
3
+ Use Skeleton to show low-contrast placeholders while content is loading.
4
+
5
+ The component mirrors shadcn/ui's Skeleton primitive: it supplies the pulsing muted surface, while dimensions, shape, and layout are provided by utility classes at the call site.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { SkeletonComponent } from '@ojiepermana/angular-component/skeleton';
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Give each skeleton an explicit width, height, and optional radius. Without dimensions, the element exists in the DOM but will not create a visible placeholder.
16
+
17
+ ```html
18
+ <Skeleton class="h-5 w-25 rounded-full" />
19
+ ```
20
+
21
+ ```html
22
+ <div class="flex items-center gap-4">
23
+ <Skeleton class="h-12 w-12 rounded-full" />
24
+ <div class="space-y-2">
25
+ <Skeleton class="h-4 w-62.5" />
26
+ <Skeleton class="h-4 w-50" />
27
+ </div>
28
+ </div>
29
+ ```
30
+
31
+ ## Common patterns
32
+
33
+ ### Avatar
34
+
35
+ Use a round placeholder and two lines when loading profile identity, assignee, or author metadata.
36
+
37
+ ```html
38
+ <div class="flex w-fit items-center gap-4">
39
+ <Skeleton class="size-10 shrink-0 rounded-full" />
40
+ <div class="grid gap-2">
41
+ <Skeleton class="h-4 w-37.5" />
42
+ <Skeleton class="h-4 w-25" />
43
+ </div>
44
+ </div>
45
+ ```
46
+
47
+ ### Card
48
+
49
+ Skeleton composes inside `Card` parts. Match the final loaded geometry to avoid layout shift.
50
+
51
+ ```html
52
+ <Card class="w-full max-w-xs">
53
+ <CardHeader>
54
+ <div class="col-span-2 grid gap-2">
55
+ <Skeleton class="h-4 w-2/3" />
56
+ <Skeleton class="h-4 w-1/2" />
57
+ </div>
58
+ </CardHeader>
59
+ <CardContent>
60
+ <Skeleton class="aspect-video w-full" />
61
+ </CardContent>
62
+ </Card>
63
+ ```
64
+
65
+ ### Text
66
+
67
+ Use repeated bars and shorten the final line for paragraph rhythm.
68
+
69
+ ```html
70
+ <div class="flex w-full max-w-xs flex-col gap-2">
71
+ <Skeleton class="h-4 w-full" />
72
+ <Skeleton class="h-4 w-full" />
73
+ <Skeleton class="h-4 w-3/4" />
74
+ </div>
75
+ ```
76
+
77
+ ### Form
78
+
79
+ Pair short label placeholders with wider control placeholders when loading form metadata.
80
+
81
+ ```html
82
+ <div class="flex w-full max-w-xs flex-col gap-7">
83
+ <div class="flex flex-col gap-3">
84
+ <Skeleton class="h-4 w-20" />
85
+ <Skeleton class="h-8 w-full" />
86
+ </div>
87
+ <div class="flex flex-col gap-3">
88
+ <Skeleton class="h-4 w-24" />
89
+ <Skeleton class="h-8 w-full" />
90
+ </div>
91
+ <Skeleton class="h-8 w-24" />
92
+ </div>
93
+ ```
94
+
95
+ ### Table
96
+
97
+ Repeat rows with matching column proportions so tabular data keeps a stable footprint while loading.
98
+
99
+ ```html
100
+ <div class="flex w-full max-w-sm flex-col gap-2">
101
+ @for (row of tableRows; track row) {
102
+ <div class="flex gap-4">
103
+ <Skeleton class="h-4 flex-1" />
104
+ <Skeleton class="h-4 w-24" />
105
+ <Skeleton class="h-4 w-20" />
106
+ </div>
107
+ }
108
+ </div>
109
+ ```
110
+
111
+ ### RTL
112
+
113
+ Skeleton is direction-agnostic. Put `dir="rtl"` on the wrapper when the placeholder should reserve right-to-left layout space.
114
+
115
+ ```html
116
+ <div dir="rtl" lang="ar" class="flex items-center gap-4">
117
+ <Skeleton class="h-12 w-12 rounded-full" />
118
+ <div class="space-y-2">
119
+ <Skeleton class="h-4 w-62.5" />
120
+ <Skeleton class="h-4 w-50" />
121
+ </div>
122
+ </div>
123
+ ```
124
+
125
+ ## API reference
126
+
127
+ ### `SkeletonComponent`
128
+
129
+ | Input | Type | Default | Description |
130
+ | ------- | -------- | ------- | ----------------------------------------------------- |
131
+ | `class` | `string` | `''` | Supplies visible dimensions, shape, and extra layout. |
132
+
133
+ ## Styling and theming
134
+
135
+ Base classes: `block animate-pulse rounded-md bg-muted`.
136
+
137
+ The component consumes the shared muted theme token through `bg-muted`. Pass utility classes for width, height, radius, flex behavior, margins, and responsive variants. Because the host is block-level, width and height utilities behave like they do on the shadcn React `<div>` implementation.
138
+
139
+ ## Accessibility
140
+
141
+ `Skeleton` emits `aria-hidden="true"` because it is decorative loading chrome. Pair it with status text, a live region, or a busy state on the loaded region when the loading state needs to be announced.
142
+
143
+ Avoid replacing labels or meaningful headings with only skeletons for long periods. Keep the eventual content area stable and announce changes when data arrives.
144
+
145
+ ## Keyboard interactions
146
+
147
+ Skeleton has no keyboard interaction. It should not receive focus and should not contain interactive content.
148
+
149
+ ## Angular notes
150
+
151
+ - Import `SkeletonComponent` directly into the standalone component that renders the loading state.
152
+ - The `class` input is intentionally the main API so Angular examples stay close to shadcn utility-class composition.
153
+ - Use Angular control flow for repeated rows: `@for (row of tableRows; track row) { ... }`.
154
+ - Keep placeholder dimensions close to the loaded content to reduce layout shift.
155
+
156
+ ## Source parity
157
+
158
+ This Angular implementation follows the shadcn Skeleton docs and examples for preview, usage, Avatar, Card, Text, Form, Table, and RTL. React `className` becomes Angular `class`, and the primitive renders as a block-level custom element so sizing utilities match the upstream `<div>` behavior.