@ng-cn/core 1.0.11 → 1.0.14
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 +8 -3
- package/schematics/ng-add/index.ts +11 -4
- 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,241 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
inject,
|
|
7
|
+
input,
|
|
8
|
+
OnDestroy,
|
|
9
|
+
OnInit,
|
|
10
|
+
} from '@angular/core';
|
|
11
|
+
import { toggleVariants, type ToggleVariants } from '../toggle/toggle-variants';
|
|
12
|
+
import { TOGGLE_GROUP_CONTEXT } from './toggle-group-context';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Types
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
export type ToggleGroupItemProps = {
|
|
19
|
+
/** The unique value for this toggle item */
|
|
20
|
+
value: string;
|
|
21
|
+
/** Override the variant from the group */
|
|
22
|
+
variant?: ToggleVariants['variant'];
|
|
23
|
+
/** Override the size from the group */
|
|
24
|
+
size?: ToggleVariants['size'];
|
|
25
|
+
/** Whether this toggle item is disabled */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Additional CSS classes */
|
|
28
|
+
class?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// ToggleGroupItem Component
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* ToggleGroupItem component - individual toggle button within a group.
|
|
37
|
+
* Based on Radix UI ToggleGroup.Item with shadcn/ui styling.
|
|
38
|
+
* Supports keyboard navigation with arrow keys.
|
|
39
|
+
*
|
|
40
|
+
* ## Features
|
|
41
|
+
* - Can be individually styled with variant/size overrides
|
|
42
|
+
* - Inherits disabled state from parent group
|
|
43
|
+
* - Roving tabindex for efficient keyboard navigation
|
|
44
|
+
* - Full keyboard support
|
|
45
|
+
*
|
|
46
|
+
* ## Accessibility
|
|
47
|
+
* - Uses `aria-pressed` to indicate pressed state
|
|
48
|
+
* - Part of roving tabindex pattern
|
|
49
|
+
* - Supports keyboard navigation from parent group
|
|
50
|
+
*
|
|
51
|
+
* ## Data Attributes
|
|
52
|
+
* - `data-state`: "on" | "off"
|
|
53
|
+
* - `data-disabled`: Present when disabled
|
|
54
|
+
* - `data-value`: The item's value
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* <ToggleGroupItem value="bold" aria-label="Toggle bold">
|
|
58
|
+
* <BoldIcon />
|
|
59
|
+
* </ToggleGroupItem>
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <!-- With custom variant override -->
|
|
63
|
+
* <ToggleGroupItem value="special" variant="outline">
|
|
64
|
+
* Special
|
|
65
|
+
* </ToggleGroupItem>
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* <!-- Individually disabled -->
|
|
69
|
+
* <ToggleGroupItem value="unavailable" [disabled]="true">
|
|
70
|
+
* Unavailable
|
|
71
|
+
* </ToggleGroupItem>
|
|
72
|
+
*
|
|
73
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/toggle-group Radix ToggleGroup}
|
|
74
|
+
* @see {@link https://ui.shadcn.com/docs/components/toggle-group shadcn/ui ToggleGroup}
|
|
75
|
+
*/
|
|
76
|
+
@Component({
|
|
77
|
+
selector: 'ToggleGroupItem',
|
|
78
|
+
template: `<ng-content />`,
|
|
79
|
+
host: {
|
|
80
|
+
'[class]': 'computedClass()',
|
|
81
|
+
type: 'button',
|
|
82
|
+
'[attr.aria-pressed]': 'isPressed()',
|
|
83
|
+
'[attr.data-state]': 'state()',
|
|
84
|
+
'[attr.data-disabled]': 'isDisabled() ? "" : null',
|
|
85
|
+
'[attr.data-value]': 'value()',
|
|
86
|
+
'[attr.disabled]': 'isDisabled() ? "" : null',
|
|
87
|
+
'[attr.tabindex]': 'tabIndex()',
|
|
88
|
+
'(click)': 'toggle()',
|
|
89
|
+
'(keydown)': 'onKeyDown($event)',
|
|
90
|
+
'data-slot': 'toggle-group-item',
|
|
91
|
+
},
|
|
92
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
93
|
+
})
|
|
94
|
+
export class ToggleGroupItem implements OnInit, OnDestroy {
|
|
95
|
+
private readonly context = inject(TOGGLE_GROUP_CONTEXT, { optional: true });
|
|
96
|
+
|
|
97
|
+
/** The value of this toggle item */
|
|
98
|
+
readonly value = input.required<string>();
|
|
99
|
+
|
|
100
|
+
/** Override the variant from the group */
|
|
101
|
+
readonly variant = input<ToggleVariants['variant']>();
|
|
102
|
+
|
|
103
|
+
/** Override the size from the group */
|
|
104
|
+
readonly size = input<ToggleVariants['size']>();
|
|
105
|
+
|
|
106
|
+
/** Whether this toggle item is disabled */
|
|
107
|
+
readonly disabled = input<boolean>(false);
|
|
108
|
+
|
|
109
|
+
/** Additional CSS classes to apply */
|
|
110
|
+
readonly class = input<string>('');
|
|
111
|
+
|
|
112
|
+
/** Whether this item is pressed */
|
|
113
|
+
protected readonly isPressed = computed(() => {
|
|
114
|
+
return this.context?.isPressed(this.value()) ?? false;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
/** State for data attribute */
|
|
118
|
+
protected readonly state = computed(() => (this.isPressed() ? 'on' : 'off'));
|
|
119
|
+
|
|
120
|
+
/** Whether this item is disabled */
|
|
121
|
+
protected readonly isDisabled = computed(() => {
|
|
122
|
+
return this.disabled() || this.context?.disabled() || false;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Roving tabindex pattern:
|
|
127
|
+
* - If roving focus is enabled: first item or focused item is tabbable
|
|
128
|
+
* - Otherwise: all items are tabbable
|
|
129
|
+
*/
|
|
130
|
+
protected readonly tabIndex = computed(() => {
|
|
131
|
+
if (this.isDisabled()) return -1;
|
|
132
|
+
if (!this.context) return 0;
|
|
133
|
+
|
|
134
|
+
const rovingFocus = this.context.rovingFocus();
|
|
135
|
+
if (!rovingFocus) return 0;
|
|
136
|
+
|
|
137
|
+
const itemValues = this.context.itemValues();
|
|
138
|
+
const focusedValue = this.context.focusedValue();
|
|
139
|
+
|
|
140
|
+
// If an item is explicitly focused, only that item is tabbable
|
|
141
|
+
if (focusedValue !== null) {
|
|
142
|
+
return focusedValue === this.value() ? 0 : -1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Otherwise, first item is tabbable
|
|
146
|
+
if (itemValues.length > 0 && itemValues[0] === this.value()) {
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return -1;
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
/** Get the effective variant */
|
|
154
|
+
protected readonly effectiveVariant = computed(() => {
|
|
155
|
+
return this.variant() ?? this.context?.variant() ?? 'default';
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
/** Get the effective size */
|
|
159
|
+
protected readonly effectiveSize = computed(() => {
|
|
160
|
+
return this.size() ?? this.context?.size() ?? 'default';
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
ngOnInit(): void {
|
|
164
|
+
// Register this item with the group
|
|
165
|
+
this.context?.itemValues.update((values) => {
|
|
166
|
+
if (!values.includes(this.value())) {
|
|
167
|
+
return [...values, this.value()];
|
|
168
|
+
}
|
|
169
|
+
return values;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
ngOnDestroy(): void {
|
|
174
|
+
// Unregister this item from the group
|
|
175
|
+
this.context?.itemValues.update((values) =>
|
|
176
|
+
values.filter((v) => v !== this.value())
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Toggle this item */
|
|
181
|
+
toggle(): void {
|
|
182
|
+
if (!this.isDisabled()) {
|
|
183
|
+
this.context?.toggle(this.value());
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Handle keyboard navigation */
|
|
188
|
+
onKeyDown(event: KeyboardEvent): void {
|
|
189
|
+
if (this.isDisabled() || !this.context) return;
|
|
190
|
+
|
|
191
|
+
const orientation = this.context.orientation();
|
|
192
|
+
const isVertical = orientation === 'vertical';
|
|
193
|
+
const isHorizontal = orientation === 'horizontal';
|
|
194
|
+
|
|
195
|
+
switch (event.key) {
|
|
196
|
+
case 'ArrowDown':
|
|
197
|
+
if (isVertical) {
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
this.context.focusNext(this.value());
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case 'ArrowUp':
|
|
203
|
+
if (isVertical) {
|
|
204
|
+
event.preventDefault();
|
|
205
|
+
this.context.focusPrevious(this.value());
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
case 'ArrowRight':
|
|
209
|
+
if (isHorizontal) {
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
this.context.focusNext(this.value());
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
214
|
+
case 'ArrowLeft':
|
|
215
|
+
if (isHorizontal) {
|
|
216
|
+
event.preventDefault();
|
|
217
|
+
this.context.focusPrevious(this.value());
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
case 'Home':
|
|
221
|
+
event.preventDefault();
|
|
222
|
+
this.context.focusFirst();
|
|
223
|
+
break;
|
|
224
|
+
case 'End':
|
|
225
|
+
event.preventDefault();
|
|
226
|
+
this.context.focusLast();
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Computed class combining variants and custom classes */
|
|
232
|
+
protected readonly computedClass = computed(() =>
|
|
233
|
+
cn(
|
|
234
|
+
toggleVariants({
|
|
235
|
+
variant: this.effectiveVariant(),
|
|
236
|
+
size: this.effectiveSize(),
|
|
237
|
+
}),
|
|
238
|
+
this.class()
|
|
239
|
+
)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
ElementRef,
|
|
7
|
+
forwardRef,
|
|
8
|
+
inject,
|
|
9
|
+
input,
|
|
10
|
+
model,
|
|
11
|
+
output,
|
|
12
|
+
signal,
|
|
13
|
+
} from '@angular/core';
|
|
14
|
+
import type { ToggleVariants } from '../toggle/toggle-variants';
|
|
15
|
+
import {
|
|
16
|
+
TOGGLE_GROUP_CONTEXT,
|
|
17
|
+
type ToggleGroupContext,
|
|
18
|
+
type ToggleGroupOrientation,
|
|
19
|
+
type ToggleGroupType,
|
|
20
|
+
} from './toggle-group-context';
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Types
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
export type ToggleGroupProps = {
|
|
27
|
+
/** Selection type: single or multiple */
|
|
28
|
+
type?: ToggleGroupType;
|
|
29
|
+
/** Current selected value(s) */
|
|
30
|
+
value?: string | string[];
|
|
31
|
+
/** Default value for uncontrolled mode */
|
|
32
|
+
defaultValue?: string | string[];
|
|
33
|
+
/** Whether the group is disabled */
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
/** Visual variant for all items */
|
|
36
|
+
variant?: ToggleVariants['variant'];
|
|
37
|
+
/** Size for all items */
|
|
38
|
+
size?: ToggleVariants['size'];
|
|
39
|
+
/** Orientation for keyboard navigation */
|
|
40
|
+
orientation?: ToggleGroupOrientation;
|
|
41
|
+
/** Whether to loop focus at boundaries */
|
|
42
|
+
loop?: boolean;
|
|
43
|
+
/** Whether focus should follow selection */
|
|
44
|
+
rovingFocus?: boolean;
|
|
45
|
+
/** Additional CSS classes */
|
|
46
|
+
class?: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// ToggleGroup Component
|
|
51
|
+
// ============================================================================
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* ToggleGroup component - a set of toggle buttons where one or more can be pressed.
|
|
55
|
+
* Based on Radix UI ToggleGroup primitive with shadcn/ui styling.
|
|
56
|
+
* Implements keyboard navigation per WAI-ARIA toolbar pattern.
|
|
57
|
+
*
|
|
58
|
+
* ## Features
|
|
59
|
+
* - Single selection (only one item pressed at a time)
|
|
60
|
+
* - Multiple selection (any number of items can be pressed)
|
|
61
|
+
* - Full keyboard navigation with arrow keys
|
|
62
|
+
* - Roving tabindex for efficient keyboard navigation
|
|
63
|
+
* - Configurable variants and sizes for all items
|
|
64
|
+
* - Horizontal or vertical orientation
|
|
65
|
+
*
|
|
66
|
+
* ## Accessibility
|
|
67
|
+
* - Uses `role="group"` for grouping semantics
|
|
68
|
+
* - `aria-orientation` indicates layout direction
|
|
69
|
+
* - Roving tabindex: only one item is in tab order
|
|
70
|
+
* - Arrow keys navigate between items
|
|
71
|
+
* - Home/End keys navigate to first/last item
|
|
72
|
+
*
|
|
73
|
+
* ## Keyboard Navigation
|
|
74
|
+
* - **ArrowRight/ArrowDown**: Focus next item
|
|
75
|
+
* - **ArrowLeft/ArrowUp**: Focus previous item
|
|
76
|
+
* - **Home**: Focus first item
|
|
77
|
+
* - **End**: Focus last item
|
|
78
|
+
* - **Space/Enter**: Toggle focused item
|
|
79
|
+
*
|
|
80
|
+
* ## Data Attributes
|
|
81
|
+
* - `data-orientation`: "horizontal" | "vertical"
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* <!-- Single selection -->
|
|
85
|
+
* <ToggleGroup type="single" [(value)]="alignment">
|
|
86
|
+
* <ToggleGroupItem value="left" aria-label="Align left">
|
|
87
|
+
* <AlignLeftIcon />
|
|
88
|
+
* </ToggleGroupItem>
|
|
89
|
+
* <ToggleGroupItem value="center" aria-label="Align center">
|
|
90
|
+
* <AlignCenterIcon />
|
|
91
|
+
* </ToggleGroupItem>
|
|
92
|
+
* <ToggleGroupItem value="right" aria-label="Align right">
|
|
93
|
+
* <AlignRightIcon />
|
|
94
|
+
* </ToggleGroupItem>
|
|
95
|
+
* </ToggleGroup>
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* <!-- Multiple selection -->
|
|
99
|
+
* <ToggleGroup type="multiple" [(value)]="formats">
|
|
100
|
+
* <ToggleGroupItem value="bold" aria-label="Toggle bold">
|
|
101
|
+
* <BoldIcon />
|
|
102
|
+
* </ToggleGroupItem>
|
|
103
|
+
* <ToggleGroupItem value="italic" aria-label="Toggle italic">
|
|
104
|
+
* <ItalicIcon />
|
|
105
|
+
* </ToggleGroupItem>
|
|
106
|
+
* <ToggleGroupItem value="underline" aria-label="Toggle underline">
|
|
107
|
+
* <UnderlineIcon />
|
|
108
|
+
* </ToggleGroupItem>
|
|
109
|
+
* </ToggleGroup>
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* <!-- With outline variant -->
|
|
113
|
+
* <ToggleGroup type="single" variant="outline" [(value)]="view">
|
|
114
|
+
* <ToggleGroupItem value="list">List</ToggleGroupItem>
|
|
115
|
+
* <ToggleGroupItem value="grid">Grid</ToggleGroupItem>
|
|
116
|
+
* </ToggleGroup>
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* <!-- Vertical orientation -->
|
|
120
|
+
* <ToggleGroup type="single" orientation="vertical" [(value)]="size">
|
|
121
|
+
* <ToggleGroupItem value="sm">Small</ToggleGroupItem>
|
|
122
|
+
* <ToggleGroupItem value="md">Medium</ToggleGroupItem>
|
|
123
|
+
* <ToggleGroupItem value="lg">Large</ToggleGroupItem>
|
|
124
|
+
* </ToggleGroup>
|
|
125
|
+
*
|
|
126
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/toggle-group Radix ToggleGroup}
|
|
127
|
+
* @see {@link https://ui.shadcn.com/docs/components/toggle-group shadcn/ui ToggleGroup}
|
|
128
|
+
*/
|
|
129
|
+
@Component({
|
|
130
|
+
selector: 'ToggleGroup',
|
|
131
|
+
template: `<ng-content />`,
|
|
132
|
+
host: {
|
|
133
|
+
'[class]': 'computedClass()',
|
|
134
|
+
role: 'group',
|
|
135
|
+
'[attr.aria-orientation]': 'orientation()',
|
|
136
|
+
'[attr.data-orientation]': 'orientation()',
|
|
137
|
+
'data-slot': 'toggle-group',
|
|
138
|
+
},
|
|
139
|
+
providers: [
|
|
140
|
+
{
|
|
141
|
+
provide: TOGGLE_GROUP_CONTEXT,
|
|
142
|
+
useFactory: (component: ToggleGroup) => component.context,
|
|
143
|
+
deps: [forwardRef(() => ToggleGroup)],
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
147
|
+
})
|
|
148
|
+
export class ToggleGroup {
|
|
149
|
+
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
|
150
|
+
|
|
151
|
+
/** The current selected value(s) */
|
|
152
|
+
readonly value = model<string | string[]>('');
|
|
153
|
+
|
|
154
|
+
/** Default value for uncontrolled mode */
|
|
155
|
+
readonly defaultValue = input<string | string[]>('');
|
|
156
|
+
|
|
157
|
+
/** Selection type: single or multiple */
|
|
158
|
+
readonly type = input<ToggleGroupType>('single');
|
|
159
|
+
|
|
160
|
+
/** The visual style variant of the toggle items */
|
|
161
|
+
readonly variant = input<ToggleVariants['variant']>('default');
|
|
162
|
+
|
|
163
|
+
/** The size of the toggle items */
|
|
164
|
+
readonly size = input<ToggleVariants['size']>('default');
|
|
165
|
+
|
|
166
|
+
/** Whether the toggle group is disabled */
|
|
167
|
+
readonly disabled = input<boolean>(false);
|
|
168
|
+
|
|
169
|
+
/** The orientation of the toggle group */
|
|
170
|
+
readonly orientation = input<ToggleGroupOrientation>('horizontal');
|
|
171
|
+
|
|
172
|
+
/** Whether to loop focus at boundaries */
|
|
173
|
+
readonly loop = input<boolean>(true);
|
|
174
|
+
|
|
175
|
+
/** Whether focus should follow selection in single mode */
|
|
176
|
+
readonly rovingFocus = input<boolean>(true);
|
|
177
|
+
|
|
178
|
+
/** Additional CSS classes to apply */
|
|
179
|
+
readonly class = input<string>('');
|
|
180
|
+
|
|
181
|
+
/** Emitted when value changes */
|
|
182
|
+
readonly valueChange = output<string | string[]>();
|
|
183
|
+
|
|
184
|
+
/** Context for child ToggleGroupItem components */
|
|
185
|
+
readonly context: ToggleGroupContext = {
|
|
186
|
+
value: signal(this.value()),
|
|
187
|
+
type: signal(this.type()),
|
|
188
|
+
disabled: signal(this.disabled()),
|
|
189
|
+
variant: signal(this.variant()),
|
|
190
|
+
size: signal(this.size()),
|
|
191
|
+
orientation: signal(this.orientation()),
|
|
192
|
+
loop: signal(this.loop()),
|
|
193
|
+
rovingFocus: signal(this.rovingFocus()),
|
|
194
|
+
itemValues: signal<string[]>([]),
|
|
195
|
+
focusedValue: signal<string | null>(null),
|
|
196
|
+
toggle: (itemValue: string) => {
|
|
197
|
+
const currentType = this.type();
|
|
198
|
+
const currentValue = this.value();
|
|
199
|
+
|
|
200
|
+
let newValue: string | string[];
|
|
201
|
+
|
|
202
|
+
if (currentType === 'single') {
|
|
203
|
+
// In single mode, toggle off if same value, otherwise set new value
|
|
204
|
+
newValue = currentValue === itemValue ? '' : itemValue;
|
|
205
|
+
} else {
|
|
206
|
+
// In multiple mode, add or remove from array
|
|
207
|
+
const currentArray = Array.isArray(currentValue) ? currentValue : [];
|
|
208
|
+
newValue = currentArray.includes(itemValue)
|
|
209
|
+
? currentArray.filter((v) => v !== itemValue)
|
|
210
|
+
: [...currentArray, itemValue];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this.value.set(newValue);
|
|
214
|
+
this.context.value.set(newValue);
|
|
215
|
+
this.valueChange.emit(newValue);
|
|
216
|
+
},
|
|
217
|
+
isPressed: (itemValue: string) => {
|
|
218
|
+
const currentValue = this.context.value();
|
|
219
|
+
if (Array.isArray(currentValue)) {
|
|
220
|
+
return currentValue.includes(itemValue);
|
|
221
|
+
}
|
|
222
|
+
return currentValue === itemValue;
|
|
223
|
+
},
|
|
224
|
+
focusNext: (currentValue: string) => this.focusItem(currentValue, 1),
|
|
225
|
+
focusPrevious: (currentValue: string) => this.focusItem(currentValue, -1),
|
|
226
|
+
focusFirst: () => this.focusItemByIndex(0),
|
|
227
|
+
focusLast: () =>
|
|
228
|
+
this.focusItemByIndex(this.context.itemValues().length - 1),
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/** Computed class combining base styles and custom classes */
|
|
232
|
+
protected readonly computedClass = computed(() =>
|
|
233
|
+
cn(
|
|
234
|
+
'flex items-center justify-center gap-1',
|
|
235
|
+
this.orientation() === 'vertical' && 'flex-col',
|
|
236
|
+
this.class()
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
ngOnChanges(): void {
|
|
241
|
+
this.context.value.set(this.value());
|
|
242
|
+
this.context.type.set(this.type());
|
|
243
|
+
this.context.disabled.set(this.disabled());
|
|
244
|
+
this.context.variant.set(this.variant());
|
|
245
|
+
this.context.size.set(this.size());
|
|
246
|
+
this.context.orientation.set(this.orientation());
|
|
247
|
+
this.context.loop.set(this.loop());
|
|
248
|
+
this.context.rovingFocus.set(this.rovingFocus());
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** Focus a toggle item relative to the current item */
|
|
252
|
+
private focusItem(currentValue: string, direction: number): void {
|
|
253
|
+
const values = this.context.itemValues();
|
|
254
|
+
const currentIndex = values.indexOf(currentValue);
|
|
255
|
+
if (currentIndex === -1) return;
|
|
256
|
+
|
|
257
|
+
const shouldLoop = this.loop();
|
|
258
|
+
let nextIndex = currentIndex + direction;
|
|
259
|
+
|
|
260
|
+
if (shouldLoop) {
|
|
261
|
+
// Wrap around
|
|
262
|
+
if (nextIndex < 0) nextIndex = values.length - 1;
|
|
263
|
+
if (nextIndex >= values.length) nextIndex = 0;
|
|
264
|
+
} else {
|
|
265
|
+
// Clamp to boundaries
|
|
266
|
+
if (nextIndex < 0 || nextIndex >= values.length) return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
this.focusItemByIndex(nextIndex);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Focus a toggle item by index */
|
|
273
|
+
private focusItemByIndex(index: number): void {
|
|
274
|
+
const values = this.context.itemValues();
|
|
275
|
+
if (index < 0 || index >= values.length) return;
|
|
276
|
+
|
|
277
|
+
const value = values[index];
|
|
278
|
+
this.context.focusedValue.set(value);
|
|
279
|
+
|
|
280
|
+
const item = this.elementRef.nativeElement.querySelector(
|
|
281
|
+
`[data-slot="toggle-group-item"][data-value="${value}"]`
|
|
282
|
+
) as HTMLElement;
|
|
283
|
+
|
|
284
|
+
if (item) {
|
|
285
|
+
item.focus();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Context and types
|
|
2
|
+
export {
|
|
3
|
+
TOOLTIP_CONTEXT,
|
|
4
|
+
type TooltipAlign,
|
|
5
|
+
type TooltipContextValue,
|
|
6
|
+
type TooltipSide
|
|
7
|
+
} from './tooltip-context';
|
|
8
|
+
|
|
9
|
+
// Components and their types
|
|
10
|
+
export { TooltipContent, type TooltipContentProps, type TooltipContentState } from './tooltip-content.component';
|
|
11
|
+
export { TooltipProvider, type TooltipProviderProps } from './tooltip-provider.component';
|
|
12
|
+
export { TooltipTrigger, type TooltipTriggerProps } from './tooltip-trigger.component';
|
|
13
|
+
export { Tooltip, type TooltipProps, type TooltipState } from './tooltip.component';
|
|
14
|
+
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { cn, Presence } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
inject,
|
|
7
|
+
input,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { TOOLTIP_CONTEXT, TooltipAlign, TooltipSide } from './tooltip-context';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Types
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export type TooltipContentState = 'open' | 'closed';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the TooltipContent component
|
|
19
|
+
*/
|
|
20
|
+
export interface TooltipContentProps {
|
|
21
|
+
/** The preferred side of the trigger to render against.
|
|
22
|
+
* @default 'top' */
|
|
23
|
+
side?: TooltipSide;
|
|
24
|
+
/** The distance in pixels from the trigger.
|
|
25
|
+
* @default 4 */
|
|
26
|
+
sideOffset?: number;
|
|
27
|
+
/** The preferred alignment against the trigger.
|
|
28
|
+
* @default 'center' */
|
|
29
|
+
align?: TooltipAlign;
|
|
30
|
+
/** An offset in pixels from the "start" or "end" alignment options.
|
|
31
|
+
* @default 0 */
|
|
32
|
+
alignOffset?: number;
|
|
33
|
+
/** The padding between the arrow and the edges of the content.
|
|
34
|
+
* @default 0 */
|
|
35
|
+
arrowPadding?: number;
|
|
36
|
+
/** Additional CSS classes */
|
|
37
|
+
class?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Component
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @component TooltipContent
|
|
46
|
+
*
|
|
47
|
+
* The component that pops out when the tooltip is open.
|
|
48
|
+
*
|
|
49
|
+
* @description
|
|
50
|
+
* TooltipContent displays the actual tooltip content. It supports positioning
|
|
51
|
+
* on different sides and alignments relative to the trigger.
|
|
52
|
+
*
|
|
53
|
+
* ## Features
|
|
54
|
+
* - Configurable side (top, right, bottom, left)
|
|
55
|
+
* - Configurable alignment (start, center, end)
|
|
56
|
+
* - Customizable offset from trigger
|
|
57
|
+
* - Smooth enter/exit animations
|
|
58
|
+
* - Uses Presence for proper exit animations
|
|
59
|
+
*
|
|
60
|
+
* ## Accessibility
|
|
61
|
+
* - `role="tooltip"` on the element
|
|
62
|
+
* - Unique ID for aria-describedby relationship with trigger
|
|
63
|
+
*
|
|
64
|
+
* @example Basic usage
|
|
65
|
+
* ```html
|
|
66
|
+
* <TooltipContent>
|
|
67
|
+
* <p>Tooltip content</p>
|
|
68
|
+
* </TooltipContent>
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example With side and alignment
|
|
72
|
+
* ```html
|
|
73
|
+
* <TooltipContent side="right" align="start">
|
|
74
|
+
* <p>Right-aligned tooltip</p>
|
|
75
|
+
* </TooltipContent>
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example With offset
|
|
79
|
+
* ```html
|
|
80
|
+
* <TooltipContent [sideOffset]="8">
|
|
81
|
+
* <p>Tooltip with more spacing</p>
|
|
82
|
+
* </TooltipContent>
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @data-attributes
|
|
86
|
+
* - `data-state` - 'open' | 'closed'
|
|
87
|
+
* - `data-side` - 'top' | 'right' | 'bottom' | 'left'
|
|
88
|
+
* - `data-align` - 'start' | 'center' | 'end'
|
|
89
|
+
*/
|
|
90
|
+
@Component({
|
|
91
|
+
selector: 'TooltipContent',
|
|
92
|
+
imports: [Presence],
|
|
93
|
+
template: `
|
|
94
|
+
<Presence [present]="context.open()">
|
|
95
|
+
<div
|
|
96
|
+
[class]="computedClass()"
|
|
97
|
+
[attr.data-state]="state()"
|
|
98
|
+
[attr.data-side]="side()"
|
|
99
|
+
[attr.data-align]="align()"
|
|
100
|
+
role="tooltip"
|
|
101
|
+
[id]="context.tooltipId"
|
|
102
|
+
>
|
|
103
|
+
<ng-content />
|
|
104
|
+
</div>
|
|
105
|
+
</Presence>
|
|
106
|
+
`,
|
|
107
|
+
host: {
|
|
108
|
+
class: 'contents',
|
|
109
|
+
},
|
|
110
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
111
|
+
})
|
|
112
|
+
export class TooltipContent {
|
|
113
|
+
protected readonly context = inject(TOOLTIP_CONTEXT);
|
|
114
|
+
|
|
115
|
+
/** The preferred side of the trigger to render against */
|
|
116
|
+
readonly side = input<TooltipSide>('top');
|
|
117
|
+
|
|
118
|
+
/** The distance in pixels from the trigger */
|
|
119
|
+
readonly sideOffset = input<number>(4);
|
|
120
|
+
|
|
121
|
+
/** The preferred alignment against the trigger */
|
|
122
|
+
readonly align = input<TooltipAlign>('center');
|
|
123
|
+
|
|
124
|
+
/** An offset in pixels from the alignment options */
|
|
125
|
+
readonly alignOffset = input<number>(0);
|
|
126
|
+
|
|
127
|
+
/** Additional CSS classes */
|
|
128
|
+
readonly class = input<string>('');
|
|
129
|
+
|
|
130
|
+
/** Current state: open or closed */
|
|
131
|
+
protected readonly state = computed<TooltipContentState>(() =>
|
|
132
|
+
this.context.open() ? 'open' : 'closed'
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
protected readonly computedClass = computed(() => {
|
|
136
|
+
const sideClasses = {
|
|
137
|
+
top: 'bottom-full left-1/2 -translate-x-1/2 mb-2',
|
|
138
|
+
bottom: 'top-full left-1/2 -translate-x-1/2 mt-2',
|
|
139
|
+
left: 'right-full top-1/2 -translate-y-1/2 mr-2',
|
|
140
|
+
right: 'left-full top-1/2 -translate-y-1/2 ml-2',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return cn(
|
|
144
|
+
'absolute z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md',
|
|
145
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
146
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
147
|
+
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
148
|
+
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
|
|
149
|
+
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
150
|
+
sideClasses[this.side()],
|
|
151
|
+
this.class()
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
}
|