@ng-cn/core 1.0.10 → 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 +3 -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,212 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
input,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
export type ProgressState = 'indeterminate' | 'loading' | 'complete';
|
|
14
|
+
|
|
15
|
+
export type ProgressProps = {
|
|
16
|
+
/** The current progress value (0 to max). Null for indeterminate. */
|
|
17
|
+
value?: number | null;
|
|
18
|
+
/** The maximum progress value */
|
|
19
|
+
max?: number;
|
|
20
|
+
/** Accessible label for the progress bar */
|
|
21
|
+
ariaLabel?: string;
|
|
22
|
+
/** Text description of current progress (e.g., "50% complete") */
|
|
23
|
+
ariaValueText?: string;
|
|
24
|
+
/** Additional CSS classes to apply to the root */
|
|
25
|
+
class?: string;
|
|
26
|
+
/** Additional CSS classes to apply to the indicator */
|
|
27
|
+
indicatorClass?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Function to get value label for accessibility.
|
|
30
|
+
* Receives current value and returns descriptive text.
|
|
31
|
+
*/
|
|
32
|
+
getValueLabel?: (value: number, max: number) => string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Progress Component
|
|
37
|
+
// ============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Progress component displays progress feedback for tasks and operations.
|
|
41
|
+
* Based on Radix UI Progress primitive with shadcn/ui styling.
|
|
42
|
+
*
|
|
43
|
+
* ## Features
|
|
44
|
+
* - Determinate mode with value from 0 to max
|
|
45
|
+
* - Indeterminate mode when value is null (shows loading animation)
|
|
46
|
+
* - Complete state when value reaches max
|
|
47
|
+
* - Full ARIA progressbar implementation
|
|
48
|
+
* - Customizable indicator styling
|
|
49
|
+
*
|
|
50
|
+
* ## Accessibility
|
|
51
|
+
* - Uses native `progressbar` role
|
|
52
|
+
* - `aria-valuenow`, `aria-valuemin`, `aria-valuemax` for current state
|
|
53
|
+
* - `aria-valuetext` provides human-readable progress description
|
|
54
|
+
* - `aria-label` for accessible name
|
|
55
|
+
* - `aria-live="polite"` for screen reader announcements
|
|
56
|
+
*
|
|
57
|
+
* ## Data Attributes
|
|
58
|
+
* - `data-state`: "indeterminate" | "loading" | "complete"
|
|
59
|
+
* - `data-value`: Current numeric value
|
|
60
|
+
* - `data-max`: Maximum value
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* <!-- Basic progress -->
|
|
64
|
+
* <Progress [value]="50" />
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* <!-- With custom max -->
|
|
68
|
+
* <Progress [value]="30" [max]="50" />
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* <!-- Indeterminate (loading) -->
|
|
72
|
+
* <Progress />
|
|
73
|
+
* <!-- or explicitly -->
|
|
74
|
+
* <Progress [value]="null" />
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* <!-- Complete state -->
|
|
78
|
+
* <Progress [value]="100" />
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* <!-- With accessible label -->
|
|
82
|
+
* <Progress [value]="66" ariaLabel="Downloading file" />
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* <!-- With custom value text -->
|
|
86
|
+
* <Progress
|
|
87
|
+
* [value]="3"
|
|
88
|
+
* [max]="10"
|
|
89
|
+
* ariaValueText="Step 3 of 10"
|
|
90
|
+
* />
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* <!-- With custom value label function -->
|
|
94
|
+
* <Progress
|
|
95
|
+
* [value]="bytesLoaded"
|
|
96
|
+
* [max]="totalBytes"
|
|
97
|
+
* [getValueLabel]="formatBytes"
|
|
98
|
+
* />
|
|
99
|
+
*
|
|
100
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/progress Radix Progress}
|
|
101
|
+
* @see {@link https://ui.shadcn.com/docs/components/progress shadcn/ui Progress}
|
|
102
|
+
*/
|
|
103
|
+
@Component({
|
|
104
|
+
selector: 'Progress',
|
|
105
|
+
template: `
|
|
106
|
+
<div
|
|
107
|
+
data-slot="progress-indicator"
|
|
108
|
+
[class]="computedIndicatorClass()"
|
|
109
|
+
[style.transform]="indicatorTransform()"
|
|
110
|
+
></div>
|
|
111
|
+
`,
|
|
112
|
+
host: {
|
|
113
|
+
'[class]': 'computedClass()',
|
|
114
|
+
role: 'progressbar',
|
|
115
|
+
'[attr.aria-label]': 'ariaLabel()',
|
|
116
|
+
'[attr.aria-valuemin]': '0',
|
|
117
|
+
'[attr.aria-valuemax]': 'max()',
|
|
118
|
+
'[attr.aria-valuenow]': 'value()',
|
|
119
|
+
'[attr.aria-valuetext]': 'computedValueText()',
|
|
120
|
+
'[attr.aria-live]': '"polite"',
|
|
121
|
+
'[attr.data-state]': 'state()',
|
|
122
|
+
'[attr.data-value]': 'value()',
|
|
123
|
+
'[attr.data-max]': 'max()',
|
|
124
|
+
'data-slot': 'progress',
|
|
125
|
+
},
|
|
126
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
127
|
+
})
|
|
128
|
+
export class Progress {
|
|
129
|
+
/** The current progress value (0 to max). Null for indeterminate. */
|
|
130
|
+
readonly value = input<number | null>(null);
|
|
131
|
+
|
|
132
|
+
/** The maximum progress value */
|
|
133
|
+
readonly max = input<number>(100);
|
|
134
|
+
|
|
135
|
+
/** Accessible label for the progress bar */
|
|
136
|
+
readonly ariaLabel = input<string>('Progress');
|
|
137
|
+
|
|
138
|
+
/** Text description of current progress (e.g., "50% complete") */
|
|
139
|
+
readonly ariaValueText = input<string | undefined>(undefined);
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Function to get value label for accessibility.
|
|
143
|
+
* Receives current value and returns descriptive text.
|
|
144
|
+
*/
|
|
145
|
+
readonly getValueLabel = input<
|
|
146
|
+
((value: number, max: number) => string) | undefined
|
|
147
|
+
>(undefined);
|
|
148
|
+
|
|
149
|
+
/** Additional CSS classes to apply to the root */
|
|
150
|
+
readonly class = input<string>('');
|
|
151
|
+
|
|
152
|
+
/** Additional CSS classes to apply to the indicator */
|
|
153
|
+
readonly indicatorClass = input<string>('');
|
|
154
|
+
|
|
155
|
+
/** Calculate percentage (0-100) */
|
|
156
|
+
protected readonly percentage = computed(() => {
|
|
157
|
+
const val = this.value();
|
|
158
|
+
const maxVal = this.max();
|
|
159
|
+
if (val === null || maxVal === 0) return 0;
|
|
160
|
+
return Math.min(100, Math.max(0, (val / maxVal) * 100));
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
/** Calculate state for data attribute */
|
|
164
|
+
protected readonly state = computed((): ProgressState => {
|
|
165
|
+
const val = this.value();
|
|
166
|
+
if (val === null) return 'indeterminate';
|
|
167
|
+
return val >= this.max() ? 'complete' : 'loading';
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/** Compute aria-valuetext */
|
|
171
|
+
protected readonly computedValueText = computed(() => {
|
|
172
|
+
const customText = this.ariaValueText();
|
|
173
|
+
if (customText) return customText;
|
|
174
|
+
|
|
175
|
+
const val = this.value();
|
|
176
|
+
if (val === null) return 'Loading';
|
|
177
|
+
|
|
178
|
+
const getLabel = this.getValueLabel();
|
|
179
|
+
if (getLabel) {
|
|
180
|
+
return getLabel(val, this.max());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return `${this.percentage().toFixed(0)}% complete`;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/** Transform for the indicator */
|
|
187
|
+
protected readonly indicatorTransform = computed(() => {
|
|
188
|
+
return `translateX(-${100 - this.percentage()}%)`;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
/** Computed class combining base styles and custom classes */
|
|
192
|
+
protected readonly computedClass = computed(() =>
|
|
193
|
+
cn(
|
|
194
|
+
// Base styles
|
|
195
|
+
'bg-primary/20 relative h-2 w-full overflow-hidden rounded-full',
|
|
196
|
+
// Custom classes
|
|
197
|
+
this.class()
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
/** Computed indicator class */
|
|
202
|
+
protected readonly computedIndicatorClass = computed(() =>
|
|
203
|
+
cn(
|
|
204
|
+
// Base styles
|
|
205
|
+
'bg-primary h-full w-full flex-1 transition-all duration-300 ease-in-out',
|
|
206
|
+
// Indeterminate animation
|
|
207
|
+
this.state() === 'indeterminate' && 'animate-pulse',
|
|
208
|
+
// Custom classes
|
|
209
|
+
this.indicatorClass()
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
RADIO_GROUP_CONTEXT,
|
|
3
|
+
type RadioGroupContext,
|
|
4
|
+
type RadioGroupOrientation,
|
|
5
|
+
} from './radio-group-context';
|
|
6
|
+
export {
|
|
7
|
+
RadioGroupItem,
|
|
8
|
+
type RadioGroupItemProps,
|
|
9
|
+
} from './radio-group-item.component';
|
|
10
|
+
export { RadioGroup, type RadioGroupProps } from './radio-group.component';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { InjectionToken, WritableSignal } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Types
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
export type RadioGroupOrientation = 'horizontal' | 'vertical';
|
|
8
|
+
|
|
9
|
+
export interface RadioGroupContext {
|
|
10
|
+
/** Current selected value */
|
|
11
|
+
value: WritableSignal<string>;
|
|
12
|
+
/** Whether the group is disabled */
|
|
13
|
+
disabled: WritableSignal<boolean>;
|
|
14
|
+
/** The name for radio inputs */
|
|
15
|
+
name: WritableSignal<string>;
|
|
16
|
+
/** Orientation for keyboard navigation */
|
|
17
|
+
orientation: WritableSignal<RadioGroupOrientation>;
|
|
18
|
+
/** Whether to loop focus at boundaries */
|
|
19
|
+
loop: WritableSignal<boolean>;
|
|
20
|
+
/** Whether the group is required */
|
|
21
|
+
required: WritableSignal<boolean>;
|
|
22
|
+
/** Registry of all radio item values */
|
|
23
|
+
itemValues: WritableSignal<string[]>;
|
|
24
|
+
/** Set the selected value */
|
|
25
|
+
setValue: (value: string) => void;
|
|
26
|
+
/** Move focus to the next radio item */
|
|
27
|
+
focusNext: (currentValue: string) => void;
|
|
28
|
+
/** Move focus to the previous radio item */
|
|
29
|
+
focusPrevious: (currentValue: string) => void;
|
|
30
|
+
/** Move focus to the first radio item */
|
|
31
|
+
focusFirst: () => void;
|
|
32
|
+
/** Move focus to the last radio item */
|
|
33
|
+
focusLast: () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const RADIO_GROUP_CONTEXT = new InjectionToken<RadioGroupContext>(
|
|
37
|
+
'RadioGroupContext'
|
|
38
|
+
);
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
ElementRef,
|
|
7
|
+
inject,
|
|
8
|
+
input,
|
|
9
|
+
OnDestroy,
|
|
10
|
+
OnInit,
|
|
11
|
+
viewChild,
|
|
12
|
+
} from '@angular/core';
|
|
13
|
+
import { RADIO_GROUP_CONTEXT } from './radio-group-context';
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
export type RadioGroupItemProps = {
|
|
20
|
+
/** The unique value for this radio item */
|
|
21
|
+
value: string;
|
|
22
|
+
/** The id for the radio input */
|
|
23
|
+
id?: string;
|
|
24
|
+
/** Whether this radio item is disabled */
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/** Whether the item is required (inherited from group if not set) */
|
|
27
|
+
required?: boolean;
|
|
28
|
+
/** Additional CSS classes */
|
|
29
|
+
class?: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// RadioGroupItem Component
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* RadioGroupItem component - individual radio option within a group.
|
|
38
|
+
* Based on Radix UI RadioGroup.Item with shadcn/ui styling.
|
|
39
|
+
* Implements roving tabindex (only checked or first item is tabbable).
|
|
40
|
+
*
|
|
41
|
+
* ## Features
|
|
42
|
+
* - Visual indicator shows checked state
|
|
43
|
+
* - Inherits disabled state from parent group
|
|
44
|
+
* - Roving tabindex for efficient keyboard navigation
|
|
45
|
+
* - Full keyboard support
|
|
46
|
+
*
|
|
47
|
+
* ## Accessibility
|
|
48
|
+
* - Uses native radio input for built-in accessibility
|
|
49
|
+
* - `aria-checked` indicates checked state
|
|
50
|
+
* - Part of roving tabindex pattern
|
|
51
|
+
* - Supports keyboard navigation from parent group
|
|
52
|
+
*
|
|
53
|
+
* ## Data Attributes
|
|
54
|
+
* - `data-state`: "checked" | "unchecked"
|
|
55
|
+
* - `data-disabled`: Present when disabled
|
|
56
|
+
* - `data-value`: The item's value
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* <RadioGroupItem value="option1" id="option1" />
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <!-- With label -->
|
|
63
|
+
* <div class="flex items-center gap-2">
|
|
64
|
+
* <RadioGroupItem value="apple" id="apple" />
|
|
65
|
+
* <Label for="apple">Apple</Label>
|
|
66
|
+
* </div>
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* <!-- Individually disabled -->
|
|
70
|
+
* <RadioGroupItem value="unavailable" [disabled]="true" />
|
|
71
|
+
*
|
|
72
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/radio-group Radix RadioGroup}
|
|
73
|
+
* @see {@link https://ui.shadcn.com/docs/components/radio-group shadcn/ui RadioGroup}
|
|
74
|
+
*/
|
|
75
|
+
@Component({
|
|
76
|
+
selector: 'RadioGroupItem',
|
|
77
|
+
template: `
|
|
78
|
+
<button
|
|
79
|
+
#buttonElement
|
|
80
|
+
type="button"
|
|
81
|
+
role="radio"
|
|
82
|
+
[attr.id]="id()"
|
|
83
|
+
[attr.aria-checked]="isChecked()"
|
|
84
|
+
[attr.data-state]="state()"
|
|
85
|
+
[attr.data-disabled]="isDisabled() ? '' : null"
|
|
86
|
+
[attr.data-value]="value()"
|
|
87
|
+
[disabled]="isDisabled()"
|
|
88
|
+
[attr.tabindex]="tabIndex()"
|
|
89
|
+
[class]="radioClass()"
|
|
90
|
+
(click)="select()"
|
|
91
|
+
(keydown)="onKeyDown($event)"
|
|
92
|
+
>
|
|
93
|
+
@if (isChecked()) {
|
|
94
|
+
<span
|
|
95
|
+
data-slot="radio-group-indicator"
|
|
96
|
+
class="flex items-center justify-center"
|
|
97
|
+
>
|
|
98
|
+
<svg
|
|
99
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
100
|
+
width="24"
|
|
101
|
+
height="24"
|
|
102
|
+
viewBox="0 0 24 24"
|
|
103
|
+
fill="currentColor"
|
|
104
|
+
class="size-2.5"
|
|
105
|
+
>
|
|
106
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
107
|
+
</svg>
|
|
108
|
+
</span>
|
|
109
|
+
}
|
|
110
|
+
</button>
|
|
111
|
+
<!-- Hidden input for form submission -->
|
|
112
|
+
@if (context?.name()) {
|
|
113
|
+
<input
|
|
114
|
+
type="radio"
|
|
115
|
+
[attr.name]="context?.name()"
|
|
116
|
+
[attr.value]="value()"
|
|
117
|
+
[checked]="isChecked()"
|
|
118
|
+
[disabled]="isDisabled()"
|
|
119
|
+
[required]="isRequired()"
|
|
120
|
+
aria-hidden="true"
|
|
121
|
+
tabindex="-1"
|
|
122
|
+
class="sr-only"
|
|
123
|
+
/>
|
|
124
|
+
}
|
|
125
|
+
`,
|
|
126
|
+
host: {
|
|
127
|
+
'[class]': 'computedClass()',
|
|
128
|
+
'data-slot': 'radio-group-item',
|
|
129
|
+
},
|
|
130
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
131
|
+
})
|
|
132
|
+
export class RadioGroupItem implements OnInit, OnDestroy {
|
|
133
|
+
protected readonly context = inject(RADIO_GROUP_CONTEXT, { optional: true });
|
|
134
|
+
private readonly buttonElement =
|
|
135
|
+
viewChild<ElementRef<HTMLButtonElement>>('buttonElement');
|
|
136
|
+
|
|
137
|
+
/** The id for the radio button - used for label association */
|
|
138
|
+
readonly id = input<string>();
|
|
139
|
+
|
|
140
|
+
/** The value of this radio option */
|
|
141
|
+
readonly value = input.required<string>();
|
|
142
|
+
|
|
143
|
+
/** Whether this radio is disabled */
|
|
144
|
+
readonly disabled = input<boolean>(false);
|
|
145
|
+
|
|
146
|
+
/** Whether this radio is required (inherited from group if not set) */
|
|
147
|
+
readonly required = input<boolean | undefined>(undefined);
|
|
148
|
+
|
|
149
|
+
/** Additional CSS classes to apply */
|
|
150
|
+
readonly class = input<string>('');
|
|
151
|
+
|
|
152
|
+
/** Whether this item is checked */
|
|
153
|
+
protected readonly isChecked = computed(() => {
|
|
154
|
+
return this.context?.value() === this.value();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
/** State for data attribute */
|
|
158
|
+
protected readonly state = computed(() =>
|
|
159
|
+
this.isChecked() ? 'checked' : 'unchecked'
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
/** Whether this item is disabled */
|
|
163
|
+
protected readonly isDisabled = computed(() => {
|
|
164
|
+
return this.disabled() || this.context?.disabled() || false;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
/** Whether this item is required */
|
|
168
|
+
protected readonly isRequired = computed(() => {
|
|
169
|
+
const explicitRequired = this.required();
|
|
170
|
+
if (explicitRequired !== undefined) return explicitRequired;
|
|
171
|
+
return this.context?.required() || false;
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Roving tabindex: only the checked item (or first item if none checked) is tabbable.
|
|
176
|
+
*/
|
|
177
|
+
protected readonly tabIndex = computed(() => {
|
|
178
|
+
if (this.isDisabled()) return -1;
|
|
179
|
+
if (!this.context) return 0;
|
|
180
|
+
|
|
181
|
+
const currentValue = this.context.value();
|
|
182
|
+
const itemValues = this.context.itemValues();
|
|
183
|
+
|
|
184
|
+
// If this item is checked, it's tabbable
|
|
185
|
+
if (currentValue === this.value()) return 0;
|
|
186
|
+
|
|
187
|
+
// If no item is checked and this is the first item, it's tabbable
|
|
188
|
+
if (
|
|
189
|
+
!currentValue &&
|
|
190
|
+
itemValues.length > 0 &&
|
|
191
|
+
itemValues[0] === this.value()
|
|
192
|
+
) {
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return -1;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
ngOnInit(): void {
|
|
200
|
+
// Register this item with the group
|
|
201
|
+
this.context?.itemValues.update((values) => {
|
|
202
|
+
if (!values.includes(this.value())) {
|
|
203
|
+
return [...values, this.value()];
|
|
204
|
+
}
|
|
205
|
+
return values;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ngOnDestroy(): void {
|
|
210
|
+
// Unregister this item from the group
|
|
211
|
+
this.context?.itemValues.update((values) =>
|
|
212
|
+
values.filter((v) => v !== this.value())
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Select this radio option */
|
|
217
|
+
select(): void {
|
|
218
|
+
if (!this.isDisabled()) {
|
|
219
|
+
this.context?.setValue(this.value());
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Focus the button element */
|
|
224
|
+
focus(): void {
|
|
225
|
+
this.buttonElement()?.nativeElement.focus();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Handle keyboard navigation */
|
|
229
|
+
onKeyDown(event: KeyboardEvent): void {
|
|
230
|
+
if (this.isDisabled() || !this.context) return;
|
|
231
|
+
|
|
232
|
+
const orientation = this.context.orientation();
|
|
233
|
+
const isVertical = orientation === 'vertical';
|
|
234
|
+
const isHorizontal = orientation === 'horizontal';
|
|
235
|
+
|
|
236
|
+
switch (event.key) {
|
|
237
|
+
case 'ArrowDown':
|
|
238
|
+
if (isVertical) {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
this.context.focusNext(this.value());
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
case 'ArrowUp':
|
|
244
|
+
if (isVertical) {
|
|
245
|
+
event.preventDefault();
|
|
246
|
+
this.context.focusPrevious(this.value());
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case 'ArrowRight':
|
|
250
|
+
if (isHorizontal) {
|
|
251
|
+
event.preventDefault();
|
|
252
|
+
this.context.focusNext(this.value());
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case 'ArrowLeft':
|
|
256
|
+
if (isHorizontal) {
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
this.context.focusPrevious(this.value());
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
case 'Home':
|
|
262
|
+
event.preventDefault();
|
|
263
|
+
this.context.focusFirst();
|
|
264
|
+
break;
|
|
265
|
+
case 'End':
|
|
266
|
+
event.preventDefault();
|
|
267
|
+
this.context.focusLast();
|
|
268
|
+
break;
|
|
269
|
+
case ' ':
|
|
270
|
+
// Space should select if not already selected
|
|
271
|
+
event.preventDefault();
|
|
272
|
+
this.select();
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Computed class for wrapper */
|
|
278
|
+
protected readonly computedClass = computed(() =>
|
|
279
|
+
cn('relative inline-flex', this.class())
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
/** Computed radio visual class */
|
|
283
|
+
protected readonly radioClass = computed(() =>
|
|
284
|
+
cn(
|
|
285
|
+
// Base styles
|
|
286
|
+
'aspect-square size-4 shrink-0 rounded-full border shadow-xs',
|
|
287
|
+
'inline-flex items-center justify-center cursor-pointer',
|
|
288
|
+
'transition-[color,box-shadow] outline-none',
|
|
289
|
+
// Focus styles
|
|
290
|
+
'focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:border-ring',
|
|
291
|
+
// State styles
|
|
292
|
+
'border-input text-primary',
|
|
293
|
+
'data-[state=checked]:border-primary',
|
|
294
|
+
// Disabled styles
|
|
295
|
+
'disabled:cursor-not-allowed disabled:opacity-50'
|
|
296
|
+
)
|
|
297
|
+
);
|
|
298
|
+
}
|