@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.
- package/README.md +40 -0
- package/accordion/README.md +195 -0
- package/alert/README.md +177 -0
- package/alert-dialog/README.md +239 -0
- package/aspect-ratio/README.md +112 -0
- package/avatar/README.md +176 -0
- package/badge/README.md +133 -0
- package/breadcrumb/README.md +216 -0
- package/button/README.md +139 -0
- package/button-group/README.md +204 -0
- package/calendar/README.md +132 -0
- package/card/README.md +220 -0
- package/carousel/README.md +276 -0
- package/chart/README.md +249 -0
- package/checkbox/README.md +149 -0
- package/collapsible/README.md +191 -0
- package/combobox/README.md +198 -0
- package/command/README.md +275 -0
- package/composer/README.md +235 -0
- package/context-menu/README.md +267 -0
- package/date-picker/README.md +177 -0
- package/dialog/README.md +237 -0
- package/drawer/README.md +145 -0
- package/dropdown-menu/README.md +311 -0
- package/editor/README.md +136 -0
- package/empty/README.md +183 -0
- package/fesm2022/edsis-ui-accordion.mjs +174 -0
- package/fesm2022/edsis-ui-accordion.mjs.map +1 -0
- package/fesm2022/edsis-ui-alert-dialog.mjs +242 -0
- package/fesm2022/edsis-ui-alert-dialog.mjs.map +1 -0
- package/fesm2022/edsis-ui-alert.mjs +90 -0
- package/fesm2022/edsis-ui-alert.mjs.map +1 -0
- package/fesm2022/edsis-ui-aspect-ratio.mjs +33 -0
- package/fesm2022/edsis-ui-aspect-ratio.mjs.map +1 -0
- package/fesm2022/edsis-ui-avatar.mjs +123 -0
- package/fesm2022/edsis-ui-avatar.mjs.map +1 -0
- package/fesm2022/edsis-ui-badge.mjs +47 -0
- package/fesm2022/edsis-ui-badge.mjs.map +1 -0
- package/fesm2022/edsis-ui-breadcrumb.mjs +186 -0
- package/fesm2022/edsis-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/edsis-ui-button-group.mjs +95 -0
- package/fesm2022/edsis-ui-button-group.mjs.map +1 -0
- package/fesm2022/edsis-ui-button.mjs +64 -0
- package/fesm2022/edsis-ui-button.mjs.map +1 -0
- package/fesm2022/edsis-ui-calendar.mjs +78 -0
- package/fesm2022/edsis-ui-calendar.mjs.map +1 -0
- package/fesm2022/edsis-ui-card.mjs +137 -0
- package/fesm2022/edsis-ui-card.mjs.map +1 -0
- package/fesm2022/edsis-ui-carousel.mjs +310 -0
- package/fesm2022/edsis-ui-carousel.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-area.mjs +6 -0
- package/fesm2022/edsis-ui-chart-area.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-bar.mjs +6 -0
- package/fesm2022/edsis-ui-chart-bar.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-line.mjs +6 -0
- package/fesm2022/edsis-ui-chart-line.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-pie.mjs +6 -0
- package/fesm2022/edsis-ui-chart-pie.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-radar.mjs +6 -0
- package/fesm2022/edsis-ui-chart-radar.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-radial.mjs +6 -0
- package/fesm2022/edsis-ui-chart-radial.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart-scatter.mjs +6 -0
- package/fesm2022/edsis-ui-chart-scatter.mjs.map +1 -0
- package/fesm2022/edsis-ui-chart.mjs +3714 -0
- package/fesm2022/edsis-ui-chart.mjs.map +1 -0
- package/fesm2022/edsis-ui-checkbox.mjs +104 -0
- package/fesm2022/edsis-ui-checkbox.mjs.map +1 -0
- package/fesm2022/edsis-ui-collapsible.mjs +116 -0
- package/fesm2022/edsis-ui-collapsible.mjs.map +1 -0
- package/fesm2022/edsis-ui-combobox.mjs +263 -0
- package/fesm2022/edsis-ui-combobox.mjs.map +1 -0
- package/fesm2022/edsis-ui-command.mjs +268 -0
- package/fesm2022/edsis-ui-command.mjs.map +1 -0
- package/fesm2022/edsis-ui-composer.mjs +329 -0
- package/fesm2022/edsis-ui-composer.mjs.map +1 -0
- package/fesm2022/edsis-ui-context-menu.mjs +100 -0
- package/fesm2022/edsis-ui-context-menu.mjs.map +1 -0
- package/fesm2022/edsis-ui-date-picker.mjs +155 -0
- package/fesm2022/edsis-ui-date-picker.mjs.map +1 -0
- package/fesm2022/edsis-ui-dialog.mjs +262 -0
- package/fesm2022/edsis-ui-dialog.mjs.map +1 -0
- package/fesm2022/edsis-ui-drawer.mjs +6 -0
- package/fesm2022/edsis-ui-drawer.mjs.map +1 -0
- package/fesm2022/edsis-ui-dropdown-menu.mjs +466 -0
- package/fesm2022/edsis-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/edsis-ui-editor.mjs +692 -0
- package/fesm2022/edsis-ui-editor.mjs.map +1 -0
- package/fesm2022/edsis-ui-empty.mjs +132 -0
- package/fesm2022/edsis-ui-empty.mjs.map +1 -0
- package/fesm2022/edsis-ui-form.mjs +334 -0
- package/fesm2022/edsis-ui-form.mjs.map +1 -0
- package/fesm2022/edsis-ui-hover-card.mjs +284 -0
- package/fesm2022/edsis-ui-hover-card.mjs.map +1 -0
- package/fesm2022/edsis-ui-input-group.mjs +164 -0
- package/fesm2022/edsis-ui-input-group.mjs.map +1 -0
- package/fesm2022/edsis-ui-input-otp.mjs +485 -0
- package/fesm2022/edsis-ui-input-otp.mjs.map +1 -0
- package/fesm2022/edsis-ui-input.mjs +43 -0
- package/fesm2022/edsis-ui-input.mjs.map +1 -0
- package/fesm2022/edsis-ui-item.mjs +241 -0
- package/fesm2022/edsis-ui-item.mjs.map +1 -0
- package/fesm2022/edsis-ui-kanban.mjs +289 -0
- package/fesm2022/edsis-ui-kanban.mjs.map +1 -0
- package/fesm2022/edsis-ui-kbd.mjs +51 -0
- package/fesm2022/edsis-ui-kbd.mjs.map +1 -0
- package/fesm2022/edsis-ui-label.mjs +30 -0
- package/fesm2022/edsis-ui-label.mjs.map +1 -0
- package/fesm2022/edsis-ui-menubar.mjs +302 -0
- package/fesm2022/edsis-ui-menubar.mjs.map +1 -0
- package/fesm2022/edsis-ui-native-select.mjs +61 -0
- package/fesm2022/edsis-ui-native-select.mjs.map +1 -0
- package/fesm2022/edsis-ui-navigation-menu.mjs +399 -0
- package/fesm2022/edsis-ui-navigation-menu.mjs.map +1 -0
- package/fesm2022/edsis-ui-pagination.mjs +216 -0
- package/fesm2022/edsis-ui-pagination.mjs.map +1 -0
- package/fesm2022/edsis-ui-pillbox.mjs +777 -0
- package/fesm2022/edsis-ui-pillbox.mjs.map +1 -0
- package/fesm2022/edsis-ui-popover.mjs +163 -0
- package/fesm2022/edsis-ui-popover.mjs.map +1 -0
- package/fesm2022/edsis-ui-progress.mjs +53 -0
- package/fesm2022/edsis-ui-progress.mjs.map +1 -0
- package/fesm2022/edsis-ui-radio.mjs +111 -0
- package/fesm2022/edsis-ui-radio.mjs.map +1 -0
- package/fesm2022/edsis-ui-resizable.mjs +454 -0
- package/fesm2022/edsis-ui-resizable.mjs.map +1 -0
- package/fesm2022/edsis-ui-scroll-area.mjs +48 -0
- package/fesm2022/edsis-ui-scroll-area.mjs.map +1 -0
- package/fesm2022/edsis-ui-select.mjs +164 -0
- package/fesm2022/edsis-ui-select.mjs.map +1 -0
- package/fesm2022/edsis-ui-separator.mjs +33 -0
- package/fesm2022/edsis-ui-separator.mjs.map +1 -0
- package/fesm2022/edsis-ui-sheet.mjs +264 -0
- package/fesm2022/edsis-ui-sheet.mjs.map +1 -0
- package/fesm2022/edsis-ui-skeleton.mjs +29 -0
- package/fesm2022/edsis-ui-skeleton.mjs.map +1 -0
- package/fesm2022/edsis-ui-slider.mjs +405 -0
- package/fesm2022/edsis-ui-slider.mjs.map +1 -0
- package/fesm2022/edsis-ui-spinner.mjs +58 -0
- package/fesm2022/edsis-ui-spinner.mjs.map +1 -0
- package/fesm2022/edsis-ui-switch.mjs +107 -0
- package/fesm2022/edsis-ui-switch.mjs.map +1 -0
- package/fesm2022/edsis-ui-table.mjs +139 -0
- package/fesm2022/edsis-ui-table.mjs.map +1 -0
- package/fesm2022/edsis-ui-tabs.mjs +252 -0
- package/fesm2022/edsis-ui-tabs.mjs.map +1 -0
- package/fesm2022/edsis-ui-textarea.mjs +37 -0
- package/fesm2022/edsis-ui-textarea.mjs.map +1 -0
- package/fesm2022/edsis-ui-timeline.mjs +213 -0
- package/fesm2022/edsis-ui-timeline.mjs.map +1 -0
- package/fesm2022/edsis-ui-toast.mjs +71 -0
- package/fesm2022/edsis-ui-toast.mjs.map +1 -0
- package/fesm2022/edsis-ui-toggle-group.mjs +269 -0
- package/fesm2022/edsis-ui-toggle-group.mjs.map +1 -0
- package/fesm2022/edsis-ui-toggle.mjs +76 -0
- package/fesm2022/edsis-ui-toggle.mjs.map +1 -0
- package/fesm2022/edsis-ui-tooltip.mjs +339 -0
- package/fesm2022/edsis-ui-tooltip.mjs.map +1 -0
- package/fesm2022/edsis-ui-utils.mjs +13 -0
- package/fesm2022/edsis-ui-utils.mjs.map +1 -0
- package/fesm2022/edsis-ui.mjs +11 -0
- package/fesm2022/edsis-ui.mjs.map +1 -0
- package/form/README.md +210 -0
- package/hover-card/README.md +146 -0
- package/input/README.md +159 -0
- package/input-group/README.md +234 -0
- package/input-otp/README.md +273 -0
- package/item/README.md +247 -0
- package/kanban/README.md +81 -0
- package/kbd/README.md +139 -0
- package/label/README.md +136 -0
- package/menubar/README.md +269 -0
- package/native-select/README.md +176 -0
- package/navigation-menu/README.md +160 -0
- package/package.json +310 -0
- package/pagination/README.md +144 -0
- package/pillbox/README.md +67 -0
- package/popover/README.md +43 -0
- package/progress/README.md +160 -0
- package/radio/README.md +209 -0
- package/resizable/README.md +164 -0
- package/scroll-area/README.md +143 -0
- package/select/README.md +174 -0
- package/separator/README.md +170 -0
- package/sheet/README.md +183 -0
- package/skeleton/README.md +158 -0
- package/slider/README.md +207 -0
- package/spinner/README.md +160 -0
- package/switch/README.md +166 -0
- package/table/README.md +291 -0
- package/tabs/README.md +214 -0
- package/textarea/README.md +154 -0
- package/timeline/README.md +94 -0
- package/toast/README.md +321 -0
- package/toggle/README.md +131 -0
- package/toggle-group/README.md +206 -0
- package/tooltip/README.md +211 -0
- package/types/edsis-ui-accordion.d.ts +51 -0
- package/types/edsis-ui-alert-dialog.d.ts +93 -0
- package/types/edsis-ui-alert.d.ts +37 -0
- package/types/edsis-ui-aspect-ratio.d.ts +12 -0
- package/types/edsis-ui-avatar.d.ts +51 -0
- package/types/edsis-ui-badge.d.ts +19 -0
- package/types/edsis-ui-breadcrumb.d.ts +46 -0
- package/types/edsis-ui-button-group.d.ts +26 -0
- package/types/edsis-ui-button.d.ts +22 -0
- package/types/edsis-ui-calendar.d.ts +33 -0
- package/types/edsis-ui-card.d.ts +60 -0
- package/types/edsis-ui-carousel.d.ts +86 -0
- package/types/edsis-ui-chart-area.d.ts +1 -0
- package/types/edsis-ui-chart-bar.d.ts +1 -0
- package/types/edsis-ui-chart-line.d.ts +1 -0
- package/types/edsis-ui-chart-pie.d.ts +1 -0
- package/types/edsis-ui-chart-radar.d.ts +1 -0
- package/types/edsis-ui-chart-radial.d.ts +1 -0
- package/types/edsis-ui-chart-scatter.d.ts +1 -0
- package/types/edsis-ui-chart.d.ts +1094 -0
- package/types/edsis-ui-checkbox.d.ts +35 -0
- package/types/edsis-ui-collapsible.d.ts +42 -0
- package/types/edsis-ui-combobox.d.ts +51 -0
- package/types/edsis-ui-command.d.ts +99 -0
- package/types/edsis-ui-composer.d.ts +90 -0
- package/types/edsis-ui-context-menu.d.ts +35 -0
- package/types/edsis-ui-date-picker.d.ts +41 -0
- package/types/edsis-ui-dialog.d.ts +87 -0
- package/types/edsis-ui-drawer.d.ts +1 -0
- package/types/edsis-ui-dropdown-menu.d.ts +136 -0
- package/types/edsis-ui-editor.d.ts +123 -0
- package/types/edsis-ui-empty.d.ts +50 -0
- package/types/edsis-ui-form.d.ts +141 -0
- package/types/edsis-ui-hover-card.d.ts +74 -0
- package/types/edsis-ui-input-group.d.ts +51 -0
- package/types/edsis-ui-input-otp.d.ts +136 -0
- package/types/edsis-ui-input.d.ts +16 -0
- package/types/edsis-ui-item.d.ts +88 -0
- package/types/edsis-ui-kanban.d.ts +70 -0
- package/types/edsis-ui-kbd.d.ts +16 -0
- package/types/edsis-ui-label.d.ts +11 -0
- package/types/edsis-ui-menubar.d.ts +67 -0
- package/types/edsis-ui-native-select.d.ts +26 -0
- package/types/edsis-ui-navigation-menu.d.ts +96 -0
- package/types/edsis-ui-pagination.d.ts +34 -0
- package/types/edsis-ui-pillbox.d.ts +157 -0
- package/types/edsis-ui-popover.d.ts +43 -0
- package/types/edsis-ui-progress.d.ts +17 -0
- package/types/edsis-ui-radio.d.ts +40 -0
- package/types/edsis-ui-resizable.d.ts +99 -0
- package/types/edsis-ui-scroll-area.d.ts +19 -0
- package/types/edsis-ui-select.d.ts +57 -0
- package/types/edsis-ui-separator.d.ts +14 -0
- package/types/edsis-ui-sheet.d.ts +76 -0
- package/types/edsis-ui-skeleton.d.ts +10 -0
- package/types/edsis-ui-slider.d.ts +74 -0
- package/types/edsis-ui-spinner.d.ts +13 -0
- package/types/edsis-ui-switch.d.ts +40 -0
- package/types/edsis-ui-table.d.ts +52 -0
- package/types/edsis-ui-tabs.d.ts +92 -0
- package/types/edsis-ui-textarea.d.ts +12 -0
- package/types/edsis-ui-timeline.d.ts +63 -0
- package/types/edsis-ui-toast.d.ts +38 -0
- package/types/edsis-ui-toggle-group.d.ts +89 -0
- package/types/edsis-ui-toggle.d.ts +25 -0
- package/types/edsis-ui-tooltip.d.ts +89 -0
- package/types/edsis-ui-utils.d.ts +5 -0
- 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.
|
package/select/README.md
ADDED
|
@@ -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 & 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 & 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.
|