@edsis/ui 0.0.2

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 (265) hide show
  1. package/README.md +40 -0
  2. package/accordion/README.md +195 -0
  3. package/alert/README.md +177 -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 +204 -0
  11. package/calendar/README.md +132 -0
  12. package/card/README.md +220 -0
  13. package/carousel/README.md +276 -0
  14. package/chart/README.md +249 -0
  15. package/checkbox/README.md +149 -0
  16. package/collapsible/README.md +191 -0
  17. package/combobox/README.md +198 -0
  18. package/command/README.md +275 -0
  19. package/composer/README.md +235 -0
  20. package/context-menu/README.md +267 -0
  21. package/date-picker/README.md +177 -0
  22. package/dialog/README.md +237 -0
  23. package/drawer/README.md +145 -0
  24. package/dropdown-menu/README.md +311 -0
  25. package/editor/README.md +136 -0
  26. package/empty/README.md +183 -0
  27. package/fesm2022/edsis-ui-accordion.mjs +174 -0
  28. package/fesm2022/edsis-ui-accordion.mjs.map +1 -0
  29. package/fesm2022/edsis-ui-alert-dialog.mjs +242 -0
  30. package/fesm2022/edsis-ui-alert-dialog.mjs.map +1 -0
  31. package/fesm2022/edsis-ui-alert.mjs +90 -0
  32. package/fesm2022/edsis-ui-alert.mjs.map +1 -0
  33. package/fesm2022/edsis-ui-aspect-ratio.mjs +33 -0
  34. package/fesm2022/edsis-ui-aspect-ratio.mjs.map +1 -0
  35. package/fesm2022/edsis-ui-avatar.mjs +123 -0
  36. package/fesm2022/edsis-ui-avatar.mjs.map +1 -0
  37. package/fesm2022/edsis-ui-badge.mjs +47 -0
  38. package/fesm2022/edsis-ui-badge.mjs.map +1 -0
  39. package/fesm2022/edsis-ui-breadcrumb.mjs +186 -0
  40. package/fesm2022/edsis-ui-breadcrumb.mjs.map +1 -0
  41. package/fesm2022/edsis-ui-button-group.mjs +95 -0
  42. package/fesm2022/edsis-ui-button-group.mjs.map +1 -0
  43. package/fesm2022/edsis-ui-button.mjs +64 -0
  44. package/fesm2022/edsis-ui-button.mjs.map +1 -0
  45. package/fesm2022/edsis-ui-calendar.mjs +78 -0
  46. package/fesm2022/edsis-ui-calendar.mjs.map +1 -0
  47. package/fesm2022/edsis-ui-card.mjs +137 -0
  48. package/fesm2022/edsis-ui-card.mjs.map +1 -0
  49. package/fesm2022/edsis-ui-carousel.mjs +310 -0
  50. package/fesm2022/edsis-ui-carousel.mjs.map +1 -0
  51. package/fesm2022/edsis-ui-chart-area.mjs +6 -0
  52. package/fesm2022/edsis-ui-chart-area.mjs.map +1 -0
  53. package/fesm2022/edsis-ui-chart-bar.mjs +6 -0
  54. package/fesm2022/edsis-ui-chart-bar.mjs.map +1 -0
  55. package/fesm2022/edsis-ui-chart-line.mjs +6 -0
  56. package/fesm2022/edsis-ui-chart-line.mjs.map +1 -0
  57. package/fesm2022/edsis-ui-chart-pie.mjs +6 -0
  58. package/fesm2022/edsis-ui-chart-pie.mjs.map +1 -0
  59. package/fesm2022/edsis-ui-chart-radar.mjs +6 -0
  60. package/fesm2022/edsis-ui-chart-radar.mjs.map +1 -0
  61. package/fesm2022/edsis-ui-chart-radial.mjs +6 -0
  62. package/fesm2022/edsis-ui-chart-radial.mjs.map +1 -0
  63. package/fesm2022/edsis-ui-chart-scatter.mjs +6 -0
  64. package/fesm2022/edsis-ui-chart-scatter.mjs.map +1 -0
  65. package/fesm2022/edsis-ui-chart.mjs +3714 -0
  66. package/fesm2022/edsis-ui-chart.mjs.map +1 -0
  67. package/fesm2022/edsis-ui-checkbox.mjs +104 -0
  68. package/fesm2022/edsis-ui-checkbox.mjs.map +1 -0
  69. package/fesm2022/edsis-ui-collapsible.mjs +116 -0
  70. package/fesm2022/edsis-ui-collapsible.mjs.map +1 -0
  71. package/fesm2022/edsis-ui-combobox.mjs +263 -0
  72. package/fesm2022/edsis-ui-combobox.mjs.map +1 -0
  73. package/fesm2022/edsis-ui-command.mjs +268 -0
  74. package/fesm2022/edsis-ui-command.mjs.map +1 -0
  75. package/fesm2022/edsis-ui-composer.mjs +329 -0
  76. package/fesm2022/edsis-ui-composer.mjs.map +1 -0
  77. package/fesm2022/edsis-ui-context-menu.mjs +100 -0
  78. package/fesm2022/edsis-ui-context-menu.mjs.map +1 -0
  79. package/fesm2022/edsis-ui-date-picker.mjs +155 -0
  80. package/fesm2022/edsis-ui-date-picker.mjs.map +1 -0
  81. package/fesm2022/edsis-ui-dialog.mjs +262 -0
  82. package/fesm2022/edsis-ui-dialog.mjs.map +1 -0
  83. package/fesm2022/edsis-ui-drawer.mjs +6 -0
  84. package/fesm2022/edsis-ui-drawer.mjs.map +1 -0
  85. package/fesm2022/edsis-ui-dropdown-menu.mjs +466 -0
  86. package/fesm2022/edsis-ui-dropdown-menu.mjs.map +1 -0
  87. package/fesm2022/edsis-ui-editor.mjs +692 -0
  88. package/fesm2022/edsis-ui-editor.mjs.map +1 -0
  89. package/fesm2022/edsis-ui-empty.mjs +132 -0
  90. package/fesm2022/edsis-ui-empty.mjs.map +1 -0
  91. package/fesm2022/edsis-ui-form.mjs +334 -0
  92. package/fesm2022/edsis-ui-form.mjs.map +1 -0
  93. package/fesm2022/edsis-ui-hover-card.mjs +284 -0
  94. package/fesm2022/edsis-ui-hover-card.mjs.map +1 -0
  95. package/fesm2022/edsis-ui-input-group.mjs +164 -0
  96. package/fesm2022/edsis-ui-input-group.mjs.map +1 -0
  97. package/fesm2022/edsis-ui-input-otp.mjs +485 -0
  98. package/fesm2022/edsis-ui-input-otp.mjs.map +1 -0
  99. package/fesm2022/edsis-ui-input.mjs +43 -0
  100. package/fesm2022/edsis-ui-input.mjs.map +1 -0
  101. package/fesm2022/edsis-ui-item.mjs +241 -0
  102. package/fesm2022/edsis-ui-item.mjs.map +1 -0
  103. package/fesm2022/edsis-ui-kanban.mjs +289 -0
  104. package/fesm2022/edsis-ui-kanban.mjs.map +1 -0
  105. package/fesm2022/edsis-ui-kbd.mjs +51 -0
  106. package/fesm2022/edsis-ui-kbd.mjs.map +1 -0
  107. package/fesm2022/edsis-ui-label.mjs +30 -0
  108. package/fesm2022/edsis-ui-label.mjs.map +1 -0
  109. package/fesm2022/edsis-ui-menubar.mjs +302 -0
  110. package/fesm2022/edsis-ui-menubar.mjs.map +1 -0
  111. package/fesm2022/edsis-ui-native-select.mjs +61 -0
  112. package/fesm2022/edsis-ui-native-select.mjs.map +1 -0
  113. package/fesm2022/edsis-ui-navigation-menu.mjs +399 -0
  114. package/fesm2022/edsis-ui-navigation-menu.mjs.map +1 -0
  115. package/fesm2022/edsis-ui-pagination.mjs +216 -0
  116. package/fesm2022/edsis-ui-pagination.mjs.map +1 -0
  117. package/fesm2022/edsis-ui-pillbox.mjs +777 -0
  118. package/fesm2022/edsis-ui-pillbox.mjs.map +1 -0
  119. package/fesm2022/edsis-ui-popover.mjs +163 -0
  120. package/fesm2022/edsis-ui-popover.mjs.map +1 -0
  121. package/fesm2022/edsis-ui-progress.mjs +53 -0
  122. package/fesm2022/edsis-ui-progress.mjs.map +1 -0
  123. package/fesm2022/edsis-ui-radio.mjs +111 -0
  124. package/fesm2022/edsis-ui-radio.mjs.map +1 -0
  125. package/fesm2022/edsis-ui-resizable.mjs +454 -0
  126. package/fesm2022/edsis-ui-resizable.mjs.map +1 -0
  127. package/fesm2022/edsis-ui-scroll-area.mjs +48 -0
  128. package/fesm2022/edsis-ui-scroll-area.mjs.map +1 -0
  129. package/fesm2022/edsis-ui-select.mjs +164 -0
  130. package/fesm2022/edsis-ui-select.mjs.map +1 -0
  131. package/fesm2022/edsis-ui-separator.mjs +33 -0
  132. package/fesm2022/edsis-ui-separator.mjs.map +1 -0
  133. package/fesm2022/edsis-ui-sheet.mjs +264 -0
  134. package/fesm2022/edsis-ui-sheet.mjs.map +1 -0
  135. package/fesm2022/edsis-ui-skeleton.mjs +29 -0
  136. package/fesm2022/edsis-ui-skeleton.mjs.map +1 -0
  137. package/fesm2022/edsis-ui-slider.mjs +405 -0
  138. package/fesm2022/edsis-ui-slider.mjs.map +1 -0
  139. package/fesm2022/edsis-ui-spinner.mjs +58 -0
  140. package/fesm2022/edsis-ui-spinner.mjs.map +1 -0
  141. package/fesm2022/edsis-ui-switch.mjs +107 -0
  142. package/fesm2022/edsis-ui-switch.mjs.map +1 -0
  143. package/fesm2022/edsis-ui-table.mjs +139 -0
  144. package/fesm2022/edsis-ui-table.mjs.map +1 -0
  145. package/fesm2022/edsis-ui-tabs.mjs +252 -0
  146. package/fesm2022/edsis-ui-tabs.mjs.map +1 -0
  147. package/fesm2022/edsis-ui-textarea.mjs +37 -0
  148. package/fesm2022/edsis-ui-textarea.mjs.map +1 -0
  149. package/fesm2022/edsis-ui-timeline.mjs +213 -0
  150. package/fesm2022/edsis-ui-timeline.mjs.map +1 -0
  151. package/fesm2022/edsis-ui-toast.mjs +71 -0
  152. package/fesm2022/edsis-ui-toast.mjs.map +1 -0
  153. package/fesm2022/edsis-ui-toggle-group.mjs +269 -0
  154. package/fesm2022/edsis-ui-toggle-group.mjs.map +1 -0
  155. package/fesm2022/edsis-ui-toggle.mjs +76 -0
  156. package/fesm2022/edsis-ui-toggle.mjs.map +1 -0
  157. package/fesm2022/edsis-ui-tooltip.mjs +339 -0
  158. package/fesm2022/edsis-ui-tooltip.mjs.map +1 -0
  159. package/fesm2022/edsis-ui-utils.mjs +13 -0
  160. package/fesm2022/edsis-ui-utils.mjs.map +1 -0
  161. package/fesm2022/edsis-ui.mjs +11 -0
  162. package/fesm2022/edsis-ui.mjs.map +1 -0
  163. package/form/README.md +210 -0
  164. package/hover-card/README.md +146 -0
  165. package/input/README.md +159 -0
  166. package/input-group/README.md +234 -0
  167. package/input-otp/README.md +273 -0
  168. package/item/README.md +247 -0
  169. package/kanban/README.md +81 -0
  170. package/kbd/README.md +139 -0
  171. package/label/README.md +136 -0
  172. package/menubar/README.md +269 -0
  173. package/native-select/README.md +176 -0
  174. package/navigation-menu/README.md +160 -0
  175. package/package.json +310 -0
  176. package/pagination/README.md +144 -0
  177. package/pillbox/README.md +67 -0
  178. package/popover/README.md +43 -0
  179. package/progress/README.md +160 -0
  180. package/radio/README.md +209 -0
  181. package/resizable/README.md +164 -0
  182. package/scroll-area/README.md +143 -0
  183. package/select/README.md +174 -0
  184. package/separator/README.md +170 -0
  185. package/sheet/README.md +183 -0
  186. package/skeleton/README.md +158 -0
  187. package/slider/README.md +207 -0
  188. package/spinner/README.md +160 -0
  189. package/switch/README.md +166 -0
  190. package/table/README.md +291 -0
  191. package/tabs/README.md +214 -0
  192. package/textarea/README.md +154 -0
  193. package/timeline/README.md +94 -0
  194. package/toast/README.md +321 -0
  195. package/toggle/README.md +131 -0
  196. package/toggle-group/README.md +206 -0
  197. package/tooltip/README.md +211 -0
  198. package/types/edsis-ui-accordion.d.ts +51 -0
  199. package/types/edsis-ui-alert-dialog.d.ts +93 -0
  200. package/types/edsis-ui-alert.d.ts +37 -0
  201. package/types/edsis-ui-aspect-ratio.d.ts +12 -0
  202. package/types/edsis-ui-avatar.d.ts +51 -0
  203. package/types/edsis-ui-badge.d.ts +19 -0
  204. package/types/edsis-ui-breadcrumb.d.ts +46 -0
  205. package/types/edsis-ui-button-group.d.ts +26 -0
  206. package/types/edsis-ui-button.d.ts +22 -0
  207. package/types/edsis-ui-calendar.d.ts +33 -0
  208. package/types/edsis-ui-card.d.ts +60 -0
  209. package/types/edsis-ui-carousel.d.ts +86 -0
  210. package/types/edsis-ui-chart-area.d.ts +1 -0
  211. package/types/edsis-ui-chart-bar.d.ts +1 -0
  212. package/types/edsis-ui-chart-line.d.ts +1 -0
  213. package/types/edsis-ui-chart-pie.d.ts +1 -0
  214. package/types/edsis-ui-chart-radar.d.ts +1 -0
  215. package/types/edsis-ui-chart-radial.d.ts +1 -0
  216. package/types/edsis-ui-chart-scatter.d.ts +1 -0
  217. package/types/edsis-ui-chart.d.ts +1094 -0
  218. package/types/edsis-ui-checkbox.d.ts +35 -0
  219. package/types/edsis-ui-collapsible.d.ts +42 -0
  220. package/types/edsis-ui-combobox.d.ts +51 -0
  221. package/types/edsis-ui-command.d.ts +99 -0
  222. package/types/edsis-ui-composer.d.ts +90 -0
  223. package/types/edsis-ui-context-menu.d.ts +35 -0
  224. package/types/edsis-ui-date-picker.d.ts +41 -0
  225. package/types/edsis-ui-dialog.d.ts +87 -0
  226. package/types/edsis-ui-drawer.d.ts +1 -0
  227. package/types/edsis-ui-dropdown-menu.d.ts +136 -0
  228. package/types/edsis-ui-editor.d.ts +123 -0
  229. package/types/edsis-ui-empty.d.ts +50 -0
  230. package/types/edsis-ui-form.d.ts +141 -0
  231. package/types/edsis-ui-hover-card.d.ts +74 -0
  232. package/types/edsis-ui-input-group.d.ts +51 -0
  233. package/types/edsis-ui-input-otp.d.ts +136 -0
  234. package/types/edsis-ui-input.d.ts +16 -0
  235. package/types/edsis-ui-item.d.ts +88 -0
  236. package/types/edsis-ui-kanban.d.ts +70 -0
  237. package/types/edsis-ui-kbd.d.ts +16 -0
  238. package/types/edsis-ui-label.d.ts +11 -0
  239. package/types/edsis-ui-menubar.d.ts +67 -0
  240. package/types/edsis-ui-native-select.d.ts +26 -0
  241. package/types/edsis-ui-navigation-menu.d.ts +96 -0
  242. package/types/edsis-ui-pagination.d.ts +34 -0
  243. package/types/edsis-ui-pillbox.d.ts +157 -0
  244. package/types/edsis-ui-popover.d.ts +43 -0
  245. package/types/edsis-ui-progress.d.ts +17 -0
  246. package/types/edsis-ui-radio.d.ts +40 -0
  247. package/types/edsis-ui-resizable.d.ts +99 -0
  248. package/types/edsis-ui-scroll-area.d.ts +19 -0
  249. package/types/edsis-ui-select.d.ts +57 -0
  250. package/types/edsis-ui-separator.d.ts +14 -0
  251. package/types/edsis-ui-sheet.d.ts +76 -0
  252. package/types/edsis-ui-skeleton.d.ts +10 -0
  253. package/types/edsis-ui-slider.d.ts +74 -0
  254. package/types/edsis-ui-spinner.d.ts +13 -0
  255. package/types/edsis-ui-switch.d.ts +40 -0
  256. package/types/edsis-ui-table.d.ts +52 -0
  257. package/types/edsis-ui-tabs.d.ts +92 -0
  258. package/types/edsis-ui-textarea.d.ts +12 -0
  259. package/types/edsis-ui-timeline.d.ts +63 -0
  260. package/types/edsis-ui-toast.d.ts +38 -0
  261. package/types/edsis-ui-toggle-group.d.ts +89 -0
  262. package/types/edsis-ui-toggle.d.ts +25 -0
  263. package/types/edsis-ui-tooltip.d.ts +89 -0
  264. package/types/edsis-ui-utils.d.ts +5 -0
  265. package/types/edsis-ui.d.ts +2 -0
