@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
package/chart/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Chart
|
|
2
|
+
|
|
3
|
+
Angular chart primitives and chart families inspired by shadcn Chart.
|
|
4
|
+
|
|
5
|
+
In this repository, shadcn's single Chart page maps to the dedicated `/ui/chart/*` demo route group so each chart family can keep focused, production-like examples without forcing everything into one `/ui/shadcn/chart` page.
|
|
6
|
+
|
|
7
|
+
Use Chart for dashboards, KPI cards, trend comparisons, radial summaries, and interactive data views where one shared config should drive labels, colors, legends, and tooltip copy.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add @edsis/ui
|
|
13
|
+
npm install @edsis/ui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Import
|
|
17
|
+
|
|
18
|
+
Import shared primitives from the chart root entrypoint, then import the concrete chart family from its granular subpath.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import {
|
|
22
|
+
ChartAxisX,
|
|
23
|
+
ChartAxisY,
|
|
24
|
+
ChartContainer,
|
|
25
|
+
ChartGrid,
|
|
26
|
+
ChartLegend,
|
|
27
|
+
ChartTooltip,
|
|
28
|
+
type ChartConfig,
|
|
29
|
+
} from '@edsis/ui/chart';
|
|
30
|
+
import { BarChart } from '@edsis/ui/chart/bar';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Supported chart entrypoints
|
|
34
|
+
|
|
35
|
+
| Import path | Selector | Best for |
|
|
36
|
+
| ------------------------- | ------------------ | ----------------------------------------------------------------- |
|
|
37
|
+
| `@edsis/ui/chart/bar` | `ui-bar-chart` | grouped, stacked, horizontal, active, and mixed-color bar layouts |
|
|
38
|
+
| `@edsis/ui/chart/line` | `ui-line-chart` | trends, comparisons, and zoomable time-series lines |
|
|
39
|
+
| `@edsis/ui/chart/area` | `ui-area-chart` | filled trend bands, stacked areas, and expanded percent views |
|
|
40
|
+
| `@edsis/ui/chart/pie` | `ui-pie-chart` | part-to-whole slices and donut charts |
|
|
41
|
+
| `@edsis/ui/chart/radar` | `ui-radar-chart` | multi-axis performance comparisons |
|
|
42
|
+
| `@edsis/ui/chart/radial` | `ui-radial-chart` | progress rings, radial comparisons, and center-metric summaries |
|
|
43
|
+
| `@edsis/ui/chart/scatter` | `ui-scatter-chart` | XY correlation plots and point clouds |
|
|
44
|
+
|
|
45
|
+
## Composition
|
|
46
|
+
|
|
47
|
+
The Angular structure keeps the same high-level idea as shadcn Chart: define a shared chart config once, then compose a specific chart type with optional grid, axis, tooltip, legend, and center content.
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
ui-chart-container
|
|
51
|
+
├── ui-bar-chart | ui-line-chart | ui-area-chart | ui-scatter-chart
|
|
52
|
+
│ ├── svg:g[ui-chart-grid]
|
|
53
|
+
│ ├── svg:g[ui-chart-axis-x]
|
|
54
|
+
│ ├── svg:g[ui-chart-axis-y]
|
|
55
|
+
│ └── svg:g[ui-chart-crosshair] / svg:g[ui-chart-brush] (optional)
|
|
56
|
+
├── ui-pie-chart | ui-radial-chart | ui-radar-chart
|
|
57
|
+
│ └── ui-pie-center | ui-radial-center (optional)
|
|
58
|
+
├── ui-chart-tooltip
|
|
59
|
+
├── ui-chart-legend
|
|
60
|
+
└── ui-chart-zoom-controls (optional)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
All child primitives read dimensions, series metadata, and scoped color tokens from `ui-chart-container`.
|
|
64
|
+
|
|
65
|
+
## Basic usage
|
|
66
|
+
|
|
67
|
+
Start with a readonly `ChartConfig`, keep the dataset in any shape that makes sense for your feature, and map the chart to the relevant keys.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const trafficChartConfig = {
|
|
71
|
+
desktop: { label: 'Desktop', color: 'var(--chart-1)' },
|
|
72
|
+
mobile: { label: 'Mobile', color: 'var(--chart-2)' },
|
|
73
|
+
} satisfies ChartConfig;
|
|
74
|
+
|
|
75
|
+
const trafficData = [
|
|
76
|
+
{ month: 'January', desktop: 186, mobile: 80 },
|
|
77
|
+
{ month: 'February', desktop: 305, mobile: 200 },
|
|
78
|
+
{ month: 'March', desktop: 237, mobile: 120 },
|
|
79
|
+
{ month: 'April', desktop: 73, mobile: 190 },
|
|
80
|
+
{ month: 'May', desktop: 209, mobile: 130 },
|
|
81
|
+
{ month: 'June', desktop: 214, mobile: 140 },
|
|
82
|
+
];
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<div class="w-full max-w-3xl">
|
|
87
|
+
<ui-chart-container [config]="trafficChartConfig" chartId="traffic-overview">
|
|
88
|
+
<ui-bar-chart [data]="trafficData" xKey="month">
|
|
89
|
+
<svg:g ui-chart-grid></svg:g>
|
|
90
|
+
<svg:g ui-chart-axis-x></svg:g>
|
|
91
|
+
<svg:g ui-chart-axis-y></svg:g>
|
|
92
|
+
</ui-bar-chart>
|
|
93
|
+
<ui-chart-tooltip [data]="trafficData" xKey="month" />
|
|
94
|
+
<ui-chart-legend />
|
|
95
|
+
</ui-chart-container>
|
|
96
|
+
</div>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Common patterns
|
|
100
|
+
|
|
101
|
+
### First chart flow
|
|
102
|
+
|
|
103
|
+
The closest Angular equivalent to the upstream shadcn walkthrough is:
|
|
104
|
+
|
|
105
|
+
1. Define your dataset.
|
|
106
|
+
2. Define `ChartConfig` so labels and colors stay decoupled from the raw data.
|
|
107
|
+
3. Wrap the chart in `ui-chart-container`.
|
|
108
|
+
4. Add `svg:g[ui-chart-grid]`, axis directives, `ui-chart-tooltip`, and `ui-chart-legend` only where they add value.
|
|
109
|
+
|
|
110
|
+
This keeps the chart family focused while still letting the shared primitives manage the common UI pieces.
|
|
111
|
+
|
|
112
|
+
### Swapping chart families
|
|
113
|
+
|
|
114
|
+
The same `ChartConfig` can back multiple chart families. In most cases you only swap the concrete chart import and the family-specific inputs.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { AreaChart } from '@edsis/ui/chart/area';
|
|
118
|
+
import { LineChart } from '@edsis/ui/chart/line';
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- `ui-line-chart` adds inputs such as `curve`, `showDots`, and `showValueLabels`.
|
|
122
|
+
- `ui-area-chart` adds `stacked`, `expanded`, `gradient`, and `curve`.
|
|
123
|
+
- `ui-bar-chart` adds `orientation`, `variant`, `colorKey`, `activeKey`, and `activeValue`.
|
|
124
|
+
|
|
125
|
+
### Pie and radial summaries
|
|
126
|
+
|
|
127
|
+
For donut, pie, and radial progress layouts, use `nameKey` plus `valueKey` instead of `xKey`.
|
|
128
|
+
|
|
129
|
+
```html
|
|
130
|
+
<ui-chart-container [config]="browserConfig" aspect="aspect-square">
|
|
131
|
+
<ui-pie-chart
|
|
132
|
+
[data]="browserData"
|
|
133
|
+
nameKey="browser"
|
|
134
|
+
valueKey="visitors"
|
|
135
|
+
[seriesKeys]="browserSeriesKeys"
|
|
136
|
+
[innerRadius]="64">
|
|
137
|
+
</ui-pie-chart>
|
|
138
|
+
<ui-chart-tooltip [data]="browserData" xKey="browser" valueKey="visitors" indicator="dot" />
|
|
139
|
+
<ui-chart-legend />
|
|
140
|
+
</ui-chart-container>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Tooltip formatting
|
|
144
|
+
|
|
145
|
+
`ui-chart-tooltip` is where most presentational customization lives.
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<ui-chart-tooltip
|
|
149
|
+
[data]="activityData"
|
|
150
|
+
xKey="date"
|
|
151
|
+
indicator="line"
|
|
152
|
+
labelKey="views"
|
|
153
|
+
[labelFormatter]="longDateFormatter"
|
|
154
|
+
[formatter]="compactNumberFormatter" />
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Use `valueKey` for single-value radial and pie datasets, `hideLabel` when the card already provides the label context, and `indicator="none"` when you want a copy-first tooltip layout.
|
|
158
|
+
|
|
159
|
+
### Per-row colors and active emphasis
|
|
160
|
+
|
|
161
|
+
Use `colorKey` when the dataset itself carries a color token such as `fill`, and use `activeKey` plus `activeValue` when one category should be visually emphasized without rewriting the whole series config.
|
|
162
|
+
|
|
163
|
+
## API reference
|
|
164
|
+
|
|
165
|
+
### `ChartContainer`
|
|
166
|
+
|
|
167
|
+
| Input | Type | Default |
|
|
168
|
+
| --------- | ---------------- | ---------------- |
|
|
169
|
+
| `config` | `ChartConfig` | — |
|
|
170
|
+
| `aspect` | `string` | `'aspect-video'` |
|
|
171
|
+
| `chartId` | `string \| null` | auto-generated |
|
|
172
|
+
|
|
173
|
+
`ChartConfig` is a readonly record of series keys to labels, icons, colors, or theme-aware light/dark color maps.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
type ChartConfig = Readonly<
|
|
177
|
+
Record<
|
|
178
|
+
string,
|
|
179
|
+
{
|
|
180
|
+
label?: string;
|
|
181
|
+
icon?: Type<unknown>;
|
|
182
|
+
color?: string;
|
|
183
|
+
theme?: Readonly<Record<'light' | 'dark', string>>;
|
|
184
|
+
}
|
|
185
|
+
>
|
|
186
|
+
>;
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Shared primitives
|
|
190
|
+
|
|
191
|
+
| Part | Key inputs | Notes |
|
|
192
|
+
| ------------------------ | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
193
|
+
| `svg:g[ui-chart-grid]` | none | Adds cartesian grid lines behind bar, line, and area charts. |
|
|
194
|
+
| `svg:g[ui-chart-axis-x]` | `tickCount`, `tickLine`, `tickFormat` | Categorical axis for cartesian layouts. |
|
|
195
|
+
| `svg:g[ui-chart-axis-y]` | `tickCount`, `tickLine`, `tickFormat` | Numeric axis for cartesian layouts. |
|
|
196
|
+
| `ui-chart-tooltip` | `data`, `xKey`, `valueKey`, `indicator`, `label`, `labelKey`, `labelFormatter`, `formatter`, `hideLabel` | Handles default tooltip layout plus custom template projection. |
|
|
197
|
+
| `ui-chart-legend` | none | Renders toggle buttons for visible series. |
|
|
198
|
+
| `ui-chart-zoom-controls` | none | Pair with zoomable line and scatter views. |
|
|
199
|
+
| `ui-pie-center` | projected content | Centers labels or KPIs inside pie layouts. |
|
|
200
|
+
| `ui-radial-center` | projected content | Centers labels or KPIs inside radial layouts. |
|
|
201
|
+
|
|
202
|
+
### Chart families
|
|
203
|
+
|
|
204
|
+
| Selector | Key inputs |
|
|
205
|
+
| ------------------ | --------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| `ui-bar-chart` | `data`, `xKey`, `orientation`, `variant`, `colorKey`, `activeKey`, `activeValue`, `showValueLabels` |
|
|
207
|
+
| `ui-line-chart` | `data`, `xKey`, `curve`, `showDots`, `dotRadius`, `showValueLabels` |
|
|
208
|
+
| `ui-area-chart` | `data`, `xKey`, `stacked`, `expanded`, `gradient`, `curve` |
|
|
209
|
+
| `ui-pie-chart` | `data`, `nameKey`, `valueKey`, `seriesKeys`, `innerRadius`, `activeIndex`, `activeOffset` |
|
|
210
|
+
| `ui-radar-chart` | `data`, `axisKey`, `curve`, `levels`, `grid`, `showLabels`, `showDots` |
|
|
211
|
+
| `ui-radial-chart` | `data`, `nameKey`, `valueKey`, `seriesKeys`, `maxValue`, `showTrack`, `showValueLabels` |
|
|
212
|
+
| `ui-scatter-chart` | `data`, `xKey`, `yKey`, `sizeKey`, `seriesKey`, `xDomain`, `yDomain` |
|
|
213
|
+
|
|
214
|
+
## Styling and theming
|
|
215
|
+
|
|
216
|
+
- Prefer CSS variables such as `var(--chart-1)` and `var(--chart-2)` in `ChartConfig`. This matches the current shadcn guidance and the theme tokens shipped by this library.
|
|
217
|
+
- `ui-chart-container` scopes generated `--color-<series>` variables to the chart instance, so tooltip rows, legends, and series shapes stay aligned.
|
|
218
|
+
- Use `theme: { light, dark }` on a series config entry when the chart needs different values per color scheme.
|
|
219
|
+
- Keep the parent container responsible for width, and use the `aspect` input when the default `aspect-video` does not match the layout.
|
|
220
|
+
- Use `colorKey` only when the dataset should override per-series colors with a row-specific token such as `fill`.
|
|
221
|
+
|
|
222
|
+
## Accessibility
|
|
223
|
+
|
|
224
|
+
- Chart hosts expose an `aria-label` summary describing the chart type, category count, and visible series.
|
|
225
|
+
- Interactive marks such as bars, dots, and slices are keyboard focusable where the layout supports activation.
|
|
226
|
+
- `ui-chart-tooltip` includes a polite live region so changing categories can be announced to assistive technology.
|
|
227
|
+
- `ui-chart-legend` uses native buttons with `aria-pressed` to reflect hidden and visible series state.
|
|
228
|
+
- Keep surrounding card copy descriptive so the chart has enough context when read outside its visual layout.
|
|
229
|
+
|
|
230
|
+
## Keyboard interactions
|
|
231
|
+
|
|
232
|
+
- `Tab` reaches interactive bars, dots, slices, and legend toggle buttons.
|
|
233
|
+
- `Enter` and `Space` trigger the same click behavior as pointer activation on interactive marks.
|
|
234
|
+
- Focusing a supported data mark updates the shared active point so tooltip content stays reachable without hover.
|
|
235
|
+
|
|
236
|
+
## Angular notes
|
|
237
|
+
|
|
238
|
+
- Keep chart config objects readonly and signal-friendly. A top-level `const` or signal-backed computed config works well.
|
|
239
|
+
- Every chart family must live inside `ui-chart-container`; that container provides dimensions, series visibility state, and scoped color variables to descendants.
|
|
240
|
+
- Use an explicit `chartId` when multiple charts of the same family appear on one page or when tests need a stable selector.
|
|
241
|
+
- The local shadcn mapping for Chart lives in the dedicated `/ui/chart` overview route with focused family demos under `/ui/chart/*`.
|
|
242
|
+
|
|
243
|
+
## Source parity
|
|
244
|
+
|
|
245
|
+
This Angular package follows the shadcn Chart information architecture and theming concepts, but it does not mirror the React API one-to-one.
|
|
246
|
+
|
|
247
|
+
- shadcn uses Recharts components directly and layers `ChartTooltipContent` and `ChartLegendContent` around them.
|
|
248
|
+
- This Angular library ships standalone chart families plus shared primitives, so you compose `ui-chart-container`, the relevant `ui-*-chart`, `ui-chart-tooltip`, and `ui-chart-legend` instead of wiring Recharts JSX.
|
|
249
|
+
- The dedicated `/ui/chart/*` route group is the intentional local mapping for shadcn Chart in this repo; no duplicate `/ui/shadcn/chart` page is required.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
A shadcn-style checkbox primitive built on Angular Material's `mat-checkbox`, with full `ControlValueAccessor` support for `ngModel` and reactive forms.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { CheckboxComponent } from '@edsis/ui/checkbox';
|
|
9
|
+
import { LabelComponent } from '@edsis/ui/label';
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
Wrap the control and copy in `label[ui-label]` when the text should toggle the checkbox. This is the closest Angular equivalent to the upstream shadcn `Field` + `FieldLabel` composition.
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<label ui-label class="flex items-start gap-3">
|
|
18
|
+
<ui-checkbox [(ngModel)]="accepted" name="terms-checkbox" class="mt-0.5" />
|
|
19
|
+
<span class="grid gap-1 leading-none">
|
|
20
|
+
<span>Accept terms and conditions</span>
|
|
21
|
+
<span class="text-sm font-normal leading-5 text-muted-foreground">
|
|
22
|
+
By clicking this checkbox, you agree to the terms.
|
|
23
|
+
</span>
|
|
24
|
+
</span>
|
|
25
|
+
</label>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Reactive forms continue to work through the component's value accessor.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<ui-checkbox [formControl]="form.controls.marketingOptIn" aria-label="Receive product updates" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Common patterns
|
|
35
|
+
|
|
36
|
+
### Controlled checked state
|
|
37
|
+
|
|
38
|
+
Use `checkedChange` when the parent owns the signal and you want to keep the checkbox controlled without wrapping a form model.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const marketingOptIn = signal(false);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<ui-checkbox
|
|
46
|
+
[ngModel]="marketingOptIn()"
|
|
47
|
+
(checkedChange)="marketingOptIn.set($event)"
|
|
48
|
+
aria-label="Receive product updates" />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Invalid state
|
|
52
|
+
|
|
53
|
+
Forward `aria-invalid="true"` to switch the control into the destructive invalid treatment.
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<label ui-label class="flex items-start gap-3 text-destructive">
|
|
57
|
+
<ui-checkbox aria-invalid="true" name="terms-checkbox-invalid" class="mt-0.5" />
|
|
58
|
+
<span class="grid gap-1 leading-none">
|
|
59
|
+
<span>Accept terms and conditions</span>
|
|
60
|
+
<span class="text-sm font-normal leading-5 text-muted-foreground">
|
|
61
|
+
Choose this before continuing to checkout.
|
|
62
|
+
</span>
|
|
63
|
+
</span>
|
|
64
|
+
</label>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Grouped preferences
|
|
68
|
+
|
|
69
|
+
Use a semantic `fieldset` for a checkbox list.
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<fieldset class="space-y-3">
|
|
73
|
+
<legend class="text-sm font-semibold">Show these items on the desktop:</legend>
|
|
74
|
+
@for (item of groupOptions; track item.id) {
|
|
75
|
+
<label ui-label class="flex items-start gap-3">
|
|
76
|
+
<ui-checkbox
|
|
77
|
+
[ngModel]="desktopItems().has(item.id)"
|
|
78
|
+
(checkedChange)="toggleDesktopItem(item.id, $event)"
|
|
79
|
+
[name]="item.id"
|
|
80
|
+
class="mt-0.5" />
|
|
81
|
+
<span class="font-normal">{{ item.label }}</span>
|
|
82
|
+
</label>
|
|
83
|
+
}
|
|
84
|
+
</fieldset>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Table row selection
|
|
88
|
+
|
|
89
|
+
Use `indeterminate` for the select-all checkbox and set `data-state="selected"` on the selected row so the table highlight stays in sync.
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<ui-checkbox
|
|
93
|
+
[ngModel]="selectAll()"
|
|
94
|
+
[indeterminate]="someRowsSelected()"
|
|
95
|
+
aria-label="Select all team members"
|
|
96
|
+
(checkedChange)="handleSelectAll($event)" />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## API reference
|
|
100
|
+
|
|
101
|
+
| Input | Type | Default | Notes |
|
|
102
|
+
| ------------------ | --------------------------- | -------------- | ------------------------------------------------------------------------ |
|
|
103
|
+
| `id` | `string` | auto-generated | Forwarded to Angular Material; the native input id becomes `<id>-input`. |
|
|
104
|
+
| `name` | `string \| null` | `null` | Forwarded to the native checkbox input. |
|
|
105
|
+
| `indeterminate` | `boolean` | `false` | Useful for select-all patterns. |
|
|
106
|
+
| `required` | `boolean` | `false` | Forwarded to the native input. |
|
|
107
|
+
| `aria-label` | `string \| null` | `null` | Use for icon-only or table selection checkboxes. |
|
|
108
|
+
| `aria-describedby` | `string \| null` | `null` | Links helper or error text outside the checkbox. |
|
|
109
|
+
| `aria-labelledby` | `string \| null` | `null` | Alternative to projected text or wrapper labels. |
|
|
110
|
+
| `aria-invalid` | `boolean \| string \| null` | `null` | Switches the control into the destructive invalid treatment. |
|
|
111
|
+
| `class` | `string` | `''` | Adds utility classes to the wrapped Material checkbox host. |
|
|
112
|
+
|
|
113
|
+
| Output | Payload |
|
|
114
|
+
| --------------- | --------- |
|
|
115
|
+
| `checkedChange` | `boolean` |
|
|
116
|
+
|
|
117
|
+
Public method: `focus()`.
|
|
118
|
+
|
|
119
|
+
## Styling and theming
|
|
120
|
+
|
|
121
|
+
The component uses a Material bridge so Angular Material's structural markup is restyled through the library theme tokens.
|
|
122
|
+
|
|
123
|
+
- Default borders and icon color use the shared `input` and `primary` tokens.
|
|
124
|
+
- `aria-invalid="true"` switches the control to the `destructive` token set.
|
|
125
|
+
- Pass spacing or alignment utilities through the `class` input when the checkbox needs to align with multi-line content.
|
|
126
|
+
|
|
127
|
+
Extra visual adjustments belong in `checkbox.component.css` inside the library.
|
|
128
|
+
|
|
129
|
+
## Accessibility
|
|
130
|
+
|
|
131
|
+
- Always give the checkbox an accessible name via wrapper label text, projected content, `aria-label`, or `aria-labelledby`.
|
|
132
|
+
- Use `aria-describedby` to connect helper or error text rendered outside the checkbox.
|
|
133
|
+
- Use `indeterminate` for tri-state list headers and table select-all behavior.
|
|
134
|
+
- `required` and `name` are forwarded to the underlying native input.
|
|
135
|
+
|
|
136
|
+
## Keyboard interactions
|
|
137
|
+
|
|
138
|
+
- `Tab` moves focus to the checkbox in DOM order.
|
|
139
|
+
- `Space` toggles the checked state.
|
|
140
|
+
|
|
141
|
+
## Angular notes
|
|
142
|
+
|
|
143
|
+
- `ngModel`, reactive forms, and `checkedChange` all work with the same primitive.
|
|
144
|
+
- When you pass `id`, Angular Material derives the native input id as `<id>-input`; wrapper labels or `aria-labelledby` are usually the simplest Angular pattern.
|
|
145
|
+
- Projected text still works if you prefer `<ui-checkbox>Accept</ui-checkbox>` for compact markup.
|
|
146
|
+
|
|
147
|
+
## Source parity
|
|
148
|
+
|
|
149
|
+
This Angular implementation follows the shadcn Checkbox examples while mapping the upstream `Field` helpers to Angular-native label wrappers, `fieldset` composition, semantic table rows, and signal-friendly state handling.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Collapsible
|
|
2
|
+
|
|
3
|
+
Displays an interactive disclosure region that expands and collapses inline content.
|
|
4
|
+
|
|
5
|
+
Use Collapsible for settings drawers, detail rows, compact status cards, and nested explorers where content should stay in the same document flow.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerDirective } from '@edsis/ui/collapsible';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Composition
|
|
14
|
+
|
|
15
|
+
The Angular composition follows the shadcn and Radix structure while using a root component, a trigger directive on a native button, and a content component.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
ui-collapsible
|
|
19
|
+
├── button[ui-collapsible-trigger]
|
|
20
|
+
└── ui-collapsible-content
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Basic usage
|
|
24
|
+
|
|
25
|
+
Bind `[(open)]` when the parent should control the disclosure state or seed a default open panel.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
readonly detailsOpen = signal(false);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<ui-collapsible [(open)]="detailsOpen" class="w-full max-w-md rounded-lg border border-border p-3">
|
|
33
|
+
<button
|
|
34
|
+
ui-collapsible-trigger
|
|
35
|
+
class="inline-flex w-full items-center justify-between gap-2 text-left text-sm font-medium">
|
|
36
|
+
Can I use this in my project?
|
|
37
|
+
<span aria-hidden="true">+</span>
|
|
38
|
+
</button>
|
|
39
|
+
|
|
40
|
+
<ui-collapsible-content class="pt-3 text-sm text-muted-foreground">
|
|
41
|
+
Yes. The trigger and content follow the disclosure ARIA pattern and stay in normal layout flow.
|
|
42
|
+
</ui-collapsible-content>
|
|
43
|
+
</ui-collapsible>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Common patterns
|
|
47
|
+
|
|
48
|
+
### Controlled state
|
|
49
|
+
|
|
50
|
+
Use a signal boolean with `[(open)]` when another control needs to observe or update the open state.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
readonly isOpen = signal(false);
|
|
54
|
+
|
|
55
|
+
toggleFromElsewhere(): void {
|
|
56
|
+
this.isOpen.update((value) => !value);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Button composition
|
|
61
|
+
|
|
62
|
+
`button[ui-collapsible-trigger]` is a directive, so it can compose with the local button primitive on the same element.
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<ui-collapsible [(open)]="basicOpen" class="rounded-md border border-border p-2">
|
|
66
|
+
<button ui-button ui-collapsible-trigger variant="ghost" class="w-full justify-between px-2">
|
|
67
|
+
Product details
|
|
68
|
+
<svg aria-hidden="true" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
69
|
+
<polyline points="6 9 12 15 18 9" />
|
|
70
|
+
</svg>
|
|
71
|
+
</button>
|
|
72
|
+
|
|
73
|
+
<ui-collapsible-content class="px-2 pb-2 pt-1 text-sm text-muted-foreground">
|
|
74
|
+
This panel can reveal additional details without leaving the page.
|
|
75
|
+
</ui-collapsible-content>
|
|
76
|
+
</ui-collapsible>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Settings drawer
|
|
80
|
+
|
|
81
|
+
Wrap the trigger and content inside a card-like surface when the disclosure belongs to a small settings editor.
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<ui-collapsible [(open)]="settingsOpen" class="rounded-lg border border-border p-4">
|
|
85
|
+
<div class="flex items-start gap-3">
|
|
86
|
+
<div class="grid flex-1 grid-cols-2 gap-2">
|
|
87
|
+
<input ui-input placeholder="Radius X" />
|
|
88
|
+
<input ui-input placeholder="Radius Y" />
|
|
89
|
+
<ui-collapsible-content class="col-span-full grid grid-cols-2 gap-2 pt-0">
|
|
90
|
+
<input ui-input placeholder="Blur" />
|
|
91
|
+
<input ui-input placeholder="Spread" />
|
|
92
|
+
</ui-collapsible-content>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<button ui-button ui-collapsible-trigger variant="outline" size="icon" aria-label="Toggle advanced fields">
|
|
96
|
+
<span aria-hidden="true">...</span>
|
|
97
|
+
</button>
|
|
98
|
+
</div>
|
|
99
|
+
</ui-collapsible>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Nested file tree
|
|
103
|
+
|
|
104
|
+
Nested `ui-collapsible` roots work well for compact explorers and outline views.
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<ui-collapsible [(open)]="componentsOpen">
|
|
108
|
+
<button ui-collapsible-trigger class="inline-flex items-center gap-2 text-sm font-medium">components</button>
|
|
109
|
+
|
|
110
|
+
<ui-collapsible-content class="ml-5 mt-2 flex flex-col gap-1">
|
|
111
|
+
<ui-collapsible [(open)]="uiOpen">
|
|
112
|
+
<button ui-collapsible-trigger class="inline-flex items-center gap-2 text-sm font-medium">ui</button>
|
|
113
|
+
<ui-collapsible-content class="ml-5 mt-2 flex flex-col gap-1 text-sm text-muted-foreground">
|
|
114
|
+
<span>button.ts</span>
|
|
115
|
+
<span>collapsible.ts</span>
|
|
116
|
+
</ui-collapsible-content>
|
|
117
|
+
</ui-collapsible>
|
|
118
|
+
</ui-collapsible-content>
|
|
119
|
+
</ui-collapsible>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### RTL
|
|
123
|
+
|
|
124
|
+
For right-to-left interfaces, set `dir="rtl"` on a wrapping container or the collapsible root.
|
|
125
|
+
|
|
126
|
+
```html
|
|
127
|
+
<section dir="rtl" lang="ar" class="max-w-md text-right">
|
|
128
|
+
<ui-collapsible [(open)]="rtlOpen" class="flex flex-col gap-2">
|
|
129
|
+
<button ui-collapsible-trigger class="inline-flex items-center justify-between gap-2 text-sm font-medium">
|
|
130
|
+
تبديل التفاصيل
|
|
131
|
+
</button>
|
|
132
|
+
<ui-collapsible-content class="flex flex-col gap-2 text-sm">
|
|
133
|
+
<div class="rounded-md border border-border px-4 py-2">عنوان الشحن</div>
|
|
134
|
+
<div class="rounded-md border border-border px-4 py-2">2x سماعات الاستوديو</div>
|
|
135
|
+
</ui-collapsible-content>
|
|
136
|
+
</ui-collapsible>
|
|
137
|
+
</section>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## API reference
|
|
141
|
+
|
|
142
|
+
### `CollapsibleComponent`
|
|
143
|
+
|
|
144
|
+
| Input | Type | Default |
|
|
145
|
+
| -------------- | --------- | ------- |
|
|
146
|
+
| `open` (model) | `boolean` | `false` |
|
|
147
|
+
| `disabled` | `boolean` | `false` |
|
|
148
|
+
| `class` | `string` | `''` |
|
|
149
|
+
|
|
150
|
+
### `CollapsibleContentComponent`
|
|
151
|
+
|
|
152
|
+
| Input | Type | Default |
|
|
153
|
+
| ------------ | --------- | ------- |
|
|
154
|
+
| `forceMount` | `boolean` | `false` |
|
|
155
|
+
| `class` | `string` | `''` |
|
|
156
|
+
|
|
157
|
+
### Parts
|
|
158
|
+
|
|
159
|
+
- `button[ui-collapsible-trigger]` is the interactive control. It manages `aria-expanded`, `aria-controls`, `data-state`, and root toggling.
|
|
160
|
+
- `ui-collapsible-content` is the panel region. It applies `role="region"`, `aria-labelledby`, `data-state`, and optional persistent projection via `forceMount`.
|
|
161
|
+
- Lower-level behavior follows the Radix Collapsible model: <https://www.radix-ui.com/primitives/docs/components/collapsible#api-reference>.
|
|
162
|
+
|
|
163
|
+
## Styling and theming
|
|
164
|
+
|
|
165
|
+
Pass `class` to the root or content, and use the native `class` attribute on the trigger button. The root and content expose `data-state="open" | "closed"` so surrounding styles or transitions can react to the current disclosure state.
|
|
166
|
+
|
|
167
|
+
Use theme tokens such as `border-border`, `bg-card`, `text-muted-foreground`, and spacing utilities to match the rest of the library.
|
|
168
|
+
|
|
169
|
+
## Accessibility
|
|
170
|
+
|
|
171
|
+
- The primitive follows the disclosure WAI-ARIA pattern.
|
|
172
|
+
- Trigger is a native button, so Enter and Space work without extra key handling.
|
|
173
|
+
- Trigger receives `aria-controls` and `aria-expanded`; content receives `role="region"` and `aria-labelledby`.
|
|
174
|
+
- `disabled` keeps the control visible while preventing interaction.
|
|
175
|
+
|
|
176
|
+
## Keyboard interactions
|
|
177
|
+
|
|
178
|
+
- `Enter` toggles the collapsible.
|
|
179
|
+
- `Space` toggles the collapsible.
|
|
180
|
+
- Tab order follows the DOM order of the trigger and any focusable controls inside the content.
|
|
181
|
+
|
|
182
|
+
## Angular notes
|
|
183
|
+
|
|
184
|
+
- `[(open)]` is the Angular equivalent of shadcn's `open` and `onOpenChange` props.
|
|
185
|
+
- `button[ui-collapsible-trigger]` is a directive, not a component, so it can compose with `button[ui-button]` on the same element.
|
|
186
|
+
- `forceMount` keeps projected content rendered even when the panel is closed, which is useful for measuring or animating content without re-creating it.
|
|
187
|
+
- The local API intentionally does not add an `asChild` prop; Angular composition is handled through selectors and host directives instead.
|
|
188
|
+
|
|
189
|
+
## Source parity
|
|
190
|
+
|
|
191
|
+
This Angular implementation follows the shadcn Collapsible structure and examples while translating the API to standalone Angular imports, signal-backed state, button-directive composition, and Angular-friendly RTL guidance.
|