@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,291 @@
1
+ # Table
2
+
3
+ Responsive native table primitives for invoices, product lists, row actions, and compact data summaries.
4
+
5
+ Use Table when information has real row and column relationships. The Angular primitive keeps shadcn's composition model while preserving semantic `<table>`, `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, `<td>`, and `<caption>` elements.
6
+
7
+ shadcn's `data-table` guide maps to this entrypoint rather than a separate Angular package surface. Compose Table with the local button, checkbox, input, badge, and dropdown-menu primitives when you need sorting, filtering, row selection, column visibility, row actions, or pagination.
8
+
9
+ ## Import
10
+
11
+ ```ts
12
+ import {
13
+ TableBodyComponent,
14
+ TableCaptionComponent,
15
+ TableCellComponent,
16
+ TableComponent,
17
+ TableFooterComponent,
18
+ TableHeadComponent,
19
+ TableHeaderComponent,
20
+ TableRowComponent,
21
+ } from '@ojiepermana/angular-component/table';
22
+ ```
23
+
24
+ Row action menus can compose with the local button and dropdown-menu primitives.
25
+
26
+ ```ts
27
+ import { ButtonComponent } from '@ojiepermana/angular-component/button';
28
+ import {
29
+ MenuContentDirective,
30
+ MenuItemComponent,
31
+ MenuSeparatorComponent,
32
+ MenuSurfaceComponent,
33
+ MenuTriggerDirective,
34
+ } from '@ojiepermana/angular-component/dropdown-menu';
35
+ ```
36
+
37
+ ## Composition
38
+
39
+ Apply the attribute-selector parts to the matching semantic table tags.
40
+
41
+ ```text
42
+ Table
43
+ |-- caption[TableCaption]
44
+ |-- thead[TableHeader]
45
+ | `-- tr[TableRow]
46
+ | |-- th[TableHead]
47
+ | |-- th[TableHead]
48
+ | |-- th[TableHead]
49
+ | `-- th[TableHead]
50
+ |-- tbody[TableBody]
51
+ | `-- tr[TableRow]
52
+ | |-- td[TableCell]
53
+ | |-- td[TableCell]
54
+ | |-- td[TableCell]
55
+ | `-- td[TableCell]
56
+ `-- tfoot[TableFooter]
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ Use `Table` as the responsive wrapper. Bind rows with Angular control flow and stable tracking.
62
+
63
+ ```html
64
+ <table>
65
+ <caption TableCaption>
66
+ A list of your recent invoices.
67
+ </caption>
68
+ <thead TableHeader>
69
+ <tr TableRow>
70
+ <th TableHead class="w-25">Invoice</th>
71
+ <th TableHead>Status</th>
72
+ <th TableHead>Method</th>
73
+ <th TableHead class="text-right">Amount</th>
74
+ </tr>
75
+ </thead>
76
+ <tbody TableBody>
77
+ @for (invoice of invoices; track invoice.invoice) {
78
+ <tr TableRow>
79
+ <td TableCell class="font-medium">{{ invoice.invoice }}</td>
80
+ <td TableCell>{{ invoice.status }}</td>
81
+ <td TableCell>{{ invoice.method }}</td>
82
+ <td TableCell class="text-right">{{ invoice.amount }}</td>
83
+ </tr>
84
+ }
85
+ </tbody>
86
+ </table>
87
+ ```
88
+
89
+ ## Common patterns
90
+
91
+ ### Footer totals
92
+
93
+ Use `tfoot[TableFooter]` for totals and summaries. `colspan` stays on the native `td`.
94
+
95
+ ```html
96
+ <table>
97
+ <caption TableCaption>
98
+ A list of your recent invoices.
99
+ </caption>
100
+ <thead TableHeader>
101
+ ...
102
+ </thead>
103
+ <tbody TableBody>
104
+ ...
105
+ </tbody>
106
+ <tfoot TableFooter>
107
+ <tr TableRow>
108
+ <td TableCell colspan="3">Total</td>
109
+ <td TableCell class="text-right">$2,500.00</td>
110
+ </tr>
111
+ </tfoot>
112
+ </table>
113
+ ```
114
+
115
+ ### Row actions
116
+
117
+ Compose action menus with `Button`, `MenuTrigger`, and the dropdown-menu surface.
118
+
119
+ ```html
120
+ <ng-template MenuContent #productActionsMenu="MenuContent">
121
+ <MenuSurface class="w-36">
122
+ <button MenuItem>Edit</button>
123
+ <button MenuItem>Duplicate</button>
124
+ <MenuSeparator />
125
+ <button MenuItem variant="destructive">Delete</button>
126
+ </MenuSurface>
127
+ </ng-template>
128
+
129
+ <table>
130
+ <thead TableHeader>
131
+ <tr TableRow>
132
+ <th TableHead>Product</th>
133
+ <th TableHead>Price</th>
134
+ <th TableHead class="text-right">Actions</th>
135
+ </tr>
136
+ </thead>
137
+ <tbody TableBody>
138
+ @for (product of products; track product.name) {
139
+ <tr TableRow>
140
+ <td TableCell class="font-medium">{{ product.name }}</td>
141
+ <td TableCell>{{ product.price }}</td>
142
+ <td TableCell class="text-right">
143
+ <button
144
+ Button
145
+ type="button"
146
+ variant="ghost"
147
+ size="icon-sm"
148
+ [attr.aria-label]="'Open actions for ' + product.name"
149
+ [MenuTrigger]="productActionsMenu">
150
+ <span aria-hidden="true">...</span>
151
+ </button>
152
+ </td>
153
+ </tr>
154
+ }
155
+ </tbody>
156
+ </table>
157
+ ```
158
+
159
+ ### Data table guide mapping
160
+
161
+ The upstream shadcn `data-table` page is a composition guide, not a standalone primitive. In this Angular library the same guidance starts with `@ojiepermana/angular-component/table` and layers behavior around it.
162
+
163
+ ```ts
164
+ import { BadgeComponent } from '@ojiepermana/angular-component/badge';
165
+ import { ButtonComponent } from '@ojiepermana/angular-component/button';
166
+ import { CheckboxComponent } from '@ojiepermana/angular-component/checkbox';
167
+ import {
168
+ MenuCheckboxItemComponent,
169
+ MenuContentDirective,
170
+ MenuGroupComponent,
171
+ MenuItemComponent,
172
+ MenuLabelComponent,
173
+ MenuSeparatorComponent,
174
+ MenuSurfaceComponent,
175
+ MenuTriggerDirective,
176
+ } from '@ojiepermana/angular-component/dropdown-menu';
177
+ import { InputComponent } from '@ojiepermana/angular-component/input';
178
+ ```
179
+
180
+ Keep Table as the markup layer and put behavior in Angular signals, services, or a table state library. A small explicit pipeline is usually easier to maintain than a generic catch-all data-table wrapper.
181
+
182
+ ```ts
183
+ readonly filterText = signal('');
184
+ readonly sortState = signal<{ column: 'status' | 'email' | 'amount'; direction: 'asc' | 'desc' } | null>(null);
185
+ readonly selectedIds = signal<ReadonlySet<string>>(new Set());
186
+
187
+ readonly filteredRows = computed(() => {
188
+ const query = filterText().trim().toLowerCase();
189
+ return query ? rows.filter((row) => row.email.toLowerCase().includes(query)) : rows;
190
+ });
191
+
192
+ readonly sortedRows = computed(() => sortRows(filteredRows(), sortState()));
193
+ readonly pageRows = computed(() => paginateRows(sortedRows(), currentPage(), pageSize));
194
+ ```
195
+
196
+ Selected rows can use the shadcn-compatible `data-state="selected"` hook so row styling stays synchronized with the checkbox state.
197
+
198
+ ```html
199
+ <table>
200
+ <thead TableHeader>
201
+ ...
202
+ </thead>
203
+ <tbody TableBody>
204
+ @for (row of filteredRows(); track row.id) {
205
+ <tr TableRow [attr.data-state]="selectedIds().has(row.id) ? 'selected' : null">
206
+ <td TableCell>{{ row.title }}</td>
207
+ <td TableCell>{{ row.status }}</td>
208
+ <td TableCell class="text-right">{{ row.amount }}</td>
209
+ </tr>
210
+ }
211
+ </tbody>
212
+ </table>
213
+ ```
214
+
215
+ ### RTL
216
+
217
+ Set direction on a wrapper or directly on `Table`. Keep alignment explicit for amount and numeric columns.
218
+
219
+ ```html
220
+ <div dir="rtl" lang="ar" class="text-right">
221
+ <table>
222
+ <caption TableCaption>
223
+ قائمة بفواتيرك الأخيرة.
224
+ </caption>
225
+ <thead TableHeader>
226
+ <tr TableRow>
227
+ <th TableHead class="w-25 text-right">الفاتورة</th>
228
+ <th TableHead class="text-right">الحالة</th>
229
+ <th TableHead class="text-right">الطريقة</th>
230
+ <th TableHead class="text-right">المبلغ</th>
231
+ </tr>
232
+ </thead>
233
+ <tbody TableBody>
234
+ ...
235
+ </tbody>
236
+ </table>
237
+ </div>
238
+ ```
239
+
240
+ ## API reference
241
+
242
+ ### `TableComponent`
243
+
244
+ | Input | Type | Default | Description |
245
+ | ------- | -------- | ------- | ------------------------------------------------- |
246
+ | `class` | `string` | `''` | Classes applied to the rendered native `<table>`. |
247
+
248
+ ### Attribute parts
249
+
250
+ | Part | Selector | Input | Notes |
251
+ | ----------------------- | ----------------------- | ------- | ------------------------------------------------------- |
252
+ | `TableCaptionComponent` | `caption[TableCaption]` | `class` | Muted caption below the table. |
253
+ | `TableHeaderComponent` | `thead[TableHeader]` | `class` | Header section with row dividers. |
254
+ | `TableBodyComponent` | `tbody[TableBody]` | `class` | Body section that removes the final row border. |
255
+ | `TableFooterComponent` | `tfoot[TableFooter]` | `class` | Footer section with muted background and top divider. |
256
+ | `TableRowComponent` | `tr[TableRow]` | `class` | Row hover state and `data-state="selected"` support. |
257
+ | `TableHeadComponent` | `th[TableHead]` | `class` | Header cell with muted foreground and nowrap text. |
258
+ | `TableCellComponent` | `td[TableCell]` | `class` | Body or footer cell with compact padding and alignment. |
259
+
260
+ ## Styling and theming
261
+
262
+ The root host is `relative block w-full overflow-x-auto`; the rendered table is `w-full caption-bottom text-sm`.
263
+
264
+ Dividers use the shared `border-border` token, row hover uses `hover:bg-muted/50`, footer uses `bg-muted/50`, and selected rows respond to `data-state="selected"` with `bg-muted`.
265
+
266
+ Pass utility classes to individual parts for column width, alignment, density, responsive visibility, and typography.
267
+
268
+ ## Accessibility
269
+
270
+ - Use a `<caption TableCaption>` when the table conveys meaningful data.
271
+ - Keep column headers in native `<th TableHead>` cells so screen readers can announce header relationships.
272
+ - Use `scope`, `colspan`, `rowspan`, and `aria-sort` on native cells when your data model needs them.
273
+ - Do not use Table for non-tabular layout. Use CSS grid or flex layouts for purely visual alignment.
274
+
275
+ ## Keyboard interactions
276
+
277
+ Static tables do not add custom keyboard behavior. Focusable controls inside cells, such as action menu buttons, keep their own native or primitive-provided keyboard behavior.
278
+
279
+ When composing a row menu, the trigger uses native button activation and the local menu handles Arrow Up, Arrow Down, Home, End, Tab dismissal, and typeahead.
280
+
281
+ ## Angular notes
282
+
283
+ - All table parts are standalone components and can be imported directly.
284
+ - The root `Table` wraps projected content in a native `<table>`, so child parts should be direct table descendants in normal HTML order.
285
+ - Prefer Angular `@for` with a stable `track` expression for row rendering.
286
+ - Keep sorting, filtering, pagination, and selection state outside the primitive; Table is intentionally presentational.
287
+ - Attribute-selector primitives must be applied to their semantic tag, for example `th[TableHead]` and `td[TableCell]`.
288
+
289
+ ## Source parity
290
+
291
+ This Angular implementation follows the shadcn Table docs for preview, usage, composition, footer, actions, data-table guidance, and RTL. React component names map to Angular selectors, React `className` maps to `class`, and row action menus compose with the local Angular dropdown-menu primitives.
package/tabs/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # Tabs
2
+
3
+ A set of layered sections of content, known as tab panels, that are displayed one at a time.
4
+
5
+ Use Tabs for compact settings surfaces, dashboards, account forms, and any view where related panels should share the same page location.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent } from '@ojiepermana/angular-component/tabs';
11
+ ```
12
+
13
+ ## Composition
14
+
15
+ The Angular structure mirrors shadcn and Radix while using Angular selectors and native button triggers.
16
+
17
+ ```text
18
+ Tabs
19
+ ├── TabsList
20
+ │ ├── button[TabsTrigger]
21
+ │ └── button[TabsTrigger]
22
+ ├── TabsContent
23
+ └── TabsContent
24
+ ```
25
+
26
+ ## Basic usage
27
+
28
+ Pair every trigger value with a matching panel value. Bind `[(value)]` when the parent should seed the active tab or observe changes.
29
+
30
+ ```ts
31
+ const activeTab = signal<string | null>('account');
32
+ ```
33
+
34
+ ```html
35
+ <Tabs [(value)]="activeTab" class="w-full max-w-md">
36
+ <TabsList>
37
+ <button TabsTrigger value="account">Account</button>
38
+ <button TabsTrigger value="password">Password</button>
39
+ </TabsList>
40
+
41
+ <TabsContent value="account">Make changes to your account here.</TabsContent>
42
+ <TabsContent value="password">Change your password here.</TabsContent>
43
+ </Tabs>
44
+ ```
45
+
46
+ ## Common patterns
47
+
48
+ ### Line variant
49
+
50
+ Use `variant="line"` on `TabsList` for the underline treatment from the shadcn examples.
51
+
52
+ ```ts
53
+ const lineTab = signal<string | null>('overview');
54
+ ```
55
+
56
+ ```html
57
+ <Tabs [(value)]="lineTab">
58
+ <TabsList variant="line">
59
+ <button TabsTrigger value="overview">Overview</button>
60
+ <button TabsTrigger value="analytics">Analytics</button>
61
+ <button TabsTrigger value="reports">Reports</button>
62
+ </TabsList>
63
+
64
+ <TabsContent value="overview">Overview metrics are selected.</TabsContent>
65
+ <TabsContent value="analytics">Analytics metrics are selected.</TabsContent>
66
+ <TabsContent value="reports">Reports metrics are selected.</TabsContent>
67
+ </Tabs>
68
+ ```
69
+
70
+ ### Vertical orientation
71
+
72
+ Set `orientation="vertical"` on `Tabs` when triggers should stack beside the active panel.
73
+
74
+ ```ts
75
+ const verticalTab = signal<string | null>('account');
76
+ ```
77
+
78
+ ```html
79
+ <Tabs [(value)]="verticalTab" orientation="vertical" class="w-full max-w-2xl">
80
+ <TabsList class="min-w-40">
81
+ <button TabsTrigger value="account">Account</button>
82
+ <button TabsTrigger value="password">Password</button>
83
+ <button TabsTrigger value="notifications">Notifications</button>
84
+ </TabsList>
85
+
86
+ <TabsContent value="account" class="mt-0 flex-1 rounded-lg border border-border p-4">
87
+ Account preferences and details live in this panel.
88
+ </TabsContent>
89
+ </Tabs>
90
+ ```
91
+
92
+ ### Disabled triggers
93
+
94
+ Disable a trigger with `[disabled]="true"`. Disabled triggers remain visible, expose disabled state, and are skipped by arrow-key navigation.
95
+
96
+ ```ts
97
+ const disabledTab = signal<string | null>('home');
98
+ ```
99
+
100
+ ```html
101
+ <Tabs [(value)]="disabledTab">
102
+ <TabsList>
103
+ <button TabsTrigger value="home">Home</button>
104
+ <button TabsTrigger value="settings" [disabled]="true">Disabled</button>
105
+ </TabsList>
106
+
107
+ <TabsContent value="home">Home content stays reachable.</TabsContent>
108
+ <TabsContent value="settings">Settings is intentionally unavailable.</TabsContent>
109
+ </Tabs>
110
+ ```
111
+
112
+ ### Icons
113
+
114
+ Project icon components or inline SVG before trigger text. The trigger includes icon and label spacing.
115
+
116
+ ```html
117
+ <Tabs value="preview">
118
+ <TabsList>
119
+ <button TabsTrigger value="preview">
120
+ <svg aria-hidden="true" class="size-4" viewBox="0 0 24 24">...</svg>
121
+ Preview
122
+ </button>
123
+ <button TabsTrigger value="code">
124
+ <svg aria-hidden="true" class="size-4" viewBox="0 0 24 24">...</svg>
125
+ Code
126
+ </button>
127
+ </TabsList>
128
+
129
+ <TabsContent value="preview">Rendered preview is selected.</TabsContent>
130
+ <TabsContent value="code">Code sample is selected.</TabsContent>
131
+ </Tabs>
132
+ ```
133
+
134
+ ### RTL
135
+
136
+ Set `dir="rtl"` on the tabs root or an ancestor container when the surrounding interface runs right to left.
137
+
138
+ ```html
139
+ <Tabs value="overview" dir="rtl" lang="ar" class="w-full max-w-md text-right">
140
+ <TabsList>
141
+ <button TabsTrigger value="overview">نظرة عامة</button>
142
+ <button TabsTrigger value="analytics">التحليلات</button>
143
+ <button TabsTrigger value="reports">التقارير</button>
144
+ <button TabsTrigger value="settings">الإعدادات</button>
145
+ </TabsList>
146
+
147
+ <TabsContent value="overview">لديك ١٢ مشروعًا نشطًا و٣ مهام معلقة.</TabsContent>
148
+ </Tabs>
149
+ ```
150
+
151
+ ## API reference
152
+
153
+ ### `TabsComponent`
154
+
155
+ | Input | Type | Default |
156
+ | --------------- | ---------------------------- | -------------- |
157
+ | `value` (model) | `string \| null` | `null` |
158
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
159
+ | `class` | `string` | `''` |
160
+
161
+ ### `TabsListComponent`
162
+
163
+ | Input | Type | Default |
164
+ | --------- | --------------------- | ----------- |
165
+ | `variant` | `'default' \| 'line'` | `'default'` |
166
+ | `class` | `string` | `''` |
167
+
168
+ ### `TabsTriggerComponent`
169
+
170
+ | Input | Type | Default |
171
+ | ---------- | --------- | ------- |
172
+ | `value` | `string` | — |
173
+ | `disabled` | `boolean` | `false` |
174
+ | `class` | `string` | `''` |
175
+
176
+ ### `TabsContentComponent`
177
+
178
+ | Input | Type | Default |
179
+ | ------- | -------- | ------- |
180
+ | `value` | `string` | — |
181
+ | `class` | `string` | `''` |
182
+
183
+ ## Styling and theming
184
+
185
+ The default list uses `bg-muted` and active triggers use `bg-background`, `text-foreground`, and `shadow-sm` to match the shadcn look.
186
+
187
+ The line variant uses `border-border` on the list and an active `border-foreground` underline on the trigger. Pass `class` to the root, list, trigger, or content to tune width, grid layouts, spacing, and panel framing.
188
+
189
+ ## Accessibility
190
+
191
+ - `TabsList` renders `role="tablist"` and `aria-orientation`.
192
+ - `button[TabsTrigger]` renders `role="tab"`, `aria-selected`, roving `tabindex`, `aria-controls`, and `aria-disabled` when disabled.
193
+ - `TabsContent` renders `role="tabpanel"`, `aria-labelledby`, `tabindex="0"`, and `hidden` when inactive.
194
+ - Keep trigger labels concise and unique. Icons inside triggers should be decorative or have their own accessible text outside the icon.
195
+
196
+ ## Keyboard interactions
197
+
198
+ - `ArrowRight` and `ArrowLeft` move selection and focus through horizontal tabs.
199
+ - `ArrowDown` and `ArrowUp` move selection and focus through vertical tabs.
200
+ - `Home` and `End` jump to the first and last enabled trigger.
201
+ - Disabled triggers are skipped by arrow-key, Home, and End navigation.
202
+ - Enter and Space retain native button activation behavior.
203
+
204
+ ## Angular notes
205
+
206
+ - The component uses Angular signal-based `model()` binding for `value`.
207
+ - Use `signal<string | null>()` with `[(value)]` as the Angular equivalent of shadcn `defaultValue` when parent state matters.
208
+ - Values are strings and should be unique within a tabs root.
209
+ - `variant="line"` belongs to `TabsList`, matching the upstream shadcn API.
210
+ - Icons are projected content; bring an app icon component or inline SVG where needed.
211
+
212
+ ## Source parity
213
+
214
+ This Angular implementation follows the current shadcn Tabs docs: preview card tabs, usage, composition, line, vertical, disabled, icons, RTL, and Radix API guidance. React props are translated to Angular selectors, native buttons, and signal-friendly state.
@@ -0,0 +1,153 @@
1
+ # Textarea
2
+
3
+ Displays a multiline native `<textarea>` with the shared Angular theme tokens and shadcn-style field composition.
4
+
5
+ Use Textarea for feedback, notes, comments, support messages, and any form surface that needs multi-line entry while keeping browser-native editing behavior.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { TextareaComponent } from '@ojiepermana/angular-component/textarea';
11
+ ```
12
+
13
+ Import the `form`, `label`, or `button` entrypoints separately when the page also needs structured field copy or submit actions.
14
+
15
+ ## Composition
16
+
17
+ Textarea stays intentionally small because it styles the native control instead of wrapping it in a custom value accessor.
18
+
19
+ ```text
20
+ label[Label]
21
+ └── textarea[Textarea]
22
+ ```
23
+
24
+ For the richer shadcn field pattern, compose it with the existing form primitives.
25
+
26
+ ```text
27
+ FormField
28
+ ├── FormLabel
29
+ ├── textarea[Textarea][FormControl]
30
+ └── FormDescription or FormMessage
31
+ ```
32
+
33
+ ## Basic Usage
34
+
35
+ Use a visible label plus the styled native textarea when you only need the base multiline control.
36
+
37
+ ```html
38
+ <label Label for="bio">Bio</label> <textarea id="bio" Textarea rows="4" placeholder="Tell us about yourself"></textarea>
39
+ ```
40
+
41
+ When the textarea lives inside `FormField`, add `FormControl` so labels, descriptions, and invalid state stay wired together.
42
+
43
+ ```html
44
+ <FormField>
45
+ <FormLabel>Message</FormLabel>
46
+ <textarea Textarea FormControl rows="4" placeholder="Type your message here."></textarea>
47
+ <FormDescription>Enter your message below.</FormDescription>
48
+ </FormField>
49
+ ```
50
+
51
+ ## Common Patterns
52
+
53
+ ### Field Composition
54
+
55
+ The upstream shadcn `Field`, `FieldLabel`, and `FieldDescription` helpers map to the local `form` entrypoint.
56
+
57
+ ```html
58
+ <FormField>
59
+ <FormLabel>Feedback</FormLabel>
60
+ <textarea Textarea FormControl rows="4" placeholder="Your feedback helps us improve..."></textarea>
61
+ <FormDescription>Share your thoughts about our service.</FormDescription>
62
+ </FormField>
63
+ ```
64
+
65
+ ### Disabled and Invalid States
66
+
67
+ Use the native `disabled` attribute for disabled state and `aria-invalid="true"` for validation styling.
68
+
69
+ ```html
70
+ <FormField>
71
+ <FormLabel>Message</FormLabel>
72
+ <textarea Textarea FormControl rows="4" disabled></textarea>
73
+ <FormDescription>This field is currently disabled.</FormDescription>
74
+ </FormField>
75
+
76
+ <FormField>
77
+ <FormLabel>Message</FormLabel>
78
+ <textarea Textarea FormControl rows="4" aria-invalid="true"></textarea>
79
+ <FormDescription>Please enter a valid message.</FormDescription>
80
+ </FormField>
81
+ ```
82
+
83
+ ### Submit Row
84
+
85
+ Pair the textarea with `button[Button]` to create feedback and messaging layouts.
86
+
87
+ ```html
88
+ <div class="grid w-full max-w-md gap-2">
89
+ <textarea Textarea rows="5" class="min-h-[140px]" placeholder="Type your message here."></textarea>
90
+ <button Button type="button" class="w-fit">Send message</button>
91
+ </div>
92
+ ```
93
+
94
+ ### RTL
95
+
96
+ Set `dir="rtl"` on a wrapping container or manage direction globally in your layout. The textarea stays native while labels and helper text follow the document direction.
97
+
98
+ ```html
99
+ <div dir="rtl" lang="ar" class="max-w-md text-right">
100
+ <FormField>
101
+ <FormLabel>التعليقات</FormLabel>
102
+ <textarea Textarea FormControl rows="4" placeholder="تعليقاتك تساعدنا على التحسين..."></textarea>
103
+ <FormDescription>شاركنا أفكارك حول خدمتنا.</FormDescription>
104
+ </FormField>
105
+ </div>
106
+ ```
107
+
108
+ ## API Reference
109
+
110
+ ### `TextareaComponent`
111
+
112
+ | Input | Type | Default |
113
+ | ------- | -------- | ------- |
114
+ | `class` | `string` | `''` |
115
+
116
+ ### Native Attributes
117
+
118
+ All standard `<textarea>` attributes such as `rows`, `placeholder`, `disabled`, `required`, `readonly`, `dir`, and `aria-invalid` pass through unchanged.
119
+
120
+ The component also exposes a `focus()` instance method when accessed through `ViewChild(TextareaComponent)`.
121
+
122
+ ## Styling and Theming
123
+
124
+ The component uses the shared `border-input`, `ring-ring`, `text-foreground`, `placeholder:text-muted-foreground`, and `aria-[invalid=true]:border-destructive` tokens.
125
+
126
+ Base styling includes a `min-h-[60px]` guard to avoid collapsed textareas and `resize-y` so users can increase the writing area without breaking width-constrained layouts.
127
+
128
+ Pass `class` to tune height, spacing, or layout while keeping the base focus, disabled, invalid, and resize treatment.
129
+
130
+ ## Accessibility
131
+
132
+ - Pair the textarea with a visible label using `label[Label]` or `FormLabel`.
133
+ - Use `FormControl` inside `FormField` so helper and error text participate in the same accessible description chain.
134
+ - Mark validation failures with `aria-invalid="true"` and provide descriptive helper or error text nearby.
135
+ - Keep the native resize handle available so pointer and touch users can increase the input area when needed.
136
+
137
+ ## Keyboard Interactions
138
+
139
+ - `Tab` and `Shift+Tab` move focus in and out using the normal browser order.
140
+ - `Enter` inserts a new line instead of submitting by itself.
141
+ - Arrow keys, Home, End, selection, and clipboard shortcuts stay browser-native.
142
+
143
+ ## Angular Notes
144
+
145
+ - Textarea styles the native `<textarea>`, so it works with both `ngModel` and reactive forms.
146
+ - Prefer using `FormControl` when the textarea lives inside `FormField`.
147
+ - Let Angular form state drive invalid styling when possible, but `aria-invalid="true"` also works for externally managed validation.
148
+
149
+ ## Source Parity
150
+
151
+ This Angular implementation follows the shadcn Textarea page closely for the core textarea, disabled and invalid states, button layout, and RTL guidance.
152
+
153
+ The upstream `Field` helper family intentionally maps to the existing Angular `form` entrypoint instead of adding a separate `field` runtime surface.