@@ -0,0 +1,164 @@
1
+ # Resizable
2
+
3
+ Accessible resizable panel groups and layouts with pointer and keyboard support.
4
+
5
+ Use Resizable for split views, workspace layouts, drill-in dashboards, inspector panes, and settings screens where users should control how much space each pane receives.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { ResizableHandleComponent, ResizablePanelComponent, ResizablePanelGroupComponent } from '@edsis/ui/resizable';
11
+ ```
12
+
13
+ ## Composition
14
+
15
+ The Angular structure mirrors the shadcn composition while using Angular selectors and standalone imports.
16
+
17
+ ```text
18
+ ui-resizable-panel-group
19
+ ├── ui-resizable-panel
20
+ ├── ui-resizable-handle
21
+ └── ui-resizable-panel
22
+ ```
23
+
24
+ ## Basic usage
25
+
26
+ Use `ui-resizable-panel-group` as the root, place `ui-resizable-panel` elements around each separator, and insert `ui-resizable-handle` between adjacent panels.
27
+
28
+ ```html
29
+ <ui-resizable-panel-group orientation="horizontal" class="h-[200px] max-w-lg rounded-lg border border-border">
30
+ <ui-resizable-panel defaultSize="35%">
31
+ <div class="flex h-full items-center justify-center p-6">Navigation</div>
32
+ </ui-resizable-panel>
33
+
34
+ <ui-resizable-handle aria-label="Resize navigation"></ui-resizable-handle>
35
+
36
+ <ui-resizable-panel defaultSize="65%">
37
+ <div class="flex h-full items-center justify-center p-6">Content</div>
38
+ </ui-resizable-panel>
39
+ </ui-resizable-panel-group>
40
+ ```
41
+
42
+ ## Common patterns
43
+
44
+ ### Nested workspace layout
45
+
46
+ Nested groups work well for mail, support, or analytics layouts where a secondary area also needs its own split.
47
+
48
+ ```html
49
+ <ui-resizable-panel-group orientation="horizontal" class="h-[220px] rounded-lg border border-border">
50
+ <ui-resizable-panel defaultSize="50%">
51
+ <div class="flex h-full items-center justify-center p-6">Threads</div>
52
+ </ui-resizable-panel>
53
+
54
+ <ui-resizable-handle withHandle aria-label="Resize thread list"></ui-resizable-handle>
55
+
56
+ <ui-resizable-panel defaultSize="50%">
57
+ <ui-resizable-panel-group orientation="vertical" class="h-full">
58
+ <ui-resizable-panel defaultSize="28%">
59
+ <div class="flex h-full items-center justify-center p-6">Summary</div>
60
+ </ui-resizable-panel>
61
+ <ui-resizable-handle withHandle aria-label="Resize summary"></ui-resizable-handle>
62
+ <ui-resizable-panel defaultSize="72%">
63
+ <div class="flex h-full items-center justify-center p-6">Details</div>
64
+ </ui-resizable-panel>
65
+ </ui-resizable-panel-group>
66
+ </ui-resizable-panel>
67
+ </ui-resizable-panel-group>
68
+ ```
69
+
70
+ ### Vertical resizing
71
+
72
+ Use `orientation="vertical"` when panes stack top-to-bottom.
73
+
74
+ ```html
75
+ <ui-resizable-panel-group orientation="vertical" class="h-[220px] max-w-sm rounded-lg border border-border">
76
+ <ui-resizable-panel defaultSize="25%">...</ui-resizable-panel>
77
+ <ui-resizable-handle aria-label="Resize header"></ui-resizable-handle>
78
+ <ui-resizable-panel defaultSize="75%">...</ui-resizable-panel>
79
+ </ui-resizable-panel-group>
80
+ ```
81
+
82
+ ### Visible handle
83
+
84
+ Add `withHandle` when the splitter should show a grab affordance.
85
+
86
+ ```html
87
+ <ui-resizable-handle withHandle aria-label="Resize sidebar"></ui-resizable-handle>
88
+ ```
89
+
90
+ ### Size constraints
91
+
92
+ Use `minSize` and `maxSize` to keep navigation, preview, or inspector panes within useful bounds.
93
+
94
+ ```html
95
+ <ui-resizable-panel defaultSize="30%" minSize="20%" maxSize="40%">...</ui-resizable-panel>
96
+ ```
97
+
98
+ ### RTL
99
+
100
+ Set `dir="rtl"` on `ui-resizable-panel-group` or an ancestor when the layout should follow right-to-left direction. Pointer and arrow-key resizing adapt to the computed direction.
101
+
102
+ ```html
103
+ <ui-resizable-panel-group dir="rtl" orientation="horizontal" class="h-[200px] rounded-lg border border-border">
104
+ <ui-resizable-panel defaultSize="50%">...</ui-resizable-panel>
105
+ <ui-resizable-handle withHandle aria-label="تغيير حجم القائمة"></ui-resizable-handle>
106
+ <ui-resizable-panel defaultSize="50%">...</ui-resizable-panel>
107
+ </ui-resizable-panel-group>
108
+ ```
109
+
110
+ ## API reference
111
+
112
+ ### `ResizablePanelGroupComponent`
113
+
114
+ | Input | Type | Default |
115
+ | ------------- | ---------------------------- | -------------- |
116
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
117
+ | `class` | `string` | `''` |
118
+
119
+ ### `ResizablePanelComponent`
120
+
121
+ | Input | Type | Default |
122
+ | ------------- | -------------------------- | -------------- |
123
+ | `defaultSize` | `string \| number \| null` | `null` |
124
+ | `minSize` | `string \| number` | `'10%'` |
125
+ | `maxSize` | `string \| number` | `'90%'` |
126
+ | `id` | `string \| null` | auto-generated |
127
+ | `class` | `string` | `''` |
128
+
129
+ ### `ResizableHandleComponent`
130
+
131
+ | Input | Type | Default |
132
+ | ------------ | ---------------- | ---------------- |
133
+ | `withHandle` | `boolean` | `false` |
134
+ | `aria-label` | `string \| null` | `'Resize panel'` |
135
+ | `class` | `string` | `''` |
136
+
137
+ ## Styling and theming
138
+
139
+ Pass `class` to the group, panel, or handle to tune height, width, backgrounds, borders, and embedded layouts.
140
+
141
+ The primitives use the shared theme tokens, so utilities such as `border-border`, `bg-card`, `bg-muted/40`, `text-foreground`, and `focus-visible:ring-ring` work as expected.
142
+
143
+ ## Accessibility
144
+
145
+ - Each handle is a focusable `separator` with `aria-controls`, `aria-valuenow`, `aria-valuemin`, and `aria-valuemax`.
146
+ - Provide a clear `aria-label` for each handle when the surrounding pane label is not already obvious from context.
147
+ - Panels stay in normal page flow, which keeps nested forms and content accessible without extra portals or overlays.
148
+
149
+ ## Keyboard interactions
150
+
151
+ - Arrow keys resize the adjacent panes.
152
+ - `Home` moves the primary pane to its minimum allowed size.
153
+ - `End` moves the primary pane to its maximum allowed size.
154
+ - `Enter` collapses the primary pane to its minimum and restores the previous size on the next press.
155
+
156
+ ## Angular notes
157
+
158
+ - The API follows the shadcn `orientation` plus percent-size model, but does not require React or `react-resizable-panels`.
159
+ - `defaultSize`, `minSize`, and `maxSize` accept either percentage strings such as `'25%'` or numeric percentages such as `25`.
160
+ - Custom element hosts are explicitly block-level flex items so nested groups and dashboard panes size correctly inside Angular templates.
161
+
162
+ ## Source parity
163
+
164
+ This Angular implementation follows the shadcn Resizable composition and examples while translating them to standalone component imports, Angular selectors, and a signal-driven internal layout model.
@@ -0,0 +1,143 @@
1
+ # Scroll Area
2
+
3
+ Native scroll viewport with token-styled scrollbars for constrained lists,
4
+ horizontal galleries, and RTL content. It maps the shadcn Scroll Area pattern to
5
+ Angular while keeping scrolling browser-native.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import { ScrollAreaComponent } from '@edsis/ui/scroll-area';
11
+ ```
12
+
13
+ Import composed primitives separately when the content needs them:
14
+
15
+ ```ts
16
+ import { ScrollAreaComponent } from '@edsis/ui/scroll-area';
17
+ import { SeparatorComponent } from '@edsis/ui/separator';
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Give the host a stable height or width, then place padding on inner content when
23
+ the scrollbar should stay flush with the border.
24
+
25
+ ```html
26
+ <ui-scroll-area class="h-72 w-48 rounded-md border border-border" viewportAriaLabel="Release tags">
27
+ <div class="p-4">
28
+ <h4 class="mb-4 text-sm font-medium leading-none">Tags</h4>
29
+ @for (tag of tags; track tag) {
30
+ <div class="text-sm">{{ tag }}</div>
31
+ <ui-separator class="my-2" />
32
+ }
33
+ </div>
34
+ </ui-scroll-area>
35
+ ```
36
+
37
+ ## Common Patterns
38
+
39
+ ### Basic List
40
+
41
+ ```html
42
+ <ui-scroll-area class="h-64 w-56 rounded-md border border-border" viewportAriaLabel="Activity log">
43
+ <ol class="space-y-3 p-4 text-sm">
44
+ @for (event of events; track event.id) {
45
+ <li>{{ event.label }}</li>
46
+ }
47
+ </ol>
48
+ </ui-scroll-area>
49
+ ```
50
+
51
+ ### Horizontal Content
52
+
53
+ ```html
54
+ <ui-scroll-area class="w-full max-w-md rounded-md border border-border" viewportAriaLabel="Artwork gallery">
55
+ <div class="flex w-max gap-4 p-4">
56
+ @for (artwork of artworks; track artwork.id; let index = $index) {
57
+ <figure class="shrink-0">
58
+ <img
59
+ [ngSrc]="artwork.image"
60
+ [alt]="artwork.alt"
61
+ [priority]="index === 0"
62
+ width="300"
63
+ height="400"
64
+ class="aspect-3/4 h-64 w-48 rounded-md object-cover" />
65
+ <figcaption class="pt-2 text-xs text-muted-foreground">{{ artwork.caption }}</figcaption>
66
+ </figure>
67
+ }
68
+ </div>
69
+ </ui-scroll-area>
70
+ ```
71
+
72
+ ### RTL Content
73
+
74
+ ```html
75
+ <ui-scroll-area
76
+ dir="rtl"
77
+ lang="ar"
78
+ class="h-72 w-48 rounded-md border border-border text-right"
79
+ viewportAriaLabel="قائمة العلامات">
80
+ <div class="p-4">...</div>
81
+ </ui-scroll-area>
82
+ ```
83
+
84
+ ## API Reference
85
+
86
+ | Input | Type | Default | Description |
87
+ | ------------------- | ---------------- | ------- | --------------------------------------------------------------------------------------------- |
88
+ | `class` | `string` | `''` | Classes applied to the custom-element host. Use this for size, border, radius, and placement. |
89
+ | `viewportClass` | `string` | `''` | Classes merged onto the native scroll viewport for axis control, whitespace, or overflow. |
90
+ | `viewportAriaLabel` | `string \| null` | `null` | Adds an accessible label and exposes the viewport as a named region. |
91
+ | `viewportTabIndex` | `number` | `0` | Keeps the scroll viewport keyboard-focusable. Use `-1` only when focusable children suffice. |
92
+
93
+ ## Styling and Theming
94
+
95
+ The host is block-level, relatively positioned, and overflow-hidden. The inner
96
+ viewport uses native `overflow: auto`, `scrollbar-width: thin` for Firefox, and
97
+ WebKit scrollbar pseudo-elements for Chromium/Safari.
98
+
99
+ Tokens consumed:
100
+
101
+ - `--border` for the default scrollbar thumb.
102
+ - `--muted-foreground` for the hover thumb fallback.
103
+ - `--ring` for keyboard focus indication.
104
+
105
+ Pass `class` for host sizing and borders, and `viewportClass` when the viewport
106
+ itself needs adjustments such as `whitespace-nowrap`, custom padding, or axis
107
+ constraints.
108
+
109
+ ## Accessibility
110
+
111
+ The component keeps native wheel, touch, momentum, and keyboard scrolling. The
112
+ viewport is focusable by default with `tabindex="0"`, so keyboard users can
113
+ scroll overflowing content even when there are no focusable descendants.
114
+
115
+ Use `viewportAriaLabel` when the scrollable region needs a spoken name. When a
116
+ label is present, the viewport is exposed as `role="region"`. Keep long lists in
117
+ logical DOM order and avoid hiding important content behind custom-only pointer
118
+ controls.
119
+
120
+ ## Keyboard Interactions
121
+
122
+ When the viewport has focus, the browser handles scrolling keys:
123
+
124
+ - Arrow keys move in the matching direction.
125
+ - Page Up and Page Down scroll by a larger step.
126
+ - Home and End jump to the start or end where supported.
127
+ - Space follows the browser's scroll behavior for the focused region.
128
+
129
+ ## Angular Notes
130
+
131
+ `ScrollAreaComponent` is standalone and has no provider setup. Use Angular
132
+ `@for` with stable track expressions for long content. For static artwork inside
133
+ horizontal scroll examples, import `NgOptimizedImage` and use `ngSrc`.
134
+
135
+ The component intentionally does not add a child `ScrollBar` directive. Native
136
+ scrollbars are styled by CSS and remain visible only when the content overflows.
137
+
138
+ ## Source Parity
139
+
140
+ The shadcn Scroll Area docs show `ScrollArea` plus a `ScrollBar` part. This
141
+ Angular implementation preserves the same usage goals, examples, RTL guidance,
142
+ and themed scrollbar appearance while mapping `ScrollBar` to browser-native
143
+ scrollbars instead of a separate decorative child component.
@@ -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 '@your-scope/angular/component/select';
10
+ ```
11
+
12
+ ## Composition
13
+
14
+ `ui-select` owns the trigger, overlay, disabled state, and common ARIA passthrough.
15
+ Project `ui-option` children into it for the actual choices.
16
+
17
+ For grouped menus, the current Angular mapping uses `MatOptgroup` from
18
+ `@angular/material/core` inside `ui-select` rather than publishing separate
19
+ `SelectGroup`, `SelectLabel`, or `SelectSeparator` wrappers.
20
+
21
+ ```text
22
+ ui-select
23
+ ├── ui-option
24
+ ├── ui-option
25
+ └── mat-optgroup (optional grouping bridge)
26
+ ├── ui-option
27
+ └── ui-option
28
+ ```
29
+
30
+ ## Basic Usage
31
+
32
+ ```html
33
+ <ui-select class="block w-full max-w-xs" placeholder="Select a plan" [(ngModel)]="plan" aria-label="Plan">
34
+ <ui-option value="free">Free</ui-option>
35
+ <ui-option value="pro">Pro</ui-option>
36
+ <ui-option value="enterprise">Enterprise</ui-option>
37
+ </ui-select>
38
+ ```
39
+
40
+ ## Common Patterns
41
+
42
+ ### Grouped options
43
+
44
+ ```ts
45
+ import { MatOptgroup } from '@angular/material/core';
46
+ ```
47
+
48
+ ```html
49
+ <ui-select class="block w-full max-w-sm" placeholder="Select produce" [(ngModel)]="produce" aria-label="Produce">
50
+ <mat-optgroup label="Fruits">
51
+ <ui-option value="apple">Apple</ui-option>
52
+ <ui-option value="banana">Banana</ui-option>
53
+ <ui-option value="blueberry">Blueberry</ui-option>
54
+ </mat-optgroup>
55
+
56
+ <mat-optgroup label="Vegetables">
57
+ <ui-option value="carrot">Carrot</ui-option>
58
+ <ui-option value="broccoli">Broccoli</ui-option>
59
+ <ui-option value="spinach">Spinach</ui-option>
60
+ </mat-optgroup>
61
+ </ui-select>
62
+ ```
63
+
64
+ ### Disabled trigger
65
+
66
+ ```html
67
+ <ui-select placeholder="Disabled" disabled aria-label="Disabled plan">
68
+ <ui-option value="free">Free</ui-option>
69
+ <ui-option value="pro">Pro</ui-option>
70
+ <ui-option value="enterprise">Enterprise</ui-option>
71
+ </ui-select>
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
+ <ui-select class="block w-full max-w-md" placeholder="Select a timezone" [(ngModel)]="timezone" aria-label="Timezone">
81
+ <mat-optgroup label="North America">
82
+ <ui-option value="est">Eastern Standard Time</ui-option>
83
+ <ui-option value="cst">Central Standard Time</ui-option>
84
+ <ui-option value="mst">Mountain Standard Time</ui-option>
85
+ <ui-option value="pst">Pacific Standard Time</ui-option>
86
+ </mat-optgroup>
87
+
88
+ <mat-optgroup label="Europe & Africa">
89
+ <ui-option value="gmt">Greenwich Mean Time</ui-option>
90
+ <ui-option value="cet">Central European Time</ui-option>
91
+ <ui-option value="eet">Eastern European Time</ui-option>
92
+ </mat-optgroup>
93
+ </ui-select>
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
+ <ui-select
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
+ <ui-option value="engineering">Engineering</ui-option>
110
+ <ui-option value="sales">Sales</ui-option>
111
+ <ui-option value="operations">Operations</ui-option>
112
+ </ui-select>
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
+ <ui-select multiple [(ngModel)]="interests" aria-label="Interests">
121
+ @for (i of all; track i) {
122
+ <ui-option [value]="i">{{ i }}</ui-option>
123
+ }
124
+ </ui-select>
125
+ ```
126
+
127
+ ## API Reference
128
+
129
+ | Primitive | Selector | Inputs | Outputs |
130
+ | --------------------- | -------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------- |
131
+ | `SelectComponent` | `ui-select` | `placeholder`, `disabled`, `multiple`, `required`, `aria-label`, `aria-labelledby`, `aria-describedby`, `class` | `valueChange`, `openedChange` |
132
+ | `OptionComponent` | `ui-option` | `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="ui-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
+ - `ui-select` 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[ui-native-select]` 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 `ui-select` and `ui-option` 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 '@edsis/ui/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
+ <ui-separator class="my-4" /> <ui-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
+ <ui-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
+ <ui-separator orientation="vertical" class="h-5" />
53
+ <div>Docs</div>
54
+ <ui-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
+ <ui-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
+ <ui-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
+ <ui-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
+ <ui-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
+ <ui-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 `ui-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.