@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,240 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
ElementRef,
|
|
7
|
+
forwardRef,
|
|
8
|
+
input,
|
|
9
|
+
model,
|
|
10
|
+
output,
|
|
11
|
+
signal,
|
|
12
|
+
viewChild,
|
|
13
|
+
} from '@angular/core';
|
|
14
|
+
import { FormsModule } from '@angular/forms';
|
|
15
|
+
import { INPUT_OTP_CONTEXT, type InputOTPContextValue } from './input-otp-context';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Types
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Props for the InputOTP component
|
|
23
|
+
*/
|
|
24
|
+
export interface InputOTPProps {
|
|
25
|
+
/** The value of the input. Should be used with onChange. */
|
|
26
|
+
value?: string;
|
|
27
|
+
/** Maximum number of characters */
|
|
28
|
+
maxLength?: number;
|
|
29
|
+
/** Whether the input is disabled.
|
|
30
|
+
* @default false */
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
/** Pattern for input validation.
|
|
33
|
+
* @default "^[0-9]*$" */
|
|
34
|
+
pattern?: string;
|
|
35
|
+
/** Input mode for virtual keyboard.
|
|
36
|
+
* @default "numeric" */
|
|
37
|
+
inputMode?: 'numeric' | 'text' | 'decimal' | 'tel' | 'search' | 'email' | 'url';
|
|
38
|
+
/** Additional CSS classes */
|
|
39
|
+
class?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Component
|
|
44
|
+
// ============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @component InputOTP
|
|
48
|
+
*
|
|
49
|
+
* Accessible one-time password component with copy paste functionality.
|
|
50
|
+
*
|
|
51
|
+
* @description
|
|
52
|
+
* InputOTP provides an accessible OTP/verification code input with individual
|
|
53
|
+
* slots for each character. It handles paste, keyboard navigation, and auto-completion.
|
|
54
|
+
*
|
|
55
|
+
* ## Features
|
|
56
|
+
* - Individual slot rendering
|
|
57
|
+
* - Copy/paste support
|
|
58
|
+
* - Keyboard navigation
|
|
59
|
+
* - Numeric or alphanumeric modes
|
|
60
|
+
* - Accessible with proper ARIA
|
|
61
|
+
* - Disabled state support
|
|
62
|
+
* - Auto-focus next slot
|
|
63
|
+
*
|
|
64
|
+
* ## Accessibility
|
|
65
|
+
* - Uses native input for accessibility
|
|
66
|
+
* - `autocomplete="one-time-code"` for autofill
|
|
67
|
+
* - Visual focus indicator
|
|
68
|
+
* - Works with password managers
|
|
69
|
+
*
|
|
70
|
+
* ## Keyboard Navigation
|
|
71
|
+
* - Type to fill slots
|
|
72
|
+
* - `Backspace` - Clear and move back
|
|
73
|
+
* - `ArrowLeft/Right` - Navigate slots (future)
|
|
74
|
+
* - Paste - Fill from clipboard
|
|
75
|
+
*
|
|
76
|
+
* @example Basic usage
|
|
77
|
+
* ```html
|
|
78
|
+
* <InputOTP [maxLength]="6" [(value)]="otp" (onComplete)="verify($event)">
|
|
79
|
+
* <InputOTPGroup>
|
|
80
|
+
* <InputOTPSlot [index]="0" />
|
|
81
|
+
* <InputOTPSlot [index]="1" />
|
|
82
|
+
* <InputOTPSlot [index]="2" />
|
|
83
|
+
* </InputOTPGroup>
|
|
84
|
+
* <InputOTPSeparator />
|
|
85
|
+
* <InputOTPGroup>
|
|
86
|
+
* <InputOTPSlot [index]="3" />
|
|
87
|
+
* <InputOTPSlot [index]="4" />
|
|
88
|
+
* <InputOTPSlot [index]="5" />
|
|
89
|
+
* </InputOTPGroup>
|
|
90
|
+
* </InputOTP>
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example Simple 4-digit
|
|
94
|
+
* ```html
|
|
95
|
+
* <InputOTP [maxLength]="4" (onComplete)="submitCode($event)">
|
|
96
|
+
* <InputOTPGroup>
|
|
97
|
+
* @for (i of [0,1,2,3]; track i) {
|
|
98
|
+
* <InputOTPSlot [index]="i" />
|
|
99
|
+
* }
|
|
100
|
+
* </InputOTPGroup>
|
|
101
|
+
* </InputOTP>
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
@Component({
|
|
105
|
+
selector: 'InputOTP',
|
|
106
|
+
imports: [FormsModule],
|
|
107
|
+
template: `
|
|
108
|
+
<div [class]="computedClass()" (click)="focus()">
|
|
109
|
+
<input
|
|
110
|
+
#hiddenInput
|
|
111
|
+
type="text"
|
|
112
|
+
inputmode="numeric"
|
|
113
|
+
pattern="[0-9]*"
|
|
114
|
+
autocomplete="one-time-code"
|
|
115
|
+
[attr.maxlength]="maxLength()"
|
|
116
|
+
[value]="value()"
|
|
117
|
+
(input)="onInput($event)"
|
|
118
|
+
(keydown)="onKeyDown($event)"
|
|
119
|
+
(paste)="onPaste($event)"
|
|
120
|
+
(focus)="onFocus()"
|
|
121
|
+
(blur)="onBlur()"
|
|
122
|
+
class="absolute inset-0 w-full h-full opacity-0 cursor-text z-10"
|
|
123
|
+
[disabled]="disabled()"
|
|
124
|
+
[attr.aria-label]="'OTP input, ' + maxLength() + ' digits'"
|
|
125
|
+
/>
|
|
126
|
+
<ng-content />
|
|
127
|
+
</div>
|
|
128
|
+
`,
|
|
129
|
+
providers: [
|
|
130
|
+
{
|
|
131
|
+
provide: INPUT_OTP_CONTEXT,
|
|
132
|
+
useFactory: (component: InputOTP): InputOTPContextValue => ({
|
|
133
|
+
value: component.internalValue,
|
|
134
|
+
maxLength: signal(6),
|
|
135
|
+
activeIndex: component.activeIndex,
|
|
136
|
+
}),
|
|
137
|
+
deps: [forwardRef(() => InputOTP)],
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
host: {
|
|
141
|
+
class: 'contents',
|
|
142
|
+
'[attr.data-disabled]': 'disabled() ? "" : null',
|
|
143
|
+
},
|
|
144
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
145
|
+
})
|
|
146
|
+
export class InputOTP {
|
|
147
|
+
private readonly hiddenInput = viewChild<ElementRef<HTMLInputElement>>('hiddenInput');
|
|
148
|
+
|
|
149
|
+
/** The controlled value of the input */
|
|
150
|
+
readonly value = model<string>('');
|
|
151
|
+
|
|
152
|
+
/** Internal value signal for context sharing */
|
|
153
|
+
readonly internalValue = signal<string>('');
|
|
154
|
+
|
|
155
|
+
/** Maximum number of characters */
|
|
156
|
+
readonly maxLength = input<number>(6);
|
|
157
|
+
|
|
158
|
+
/** Whether the input is disabled */
|
|
159
|
+
readonly disabled = input<boolean>(false);
|
|
160
|
+
|
|
161
|
+
/** Additional CSS classes */
|
|
162
|
+
readonly class = input<string>('');
|
|
163
|
+
|
|
164
|
+
/** Event handler called when the value changes */
|
|
165
|
+
readonly onChange = output<string>();
|
|
166
|
+
|
|
167
|
+
/** Event handler called when all slots are filled */
|
|
168
|
+
readonly onComplete = output<string>();
|
|
169
|
+
|
|
170
|
+
protected readonly isFocused = signal(false);
|
|
171
|
+
readonly activeIndex = signal(-1);
|
|
172
|
+
|
|
173
|
+
protected readonly computedClass = computed(() =>
|
|
174
|
+
cn(
|
|
175
|
+
'relative flex items-center gap-2 has-[:disabled]:opacity-50',
|
|
176
|
+
this.class()
|
|
177
|
+
)
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
protected onInput(event: Event): void {
|
|
181
|
+
const target = event.target as HTMLInputElement;
|
|
182
|
+
const newValue = target.value.replace(/\D/g, '').slice(0, this.maxLength());
|
|
183
|
+
|
|
184
|
+
this.value.set(newValue);
|
|
185
|
+
this.internalValue.set(newValue);
|
|
186
|
+
this.activeIndex.set(newValue.length);
|
|
187
|
+
this.onChange.emit(newValue);
|
|
188
|
+
|
|
189
|
+
if (newValue.length === this.maxLength()) {
|
|
190
|
+
this.onComplete.emit(newValue);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
protected onKeyDown(event: KeyboardEvent): void {
|
|
195
|
+
if (event.key === 'Backspace') {
|
|
196
|
+
const currentValue = this.value();
|
|
197
|
+
if (currentValue.length > 0) {
|
|
198
|
+
const newValue = currentValue.slice(0, -1);
|
|
199
|
+
this.value.set(newValue);
|
|
200
|
+
this.internalValue.set(newValue);
|
|
201
|
+
this.activeIndex.set(newValue.length);
|
|
202
|
+
this.onChange.emit(newValue);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
protected onPaste(event: ClipboardEvent): void {
|
|
208
|
+
event.preventDefault();
|
|
209
|
+
const pastedData = event.clipboardData?.getData('text') ?? '';
|
|
210
|
+
// Extract only digits from pasted content
|
|
211
|
+
const digits = pastedData.replace(/\D/g, '').slice(0, this.maxLength());
|
|
212
|
+
|
|
213
|
+
if (digits.length > 0) {
|
|
214
|
+
this.value.set(digits);
|
|
215
|
+
this.internalValue.set(digits);
|
|
216
|
+
this.activeIndex.set(digits.length);
|
|
217
|
+
this.onChange.emit(digits);
|
|
218
|
+
|
|
219
|
+
// Auto-submit if all slots are filled
|
|
220
|
+
if (digits.length === this.maxLength()) {
|
|
221
|
+
this.onComplete.emit(digits);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
protected onFocus(): void {
|
|
227
|
+
this.isFocused.set(true);
|
|
228
|
+
this.activeIndex.set(this.value().length);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
protected onBlur(): void {
|
|
232
|
+
this.isFocused.set(false);
|
|
233
|
+
this.activeIndex.set(-1);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Programmatically focus the input */
|
|
237
|
+
focus(): void {
|
|
238
|
+
this.hiddenInput()?.nativeElement.focus();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Kbd variants using class-variance-authority
|
|
5
|
+
* Keyboard key indicator with multiple sizes
|
|
6
|
+
*/
|
|
7
|
+
export const kbdVariants = cva(
|
|
8
|
+
'pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
size: {
|
|
12
|
+
sm: 'h-4 px-1 text-[9px]',
|
|
13
|
+
default: 'h-5 px-1.5 text-[10px]',
|
|
14
|
+
lg: 'h-6 px-2 text-xs',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
size: 'default',
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export type KbdVariants = VariantProps<typeof kbdVariants>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
input,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
import { kbdVariants, type KbdVariants } from './kbd-variants';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Kbd component - displays keyboard keys or shortcuts.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <!-- Single key -->
|
|
15
|
+
* <Kbd>K</Kbd>
|
|
16
|
+
*
|
|
17
|
+
* <!-- Shortcut combination -->
|
|
18
|
+
* <span class="flex items-center gap-1">
|
|
19
|
+
* <Kbd>⌘</Kbd>
|
|
20
|
+
* <Kbd>K</Kbd>
|
|
21
|
+
* </span>
|
|
22
|
+
*
|
|
23
|
+
* <!-- With size -->
|
|
24
|
+
* <Kbd size="lg">Enter</Kbd>
|
|
25
|
+
*/
|
|
26
|
+
@Component({
|
|
27
|
+
selector: 'Kbd',
|
|
28
|
+
template: `<ng-content />`,
|
|
29
|
+
host: {
|
|
30
|
+
'[class]': 'computedClass()',
|
|
31
|
+
},
|
|
32
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33
|
+
})
|
|
34
|
+
export class Kbd {
|
|
35
|
+
/** The size of the kbd element */
|
|
36
|
+
readonly size = input<KbdVariants['size']>('default');
|
|
37
|
+
|
|
38
|
+
/** Additional CSS classes to apply */
|
|
39
|
+
readonly class = input<string>('');
|
|
40
|
+
|
|
41
|
+
/** Computed class combining variants and custom classes */
|
|
42
|
+
protected readonly computedClass = computed(() =>
|
|
43
|
+
cn(
|
|
44
|
+
kbdVariants({
|
|
45
|
+
size: this.size(),
|
|
46
|
+
}),
|
|
47
|
+
this.class()
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Label, type LabelProps } from './label.component';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
computed,
|
|
6
|
+
ElementRef,
|
|
7
|
+
inject,
|
|
8
|
+
input,
|
|
9
|
+
} from '@angular/core';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Types
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export type LabelProps = {
|
|
16
|
+
/** ID of the form element this label is for */
|
|
17
|
+
for?: string;
|
|
18
|
+
/** Alternative binding for 'for' attribute (React-style) */
|
|
19
|
+
htmlFor?: string;
|
|
20
|
+
/** Additional CSS classes to apply */
|
|
21
|
+
class?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Label Component
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Label component renders an accessible label associated with form controls.
|
|
30
|
+
* Based on Radix UI Label primitive with shadcn/ui styling.
|
|
31
|
+
*
|
|
32
|
+
* ## Features
|
|
33
|
+
* - Automatic association with form controls via `for`/`htmlFor`
|
|
34
|
+
* - Text selection prevention on double-click (matches Radix behavior)
|
|
35
|
+
* - Disabled state styling when associated control is disabled
|
|
36
|
+
* - Full accessibility support
|
|
37
|
+
*
|
|
38
|
+
* ## Accessibility
|
|
39
|
+
* - Uses native `<label>` element for built-in accessibility
|
|
40
|
+
* - Clicking the label focuses the associated form control
|
|
41
|
+
* - Screen readers announce the label when the control receives focus
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* <!-- Basic usage with form control -->
|
|
45
|
+
* <Label for="email">Email address</Label>
|
|
46
|
+
* <Input id="email" type="email" />
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* <!-- With required indicator -->
|
|
50
|
+
* <Label for="name">
|
|
51
|
+
* Name <span class="text-destructive">*</span>
|
|
52
|
+
* </Label>
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* <!-- With disabled styling (wrap in group) -->
|
|
56
|
+
* <div class="group" [attr.data-disabled]="isDisabled">
|
|
57
|
+
* <Label for="username">Username</Label>
|
|
58
|
+
* <Input id="username" [disabled]="isDisabled" />
|
|
59
|
+
* </div>
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <!-- Within FormField context -->
|
|
63
|
+
* <FormField name="email">
|
|
64
|
+
* <FormItem>
|
|
65
|
+
* <FormLabel>Email</FormLabel>
|
|
66
|
+
* <FormControl>
|
|
67
|
+
* <Input type="email" formControlName="email" />
|
|
68
|
+
* </FormControl>
|
|
69
|
+
* <FormMessage />
|
|
70
|
+
* </FormItem>
|
|
71
|
+
* </FormField>
|
|
72
|
+
*
|
|
73
|
+
* @see {@link https://www.radix-ui.com/primitives/docs/components/label Radix Label}
|
|
74
|
+
* @see {@link https://ui.shadcn.com/docs/components/label shadcn/ui Label}
|
|
75
|
+
*/
|
|
76
|
+
@Component({
|
|
77
|
+
selector: 'Label',
|
|
78
|
+
template: `
|
|
79
|
+
<label
|
|
80
|
+
[attr.for]="forId()"
|
|
81
|
+
[class]="computedClass()"
|
|
82
|
+
(mousedown)="onMouseDown($event)"
|
|
83
|
+
>
|
|
84
|
+
<ng-content />
|
|
85
|
+
</label>
|
|
86
|
+
`,
|
|
87
|
+
host: {
|
|
88
|
+
'data-slot': 'label',
|
|
89
|
+
class: 'contents',
|
|
90
|
+
},
|
|
91
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
92
|
+
})
|
|
93
|
+
export class Label {
|
|
94
|
+
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
|
95
|
+
|
|
96
|
+
/** ID of the form element this label is for */
|
|
97
|
+
readonly for = input<string>();
|
|
98
|
+
|
|
99
|
+
/** Alternative binding for 'for' attribute (React-style) */
|
|
100
|
+
readonly htmlFor = input<string>();
|
|
101
|
+
|
|
102
|
+
/** Computed ID - prefers 'for' over 'htmlFor' */
|
|
103
|
+
protected readonly forId = computed(() => this.for() || this.htmlFor());
|
|
104
|
+
|
|
105
|
+
/** Additional CSS classes to apply */
|
|
106
|
+
readonly class = input<string>('');
|
|
107
|
+
|
|
108
|
+
/** Computed class combining base styles and custom classes */
|
|
109
|
+
protected readonly computedClass = computed(() =>
|
|
110
|
+
cn(
|
|
111
|
+
// Base styles
|
|
112
|
+
'flex items-center gap-2 text-sm font-medium leading-none',
|
|
113
|
+
// Cursor
|
|
114
|
+
'cursor-pointer select-none',
|
|
115
|
+
// Disabled states - peer for sibling inputs, group for parent containers
|
|
116
|
+
'peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
|
|
117
|
+
'group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50',
|
|
118
|
+
// Custom classes
|
|
119
|
+
this.class()
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Prevents text selection on double-click (Radix behavior).
|
|
125
|
+
* This allows double-clicking the label to focus the control without selecting text.
|
|
126
|
+
*/
|
|
127
|
+
protected onMouseDown(event: MouseEvent): void {
|
|
128
|
+
// Only prevent default if the target is the label itself (not nested interactive elements)
|
|
129
|
+
const target = event.target as HTMLElement;
|
|
130
|
+
if (target.closest('button, input, select, textarea')) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Prevent text selection on double-click
|
|
135
|
+
if (event.detail > 1) {
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Context and types
|
|
2
|
+
export {
|
|
3
|
+
MENUBAR_CONTEXT,
|
|
4
|
+
MENUBAR_MENU_CONTEXT,
|
|
5
|
+
type MenubarContextValue,
|
|
6
|
+
type MenubarDirection,
|
|
7
|
+
type MenubarMenuContextValue,
|
|
8
|
+
type MenubarNavigationDirection
|
|
9
|
+
} from './menubar-context';
|
|
10
|
+
|
|
11
|
+
// Components and their types
|
|
12
|
+
export { MenubarCheckboxItem } from './menubar-checkbox-item.component';
|
|
13
|
+
export { MenubarContent } from './menubar-content.component';
|
|
14
|
+
export { MenubarItem } from './menubar-item.component';
|
|
15
|
+
export { MenubarLabel } from './menubar-label.component';
|
|
16
|
+
export { MenubarMenu } from './menubar-menu.component';
|
|
17
|
+
export { MENUBAR_RADIO_GROUP_CONTEXT, MenubarRadioGroup, type MenubarRadioGroupContext } from './menubar-radio-group.component';
|
|
18
|
+
export { MenubarRadioItem } from './menubar-radio-item.component';
|
|
19
|
+
export { MenubarSeparator } from './menubar-separator.component';
|
|
20
|
+
export { MenubarShortcut } from './menubar-shortcut.component';
|
|
21
|
+
export { MenubarSubContent } from './menubar-sub-content.component';
|
|
22
|
+
export { MenubarSubTrigger } from './menubar-sub-trigger.component';
|
|
23
|
+
export { MENUBAR_SUB_CONTEXT, MenubarSub, type MenubarSubContext } from './menubar-sub.component';
|
|
24
|
+
export { MenubarTrigger } from './menubar-trigger.component';
|
|
25
|
+
export { Menubar, type MenubarProps } from './menubar.component';
|
|
26
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, computed, inject, input, model, output } from '@angular/core';
|
|
3
|
+
import { Check, LucideAngularModule } from 'lucide-angular';
|
|
4
|
+
import { MENUBAR_CONTEXT, MENUBAR_MENU_CONTEXT } from './menubar-context';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MenubarCheckboxItem component - checkbox menu item.
|
|
8
|
+
* Matches shadcn/ui React MenubarCheckboxItem exactly.
|
|
9
|
+
*/
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'MenubarCheckboxItem',
|
|
12
|
+
imports: [LucideAngularModule],
|
|
13
|
+
template: `
|
|
14
|
+
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
15
|
+
@if (checked()) {
|
|
16
|
+
<lucide-icon [img]="CheckIcon" class="h-4 w-4" />
|
|
17
|
+
}
|
|
18
|
+
</span>
|
|
19
|
+
<ng-content />
|
|
20
|
+
`,
|
|
21
|
+
host: {
|
|
22
|
+
'[class]': 'computedClass()',
|
|
23
|
+
'[attr.role]': '"menuitemcheckbox"',
|
|
24
|
+
'[attr.aria-checked]': 'checked()',
|
|
25
|
+
'[attr.data-state]': 'checked() ? "checked" : "unchecked"',
|
|
26
|
+
'(click)': 'handleClick($event)',
|
|
27
|
+
'(keydown.enter)': 'handleClick($event)',
|
|
28
|
+
'(keydown.space)': 'handleClick($event)',
|
|
29
|
+
},
|
|
30
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
31
|
+
})
|
|
32
|
+
export class MenubarCheckboxItem {
|
|
33
|
+
private readonly context = inject(MENUBAR_CONTEXT);
|
|
34
|
+
private readonly menuContext = inject(MENUBAR_MENU_CONTEXT);
|
|
35
|
+
protected readonly CheckIcon = Check;
|
|
36
|
+
|
|
37
|
+
/** Whether the checkbox is checked */
|
|
38
|
+
readonly checked = model<boolean>(false);
|
|
39
|
+
|
|
40
|
+
/** Whether the item is disabled */
|
|
41
|
+
readonly disabled = input<boolean>(false);
|
|
42
|
+
|
|
43
|
+
/** Additional CSS classes */
|
|
44
|
+
readonly class = input<string>('');
|
|
45
|
+
|
|
46
|
+
/** Checked change event */
|
|
47
|
+
readonly onCheckedChange = output<boolean>();
|
|
48
|
+
|
|
49
|
+
protected readonly computedClass = computed(() =>
|
|
50
|
+
cn(
|
|
51
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
52
|
+
!this.disabled() && 'cursor-pointer hover:bg-accent hover:text-accent-foreground',
|
|
53
|
+
this.class()
|
|
54
|
+
)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
protected handleClick(event: Event): void {
|
|
58
|
+
if (this.disabled()) {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const newValue = !this.checked();
|
|
63
|
+
this.checked.set(newValue);
|
|
64
|
+
this.onCheckedChange.emit(newValue);
|
|
65
|
+
}
|
|
66
|
+
}
|