@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/toast/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Toast
|
|
2
|
+
|
|
3
|
+
Imperative notification service wrapping `MatSnackBar` with shadcn styling and a Sonner-style API surface.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { ToastService } from '@your-scope/ui/toast';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Application Setup
|
|
12
|
+
|
|
13
|
+
Angular Material snack bars require animations to be configured once at application bootstrap.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { bootstrapApplication } from '@angular/platform-browser';
|
|
17
|
+
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
|
18
|
+
|
|
19
|
+
bootstrapApplication(AppComponent, {
|
|
20
|
+
providers: [provideAnimationsAsync()],
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use `provideNoopAnimations()` instead when the host application intentionally disables animations.
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { inject } from '@angular/core';
|
|
30
|
+
import { ToastService } from '@your-scope/ui/toast';
|
|
31
|
+
|
|
32
|
+
export class SaveButtonComponent {
|
|
33
|
+
private readonly toast = inject(ToastService);
|
|
34
|
+
|
|
35
|
+
save(): void {
|
|
36
|
+
this.toast.success({
|
|
37
|
+
title: 'Saved',
|
|
38
|
+
description: 'Your changes have been saved.',
|
|
39
|
+
action: 'Undo',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fail(): void {
|
|
44
|
+
this.toast.error({ title: 'Upload failed', description: 'Check your connection.' });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Common Patterns
|
|
50
|
+
|
|
51
|
+
### Variants
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
this.toast.show({ title: 'Draft created' });
|
|
55
|
+
this.toast.success({ title: 'Invoice paid' });
|
|
56
|
+
this.toast.info({ title: 'Deploy starts in 10 minutes' });
|
|
57
|
+
this.toast.warning({ title: 'Storage is almost full' });
|
|
58
|
+
this.toast.error({ title: 'Payment failed' });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Position
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
this.toast.show({
|
|
65
|
+
title: 'Event has been created',
|
|
66
|
+
horizontalPosition: 'start',
|
|
67
|
+
verticalPosition: 'top',
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Promise State
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
void this.toast.promise(() => this.createEvent(), {
|
|
75
|
+
loading: 'Loading...',
|
|
76
|
+
success: (event) => `${event.name} has been created`,
|
|
77
|
+
error: 'Error',
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The loading toast uses `durationMs: null` internally so it stays visible until the promise settles.
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
### `ToastService`
|
|
86
|
+
|
|
87
|
+
| Method | Returns |
|
|
88
|
+
| ---------------------------------- | ------------------------- |
|
|
89
|
+
| `show(options: ToastOptions)` | `MatSnackBarRef<unknown>` |
|
|
90
|
+
| `success(options)` | `MatSnackBarRef<unknown>` |
|
|
91
|
+
| `info(options)` | `MatSnackBarRef<unknown>` |
|
|
92
|
+
| `warning(options)` | `MatSnackBarRef<unknown>` |
|
|
93
|
+
| `error(options)` | `MatSnackBarRef<unknown>` |
|
|
94
|
+
| `promise(taskOrFactory, messages)` | `Promise<T>` |
|
|
95
|
+
| `dismiss()` | `void` |
|
|
96
|
+
|
|
97
|
+
### `ToastOptions`
|
|
98
|
+
|
|
99
|
+
| Field | Type | Default |
|
|
100
|
+
| -------------------- | ---------------------------------------------------------------- | ----------- |
|
|
101
|
+
| `title` | `string` | — |
|
|
102
|
+
| `description` | `string` | — |
|
|
103
|
+
| `action` | `string` | `''` |
|
|
104
|
+
| `variant` | `'default' \| 'destructive' \| 'success' \| 'info' \| 'warning'` | `'default'` |
|
|
105
|
+
| `durationMs` | `number \| null` | `5000` |
|
|
106
|
+
| `horizontalPosition` | `MatSnackBarConfig['horizontalPosition']` | `'end'` |
|
|
107
|
+
| `verticalPosition` | `MatSnackBarConfig['verticalPosition']` | `'bottom'` |
|
|
108
|
+
|
|
109
|
+
Set `durationMs` to `null` when the toast should stay visible until `dismiss()` is called.
|
|
110
|
+
|
|
111
|
+
### `ToastPromiseMessages<T>`
|
|
112
|
+
|
|
113
|
+
| Field | Type | Notes |
|
|
114
|
+
| --------- | ---------------------------------------- | ----------------------------------------- |
|
|
115
|
+
| `loading` | `string` | Title shown while the promise is pending. |
|
|
116
|
+
| `success` | `string \| ((value: T) => string)` | Title shown when the promise resolves. |
|
|
117
|
+
| `error` | `string \| ((error: unknown) => string)` | Title shown when the promise rejects. |
|
|
118
|
+
|
|
119
|
+
## Styling And Theming
|
|
120
|
+
|
|
121
|
+
The service applies `ui-toast-panel` plus `ui-toast-<variant>` panel classes to the Angular Material snack-bar container.
|
|
122
|
+
|
|
123
|
+
- `default` keeps the background and foreground tokens from the active theme.
|
|
124
|
+
- `success` uses the primary theme tokens.
|
|
125
|
+
- `info` uses the shared `info` tokens.
|
|
126
|
+
- `warning` uses the shared `warning` tokens.
|
|
127
|
+
- `error` maps to the destructive tokens.
|
|
128
|
+
|
|
129
|
+
If you need to override a variant, target the container class and set the Material snack-bar CSS custom properties:
|
|
130
|
+
|
|
131
|
+
```css
|
|
132
|
+
.mat-mdc-snack-bar-container.ui-toast-warning {
|
|
133
|
+
--mdc-snackbar-container-color: hsl(var(--warning));
|
|
134
|
+
--mdc-snackbar-supporting-text-color: hsl(var(--warning-foreground));
|
|
135
|
+
--mat-snack-bar-button-color: hsl(var(--warning-foreground));
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Accessibility
|
|
140
|
+
|
|
141
|
+
`MatSnackBar` manages live-region announcements automatically. Keep titles short, use `action` for a single primary follow-up, and avoid moving focus into the toast.
|
|
142
|
+
|
|
143
|
+
## Angular Notes
|
|
144
|
+
|
|
145
|
+
Inject the service where the interaction starts instead of creating a global host component. `MatSnackBar` shows one visible toast at a time, so `promise()` dismisses the loading state before showing its success or error follow-up.
|
|
146
|
+
|
|
147
|
+
## Source Parity
|
|
148
|
+
|
|
149
|
+
This entrypoint is the local Angular mapping for shadcn Sonner as well as the simpler toast examples in the demo. It intentionally preserves the imperative API mental model, variant coverage, and placement controls while staying honest about the implementation boundary: the runtime surface is still a focused `MatSnackBar` wrapper, not Sonner's stacked multi-toast viewport.
|
|
150
|
+
|
|
151
|
+
# Toast
|
|
152
|
+
|
|
153
|
+
Imperative notification service backed by `MatSnackBar`, styled for the local shadcn-inspired theme.
|
|
154
|
+
|
|
155
|
+
The upstream shadcn toast page is deprecated in favor of Sonner. This entrypoint remains useful for lightweight single-message flows in Angular apps, while richer stacked notification workflows can move to a future Sonner-style surface.
|
|
156
|
+
|
|
157
|
+
## Import
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { ToastService } from '@edsis/ui/toast';
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## App setup
|
|
164
|
+
|
|
165
|
+
Enable browser or noop animations so the underlying snackbar overlay can render correctly.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import type { ApplicationConfig } from '@angular/core';
|
|
169
|
+
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
|
170
|
+
|
|
171
|
+
export const appConfig: ApplicationConfig = {
|
|
172
|
+
providers: [provideAnimationsAsync()],
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Use `provideNoopAnimations()` instead when the host application deliberately disables animations.
|
|
177
|
+
|
|
178
|
+
## Structure
|
|
179
|
+
|
|
180
|
+
This entrypoint exports a service rather than a component tree. `ToastService` keeps the API at the same event-handling layer as your save, delete, archive, or publish action, while rendering is delegated to Angular Material overlays.
|
|
181
|
+
|
|
182
|
+
## Basic usage
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { inject } from '@angular/core';
|
|
186
|
+
import { ToastService } from '@edsis/ui/toast';
|
|
187
|
+
|
|
188
|
+
export class SaveButton {
|
|
189
|
+
private readonly toast = inject(ToastService);
|
|
190
|
+
|
|
191
|
+
save(): void {
|
|
192
|
+
this.toast.success({
|
|
193
|
+
title: 'Saved',
|
|
194
|
+
description: 'Your changes have been saved.',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Common patterns
|
|
201
|
+
|
|
202
|
+
### Status shortcuts
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
this.toast.show({
|
|
206
|
+
title: 'Deployment queued',
|
|
207
|
+
description: 'We will notify you when the build is ready.',
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
this.toast.success({
|
|
211
|
+
title: 'Saved',
|
|
212
|
+
description: 'Your changes have been saved.',
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
this.toast.info({
|
|
216
|
+
title: 'Heads up',
|
|
217
|
+
description: 'The deployment window starts in 10 minutes.',
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
this.toast.warning({
|
|
221
|
+
title: 'Storage almost full',
|
|
222
|
+
description: 'Archive older uploads before the next sync.',
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
this.toast.error({
|
|
226
|
+
title: 'Failed to save',
|
|
227
|
+
description: 'Network error. Please retry.',
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Persistent action
|
|
232
|
+
|
|
233
|
+
For an important action, keep the toast open and handle the snackbar action from the returned reference.
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
const ref = this.toast.show({
|
|
237
|
+
title: 'Event archived',
|
|
238
|
+
description: 'Restore it from the calendar within the next minute.',
|
|
239
|
+
action: 'Undo',
|
|
240
|
+
durationMs: null,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
ref.onAction().subscribe(() => {
|
|
244
|
+
this.toast.info({
|
|
245
|
+
title: 'Archive cancelled',
|
|
246
|
+
description: 'The event is back on the calendar.',
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Promise helper
|
|
252
|
+
|
|
253
|
+
Use `toast.promise()` when one async task should produce loading, success, and failure feedback in sequence.
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
await this.toast.promise(
|
|
257
|
+
() =>
|
|
258
|
+
new Promise<{ name: string }>((resolve) => {
|
|
259
|
+
window.setTimeout(() => resolve({ name: 'Summer launch checklist' }), 900);
|
|
260
|
+
}),
|
|
261
|
+
{
|
|
262
|
+
loading: 'Archiving draft...',
|
|
263
|
+
success: (draft) => `${draft.name} archived`,
|
|
264
|
+
error: 'Unable to archive draft',
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## API Reference
|
|
270
|
+
|
|
271
|
+
### `ToastService`
|
|
272
|
+
|
|
273
|
+
| Method | Returns | Notes |
|
|
274
|
+
| ---------------------------------- | ------------------------- | ---------------------------------------------------------- |
|
|
275
|
+
| `show(options)` | `MatSnackBarRef<unknown>` | Lowest-level method with full option control. |
|
|
276
|
+
| `success(options)` | `MatSnackBarRef<unknown>` | Shortcut for `variant: 'success'`. |
|
|
277
|
+
| `info(options)` | `MatSnackBarRef<unknown>` | Angular-local semantic shortcut. |
|
|
278
|
+
| `warning(options)` | `MatSnackBarRef<unknown>` | Angular-local semantic shortcut. |
|
|
279
|
+
| `error(options)` | `MatSnackBarRef<unknown>` | Shortcut for `variant: 'destructive'`. |
|
|
280
|
+
| `promise(taskOrFactory, messages)` | `Promise<T>` | Shows loading first, then success or destructive feedback. |
|
|
281
|
+
| `dismiss()` | `void` | Closes the active toast. |
|
|
282
|
+
|
|
283
|
+
### `ToastOptions`
|
|
284
|
+
|
|
285
|
+
| Field | Type | Default | Notes |
|
|
286
|
+
| -------------------- | ---------------------------------------------------------------- | ----------- | ---------------------------------------------------------- |
|
|
287
|
+
| `title` | `string` | unset | Primary message line. |
|
|
288
|
+
| `description` | `string` | unset | Optional secondary line. |
|
|
289
|
+
| `action` | `string` | `''` | Single action label shown by the snackbar. |
|
|
290
|
+
| `variant` | `'default' \| 'destructive' \| 'success' \| 'info' \| 'warning'` | `'default'` | Visual variant applied through `ui-toast-*` panel classes. |
|
|
291
|
+
| `durationMs` | `number \| null` | `5000` | Set to `null` to keep the toast open until dismissed. |
|
|
292
|
+
| `horizontalPosition` | `MatSnackBarConfig['horizontalPosition']` | `'end'` | Snackbar x-axis placement. |
|
|
293
|
+
| `verticalPosition` | `MatSnackBarConfig['verticalPosition']` | `'bottom'` | Snackbar y-axis placement. |
|
|
294
|
+
|
|
295
|
+
### `ToastPromiseMessages<T>`
|
|
296
|
+
|
|
297
|
+
| Field | Type | Notes |
|
|
298
|
+
| --------- | ---------------------------------------- | --------------------------------------------------- |
|
|
299
|
+
| `loading` | `string` | Required loading message while the task is pending. |
|
|
300
|
+
| `success` | `string \| ((value: T) => string)` | Static or data-derived success copy. |
|
|
301
|
+
| `error` | `string \| ((error: unknown) => string)` | Static or error-derived destructive copy. |
|
|
302
|
+
|
|
303
|
+
## Styling and theming
|
|
304
|
+
|
|
305
|
+
The service applies `ui-toast-panel` and `ui-toast-<variant>` classes on the snackbar container. The shared Material integration maps those classes to the local semantic tokens for default, destructive, success, info, and warning states, and preserves line breaks between `title` and `description`.
|
|
306
|
+
|
|
307
|
+
## Accessibility
|
|
308
|
+
|
|
309
|
+
`MatSnackBar` manages live-region announcements automatically. Keep toast copy short, reserve it for transient status updates, and prefer `durationMs: null` when the action button must stay available long enough for keyboard and assistive-technology users.
|
|
310
|
+
|
|
311
|
+
## Keyboard interactions
|
|
312
|
+
|
|
313
|
+
The toast body itself is not a roving-focus widget. Keyboard interaction is limited to the optional action button exposed by the snackbar when `action` is present.
|
|
314
|
+
|
|
315
|
+
## Angular notes
|
|
316
|
+
|
|
317
|
+
This API is intentionally Angular-first rather than a one-to-one port of Radix toast composition. You trigger notifications from event handlers or async workflows, not by managing a dedicated toast viewport in every template.
|
|
318
|
+
|
|
319
|
+
## Source parity
|
|
320
|
+
|
|
321
|
+
Default and destructive map most closely to the historical shadcn toast examples. `success`, `info`, and `warning` are Angular-local semantic additions that fit the service-style API better. The upstream shadcn page now points users to Sonner, so this entrypoint deliberately focuses on simple, single-message feedback instead of stacked queue management.
|
package/toggle/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Toggle
|
|
2
|
+
|
|
3
|
+
A two-state button that can be either on or off.
|
|
4
|
+
|
|
5
|
+
Use Toggle for persistent formatting, bookmarking, pinning, or filter state where a pressed button is the right semantic pattern.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ToggleComponent } from '@edsis/ui/toggle';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Composition
|
|
14
|
+
|
|
15
|
+
The Angular surface keeps the same single-host shape as shadcn and Radix while mapping it to a native button selector.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
button[ui-toggle]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Basic usage
|
|
22
|
+
|
|
23
|
+
Bind `[(pressed)]` when the parent should observe or control the state. The host always renders as a native button with `aria-pressed`.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
readonly bookmarked = signal(false);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<button ui-toggle aria-label="Toggle bookmark" [(pressed)]="bookmarked" variant="outline" size="sm">
|
|
31
|
+
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
32
|
+
<path d="M6 4.75c0-.41.34-.75.75-.75h10.5c.41 0 .75.34.75.75V20l-6-3.5L6 20V4.75Z" />
|
|
33
|
+
</svg>
|
|
34
|
+
Bookmark
|
|
35
|
+
</button>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Common patterns
|
|
39
|
+
|
|
40
|
+
### Outline variant
|
|
41
|
+
|
|
42
|
+
Use `variant="outline"` when the toggle should read like a bordered tool button.
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<button ui-toggle aria-label="Toggle italic" variant="outline">Italic</button>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### With text
|
|
49
|
+
|
|
50
|
+
Project an icon and visible text when the label should stay on screen.
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<button ui-toggle aria-label="Toggle italic">
|
|
54
|
+
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
55
|
+
<path d="M10 4h8" />
|
|
56
|
+
<path d="M6 20h8" />
|
|
57
|
+
<path d="M14 4 10 20" />
|
|
58
|
+
</svg>
|
|
59
|
+
Italic
|
|
60
|
+
</button>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Sizes
|
|
64
|
+
|
|
65
|
+
The toggle supports the shadcn size names `sm`, `default`, and `lg`.
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<button ui-toggle size="sm" variant="outline" aria-label="Toggle small">Small</button>
|
|
69
|
+
<button ui-toggle size="default" variant="outline" aria-label="Toggle default">Default</button>
|
|
70
|
+
<button ui-toggle size="lg" variant="outline" aria-label="Toggle large">Large</button>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Disabled state
|
|
74
|
+
|
|
75
|
+
Set `[disabled]="true"` when the control should remain visible but unavailable.
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<button ui-toggle aria-label="Toggle bookmark" [disabled]="true">Bookmark</button>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### RTL
|
|
82
|
+
|
|
83
|
+
Direction comes from the surrounding layout. The API stays the same.
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<div dir="rtl" lang="ar" class="text-right">
|
|
87
|
+
<button ui-toggle aria-label="تبديل الإشارة المرجعية" variant="outline" size="sm">إشارة مرجعية</button>
|
|
88
|
+
</div>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## API reference
|
|
92
|
+
|
|
93
|
+
| Input or model | Type | Default |
|
|
94
|
+
| -------------- | --------------------------- | ----------- |
|
|
95
|
+
| `pressed` | `boolean` | `false` |
|
|
96
|
+
| `disabled` | `boolean` | `false` |
|
|
97
|
+
| `variant` | `'default' \| 'outline'` | `'default'` |
|
|
98
|
+
| `size` | `'sm' \| 'default' \| 'lg'` | `'default'` |
|
|
99
|
+
| `class` | `string` | `''` |
|
|
100
|
+
|
|
101
|
+
Host: `button[ui-toggle]`.
|
|
102
|
+
|
|
103
|
+
The host exposes `aria-pressed`, `data-state="on|off"`, `data-variant`, `data-size`, and `data-disabled` for styling and testing hooks.
|
|
104
|
+
|
|
105
|
+
## Styling and theming
|
|
106
|
+
|
|
107
|
+
The primitive uses the shared library color tokens for `foreground`, `accent`, `muted`, `input`, and `ring`.
|
|
108
|
+
|
|
109
|
+
Use `class` to add width, shape, or layout utilities such as `rounded-full`, `w-full`, or responsive flex helpers.
|
|
110
|
+
|
|
111
|
+
## Accessibility
|
|
112
|
+
|
|
113
|
+
- `button[ui-toggle]` keeps the native button semantics and adds `aria-pressed` for the two-state pattern.
|
|
114
|
+
- Provide an `aria-label` for icon-only toggles.
|
|
115
|
+
- Use Toggle for persistent on/off state. If the control changes application state like a checkbox field, prefer the dedicated switch or checkbox primitive.
|
|
116
|
+
- Disabled toggles remain visible but non-interactive.
|
|
117
|
+
|
|
118
|
+
## Keyboard interactions
|
|
119
|
+
|
|
120
|
+
- Native button behavior covers Tab focus plus Enter and Space activation.
|
|
121
|
+
- Pressing Enter or Space toggles the `pressed` model through the native click event.
|
|
122
|
+
|
|
123
|
+
## Angular notes
|
|
124
|
+
|
|
125
|
+
- Import `ToggleComponent` into the standalone component that renders the host.
|
|
126
|
+
- `[(pressed)]` is the Angular replacement for React's `pressed` and `onPressedChange` pairing.
|
|
127
|
+
- The host always defaults to `type="button"` so it does not submit ancestor forms accidentally.
|
|
128
|
+
|
|
129
|
+
## Source parity
|
|
130
|
+
|
|
131
|
+
This Angular implementation follows the shadcn Toggle information architecture, variants, sizes, and RTL guidance while translating the runtime API to a native button host with signal-friendly two-way binding.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Toggle Group
|
|
2
|
+
|
|
3
|
+
A set of two-state buttons that can be toggled on or off with either single or multiple selection.
|
|
4
|
+
|
|
5
|
+
Use Toggle Group for formatting toolbars, persistent filters, view-mode switches, or any compact control cluster where each item represents a pressed state instead of an immediate action.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ToggleGroupComponent, ToggleGroupItemDirective } from '@edsis/ui/toggle-group';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Composition
|
|
14
|
+
|
|
15
|
+
The Angular structure keeps the same root-plus-items shape as shadcn and Radix while translating the API to strongly typed Angular bindings.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
ui-toggle-group
|
|
19
|
+
├── button[ui-toggle-group-item]
|
|
20
|
+
└── button[ui-toggle-group-item]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Basic usage
|
|
24
|
+
|
|
25
|
+
Use `[(value)]` for single-select groups and `[(values)]` for multi-select groups.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
readonly alignment = signal<string | null>('center');
|
|
29
|
+
readonly styles = signal<string[]>(['bold']);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<ui-toggle-group type="single" [(value)]="alignment" variant="outline" aria-label="Text alignment">
|
|
34
|
+
<button ui-toggle-group-item value="left" aria-label="Left aligned">Left</button>
|
|
35
|
+
<button ui-toggle-group-item value="center" aria-label="Center aligned">Center</button>
|
|
36
|
+
<button ui-toggle-group-item value="right" aria-label="Right aligned">Right</button>
|
|
37
|
+
</ui-toggle-group>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<ui-toggle-group type="multiple" [(values)]="styles" variant="outline" aria-label="Text styles">
|
|
42
|
+
<button ui-toggle-group-item value="bold" aria-label="Bold">Bold</button>
|
|
43
|
+
<button ui-toggle-group-item value="italic" aria-label="Italic">Italic</button>
|
|
44
|
+
<button ui-toggle-group-item value="underline" aria-label="Underline">Underline</button>
|
|
45
|
+
</ui-toggle-group>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Common patterns
|
|
49
|
+
|
|
50
|
+
### Outline
|
|
51
|
+
|
|
52
|
+
Use `variant="outline"` when the group should read like a bordered toolbar or filter control.
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<ui-toggle-group type="single" [(value)]="filter" variant="outline" aria-label="Message filters">
|
|
56
|
+
<button ui-toggle-group-item value="all">All</button>
|
|
57
|
+
<button ui-toggle-group-item value="missed">Missed</button>
|
|
58
|
+
</ui-toggle-group>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Size
|
|
62
|
+
|
|
63
|
+
Set `size` on the root so every child item scales together.
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<ui-toggle-group type="single" [(value)]="alignment" variant="outline" size="lg" aria-label="Large alignment">
|
|
67
|
+
<button ui-toggle-group-item value="left">Left</button>
|
|
68
|
+
<button ui-toggle-group-item value="center">Center</button>
|
|
69
|
+
<button ui-toggle-group-item value="right">Right</button>
|
|
70
|
+
</ui-toggle-group>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Spacing
|
|
74
|
+
|
|
75
|
+
Spacing defaults to `2`, matching the current shadcn docs. Use `spacing="0"` for connected items or larger values for looser toolbars.
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<ui-toggle-group type="single" [(value)]="alignment" variant="outline" spacing="0" aria-label="Connected alignment">
|
|
79
|
+
<button ui-toggle-group-item value="left">Left</button>
|
|
80
|
+
<button ui-toggle-group-item value="center">Center</button>
|
|
81
|
+
<button ui-toggle-group-item value="right">Right</button>
|
|
82
|
+
</ui-toggle-group>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Vertical orientation
|
|
86
|
+
|
|
87
|
+
Use `orientation="vertical"` to stack items while keeping the same roving-focus keyboard behavior.
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<ui-toggle-group type="multiple" [(values)]="styles" orientation="vertical" spacing="1" aria-label="Text styles">
|
|
91
|
+
<button ui-toggle-group-item value="bold" aria-label="Toggle bold">Bold</button>
|
|
92
|
+
<button ui-toggle-group-item value="italic" aria-label="Toggle italic">Italic</button>
|
|
93
|
+
<button ui-toggle-group-item value="underline" aria-label="Toggle underline">Underline</button>
|
|
94
|
+
</ui-toggle-group>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Disabled group
|
|
98
|
+
|
|
99
|
+
Disable the root when the whole cluster is unavailable.
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<ui-toggle-group
|
|
103
|
+
type="multiple"
|
|
104
|
+
[(values)]="styles"
|
|
105
|
+
variant="outline"
|
|
106
|
+
[disabled]="true"
|
|
107
|
+
aria-label="Unavailable text styles">
|
|
108
|
+
<button ui-toggle-group-item value="bold">Bold</button>
|
|
109
|
+
<button ui-toggle-group-item value="italic">Italic</button>
|
|
110
|
+
<button ui-toggle-group-item value="underline">Underline</button>
|
|
111
|
+
</ui-toggle-group>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Custom controlled state
|
|
115
|
+
|
|
116
|
+
The selected value can drive any Angular signal, such as font weight, filters, or an editor mode.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
readonly fontWeight = signal<string | null>('normal');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<ui-toggle-group type="single" [(value)]="fontWeight" variant="outline" size="lg" aria-label="Font weight">
|
|
124
|
+
<button ui-toggle-group-item value="light" class="min-w-24">Light</button>
|
|
125
|
+
<button ui-toggle-group-item value="normal" class="min-w-24">Normal</button>
|
|
126
|
+
<button ui-toggle-group-item value="medium" class="min-w-24">Medium</button>
|
|
127
|
+
<button ui-toggle-group-item value="bold" class="min-w-24">Bold</button>
|
|
128
|
+
</ui-toggle-group>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### RTL
|
|
132
|
+
|
|
133
|
+
Direction comes from the surrounding layout. Horizontal arrow navigation respects the active text direction automatically.
|
|
134
|
+
|
|
135
|
+
```html
|
|
136
|
+
<div dir="rtl" lang="ar" class="text-right">
|
|
137
|
+
<ui-toggle-group type="single" [(value)]="view" variant="outline" aria-label="طريقة العرض">
|
|
138
|
+
<button ui-toggle-group-item value="list">قائمة</button>
|
|
139
|
+
<button ui-toggle-group-item value="grid">شبكة</button>
|
|
140
|
+
<button ui-toggle-group-item value="cards">بطاقات</button>
|
|
141
|
+
</ui-toggle-group>
|
|
142
|
+
</div>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## API reference
|
|
146
|
+
|
|
147
|
+
### `ToggleGroupComponent`
|
|
148
|
+
|
|
149
|
+
| Input or model | Type | Default |
|
|
150
|
+
| -------------- | ---------------------------- | -------------- |
|
|
151
|
+
| `type` | `'single' \| 'multiple'` | required |
|
|
152
|
+
| `value` | `string \| null` | `null` |
|
|
153
|
+
| `values` | `string[]` | `[]` |
|
|
154
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
|
|
155
|
+
| `variant` | `'default' \| 'outline'` | `'default'` |
|
|
156
|
+
| `size` | `'sm' \| 'default' \| 'lg'` | `'default'` |
|
|
157
|
+
| `spacing` | `0 \| 1 \| 2 \| 3 \| 4` | `2` |
|
|
158
|
+
| `loop` | `boolean` | `true` |
|
|
159
|
+
| `disabled` | `boolean` | `false` |
|
|
160
|
+
| `dir` | `'ltr' \| 'rtl' \| null` | `null` |
|
|
161
|
+
| `class` | `string` | `''` |
|
|
162
|
+
|
|
163
|
+
### `ToggleGroupItemDirective`
|
|
164
|
+
|
|
165
|
+
| Input | Type | Default |
|
|
166
|
+
| ---------- | --------- | ------- |
|
|
167
|
+
| `value` | `string` | — |
|
|
168
|
+
| `disabled` | `boolean` | `false` |
|
|
169
|
+
| `class` | `string` | `''` |
|
|
170
|
+
|
|
171
|
+
Host: `button[ui-toggle-group-item]`.
|
|
172
|
+
|
|
173
|
+
The item host exposes `aria-pressed`, `data-state="on|off"`, `data-variant`, `data-size`, `data-orientation`, and `data-disabled` for styling and testing hooks.
|
|
174
|
+
|
|
175
|
+
## Styling and theming
|
|
176
|
+
|
|
177
|
+
- Toggle Group items intentionally share the same `variant` and `size` contract as the standalone Toggle primitive, so grouped toolbars and standalone toggles stay visually aligned.
|
|
178
|
+
- Use `spacing` for inter-item layout. When `spacing="0"`, the root collapses adjacent radius and borders so outline items read as a connected control.
|
|
179
|
+
- Use `class` on the root or an item for width, alignment, or card-like custom presentations.
|
|
180
|
+
|
|
181
|
+
## Accessibility
|
|
182
|
+
|
|
183
|
+
- `ui-toggle-group` renders `role="group"`; provide `aria-label` or `aria-labelledby` when the cluster needs an accessible name.
|
|
184
|
+
- `button[ui-toggle-group-item]` keeps native button semantics and exposes `aria-pressed` for the two-state pattern.
|
|
185
|
+
- Add an `aria-label` to icon-only items.
|
|
186
|
+
- Disabled items stay visible and are skipped by the group keyboard navigation.
|
|
187
|
+
|
|
188
|
+
## Keyboard interactions
|
|
189
|
+
|
|
190
|
+
- Tab moves focus to the pressed item or the first enabled item in the group.
|
|
191
|
+
- Enter and Space activate or deactivate the current item through the native button click.
|
|
192
|
+
- Arrow keys move focus through the group.
|
|
193
|
+
- `Home` and `End` jump to the first or last enabled item.
|
|
194
|
+
- Horizontal arrow movement respects RTL direction.
|
|
195
|
+
|
|
196
|
+
## Angular notes
|
|
197
|
+
|
|
198
|
+
- Use `[(value)]` in single mode and `[(values)]` in multiple mode instead of overloading one input with two types.
|
|
199
|
+
- The item host selector is `button[ui-toggle-group-item]`; consumers do not add `ui-toggle` separately.
|
|
200
|
+
- The root owns roving focus, so consumer templates do not need extra CDK focus utilities.
|
|
201
|
+
|
|
202
|
+
## Source parity
|
|
203
|
+
|
|
204
|
+
This Angular implementation follows the current shadcn Toggle Group docs for outline styling, size scaling, spacing, vertical orientation, disabled groups, custom controlled state, RTL behavior, and the Radix roving-focus keyboard contract.
|
|
205
|
+
|
|
206
|
+
The intentional Angular deviation is the binding split between `value` and `values`, which keeps signal types explicit for single and multiple modes.
|