@ng-cn/core 1.0.11 → 1.0.12
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/package.json +2 -1
- package/schematics/ng-add/index.js +2 -2
- package/schematics/ng-add/index.ts +2 -2
- package/src/app/lib/components/ui/accordion/accordion-content.component.ts +53 -0
- package/src/app/lib/components/ui/accordion/accordion-context.ts +33 -0
- package/src/app/lib/components/ui/accordion/accordion-item.component.ts +86 -0
- package/src/app/lib/components/ui/accordion/accordion-trigger.component.ts +73 -0
- package/src/app/lib/components/ui/accordion/accordion.component.ts +197 -0
- package/src/app/lib/components/ui/accordion/index.ts +15 -0
- package/src/app/lib/components/ui/alert/alert-description.component.ts +33 -0
- package/src/app/lib/components/ui/alert/alert-title.component.ts +30 -0
- package/src/app/lib/components/ui/alert/alert-variants.ts +23 -0
- package/src/app/lib/components/ui/alert/alert.component.ts +50 -0
- package/src/app/lib/components/ui/alert/index.ts +5 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-action.component.ts +44 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-cancel.component.ts +45 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-content.component.ts +146 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-context.ts +14 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-description.component.ts +37 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-footer.component.ts +35 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-header.component.ts +35 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-title.component.ts +37 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-trigger.component.ts +44 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog.component.ts +91 -0
- package/src/app/lib/components/ui/alert-dialog/index.ts +11 -0
- package/src/app/lib/components/ui/aspect-ratio/aspect-ratio.component.ts +63 -0
- package/src/app/lib/components/ui/aspect-ratio/index.ts +1 -0
- package/src/app/lib/components/ui/avatar/avatar-fallback.component.ts +34 -0
- package/src/app/lib/components/ui/avatar/avatar-image.component.ts +31 -0
- package/src/app/lib/components/ui/avatar/avatar.component.ts +37 -0
- package/src/app/lib/components/ui/avatar/index.ts +5 -0
- package/src/app/lib/components/ui/avatar/ui-avatar.component.ts +52 -0
- package/src/app/lib/components/ui/badge/badge-variants.ts +28 -0
- package/src/app/lib/components/ui/badge/badge.component.ts +50 -0
- package/src/app/lib/components/ui/badge/index.ts +3 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-ellipsis.component.ts +48 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-item.component.ts +28 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-link.component.ts +32 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-list.component.ts +31 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-page.component.ts +31 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-separator.component.ts +47 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb.component.ts +43 -0
- package/src/app/lib/components/ui/breadcrumb/index.ts +8 -0
- package/src/app/lib/components/ui/button/button-variants.ts +38 -0
- package/src/app/lib/components/ui/button/button.component.ts +103 -0
- package/src/app/lib/components/ui/button/index.ts +3 -0
- package/src/app/lib/components/ui/button-group/button-group-variants.ts +24 -0
- package/src/app/lib/components/ui/button-group/button-group.component.ts +57 -0
- package/src/app/lib/components/ui/button-group/index.ts +6 -0
- package/src/app/lib/components/ui/calendar/calendar.component.ts +368 -0
- package/src/app/lib/components/ui/calendar/index.ts +1 -0
- package/src/app/lib/components/ui/card/card-action.component.ts +39 -0
- package/src/app/lib/components/ui/card/card-content.component.ts +31 -0
- package/src/app/lib/components/ui/card/card-description.component.ts +31 -0
- package/src/app/lib/components/ui/card/card-footer.component.ts +34 -0
- package/src/app/lib/components/ui/card/card-header.component.ts +37 -0
- package/src/app/lib/components/ui/card/card-title.component.ts +31 -0
- package/src/app/lib/components/ui/card/card.component.ts +41 -0
- package/src/app/lib/components/ui/card/index.ts +8 -0
- package/src/app/lib/components/ui/carousel/carousel-content.component.ts +38 -0
- package/src/app/lib/components/ui/carousel/carousel-context.ts +18 -0
- package/src/app/lib/components/ui/carousel/carousel-item.component.ts +32 -0
- package/src/app/lib/components/ui/carousel/carousel-next.component.ts +54 -0
- package/src/app/lib/components/ui/carousel/carousel-previous.component.ts +54 -0
- package/src/app/lib/components/ui/carousel/carousel.component.ts +125 -0
- package/src/app/lib/components/ui/carousel/index.ts +7 -0
- package/src/app/lib/components/ui/chart/chart-container.component.ts +81 -0
- package/src/app/lib/components/ui/chart/chart-context.ts +38 -0
- package/src/app/lib/components/ui/chart/chart-legend-content.component.ts +51 -0
- package/src/app/lib/components/ui/chart/chart-legend.component.ts +28 -0
- package/src/app/lib/components/ui/chart/chart-tooltip-content.component.ts +37 -0
- package/src/app/lib/components/ui/chart/chart-tooltip.component.ts +28 -0
- package/src/app/lib/components/ui/chart/chart.component.ts +308 -0
- package/src/app/lib/components/ui/chart/index.ts +16 -0
- package/src/app/lib/components/ui/checkbox/checkbox.component.ts +203 -0
- package/src/app/lib/components/ui/checkbox/index.ts +1 -0
- package/src/app/lib/components/ui/collapsible/collapsible-content.component.ts +58 -0
- package/src/app/lib/components/ui/collapsible/collapsible-context.ts +17 -0
- package/src/app/lib/components/ui/collapsible/collapsible-trigger.component.ts +56 -0
- package/src/app/lib/components/ui/collapsible/collapsible.component.ts +102 -0
- package/src/app/lib/components/ui/collapsible/index.ts +5 -0
- package/src/app/lib/components/ui/combobox/combobox-content.component.ts +59 -0
- package/src/app/lib/components/ui/combobox/combobox-context.ts +49 -0
- package/src/app/lib/components/ui/combobox/combobox-empty.component.ts +35 -0
- package/src/app/lib/components/ui/combobox/combobox-group.component.ts +32 -0
- package/src/app/lib/components/ui/combobox/combobox-input.component.ts +89 -0
- package/src/app/lib/components/ui/combobox/combobox-item.component.ts +129 -0
- package/src/app/lib/components/ui/combobox/combobox-list.component.ts +40 -0
- package/src/app/lib/components/ui/combobox/combobox-trigger.component.ts +53 -0
- package/src/app/lib/components/ui/combobox/combobox-value.component.ts +47 -0
- package/src/app/lib/components/ui/combobox/combobox.component.ts +290 -0
- package/src/app/lib/components/ui/combobox/index.ts +15 -0
- package/src/app/lib/components/ui/command/command-context.ts +24 -0
- package/src/app/lib/components/ui/command/command-dialog.component.ts +69 -0
- package/src/app/lib/components/ui/command/command-empty.component.ts +23 -0
- package/src/app/lib/components/ui/command/command-group.component.ts +66 -0
- package/src/app/lib/components/ui/command/command-input.component.ts +137 -0
- package/src/app/lib/components/ui/command/command-item.component.ts +148 -0
- package/src/app/lib/components/ui/command/command-list.component.ts +30 -0
- package/src/app/lib/components/ui/command/command-separator.component.ts +23 -0
- package/src/app/lib/components/ui/command/command-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/command/command.component.ts +105 -0
- package/src/app/lib/components/ui/command/index.ts +11 -0
- package/src/app/lib/components/ui/context-menu/context-menu-checkbox-item.component.ts +68 -0
- package/src/app/lib/components/ui/context-menu/context-menu-content.component.ts +213 -0
- package/src/app/lib/components/ui/context-menu/context-menu-context.ts +17 -0
- package/src/app/lib/components/ui/context-menu/context-menu-item.component.ts +63 -0
- package/src/app/lib/components/ui/context-menu/context-menu-label.component.ts +30 -0
- package/src/app/lib/components/ui/context-menu/context-menu-radio-group.component.ts +36 -0
- package/src/app/lib/components/ui/context-menu/context-menu-radio-item.component.ts +71 -0
- package/src/app/lib/components/ui/context-menu/context-menu-separator.component.ts +24 -0
- package/src/app/lib/components/ui/context-menu/context-menu-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub-trigger.component.ts +50 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub.component.ts +31 -0
- package/src/app/lib/components/ui/context-menu/context-menu-trigger.component.ts +51 -0
- package/src/app/lib/components/ui/context-menu/context-menu.component.ts +27 -0
- package/src/app/lib/components/ui/context-menu/index.ts +15 -0
- package/src/app/lib/components/ui/data-table/data-table-content.component.ts +226 -0
- package/src/app/lib/components/ui/data-table/data-table-context.ts +49 -0
- package/src/app/lib/components/ui/data-table/data-table-pagination.component.ts +138 -0
- package/src/app/lib/components/ui/data-table/data-table-search.component.ts +52 -0
- package/src/app/lib/components/ui/data-table/data-table-toolbar.component.ts +27 -0
- package/src/app/lib/components/ui/data-table/data-table-view-options.component.ts +92 -0
- package/src/app/lib/components/ui/data-table/data-table.component.ts +131 -0
- package/src/app/lib/components/ui/data-table/index.ts +16 -0
- package/src/app/lib/components/ui/date-picker/date-picker.component.ts +94 -0
- package/src/app/lib/components/ui/date-picker/index.ts +1 -0
- package/src/app/lib/components/ui/dialog/dialog-close.component.ts +31 -0
- package/src/app/lib/components/ui/dialog/dialog-content.component.ts +177 -0
- package/src/app/lib/components/ui/dialog/dialog-context.ts +15 -0
- package/src/app/lib/components/ui/dialog/dialog-description.component.ts +34 -0
- package/src/app/lib/components/ui/dialog/dialog-footer.component.ts +28 -0
- package/src/app/lib/components/ui/dialog/dialog-header.component.ts +28 -0
- package/src/app/lib/components/ui/dialog/dialog-title.component.ts +34 -0
- package/src/app/lib/components/ui/dialog/dialog-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/dialog/dialog.component.ts +87 -0
- package/src/app/lib/components/ui/dialog/index.ts +10 -0
- package/src/app/lib/components/ui/drawer/drawer-close.component.ts +31 -0
- package/src/app/lib/components/ui/drawer/drawer-content.component.ts +143 -0
- package/src/app/lib/components/ui/drawer/drawer-context.ts +17 -0
- package/src/app/lib/components/ui/drawer/drawer-description.component.ts +33 -0
- package/src/app/lib/components/ui/drawer/drawer-footer.component.ts +28 -0
- package/src/app/lib/components/ui/drawer/drawer-header.component.ts +28 -0
- package/src/app/lib/components/ui/drawer/drawer-title.component.ts +33 -0
- package/src/app/lib/components/ui/drawer/drawer-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/drawer/drawer.component.ts +93 -0
- package/src/app/lib/components/ui/drawer/index.ts +10 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.component.ts +68 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-content.component.ts +234 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-context.ts +15 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-group.component.ts +15 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-item.component.ts +56 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-label.component.ts +30 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.component.ts +42 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.component.ts +71 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-separator.component.ts +24 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.component.ts +53 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub.component.ts +31 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-trigger.component.ts +45 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu.component.ts +32 -0
- package/src/app/lib/components/ui/dropdown-menu/index.ts +16 -0
- package/src/app/lib/components/ui/empty/empty-action.component.ts +28 -0
- package/src/app/lib/components/ui/empty/empty-description.component.ts +31 -0
- package/src/app/lib/components/ui/empty/empty-icon.component.ts +31 -0
- package/src/app/lib/components/ui/empty/empty-title.component.ts +28 -0
- package/src/app/lib/components/ui/empty/empty.component.ts +53 -0
- package/src/app/lib/components/ui/empty/index.ts +6 -0
- package/src/app/lib/components/ui/form/form-context.ts +34 -0
- package/src/app/lib/components/ui/form/form-control.component.ts +137 -0
- package/src/app/lib/components/ui/form/form-description.component.ts +37 -0
- package/src/app/lib/components/ui/form/form-field.component.ts +84 -0
- package/src/app/lib/components/ui/form/form-item.component.ts +42 -0
- package/src/app/lib/components/ui/form/form-label.component.ts +58 -0
- package/src/app/lib/components/ui/form/form-message.component.ts +107 -0
- package/src/app/lib/components/ui/form/form.component.ts +123 -0
- package/src/app/lib/components/ui/form/index.ts +17 -0
- package/src/app/lib/components/ui/hover-card/hover-card-content.component.ts +203 -0
- package/src/app/lib/components/ui/hover-card/hover-card-context.ts +25 -0
- package/src/app/lib/components/ui/hover-card/hover-card-trigger.component.ts +160 -0
- package/src/app/lib/components/ui/hover-card/hover-card.component.ts +147 -0
- package/src/app/lib/components/ui/hover-card/index.ts +13 -0
- package/src/app/lib/components/ui/index.ts +551 -0
- package/src/app/lib/components/ui/input/index.ts +1 -0
- package/src/app/lib/components/ui/input/input.component.ts +165 -0
- package/src/app/lib/components/ui/input-group/index.ts +4 -0
- package/src/app/lib/components/ui/input-group/input-group-addon.component.ts +43 -0
- package/src/app/lib/components/ui/input-group/input-group-input.component.ts +33 -0
- package/src/app/lib/components/ui/input-group/input-group.component.ts +53 -0
- package/src/app/lib/components/ui/input-otp/index.ts +14 -0
- package/src/app/lib/components/ui/input-otp/input-otp-context.ts +31 -0
- package/src/app/lib/components/ui/input-otp/input-otp-group.component.ts +23 -0
- package/src/app/lib/components/ui/input-otp/input-otp-separator.component.ts +31 -0
- package/src/app/lib/components/ui/input-otp/input-otp-slot.component.ts +67 -0
- package/src/app/lib/components/ui/input-otp/input-otp.component.ts +240 -0
- package/src/app/lib/components/ui/kbd/index.ts +3 -0
- package/src/app/lib/components/ui/kbd/kbd-variants.ts +23 -0
- package/src/app/lib/components/ui/kbd/kbd.component.ts +50 -0
- package/src/app/lib/components/ui/label/index.ts +1 -0
- package/src/app/lib/components/ui/label/label.component.ts +139 -0
- package/src/app/lib/components/ui/menubar/index.ts +26 -0
- package/src/app/lib/components/ui/menubar/menubar-checkbox-item.component.ts +66 -0
- package/src/app/lib/components/ui/menubar/menubar-content.component.ts +236 -0
- package/src/app/lib/components/ui/menubar/menubar-context.ts +63 -0
- package/src/app/lib/components/ui/menubar/menubar-item.component.ts +60 -0
- package/src/app/lib/components/ui/menubar/menubar-label.component.ts +30 -0
- package/src/app/lib/components/ui/menubar/menubar-menu.component.ts +40 -0
- package/src/app/lib/components/ui/menubar/menubar-radio-group.component.ts +36 -0
- package/src/app/lib/components/ui/menubar/menubar-radio-item.component.ts +66 -0
- package/src/app/lib/components/ui/menubar/menubar-separator.component.ts +24 -0
- package/src/app/lib/components/ui/menubar/menubar-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/menubar/menubar-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/menubar/menubar-sub-trigger.component.ts +50 -0
- package/src/app/lib/components/ui/menubar/menubar-sub.component.ts +29 -0
- package/src/app/lib/components/ui/menubar/menubar-trigger.component.ts +132 -0
- package/src/app/lib/components/ui/menubar/menubar.component.ts +158 -0
- package/src/app/lib/components/ui/native-select/index.ts +6 -0
- package/src/app/lib/components/ui/native-select/native-select-variants.ts +23 -0
- package/src/app/lib/components/ui/native-select/native-select.component.ts +74 -0
- package/src/app/lib/components/ui/navigation-menu/index.ts +21 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-content.component.ts +66 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-context.ts +55 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-indicator.component.ts +28 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-item.component.ts +29 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-link.component.ts +43 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-list.component.ts +26 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger-style.ts +7 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger.component.ts +58 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-viewport.component.ts +26 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu.component.ts +149 -0
- package/src/app/lib/components/ui/pagination/index.ts +8 -0
- package/src/app/lib/components/ui/pagination/pagination-content.component.ts +28 -0
- package/src/app/lib/components/ui/pagination/pagination-ellipsis.component.ts +47 -0
- package/src/app/lib/components/ui/pagination/pagination-item.component.ts +28 -0
- package/src/app/lib/components/ui/pagination/pagination-link.component.ts +46 -0
- package/src/app/lib/components/ui/pagination/pagination-next.component.ts +54 -0
- package/src/app/lib/components/ui/pagination/pagination-previous.component.ts +54 -0
- package/src/app/lib/components/ui/pagination/pagination.component.ts +48 -0
- package/src/app/lib/components/ui/popover/index.ts +14 -0
- package/src/app/lib/components/ui/popover/popover-anchor.component.ts +64 -0
- package/src/app/lib/components/ui/popover/popover-content.component.ts +231 -0
- package/src/app/lib/components/ui/popover/popover-context.ts +29 -0
- package/src/app/lib/components/ui/popover/popover-trigger.component.ts +100 -0
- package/src/app/lib/components/ui/popover/popover.component.ts +163 -0
- package/src/app/lib/components/ui/progress/index.ts +6 -0
- package/src/app/lib/components/ui/progress/progress.component.ts +212 -0
- package/src/app/lib/components/ui/radio-group/index.ts +10 -0
- package/src/app/lib/components/ui/radio-group/radio-group-context.ts +38 -0
- package/src/app/lib/components/ui/radio-group/radio-group-item.component.ts +298 -0
- package/src/app/lib/components/ui/radio-group/radio-group.component.ts +275 -0
- package/src/app/lib/components/ui/resizable/index.ts +5 -0
- package/src/app/lib/components/ui/resizable/resizable-context.ts +14 -0
- package/src/app/lib/components/ui/resizable/resizable-handle.component.ts +232 -0
- package/src/app/lib/components/ui/resizable/resizable-panel-group.component.ts +140 -0
- package/src/app/lib/components/ui/resizable/resizable-panel.component.ts +77 -0
- package/src/app/lib/components/ui/scroll-area/index.ts +8 -0
- package/src/app/lib/components/ui/scroll-area/scroll-area.component.ts +126 -0
- package/src/app/lib/components/ui/scroll-area/scroll-bar.component.ts +93 -0
- package/src/app/lib/components/ui/segmented/index.ts +13 -0
- package/src/app/lib/components/ui/segmented/segmented-context.ts +11 -0
- package/src/app/lib/components/ui/segmented/segmented-item.component.ts +72 -0
- package/src/app/lib/components/ui/segmented/segmented-variants.ts +40 -0
- package/src/app/lib/components/ui/segmented/segmented.component.ts +99 -0
- package/src/app/lib/components/ui/select/index.ts +19 -0
- package/src/app/lib/components/ui/select/select-content.component.ts +97 -0
- package/src/app/lib/components/ui/select/select-context.ts +53 -0
- package/src/app/lib/components/ui/select/select-group.component.ts +56 -0
- package/src/app/lib/components/ui/select/select-item.component.ts +163 -0
- package/src/app/lib/components/ui/select/select-label.component.ts +32 -0
- package/src/app/lib/components/ui/select/select-separator.component.ts +34 -0
- package/src/app/lib/components/ui/select/select-trigger.component.ts +164 -0
- package/src/app/lib/components/ui/select/select-value.component.ts +49 -0
- package/src/app/lib/components/ui/select/select.component.ts +263 -0
- package/src/app/lib/components/ui/separator/index.ts +6 -0
- package/src/app/lib/components/ui/separator/separator.component.ts +128 -0
- package/src/app/lib/components/ui/sheet/index.ts +11 -0
- package/src/app/lib/components/ui/sheet/sheet-close.component.ts +32 -0
- package/src/app/lib/components/ui/sheet/sheet-content.component.ts +157 -0
- package/src/app/lib/components/ui/sheet/sheet-context.ts +15 -0
- package/src/app/lib/components/ui/sheet/sheet-description.component.ts +34 -0
- package/src/app/lib/components/ui/sheet/sheet-footer.component.ts +28 -0
- package/src/app/lib/components/ui/sheet/sheet-header.component.ts +28 -0
- package/src/app/lib/components/ui/sheet/sheet-title.component.ts +34 -0
- package/src/app/lib/components/ui/sheet/sheet-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/sheet/sheet-variants.ts +22 -0
- package/src/app/lib/components/ui/sheet/sheet.component.ts +97 -0
- package/src/app/lib/components/ui/sidebar/index.ts +41 -0
- package/src/app/lib/components/ui/sidebar/sidebar-content.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-context.ts +33 -0
- package/src/app/lib/components/ui/sidebar/sidebar-footer.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-action.component.ts +33 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-content.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-label.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-header.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-input.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-inset.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-action.component.ts +56 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-badge.component.ts +42 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-button.component.ts +64 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-item.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-skeleton.component.ts +39 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-button.component.ts +59 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-item.component.ts +25 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-provider.component.ts +141 -0
- package/src/app/lib/components/ui/sidebar/sidebar-rail.component.ts +47 -0
- package/src/app/lib/components/ui/sidebar/sidebar-route-active.service.ts +124 -0
- package/src/app/lib/components/ui/sidebar/sidebar-separator.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-trigger.component.ts +57 -0
- package/src/app/lib/components/ui/sidebar/sidebar.component.ts +130 -0
- package/src/app/lib/components/ui/skeleton/index.ts +1 -0
- package/src/app/lib/components/ui/skeleton/skeleton.component.ts +52 -0
- package/src/app/lib/components/ui/slider/index.ts +6 -0
- package/src/app/lib/components/ui/slider/slider.component.ts +477 -0
- package/src/app/lib/components/ui/spinner/index.ts +3 -0
- package/src/app/lib/components/ui/spinner/spinner-variants.ts +32 -0
- package/src/app/lib/components/ui/spinner/spinner.component.ts +77 -0
- package/src/app/lib/components/ui/switch/index.ts +6 -0
- package/src/app/lib/components/ui/switch/switch.component.ts +282 -0
- package/src/app/lib/components/ui/table/index.ts +9 -0
- package/src/app/lib/components/ui/table/table-body.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-caption.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-cell.component.ts +31 -0
- package/src/app/lib/components/ui/table/table-footer.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-head.component.ts +36 -0
- package/src/app/lib/components/ui/table/table-header.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-row.component.ts +34 -0
- package/src/app/lib/components/ui/table/table.component.ts +52 -0
- package/src/app/lib/components/ui/tabs/index.ts +14 -0
- package/src/app/lib/components/ui/tabs/tabs-content.component.ts +132 -0
- package/src/app/lib/components/ui/tabs/tabs-context.ts +33 -0
- package/src/app/lib/components/ui/tabs/tabs-list.component.ts +228 -0
- package/src/app/lib/components/ui/tabs/tabs-trigger.component.ts +167 -0
- package/src/app/lib/components/ui/tabs/tabs.component.ts +203 -0
- package/src/app/lib/components/ui/textarea/index.ts +1 -0
- package/src/app/lib/components/ui/textarea/textarea.component.ts +44 -0
- package/src/app/lib/components/ui/toast/index.ts +16 -0
- package/src/app/lib/components/ui/toast/toast-action.component.ts +77 -0
- package/src/app/lib/components/ui/toast/toast-description.component.ts +52 -0
- package/src/app/lib/components/ui/toast/toast-title.component.ts +52 -0
- package/src/app/lib/components/ui/toast/toast-variants.ts +24 -0
- package/src/app/lib/components/ui/toast/toast.component.ts +177 -0
- package/src/app/lib/components/ui/toast/toast.service.ts +202 -0
- package/src/app/lib/components/ui/toast/toaster.component.ts +128 -0
- package/src/app/lib/components/ui/toggle/index.ts +6 -0
- package/src/app/lib/components/ui/toggle/toggle-variants.ts +30 -0
- package/src/app/lib/components/ui/toggle/toggle.component.ts +199 -0
- package/src/app/lib/components/ui/toggle-group/index.ts +11 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group-context.ts +48 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group-item.component.ts +241 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group.component.ts +288 -0
- package/src/app/lib/components/ui/tooltip/index.ts +14 -0
- package/src/app/lib/components/ui/tooltip/tooltip-content.component.ts +154 -0
- package/src/app/lib/components/ui/tooltip/tooltip-context.ts +29 -0
- package/src/app/lib/components/ui/tooltip/tooltip-provider.component.ts +95 -0
- package/src/app/lib/components/ui/tooltip/tooltip-trigger.component.ts +138 -0
- package/src/app/lib/components/ui/tooltip/tooltip.component.ts +159 -0
- package/src/app/lib/components/ui/typography/index.ts +13 -0
- package/src/app/lib/components/ui/typography/typography-blockquote.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-h1.component.ts +32 -0
- package/src/app/lib/components/ui/typography/typography-h2.component.ts +32 -0
- package/src/app/lib/components/ui/typography/typography-h3.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-h4.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-inline-code.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-large.component.ts +28 -0
- package/src/app/lib/components/ui/typography/typography-lead.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-list.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-muted.component.ts +28 -0
- package/src/app/lib/components/ui/typography/typography-p.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-small.component.ts +28 -0
- package/src/app/lib/index.ts +7 -0
- package/src/app/lib/utils/accessibility/aria-id.service.ts +118 -0
- package/src/app/lib/utils/accessibility/click-outside.directive.ts +85 -0
- package/src/app/lib/utils/accessibility/focus-management.service.ts +231 -0
- package/src/app/lib/utils/accessibility/focus-trap.directive.ts +203 -0
- package/src/app/lib/utils/accessibility/index.ts +23 -0
- package/src/app/lib/utils/accessibility/keyboard-navigation.directive.ts +440 -0
- package/src/app/lib/utils/accessibility/live-region.directive.ts +260 -0
- package/src/app/lib/utils/accessibility/touch-target.directive.ts +81 -0
- package/src/app/lib/utils/accessibility/visually-hidden.component.ts +79 -0
- package/src/app/lib/utils/animation/animated.directive.ts +191 -0
- package/src/app/lib/utils/animation/animation-tokens.service.ts +88 -0
- package/src/app/lib/utils/animation/animation.types.ts +55 -0
- package/src/app/lib/utils/animation/animation.utils.ts +158 -0
- package/src/app/lib/utils/animation/index.ts +17 -0
- package/src/app/lib/utils/animation/presence.component.ts +168 -0
- package/src/app/lib/utils/animation/presence.directive.ts +169 -0
- package/src/app/lib/utils/cn.ts +15 -0
- package/src/app/lib/utils/index.ts +11 -0
- package/src/app/lib/utils/positioning/index.ts +218 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { computed, Injectable, signal } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Types
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Toast variant types for different notification styles
|
|
9
|
+
*/
|
|
10
|
+
export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Position options for toast placement
|
|
14
|
+
*/
|
|
15
|
+
export type ToastPosition =
|
|
16
|
+
| 'top-left'
|
|
17
|
+
| 'top-center'
|
|
18
|
+
| 'top-right'
|
|
19
|
+
| 'bottom-left'
|
|
20
|
+
| 'bottom-center'
|
|
21
|
+
| 'bottom-right';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Swipe direction for dismissing toasts
|
|
25
|
+
*/
|
|
26
|
+
export type ToastSwipeDirection = 'up' | 'down' | 'left' | 'right';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Toast data structure
|
|
30
|
+
*/
|
|
31
|
+
export interface Toast {
|
|
32
|
+
/** Unique identifier for the toast */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Title text displayed prominently */
|
|
35
|
+
title?: string;
|
|
36
|
+
/** Description text with more details */
|
|
37
|
+
description?: string;
|
|
38
|
+
/** Visual variant of the toast */
|
|
39
|
+
type: ToastType;
|
|
40
|
+
/** Duration in ms before auto-dismiss (0 = persistent) */
|
|
41
|
+
duration?: number;
|
|
42
|
+
/** Optional action button configuration */
|
|
43
|
+
action?: {
|
|
44
|
+
label: string;
|
|
45
|
+
onClick: () => void;
|
|
46
|
+
};
|
|
47
|
+
/** Callback when toast is dismissed */
|
|
48
|
+
onDismiss?: () => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Options for creating a toast
|
|
53
|
+
*/
|
|
54
|
+
export interface ToastOptions {
|
|
55
|
+
/** Title text displayed prominently */
|
|
56
|
+
title?: string;
|
|
57
|
+
/** Description text with more details */
|
|
58
|
+
description?: string;
|
|
59
|
+
/** Duration in ms before auto-dismiss (0 = persistent)
|
|
60
|
+
* @default 4000 */
|
|
61
|
+
duration?: number;
|
|
62
|
+
/** Optional action button configuration */
|
|
63
|
+
action?: {
|
|
64
|
+
label: string;
|
|
65
|
+
onClick: () => void;
|
|
66
|
+
};
|
|
67
|
+
/** Callback when toast is dismissed */
|
|
68
|
+
onDismiss?: () => void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Service
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @service ToastService
|
|
77
|
+
*
|
|
78
|
+
* Service for managing toast notifications throughout the application.
|
|
79
|
+
*
|
|
80
|
+
* @description
|
|
81
|
+
* ToastService provides a centralized way to display toast notifications.
|
|
82
|
+
* It manages toast state, handles auto-dismissal, and supports multiple
|
|
83
|
+
* toast variants for different notification types.
|
|
84
|
+
*
|
|
85
|
+
* ## Features
|
|
86
|
+
* - Multiple toast variants (default, success, error, warning, info)
|
|
87
|
+
* - Auto-dismiss with configurable duration
|
|
88
|
+
* - Persistent toasts (duration = 0)
|
|
89
|
+
* - Action buttons in toasts
|
|
90
|
+
* - Dismiss callbacks
|
|
91
|
+
* - Dismiss all functionality
|
|
92
|
+
*
|
|
93
|
+
* ## Usage
|
|
94
|
+
* The service is provided at root level and can be injected anywhere.
|
|
95
|
+
*
|
|
96
|
+
* @example Basic usage
|
|
97
|
+
* ```typescript
|
|
98
|
+
* export class MyComponent {
|
|
99
|
+
* private toast = inject(ToastService);
|
|
100
|
+
*
|
|
101
|
+
* showNotification() {
|
|
102
|
+
* this.toast.success({
|
|
103
|
+
* title: 'Saved!',
|
|
104
|
+
* description: 'Your changes have been saved.',
|
|
105
|
+
* });
|
|
106
|
+
* }
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @example With action button
|
|
111
|
+
* ```typescript
|
|
112
|
+
* this.toast.error({
|
|
113
|
+
* title: 'Error occurred',
|
|
114
|
+
* description: 'Failed to save changes.',
|
|
115
|
+
* action: {
|
|
116
|
+
* label: 'Retry',
|
|
117
|
+
* onClick: () => this.save(),
|
|
118
|
+
* },
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @example Persistent toast
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const id = this.toast.info({
|
|
125
|
+
* title: 'Uploading...',
|
|
126
|
+
* description: 'Please wait while we upload your file.',
|
|
127
|
+
* duration: 0, // Won't auto-dismiss
|
|
128
|
+
* });
|
|
129
|
+
*
|
|
130
|
+
* // Later, dismiss manually
|
|
131
|
+
* this.toast.dismiss(id);
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
@Injectable({ providedIn: 'root' })
|
|
135
|
+
export class ToastService {
|
|
136
|
+
private readonly _toasts = signal<Toast[]>([]);
|
|
137
|
+
|
|
138
|
+
/** Reactive list of active toasts */
|
|
139
|
+
readonly toasts = computed(() => this._toasts());
|
|
140
|
+
|
|
141
|
+
private generateId(): string {
|
|
142
|
+
return Math.random().toString(36).substring(2, 9);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private addToast(toast: Omit<Toast, 'id'>): string {
|
|
146
|
+
const id = this.generateId();
|
|
147
|
+
const newToast: Toast = { ...toast, id };
|
|
148
|
+
|
|
149
|
+
this._toasts.update(toasts => [...toasts, newToast]);
|
|
150
|
+
|
|
151
|
+
const duration = toast.duration ?? 4000;
|
|
152
|
+
if (duration > 0) {
|
|
153
|
+
setTimeout(() => this.dismiss(id), duration);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return id;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Show a default toast */
|
|
160
|
+
toast(options: ToastOptions): string {
|
|
161
|
+
return this.addToast({ ...options, type: 'default' });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Show a success toast */
|
|
165
|
+
success(options: ToastOptions): string {
|
|
166
|
+
return this.addToast({ ...options, type: 'success' });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Show an error toast */
|
|
170
|
+
error(options: ToastOptions): string {
|
|
171
|
+
return this.addToast({ ...options, type: 'error' });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Show a warning toast */
|
|
175
|
+
warning(options: ToastOptions): string {
|
|
176
|
+
return this.addToast({ ...options, type: 'warning' });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Show an info toast */
|
|
180
|
+
info(options: ToastOptions): string {
|
|
181
|
+
return this.addToast({ ...options, type: 'info' });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Dismiss a specific toast by ID */
|
|
185
|
+
dismiss(id: string): void {
|
|
186
|
+
const toast = this._toasts().find(t => t.id === id);
|
|
187
|
+
if (toast?.onDismiss) {
|
|
188
|
+
toast.onDismiss();
|
|
189
|
+
}
|
|
190
|
+
this._toasts.update(toasts => toasts.filter(t => t.id !== id));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Dismiss all active toasts */
|
|
194
|
+
dismissAll(): void {
|
|
195
|
+
this._toasts().forEach(toast => {
|
|
196
|
+
if (toast.onDismiss) {
|
|
197
|
+
toast.onDismiss();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
this._toasts.set([]);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
|
|
3
|
+
import { ToastAction } from './toast-action.component';
|
|
4
|
+
import { ToastDescription } from './toast-description.component';
|
|
5
|
+
import { ToastTitle } from './toast-title.component';
|
|
6
|
+
import { Toast } from './toast.component';
|
|
7
|
+
import { ToastService, type ToastPosition } from './toast.service';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Props for the Toaster component
|
|
15
|
+
*/
|
|
16
|
+
export interface ToasterProps {
|
|
17
|
+
/** Position of the toast container.
|
|
18
|
+
* @default "bottom-right" */
|
|
19
|
+
position?: ToastPosition;
|
|
20
|
+
/** Additional CSS classes */
|
|
21
|
+
class?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Component
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @component Toaster
|
|
30
|
+
*
|
|
31
|
+
* Container component that renders all active toasts from ToastService.
|
|
32
|
+
*
|
|
33
|
+
* @description
|
|
34
|
+
* Toaster is a viewport component that displays all active toasts. It should
|
|
35
|
+
* be placed once in your app layout (typically in app.component) and will
|
|
36
|
+
* automatically render toasts created via ToastService.
|
|
37
|
+
*
|
|
38
|
+
* ## Features
|
|
39
|
+
* - Multiple position options
|
|
40
|
+
* - Automatic toast rendering
|
|
41
|
+
* - Stacking animations
|
|
42
|
+
* - Responsive design
|
|
43
|
+
* - Live region for accessibility
|
|
44
|
+
*
|
|
45
|
+
* ## Accessibility
|
|
46
|
+
* - Uses `role="region"` for landmark navigation
|
|
47
|
+
* - `aria-live="polite"` for screen reader announcements
|
|
48
|
+
* - `aria-relevant="additions"` to announce new toasts
|
|
49
|
+
*
|
|
50
|
+
* @example Basic usage
|
|
51
|
+
* ```html
|
|
52
|
+
* <!-- In your app.component.html -->
|
|
53
|
+
* <Toaster />
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example Custom position
|
|
57
|
+
* ```html
|
|
58
|
+
* <Toaster position="top-center" />
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example With custom styling
|
|
62
|
+
* ```html
|
|
63
|
+
* <Toaster position="bottom-left" class="md:max-w-[350px]" />
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
@Component({
|
|
67
|
+
selector: 'Toaster',
|
|
68
|
+
imports: [Toast, ToastTitle, ToastDescription, ToastAction],
|
|
69
|
+
template: `
|
|
70
|
+
<div
|
|
71
|
+
[class]="computedClass()"
|
|
72
|
+
role="region"
|
|
73
|
+
aria-label="Notifications"
|
|
74
|
+
aria-live="polite"
|
|
75
|
+
aria-relevant="additions"
|
|
76
|
+
>
|
|
77
|
+
@for (toast of toastService.toasts(); track toast.id) {
|
|
78
|
+
<Toast
|
|
79
|
+
[variant]="toast.type"
|
|
80
|
+
(onClose)="toastService.dismiss(toast.id)"
|
|
81
|
+
>
|
|
82
|
+
@if (toast.title) {
|
|
83
|
+
<ToastTitle>{{ toast.title }}</ToastTitle>
|
|
84
|
+
}
|
|
85
|
+
@if (toast.description) {
|
|
86
|
+
<ToastDescription>{{ toast.description }}</ToastDescription>
|
|
87
|
+
}
|
|
88
|
+
@if (toast.action) {
|
|
89
|
+
<ToastAction (onClick)="toast.action.onClick()">
|
|
90
|
+
{{ toast.action.label }}
|
|
91
|
+
</ToastAction>
|
|
92
|
+
}
|
|
93
|
+
</Toast>
|
|
94
|
+
}
|
|
95
|
+
</div>
|
|
96
|
+
`,
|
|
97
|
+
host: {
|
|
98
|
+
class: 'contents',
|
|
99
|
+
'ngSkipHydration': 'true',
|
|
100
|
+
},
|
|
101
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
102
|
+
})
|
|
103
|
+
export class Toaster {
|
|
104
|
+
protected readonly toastService = inject(ToastService);
|
|
105
|
+
|
|
106
|
+
/** Position of the toast container */
|
|
107
|
+
readonly position = input<ToastPosition>('bottom-right');
|
|
108
|
+
|
|
109
|
+
/** Additional CSS classes */
|
|
110
|
+
readonly class = input<string>('');
|
|
111
|
+
|
|
112
|
+
protected readonly computedClass = computed(() => {
|
|
113
|
+
const positionClasses: Record<ToastPosition, string> = {
|
|
114
|
+
'top-left': 'top-0 left-0',
|
|
115
|
+
'top-center': 'top-0 left-1/2 -translate-x-1/2',
|
|
116
|
+
'top-right': 'top-0 right-0',
|
|
117
|
+
'bottom-left': 'bottom-0 left-0',
|
|
118
|
+
'bottom-center': 'bottom-0 left-1/2 -translate-x-1/2',
|
|
119
|
+
'bottom-right': 'bottom-0 right-0',
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return cn(
|
|
123
|
+
'fixed z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:flex-col md:max-w-[420px]',
|
|
124
|
+
positionClasses[this.position()],
|
|
125
|
+
this.class()
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Toggle variants using class-variance-authority
|
|
5
|
+
* Matches shadcn/ui React toggle exactly
|
|
6
|
+
* WCAG AA compliant contrast ratios for all variants
|
|
7
|
+
*/
|
|
8
|
+
export const toggleVariants = cva(
|
|
9
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-foreground transition-colors hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: 'bg-transparent',
|
|
14
|
+
outline:
|
|
15
|
+
'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
default: 'h-9 px-2 min-w-9',
|
|
19
|
+
sm: 'h-8 px-1.5 min-w-8',
|
|
20
|
+
lg: 'h-10 px-2.5 min-w-10',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: 'default',
|
|
25
|
+
size: 'default',
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export type ToggleVariants = VariantProps<typeof toggleVariants>;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
forwardRef,
|
|
7
|
+
input,
|
|
8
|
+
model,
|
|
9
|
+
output,
|
|
10
|
+
} from '@angular/core';
|
|
11
|
+
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
12
|
+
import { toggleVariants, type ToggleVariants } from './toggle-variants';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Types
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
export type ToggleState = 'on' | 'off';
|
|
19
|
+
|
|
20
|
+
export type ToggleProps = {
|
|
21
|
+
/** The controlled pressed state */
|
|
22
|
+
pressed?: boolean;
|
|
23
|
+
/** Whether the toggle starts pressed (uncontrolled) */
|
|
24
|
+
defaultPressed?: boolean;
|
|
25
|
+
/** Whether the toggle is disabled */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** The visual style variant */
|
|
28
|
+
variant?: ToggleVariants['variant'];
|
|
29
|
+
/** The size of the toggle */
|
|
30
|
+
size?: ToggleVariants['size'];
|
|
31
|
+
/** Additional CSS classes */
|
|
32
|
+
class?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Toggle Component
|
|
37
|
+
// ============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Toggle component - a two-state button that can be on or off.
|
|
41
|
+
* Based on Radix UI Toggle primitive with shadcn/ui styling.
|
|
42
|
+
* Implements ControlValueAccessor for Angular Forms integration.
|
|
43
|
+
*
|
|
44
|
+
* ## Features
|
|
45
|
+
* - Toggle between on/off (pressed/not pressed) states
|
|
46
|
+
* - Multiple visual variants (default, outline)
|
|
47
|
+
* - Multiple sizes (sm, default, lg)
|
|
48
|
+
* - Full keyboard support
|
|
49
|
+
* - Angular Forms integration (ngModel, formControl)
|
|
50
|
+
*
|
|
51
|
+
* ## Accessibility
|
|
52
|
+
* - Uses `aria-pressed` to indicate pressed state
|
|
53
|
+
* - Keyboard: Space/Enter to toggle
|
|
54
|
+
* - Focus ring for keyboard navigation
|
|
55
|
+
* - Disabled state removes from tab order
|
|
56
|
+
*
|
|
57
|
+
* ## Data Attributes
|
|
58
|
+
* - `data-state`: "on" | "off"
|
|
59
|
+
* - `data-disabled`: Present when disabled
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <!-- Basic toggle -->
|
|
63
|
+
* <Toggle aria-label="Toggle bold">
|
|
64
|
+
* <BoldIcon />
|
|
65
|
+
* </Toggle>
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* <!-- Controlled with two-way binding -->
|
|
69
|
+
* <Toggle [(pressed)]="isBold" aria-label="Toggle bold">
|
|
70
|
+
* <BoldIcon />
|
|
71
|
+
* </Toggle>
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* <!-- With variant -->
|
|
75
|
+
* <Toggle variant="outline" aria-label="Toggle italic">
|
|
76
|
+
* <ItalicIcon />
|
|
77
|
+
* </Toggle>
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* <!-- Different sizes -->
|
|
81
|
+
* <Toggle size="sm" aria-label="Small toggle"><Icon /></Toggle>
|
|
82
|
+
* <Toggle size="default" aria-label="Default toggle"><Icon /></Toggle>
|
|
83
|
+
* <Toggle size="lg" aria-label="Large toggle"><Icon /></Toggle>
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* <!-- With text content -->
|
|
87
|
+
* <Toggle [(pressed)]="isActive">
|
|
88
|
+
* Toggle me
|
|
89
|
+
* </Toggle>
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* <!-- Disabled -->
|
|
93
|
+
* <Toggle [disabled]="true" aria-label="Disabled toggle">
|
|
94
|
+
* <Icon />
|
|
95
|
+
* </Toggle>
|
|
96
|
+
*
|
|
97
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/toggle Radix Toggle}
|
|
98
|
+
* @see {@link https://ui.shadcn.com/docs/components/toggle shadcn/ui Toggle}
|
|
99
|
+
*/
|
|
100
|
+
@Component({
|
|
101
|
+
selector: 'Toggle',
|
|
102
|
+
template: `<ng-content />`,
|
|
103
|
+
host: {
|
|
104
|
+
'[class]': 'computedClass()',
|
|
105
|
+
type: 'button',
|
|
106
|
+
'[attr.aria-pressed]': 'pressed()',
|
|
107
|
+
'[attr.data-state]': 'state()',
|
|
108
|
+
'[attr.data-disabled]': 'disabled() ? "" : null',
|
|
109
|
+
'[attr.disabled]': 'disabled() ? "" : null',
|
|
110
|
+
'(click)': 'toggle()',
|
|
111
|
+
'data-slot': 'toggle',
|
|
112
|
+
},
|
|
113
|
+
providers: [
|
|
114
|
+
{
|
|
115
|
+
provide: NG_VALUE_ACCESSOR,
|
|
116
|
+
useExisting: forwardRef(() => Toggle),
|
|
117
|
+
multi: true,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
121
|
+
})
|
|
122
|
+
export class Toggle implements ControlValueAccessor {
|
|
123
|
+
/** Whether the toggle is pressed/on */
|
|
124
|
+
readonly pressed = model<boolean>(false);
|
|
125
|
+
|
|
126
|
+
/** Whether the toggle starts pressed (uncontrolled mode) */
|
|
127
|
+
readonly defaultPressed = input<boolean>(false);
|
|
128
|
+
|
|
129
|
+
/** The visual style variant of the toggle */
|
|
130
|
+
readonly variant = input<ToggleVariants['variant']>('default');
|
|
131
|
+
|
|
132
|
+
/** The size of the toggle */
|
|
133
|
+
readonly size = input<ToggleVariants['size']>('default');
|
|
134
|
+
|
|
135
|
+
/** Whether the toggle is disabled */
|
|
136
|
+
readonly disabled = input<boolean>(false);
|
|
137
|
+
|
|
138
|
+
/** Additional CSS classes to apply */
|
|
139
|
+
readonly class = input<string>('');
|
|
140
|
+
|
|
141
|
+
/** Emitted when pressed state changes */
|
|
142
|
+
readonly pressedChange = output<boolean>();
|
|
143
|
+
|
|
144
|
+
/** ControlValueAccessor callbacks */
|
|
145
|
+
private onChange: (value: boolean) => void = () => {};
|
|
146
|
+
private onTouched: () => void = () => {};
|
|
147
|
+
|
|
148
|
+
/** Current state for data attribute */
|
|
149
|
+
protected readonly state = computed((): ToggleState =>
|
|
150
|
+
this.pressed() ? 'on' : 'off'
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
constructor() {
|
|
154
|
+
// Initialize from defaultPressed if provided
|
|
155
|
+
if (this.defaultPressed()) {
|
|
156
|
+
this.pressed.set(true);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Toggle the pressed state */
|
|
161
|
+
toggle(): void {
|
|
162
|
+
if (!this.disabled()) {
|
|
163
|
+
const newValue = !this.pressed();
|
|
164
|
+
this.pressed.set(newValue);
|
|
165
|
+
this.onChange(newValue);
|
|
166
|
+
this.onTouched();
|
|
167
|
+
this.pressedChange.emit(newValue);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ControlValueAccessor implementation
|
|
172
|
+
writeValue(value: boolean): void {
|
|
173
|
+
this.pressed.set(value ?? false);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
registerOnChange(fn: (value: boolean) => void): void {
|
|
177
|
+
this.onChange = fn;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
registerOnTouched(fn: () => void): void {
|
|
181
|
+
this.onTouched = fn;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
setDisabledState?(isDisabled: boolean): void {
|
|
185
|
+
// Disabled state is managed by the disabled input
|
|
186
|
+
// Angular forms will call this but we use the input binding
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Computed class combining variants and custom classes */
|
|
190
|
+
protected readonly computedClass = computed(() =>
|
|
191
|
+
cn(
|
|
192
|
+
toggleVariants({
|
|
193
|
+
variant: this.variant(),
|
|
194
|
+
size: this.size(),
|
|
195
|
+
}),
|
|
196
|
+
this.class()
|
|
197
|
+
)
|
|
198
|
+
);
|
|
199
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
TOGGLE_GROUP_CONTEXT,
|
|
3
|
+
type ToggleGroupContext,
|
|
4
|
+
type ToggleGroupOrientation,
|
|
5
|
+
type ToggleGroupType,
|
|
6
|
+
} from './toggle-group-context';
|
|
7
|
+
export {
|
|
8
|
+
ToggleGroupItem,
|
|
9
|
+
type ToggleGroupItemProps,
|
|
10
|
+
} from './toggle-group-item.component';
|
|
11
|
+
export { ToggleGroup, type ToggleGroupProps } from './toggle-group.component';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { InjectionToken, WritableSignal } from '@angular/core';
|
|
2
|
+
import type { ToggleVariants } from '../toggle/toggle-variants';
|
|
3
|
+
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Types
|
|
6
|
+
// ============================================================================
|
|
7
|
+
|
|
8
|
+
export type ToggleGroupType = 'single' | 'multiple';
|
|
9
|
+
export type ToggleGroupOrientation = 'horizontal' | 'vertical';
|
|
10
|
+
|
|
11
|
+
export interface ToggleGroupContext {
|
|
12
|
+
/** Current selected value(s) */
|
|
13
|
+
value: WritableSignal<string | string[]>;
|
|
14
|
+
/** Selection type: single or multiple */
|
|
15
|
+
type: WritableSignal<ToggleGroupType>;
|
|
16
|
+
/** Whether the group is disabled */
|
|
17
|
+
disabled: WritableSignal<boolean>;
|
|
18
|
+
/** Visual variant for items */
|
|
19
|
+
variant: WritableSignal<ToggleVariants['variant']>;
|
|
20
|
+
/** Size for items */
|
|
21
|
+
size: WritableSignal<ToggleVariants['size']>;
|
|
22
|
+
/** Orientation for keyboard navigation */
|
|
23
|
+
orientation: WritableSignal<ToggleGroupOrientation>;
|
|
24
|
+
/** Whether to loop focus at boundaries */
|
|
25
|
+
loop: WritableSignal<boolean>;
|
|
26
|
+
/** Whether focus should follow selection in single mode */
|
|
27
|
+
rovingFocus: WritableSignal<boolean>;
|
|
28
|
+
/** Registry of all toggle item values */
|
|
29
|
+
itemValues: WritableSignal<string[]>;
|
|
30
|
+
/** Currently focused item value */
|
|
31
|
+
focusedValue: WritableSignal<string | null>;
|
|
32
|
+
/** Toggle an item's pressed state */
|
|
33
|
+
toggle: (value: string) => void;
|
|
34
|
+
/** Check if an item is pressed */
|
|
35
|
+
isPressed: (value: string) => boolean;
|
|
36
|
+
/** Move focus to the next toggle item */
|
|
37
|
+
focusNext: (currentValue: string) => void;
|
|
38
|
+
/** Move focus to the previous toggle item */
|
|
39
|
+
focusPrevious: (currentValue: string) => void;
|
|
40
|
+
/** Move focus to the first toggle item */
|
|
41
|
+
focusFirst: () => void;
|
|
42
|
+
/** Move focus to the last toggle item */
|
|
43
|
+
focusLast: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const TOGGLE_GROUP_CONTEXT = new InjectionToken<ToggleGroupContext>(
|
|
47
|
+
'ToggleGroupContext'
|
|
48
|
+
);
|