@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/button/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Displays a native button or anchor that looks like a shadcn-style button, translated to Angular attribute selectors and standalone imports.
|
|
4
|
+
|
|
5
|
+
Use Button for primary actions, secondary actions, icon-only controls, and semantic links that should share the same visual language.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ButtonComponent } from '@edsis/ui/button';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<button ui-button type="button" variant="default">Save</button>
|
|
17
|
+
<button ui-button variant="outline" size="sm">Cancel</button>
|
|
18
|
+
<a ui-button variant="link" href="/learn-more">Learn more</a>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Choose the correct native host for the job: `<button>` for actions and `<a>` for navigation.
|
|
22
|
+
|
|
23
|
+
## Common patterns
|
|
24
|
+
|
|
25
|
+
### Variants
|
|
26
|
+
|
|
27
|
+
Use `variant` for emphasis: `default`, `secondary`, `destructive`, `outline`, `ghost`, or `link`.
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<button ui-button variant="default">Save</button>
|
|
31
|
+
<button ui-button variant="secondary">Duplicate</button>
|
|
32
|
+
<button ui-button variant="destructive">Delete</button>
|
|
33
|
+
<button ui-button variant="outline">Outline</button>
|
|
34
|
+
<button ui-button variant="ghost">Ghost</button>
|
|
35
|
+
<a ui-button variant="link" href="/learn-more">Learn more</a>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Sizes
|
|
39
|
+
|
|
40
|
+
Use `size` for compact or icon-only controls: `xs`, `sm`, `default`, `lg`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`.
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<button ui-button size="xs" variant="outline">Extra small</button>
|
|
44
|
+
<button ui-button size="sm" variant="outline">Small</button>
|
|
45
|
+
<button ui-button size="default" variant="outline">Default</button>
|
|
46
|
+
<button ui-button size="lg" variant="outline">Large</button>
|
|
47
|
+
<button ui-button size="icon-xs" variant="outline" aria-label="Extra small icon button">+</button>
|
|
48
|
+
<button ui-button size="icon-sm" variant="outline" aria-label="Small icon button">+</button>
|
|
49
|
+
<button ui-button size="icon" variant="outline" aria-label="Default icon button">+</button>
|
|
50
|
+
<button ui-button size="icon-lg" variant="outline" aria-label="Large icon button">+</button>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Rounded buttons
|
|
54
|
+
|
|
55
|
+
Pass `class="rounded-full"` when you want a pill or circular button without changing the base API.
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<button ui-button variant="outline" class="rounded-full px-5">Invite teammate</button>
|
|
59
|
+
<button ui-button variant="outline" size="icon" class="rounded-full" aria-label="Scroll to top">
|
|
60
|
+
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
61
|
+
<path d="m12 19 0-14" />
|
|
62
|
+
<path d="m5 12 7-7 7 7" />
|
|
63
|
+
</svg>
|
|
64
|
+
</button>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Loading and disabled states
|
|
68
|
+
|
|
69
|
+
Project a spinner element into the button and set `disabled` while async work is pending.
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<button ui-button variant="outline" disabled>
|
|
73
|
+
<span
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class="inline-block h-3.5 w-3.5 animate-spin rounded-full border-2 border-current border-t-transparent"></span>
|
|
76
|
+
Generating
|
|
77
|
+
</button>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Semantic host mapping
|
|
81
|
+
|
|
82
|
+
React's `asChild` pattern maps to choosing the right native host directly in Angular templates.
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<button ui-button type="button">Save changes</button> <a ui-button href="/account" variant="link">Go to account</a>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## API reference
|
|
89
|
+
|
|
90
|
+
| Input | Type | Default |
|
|
91
|
+
| --------- | ------------------------------------------------------------------------------------ | ----------- |
|
|
92
|
+
| `variant` | `'default' \| 'secondary' \| 'destructive' \| 'outline' \| 'ghost' \| 'link'` | `'default'` |
|
|
93
|
+
| `size` | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'icon-xs' \| 'icon-sm' \| 'icon' \| 'icon-lg'` | `'default'` |
|
|
94
|
+
| `class` | `string` | `''` |
|
|
95
|
+
|
|
96
|
+
The selected variant + size are also exposed via `data-variant` / `data-size`
|
|
97
|
+
attributes on the host for styling overrides.
|
|
98
|
+
|
|
99
|
+
Hosts: `button[ui-button]` and `a[ui-button]`.
|
|
100
|
+
|
|
101
|
+
Re-exports: `buttonVariants`, `ButtonVariant`, `ButtonSize`.
|
|
102
|
+
|
|
103
|
+
## Styling and theming
|
|
104
|
+
|
|
105
|
+
Tokens: `--primary`, `--primary-foreground`, `--secondary`, `--destructive`,
|
|
106
|
+
`--border`, `--accent`, `--ring`.
|
|
107
|
+
|
|
108
|
+
Every state (hover, focus-visible, active, disabled) is covered by the variants.
|
|
109
|
+
Focus-visible uses a 2px `ring-ring` outline for keyboard users.
|
|
110
|
+
|
|
111
|
+
Pass `class` to layer width, shape, and spacing overrides such as `rounded-full`, `w-full`, or responsive layout utilities.
|
|
112
|
+
|
|
113
|
+
The local primitive already opts into `cursor-pointer` for interactive hosts, so you do not need an extra Tailwind base-layer override to restore button cursors.
|
|
114
|
+
|
|
115
|
+
## Accessibility
|
|
116
|
+
|
|
117
|
+
Attribute selectors force you to pick a real semantic element:
|
|
118
|
+
|
|
119
|
+
- Use `<button ui-button>` for actions that don't navigate.
|
|
120
|
+
- Use `<a ui-button href="…">` for navigation.
|
|
121
|
+
- Add an `aria-label` to icon-only buttons.
|
|
122
|
+
- Use `type="button"` inside forms unless the button should submit.
|
|
123
|
+
|
|
124
|
+
Avoid faking buttons with `<div>` — keyboard and screen-reader support depend on
|
|
125
|
+
the native element.
|
|
126
|
+
|
|
127
|
+
## Keyboard interactions
|
|
128
|
+
|
|
129
|
+
- Native buttons support Tab, Enter, and Space automatically.
|
|
130
|
+
- Anchors with `href` participate in normal link focus and Enter activation.
|
|
131
|
+
|
|
132
|
+
## Angular notes
|
|
133
|
+
|
|
134
|
+
- Import `ButtonComponent` into the standalone component that renders the host element.
|
|
135
|
+
- There is no Angular `asChild` input; pick the semantic host element directly.
|
|
136
|
+
|
|
137
|
+
## Source parity
|
|
138
|
+
|
|
139
|
+
This Angular version follows the shadcn Button information architecture while translating examples to native hosts, standalone imports, and Angular-friendly template patterns.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Button Group
|
|
2
|
+
|
|
3
|
+
Groups related action buttons, text pills, inputs, and nested control clusters into a single visual control boundary.
|
|
4
|
+
|
|
5
|
+
Use Button Group for toolbars, split actions, search bars, and compact action clusters where neighboring controls should read as one control family rather than isolated buttons.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ButtonComponent } from '@edsis/ui/button';
|
|
11
|
+
import { ButtonGroupComponent, ButtonGroupSeparatorComponent, ButtonGroupTextComponent } from '@edsis/ui/button-group';
|
|
12
|
+
import { InputComponent } from '@edsis/ui/input';
|
|
13
|
+
import {
|
|
14
|
+
InputGroupAddonComponent,
|
|
15
|
+
InputGroupComponent,
|
|
16
|
+
InputGroupInputComponent,
|
|
17
|
+
InputGroupTextComponent,
|
|
18
|
+
} from '@edsis/ui/input-group';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Composition
|
|
22
|
+
|
|
23
|
+
The Angular structure mirrors the shadcn composition while translating `asChild` to normal Angular content projection.
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
ui-button-group
|
|
27
|
+
├── button[ui-button] or a[ui-button]
|
|
28
|
+
├── input[ui-input] or textarea[ui-textarea]
|
|
29
|
+
├── ui-button-group-text
|
|
30
|
+
├── ui-button-group-separator
|
|
31
|
+
└── ui-button-group
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Basic usage
|
|
35
|
+
|
|
36
|
+
Label the group with `aria-label` or `aria-labelledby` whenever the buttons act as a single tool cluster.
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<ui-button-group aria-label="Search actions" class="w-full max-w-md">
|
|
40
|
+
<input ui-input placeholder="Search..." />
|
|
41
|
+
<button ui-button type="button" variant="outline" aria-label="Run search">Search</button>
|
|
42
|
+
</ui-button-group>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Common patterns
|
|
46
|
+
|
|
47
|
+
### Orientation
|
|
48
|
+
|
|
49
|
+
Use `orientation="vertical"` when the group should stack actions instead of lining them up horizontally.
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<ui-button-group orientation="vertical" aria-label="Zoom controls" class="h-fit">
|
|
53
|
+
<button ui-button type="button" variant="outline" size="icon">+</button>
|
|
54
|
+
<button ui-button type="button" variant="outline" size="icon">-</button>
|
|
55
|
+
</ui-button-group>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Text and field pairing
|
|
59
|
+
|
|
60
|
+
`ui-button-group-text` is the Angular translation of shadcn's `ButtonGroupText`. Project any semantic content inside it, including a native label.
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<ui-button-group class="w-full max-w-lg">
|
|
64
|
+
<ui-button-group-text>
|
|
65
|
+
<label for="project-name">Project</label>
|
|
66
|
+
</ui-button-group-text>
|
|
67
|
+
<input ui-input id="project-name" placeholder="Type a name..." />
|
|
68
|
+
</ui-button-group>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Separator
|
|
72
|
+
|
|
73
|
+
Use `ui-button-group-separator` when filled or secondary buttons still need a visible division.
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<ui-button-group aria-label="Clipboard actions">
|
|
77
|
+
<button ui-button type="button" variant="secondary" size="sm">Copy</button>
|
|
78
|
+
<ui-button-group-separator />
|
|
79
|
+
<button ui-button type="button" variant="secondary" size="sm">Paste</button>
|
|
80
|
+
</ui-button-group>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Split action
|
|
84
|
+
|
|
85
|
+
Split buttons are just two neighboring buttons with a separator between the primary action and the disclosure or icon action.
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<ui-button-group aria-label="Create actions">
|
|
89
|
+
<button ui-button type="button" variant="secondary">Create</button>
|
|
90
|
+
<ui-button-group-separator />
|
|
91
|
+
<button ui-button type="button" variant="secondary" size="icon" aria-label="Open create menu">+</button>
|
|
92
|
+
</ui-button-group>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Search input
|
|
96
|
+
|
|
97
|
+
Button Group works directly with the local `ui-input` primitive because both controls own their border on the host element.
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<ui-button-group aria-label="Repository search" class="w-full max-w-lg">
|
|
101
|
+
<input ui-input placeholder="Search repositories..." />
|
|
102
|
+
<button ui-button type="button" variant="outline" aria-label="Search">Search</button>
|
|
103
|
+
</ui-button-group>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Nested groups
|
|
107
|
+
|
|
108
|
+
Nest `ui-button-group` when you want separate clusters with spacing between them while keeping each inner cluster visually fused.
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<ui-button-group aria-label="Message composer" class="w-full max-w-xl">
|
|
112
|
+
<ui-button-group>
|
|
113
|
+
<button ui-button type="button" variant="outline" size="icon" aria-label="Add attachment">+</button>
|
|
114
|
+
</ui-button-group>
|
|
115
|
+
|
|
116
|
+
<ui-button-group class="min-w-0 flex-1">
|
|
117
|
+
<ui-input-group>
|
|
118
|
+
<input ui-input-group-input placeholder="Send a message..." />
|
|
119
|
+
<ui-input-group-addon align="inline-end">
|
|
120
|
+
<ui-input-group-text>⌘↵</ui-input-group-text>
|
|
121
|
+
</ui-input-group-addon>
|
|
122
|
+
</ui-input-group>
|
|
123
|
+
</ui-button-group>
|
|
124
|
+
</ui-button-group>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Popover companion
|
|
128
|
+
|
|
129
|
+
Use a neighboring popover trigger when the primary button opens a short follow-up form or assistant prompt.
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<ui-button-group aria-label="Copilot actions">
|
|
133
|
+
<button ui-button type="button" variant="outline">Copilot</button>
|
|
134
|
+
<button ui-button type="button" variant="outline" size="icon" aria-label="Open Copilot options">⋯</button>
|
|
135
|
+
</ui-button-group>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## API reference
|
|
139
|
+
|
|
140
|
+
### `ButtonGroupComponent`
|
|
141
|
+
|
|
142
|
+
| Input | Type | Default |
|
|
143
|
+
| ------------- | ---------------------------- | -------------- |
|
|
144
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
|
|
145
|
+
| `class` | `string` | `''` |
|
|
146
|
+
|
|
147
|
+
Host behavior:
|
|
148
|
+
|
|
149
|
+
- Renders `role="group"`.
|
|
150
|
+
- Adds `data-orientation` and `data-slot="button-group"`.
|
|
151
|
+
- Collapses adjoining corner radius and internal border width with RTL-safe logical properties.
|
|
152
|
+
|
|
153
|
+
### `ButtonGroupSeparatorComponent`
|
|
154
|
+
|
|
155
|
+
| Input | Type | Default |
|
|
156
|
+
| ------------- | ---------------------------- | ------------ |
|
|
157
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` |
|
|
158
|
+
| `class` | `string` | `''` |
|
|
159
|
+
|
|
160
|
+
### `ButtonGroupTextComponent`
|
|
161
|
+
|
|
162
|
+
| Input | Type | Default |
|
|
163
|
+
| ------- | -------- | ------- |
|
|
164
|
+
| `class` | `string` | `''` |
|
|
165
|
+
|
|
166
|
+
Angular mapping note: there is no `asChild` input. Project the semantic element you need, such as `<label>` or `<span>`, inside `ui-button-group-text`.
|
|
167
|
+
|
|
168
|
+
## Styling and theming
|
|
169
|
+
|
|
170
|
+
- The root collapses adjacent corners and borders with logical start/end utilities so the same component works in LTR and RTL layouts.
|
|
171
|
+
- Nested `ui-button-group` children automatically create spacing between groups while preserving the fused inner boundaries of each nested group.
|
|
172
|
+
- `ui-button-group-text` uses `border-border`, `bg-muted`, and shared radius tokens so it matches the rest of the component package.
|
|
173
|
+
- `ui-input` and `ui-input-group` compose cleanly inside Button Group because their border and radius live on the visible host. The current Material-backed `ui-select` does not expose the same host-level border contract yet, so the upstream Select example is intentionally not shipped as a parity demo.
|
|
174
|
+
|
|
175
|
+
## Accessibility
|
|
176
|
+
|
|
177
|
+
- `ui-button-group` renders with `role="group"`; provide an accessible name with `aria-label` or `aria-labelledby` when the controls act as one tool cluster.
|
|
178
|
+
- Button Group is for actions. If the clustered controls represent pressed or selected state, use a toggle-group style pattern instead.
|
|
179
|
+
- Add `aria-label` to icon-only buttons inside the group.
|
|
180
|
+
- `ui-button-group-text` is non-interactive content. Keep labels, helper text, or status copy inside it and leave action handling to the actual button or input controls.
|
|
181
|
+
|
|
182
|
+
## Keyboard interactions
|
|
183
|
+
|
|
184
|
+
- Tab order follows the DOM order of the projected controls.
|
|
185
|
+
- Native buttons keep their built-in Enter and Space activation behavior.
|
|
186
|
+
- Inputs and textareas keep their native editing behavior.
|
|
187
|
+
- Popover and menu triggers inside a group keep the keyboard behavior of their own directives; the group container does not intercept those interactions.
|
|
188
|
+
|
|
189
|
+
## Button Group vs Toggle Group
|
|
190
|
+
|
|
191
|
+
- Use Button Group when each item performs an immediate action.
|
|
192
|
+
- Use Toggle Group when each item represents persistent pressed, selected, or filter state.
|
|
193
|
+
|
|
194
|
+
## Angular notes
|
|
195
|
+
|
|
196
|
+
- Import `ButtonGroupComponent` plus only the child primitives you render on the page.
|
|
197
|
+
- There is no React-style `asChild` prop. Angular templates already let you choose the semantic element directly.
|
|
198
|
+
- Use nested `ui-button-group` elements for spacing between related clusters rather than adding gap utilities to a single fused group.
|
|
199
|
+
|
|
200
|
+
## Source parity
|
|
201
|
+
|
|
202
|
+
This Angular implementation follows the shadcn Button Group surface with a grouped root, text pill, separator, nested-group spacing, dropdown and popover composition, and RTL-friendly border collapsing.
|
|
203
|
+
|
|
204
|
+
The main documented deviation is the upstream Select example: the local `ui-select` remains Material-backed, so it is better composed next to the group in surrounding layout for now instead of being presented as a fused host-level group item.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Calendar
|
|
2
|
+
|
|
3
|
+
Inline single-date calendar built on Angular Material `MatCalendar` and wrapped with shadcn-style theme tokens.
|
|
4
|
+
|
|
5
|
+
Use Calendar when the date grid should stay visible in the page. Use `DatePickerComponent` when the same selection should live behind an input and popover trigger.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { CalendarComponent } from '@edsis/ui/calendar';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Requires a date adapter
|
|
14
|
+
|
|
15
|
+
The consumer app must provide an Angular Material date adapter. The demo app uses the native adapter:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// app.config.ts
|
|
19
|
+
import { provideNativeDateAdapter } from '@angular/material/core';
|
|
20
|
+
|
|
21
|
+
export const appConfig = {
|
|
22
|
+
providers: [provideNativeDateAdapter()],
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Bind `[(value)]` to a `Date | null` signal or component field. Use `startAt` when the first visible month should differ from the selected value.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<ui-calendar [(value)]="selectedDate" [startAt]="selectedDate()" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
protected readonly selectedDate = signal<Date | null>(new Date(2026, 4, 22));
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Common patterns
|
|
39
|
+
|
|
40
|
+
### Constrained range
|
|
41
|
+
|
|
42
|
+
Use `min` and `max` to disable dates outside an allowed window.
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<ui-calendar [(value)]="billingDate" [min]="minDate" [max]="maxDate" [startAt]="billingDate()" />
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
protected readonly billingDate = signal<Date | null>(new Date(2026, 4, 15));
|
|
50
|
+
protected readonly minDate = new Date(2026, 4, 5);
|
|
51
|
+
protected readonly maxDate = new Date(2026, 4, 25);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Disabled or booked dates
|
|
55
|
+
|
|
56
|
+
Pass a `dateFilter` function. Angular Material expects the function to return `true` for selectable dates and `false` for disabled dates.
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<ui-calendar [(value)]="visitDate" [dateFilter]="availableDateFilter" [startAt]="visitDate()" />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
protected readonly bookedDates = [new Date(2026, 1, 12), new Date(2026, 1, 13)];
|
|
64
|
+
|
|
65
|
+
protected readonly availableDateFilter = (candidate: Date | null): boolean =>
|
|
66
|
+
!!candidate && !this.bookedDates.some((bookedDate) => this.isSameDay(bookedDate, candidate));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Presets
|
|
70
|
+
|
|
71
|
+
Compose preset buttons around the calendar and update the same `value` model.
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<ui-calendar [(value)]="presetDate" [startAt]="presetDate()" class="border-0" />
|
|
75
|
+
|
|
76
|
+
<button ui-button type="button" variant="outline" size="sm" (click)="selectPreset(7)">In a week</button>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Date and time
|
|
80
|
+
|
|
81
|
+
Calendar owns the date. Native time inputs or `InputGroupComponent` can own the time value next to it.
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<ui-calendar [(value)]="meetingDate" [startAt]="meetingDate()" />
|
|
85
|
+
|
|
86
|
+
<ui-input-group>
|
|
87
|
+
<input ui-input-group-input type="time" [value]="startTime()" (input)="updateStartTime($event)" />
|
|
88
|
+
</ui-input-group>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## API reference
|
|
92
|
+
|
|
93
|
+
| Input / Model | Type | Default |
|
|
94
|
+
| ------------- | ----------------------------------- | --------- |
|
|
95
|
+
| `value` | `Date \| null` | `null` |
|
|
96
|
+
| `min` | `Date \| null` | `null` |
|
|
97
|
+
| `max` | `Date \| null` | `null` |
|
|
98
|
+
| `startAt` | `Date \| null` | `null` |
|
|
99
|
+
| `startView` | `'month' \| 'year' \| 'multi-year'` | `'month'` |
|
|
100
|
+
| `dateFilter` | `(date: Date \| null) => boolean` | `null` |
|
|
101
|
+
| `disabled` | `boolean` | `false` |
|
|
102
|
+
| `class` | `string` | `''` |
|
|
103
|
+
|
|
104
|
+
Implements `ControlValueAccessor` — usable with `[(ngModel)]` and reactive forms.
|
|
105
|
+
|
|
106
|
+
## Styling and theming
|
|
107
|
+
|
|
108
|
+
The host uses `--border`, `--background`, `--foreground`, and `--radius`. Pass `class` for layout utilities such as `shadow-sm`, `border-0`, or `[--ui-calendar-width:20rem]`.
|
|
109
|
+
|
|
110
|
+
The inner Material calendar keeps Angular Material's a11y and navigation behavior while sitting inside the shadcn token wrapper. Use `DatePickerComponent` for popover input flows; this primitive intentionally stays inline.
|
|
111
|
+
|
|
112
|
+
## Accessibility
|
|
113
|
+
|
|
114
|
+
`MatCalendar` supplies the ARIA grid semantics, focus management, active date state, and disabled date handling. Provide a visible label or surrounding section heading when the calendar appears in a form-like surface.
|
|
115
|
+
|
|
116
|
+
## Keyboard interactions
|
|
117
|
+
|
|
118
|
+
- Arrow keys move between dates.
|
|
119
|
+
- Page Up and Page Down move by month.
|
|
120
|
+
- Home and End move to the start or end of the row.
|
|
121
|
+
- Enter selects the focused date.
|
|
122
|
+
|
|
123
|
+
## Angular notes
|
|
124
|
+
|
|
125
|
+
- Provide a date adapter once at app bootstrap.
|
|
126
|
+
- `dateFilter` returns `true` for enabled dates, unlike some predicate APIs that return `true` for blocked dates.
|
|
127
|
+
- `disabled` marks the host as inert and updates the CVA disabled state.
|
|
128
|
+
- This component is a single-date primitive. Range selection is best modeled as a separate range primitive or by composing two calendars with application state.
|
|
129
|
+
|
|
130
|
+
## Source parity
|
|
131
|
+
|
|
132
|
+
The shadcn Calendar is built on React DayPicker. This Angular implementation maps the same inline calendar concept to `MatCalendar`, standalone imports, signal-friendly `[(value)]` binding, `min` and `max` constraints, `dateFilter` disabled dates, preset composition, and RTL-friendly container usage.
|