@ng-cn/core 1.0.11 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/schematics/ng-add/index.js +2 -2
- package/schematics/ng-add/index.ts +2 -2
- package/src/app/lib/components/ui/accordion/accordion-content.component.ts +53 -0
- package/src/app/lib/components/ui/accordion/accordion-context.ts +33 -0
- package/src/app/lib/components/ui/accordion/accordion-item.component.ts +86 -0
- package/src/app/lib/components/ui/accordion/accordion-trigger.component.ts +73 -0
- package/src/app/lib/components/ui/accordion/accordion.component.ts +197 -0
- package/src/app/lib/components/ui/accordion/index.ts +15 -0
- package/src/app/lib/components/ui/alert/alert-description.component.ts +33 -0
- package/src/app/lib/components/ui/alert/alert-title.component.ts +30 -0
- package/src/app/lib/components/ui/alert/alert-variants.ts +23 -0
- package/src/app/lib/components/ui/alert/alert.component.ts +50 -0
- package/src/app/lib/components/ui/alert/index.ts +5 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-action.component.ts +44 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-cancel.component.ts +45 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-content.component.ts +146 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-context.ts +14 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-description.component.ts +37 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-footer.component.ts +35 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-header.component.ts +35 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-title.component.ts +37 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog-trigger.component.ts +44 -0
- package/src/app/lib/components/ui/alert-dialog/alert-dialog.component.ts +91 -0
- package/src/app/lib/components/ui/alert-dialog/index.ts +11 -0
- package/src/app/lib/components/ui/aspect-ratio/aspect-ratio.component.ts +63 -0
- package/src/app/lib/components/ui/aspect-ratio/index.ts +1 -0
- package/src/app/lib/components/ui/avatar/avatar-fallback.component.ts +34 -0
- package/src/app/lib/components/ui/avatar/avatar-image.component.ts +31 -0
- package/src/app/lib/components/ui/avatar/avatar.component.ts +37 -0
- package/src/app/lib/components/ui/avatar/index.ts +5 -0
- package/src/app/lib/components/ui/avatar/ui-avatar.component.ts +52 -0
- package/src/app/lib/components/ui/badge/badge-variants.ts +28 -0
- package/src/app/lib/components/ui/badge/badge.component.ts +50 -0
- package/src/app/lib/components/ui/badge/index.ts +3 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-ellipsis.component.ts +48 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-item.component.ts +28 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-link.component.ts +32 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-list.component.ts +31 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-page.component.ts +31 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb-separator.component.ts +47 -0
- package/src/app/lib/components/ui/breadcrumb/breadcrumb.component.ts +43 -0
- package/src/app/lib/components/ui/breadcrumb/index.ts +8 -0
- package/src/app/lib/components/ui/button/button-variants.ts +38 -0
- package/src/app/lib/components/ui/button/button.component.ts +103 -0
- package/src/app/lib/components/ui/button/index.ts +3 -0
- package/src/app/lib/components/ui/button-group/button-group-variants.ts +24 -0
- package/src/app/lib/components/ui/button-group/button-group.component.ts +57 -0
- package/src/app/lib/components/ui/button-group/index.ts +6 -0
- package/src/app/lib/components/ui/calendar/calendar.component.ts +368 -0
- package/src/app/lib/components/ui/calendar/index.ts +1 -0
- package/src/app/lib/components/ui/card/card-action.component.ts +39 -0
- package/src/app/lib/components/ui/card/card-content.component.ts +31 -0
- package/src/app/lib/components/ui/card/card-description.component.ts +31 -0
- package/src/app/lib/components/ui/card/card-footer.component.ts +34 -0
- package/src/app/lib/components/ui/card/card-header.component.ts +37 -0
- package/src/app/lib/components/ui/card/card-title.component.ts +31 -0
- package/src/app/lib/components/ui/card/card.component.ts +41 -0
- package/src/app/lib/components/ui/card/index.ts +8 -0
- package/src/app/lib/components/ui/carousel/carousel-content.component.ts +38 -0
- package/src/app/lib/components/ui/carousel/carousel-context.ts +18 -0
- package/src/app/lib/components/ui/carousel/carousel-item.component.ts +32 -0
- package/src/app/lib/components/ui/carousel/carousel-next.component.ts +54 -0
- package/src/app/lib/components/ui/carousel/carousel-previous.component.ts +54 -0
- package/src/app/lib/components/ui/carousel/carousel.component.ts +125 -0
- package/src/app/lib/components/ui/carousel/index.ts +7 -0
- package/src/app/lib/components/ui/chart/chart-container.component.ts +81 -0
- package/src/app/lib/components/ui/chart/chart-context.ts +38 -0
- package/src/app/lib/components/ui/chart/chart-legend-content.component.ts +51 -0
- package/src/app/lib/components/ui/chart/chart-legend.component.ts +28 -0
- package/src/app/lib/components/ui/chart/chart-tooltip-content.component.ts +37 -0
- package/src/app/lib/components/ui/chart/chart-tooltip.component.ts +28 -0
- package/src/app/lib/components/ui/chart/chart.component.ts +308 -0
- package/src/app/lib/components/ui/chart/index.ts +16 -0
- package/src/app/lib/components/ui/checkbox/checkbox.component.ts +203 -0
- package/src/app/lib/components/ui/checkbox/index.ts +1 -0
- package/src/app/lib/components/ui/collapsible/collapsible-content.component.ts +58 -0
- package/src/app/lib/components/ui/collapsible/collapsible-context.ts +17 -0
- package/src/app/lib/components/ui/collapsible/collapsible-trigger.component.ts +56 -0
- package/src/app/lib/components/ui/collapsible/collapsible.component.ts +102 -0
- package/src/app/lib/components/ui/collapsible/index.ts +5 -0
- package/src/app/lib/components/ui/combobox/combobox-content.component.ts +59 -0
- package/src/app/lib/components/ui/combobox/combobox-context.ts +49 -0
- package/src/app/lib/components/ui/combobox/combobox-empty.component.ts +35 -0
- package/src/app/lib/components/ui/combobox/combobox-group.component.ts +32 -0
- package/src/app/lib/components/ui/combobox/combobox-input.component.ts +89 -0
- package/src/app/lib/components/ui/combobox/combobox-item.component.ts +129 -0
- package/src/app/lib/components/ui/combobox/combobox-list.component.ts +40 -0
- package/src/app/lib/components/ui/combobox/combobox-trigger.component.ts +53 -0
- package/src/app/lib/components/ui/combobox/combobox-value.component.ts +47 -0
- package/src/app/lib/components/ui/combobox/combobox.component.ts +290 -0
- package/src/app/lib/components/ui/combobox/index.ts +15 -0
- package/src/app/lib/components/ui/command/command-context.ts +24 -0
- package/src/app/lib/components/ui/command/command-dialog.component.ts +69 -0
- package/src/app/lib/components/ui/command/command-empty.component.ts +23 -0
- package/src/app/lib/components/ui/command/command-group.component.ts +66 -0
- package/src/app/lib/components/ui/command/command-input.component.ts +137 -0
- package/src/app/lib/components/ui/command/command-item.component.ts +148 -0
- package/src/app/lib/components/ui/command/command-list.component.ts +30 -0
- package/src/app/lib/components/ui/command/command-separator.component.ts +23 -0
- package/src/app/lib/components/ui/command/command-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/command/command.component.ts +105 -0
- package/src/app/lib/components/ui/command/index.ts +11 -0
- package/src/app/lib/components/ui/context-menu/context-menu-checkbox-item.component.ts +68 -0
- package/src/app/lib/components/ui/context-menu/context-menu-content.component.ts +213 -0
- package/src/app/lib/components/ui/context-menu/context-menu-context.ts +17 -0
- package/src/app/lib/components/ui/context-menu/context-menu-item.component.ts +63 -0
- package/src/app/lib/components/ui/context-menu/context-menu-label.component.ts +30 -0
- package/src/app/lib/components/ui/context-menu/context-menu-radio-group.component.ts +36 -0
- package/src/app/lib/components/ui/context-menu/context-menu-radio-item.component.ts +71 -0
- package/src/app/lib/components/ui/context-menu/context-menu-separator.component.ts +24 -0
- package/src/app/lib/components/ui/context-menu/context-menu-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub-trigger.component.ts +50 -0
- package/src/app/lib/components/ui/context-menu/context-menu-sub.component.ts +31 -0
- package/src/app/lib/components/ui/context-menu/context-menu-trigger.component.ts +51 -0
- package/src/app/lib/components/ui/context-menu/context-menu.component.ts +27 -0
- package/src/app/lib/components/ui/context-menu/index.ts +15 -0
- package/src/app/lib/components/ui/data-table/data-table-content.component.ts +226 -0
- package/src/app/lib/components/ui/data-table/data-table-context.ts +49 -0
- package/src/app/lib/components/ui/data-table/data-table-pagination.component.ts +138 -0
- package/src/app/lib/components/ui/data-table/data-table-search.component.ts +52 -0
- package/src/app/lib/components/ui/data-table/data-table-toolbar.component.ts +27 -0
- package/src/app/lib/components/ui/data-table/data-table-view-options.component.ts +92 -0
- package/src/app/lib/components/ui/data-table/data-table.component.ts +131 -0
- package/src/app/lib/components/ui/data-table/index.ts +16 -0
- package/src/app/lib/components/ui/date-picker/date-picker.component.ts +94 -0
- package/src/app/lib/components/ui/date-picker/index.ts +1 -0
- package/src/app/lib/components/ui/dialog/dialog-close.component.ts +31 -0
- package/src/app/lib/components/ui/dialog/dialog-content.component.ts +177 -0
- package/src/app/lib/components/ui/dialog/dialog-context.ts +15 -0
- package/src/app/lib/components/ui/dialog/dialog-description.component.ts +34 -0
- package/src/app/lib/components/ui/dialog/dialog-footer.component.ts +28 -0
- package/src/app/lib/components/ui/dialog/dialog-header.component.ts +28 -0
- package/src/app/lib/components/ui/dialog/dialog-title.component.ts +34 -0
- package/src/app/lib/components/ui/dialog/dialog-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/dialog/dialog.component.ts +87 -0
- package/src/app/lib/components/ui/dialog/index.ts +10 -0
- package/src/app/lib/components/ui/drawer/drawer-close.component.ts +31 -0
- package/src/app/lib/components/ui/drawer/drawer-content.component.ts +143 -0
- package/src/app/lib/components/ui/drawer/drawer-context.ts +17 -0
- package/src/app/lib/components/ui/drawer/drawer-description.component.ts +33 -0
- package/src/app/lib/components/ui/drawer/drawer-footer.component.ts +28 -0
- package/src/app/lib/components/ui/drawer/drawer-header.component.ts +28 -0
- package/src/app/lib/components/ui/drawer/drawer-title.component.ts +33 -0
- package/src/app/lib/components/ui/drawer/drawer-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/drawer/drawer.component.ts +93 -0
- package/src/app/lib/components/ui/drawer/index.ts +10 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.component.ts +68 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-content.component.ts +234 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-context.ts +15 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-group.component.ts +15 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-item.component.ts +56 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-label.component.ts +30 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.component.ts +42 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.component.ts +71 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-separator.component.ts +24 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.component.ts +53 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub.component.ts +31 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-trigger.component.ts +45 -0
- package/src/app/lib/components/ui/dropdown-menu/dropdown-menu.component.ts +32 -0
- package/src/app/lib/components/ui/dropdown-menu/index.ts +16 -0
- package/src/app/lib/components/ui/empty/empty-action.component.ts +28 -0
- package/src/app/lib/components/ui/empty/empty-description.component.ts +31 -0
- package/src/app/lib/components/ui/empty/empty-icon.component.ts +31 -0
- package/src/app/lib/components/ui/empty/empty-title.component.ts +28 -0
- package/src/app/lib/components/ui/empty/empty.component.ts +53 -0
- package/src/app/lib/components/ui/empty/index.ts +6 -0
- package/src/app/lib/components/ui/form/form-context.ts +34 -0
- package/src/app/lib/components/ui/form/form-control.component.ts +137 -0
- package/src/app/lib/components/ui/form/form-description.component.ts +37 -0
- package/src/app/lib/components/ui/form/form-field.component.ts +84 -0
- package/src/app/lib/components/ui/form/form-item.component.ts +42 -0
- package/src/app/lib/components/ui/form/form-label.component.ts +58 -0
- package/src/app/lib/components/ui/form/form-message.component.ts +107 -0
- package/src/app/lib/components/ui/form/form.component.ts +123 -0
- package/src/app/lib/components/ui/form/index.ts +17 -0
- package/src/app/lib/components/ui/hover-card/hover-card-content.component.ts +203 -0
- package/src/app/lib/components/ui/hover-card/hover-card-context.ts +25 -0
- package/src/app/lib/components/ui/hover-card/hover-card-trigger.component.ts +160 -0
- package/src/app/lib/components/ui/hover-card/hover-card.component.ts +147 -0
- package/src/app/lib/components/ui/hover-card/index.ts +13 -0
- package/src/app/lib/components/ui/index.ts +551 -0
- package/src/app/lib/components/ui/input/index.ts +1 -0
- package/src/app/lib/components/ui/input/input.component.ts +165 -0
- package/src/app/lib/components/ui/input-group/index.ts +4 -0
- package/src/app/lib/components/ui/input-group/input-group-addon.component.ts +43 -0
- package/src/app/lib/components/ui/input-group/input-group-input.component.ts +33 -0
- package/src/app/lib/components/ui/input-group/input-group.component.ts +53 -0
- package/src/app/lib/components/ui/input-otp/index.ts +14 -0
- package/src/app/lib/components/ui/input-otp/input-otp-context.ts +31 -0
- package/src/app/lib/components/ui/input-otp/input-otp-group.component.ts +23 -0
- package/src/app/lib/components/ui/input-otp/input-otp-separator.component.ts +31 -0
- package/src/app/lib/components/ui/input-otp/input-otp-slot.component.ts +67 -0
- package/src/app/lib/components/ui/input-otp/input-otp.component.ts +240 -0
- package/src/app/lib/components/ui/kbd/index.ts +3 -0
- package/src/app/lib/components/ui/kbd/kbd-variants.ts +23 -0
- package/src/app/lib/components/ui/kbd/kbd.component.ts +50 -0
- package/src/app/lib/components/ui/label/index.ts +1 -0
- package/src/app/lib/components/ui/label/label.component.ts +139 -0
- package/src/app/lib/components/ui/menubar/index.ts +26 -0
- package/src/app/lib/components/ui/menubar/menubar-checkbox-item.component.ts +66 -0
- package/src/app/lib/components/ui/menubar/menubar-content.component.ts +236 -0
- package/src/app/lib/components/ui/menubar/menubar-context.ts +63 -0
- package/src/app/lib/components/ui/menubar/menubar-item.component.ts +60 -0
- package/src/app/lib/components/ui/menubar/menubar-label.component.ts +30 -0
- package/src/app/lib/components/ui/menubar/menubar-menu.component.ts +40 -0
- package/src/app/lib/components/ui/menubar/menubar-radio-group.component.ts +36 -0
- package/src/app/lib/components/ui/menubar/menubar-radio-item.component.ts +66 -0
- package/src/app/lib/components/ui/menubar/menubar-separator.component.ts +24 -0
- package/src/app/lib/components/ui/menubar/menubar-shortcut.component.ts +23 -0
- package/src/app/lib/components/ui/menubar/menubar-sub-content.component.ts +51 -0
- package/src/app/lib/components/ui/menubar/menubar-sub-trigger.component.ts +50 -0
- package/src/app/lib/components/ui/menubar/menubar-sub.component.ts +29 -0
- package/src/app/lib/components/ui/menubar/menubar-trigger.component.ts +132 -0
- package/src/app/lib/components/ui/menubar/menubar.component.ts +158 -0
- package/src/app/lib/components/ui/native-select/index.ts +6 -0
- package/src/app/lib/components/ui/native-select/native-select-variants.ts +23 -0
- package/src/app/lib/components/ui/native-select/native-select.component.ts +74 -0
- package/src/app/lib/components/ui/navigation-menu/index.ts +21 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-content.component.ts +66 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-context.ts +55 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-indicator.component.ts +28 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-item.component.ts +29 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-link.component.ts +43 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-list.component.ts +26 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger-style.ts +7 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger.component.ts +58 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu-viewport.component.ts +26 -0
- package/src/app/lib/components/ui/navigation-menu/navigation-menu.component.ts +149 -0
- package/src/app/lib/components/ui/pagination/index.ts +8 -0
- package/src/app/lib/components/ui/pagination/pagination-content.component.ts +28 -0
- package/src/app/lib/components/ui/pagination/pagination-ellipsis.component.ts +47 -0
- package/src/app/lib/components/ui/pagination/pagination-item.component.ts +28 -0
- package/src/app/lib/components/ui/pagination/pagination-link.component.ts +46 -0
- package/src/app/lib/components/ui/pagination/pagination-next.component.ts +54 -0
- package/src/app/lib/components/ui/pagination/pagination-previous.component.ts +54 -0
- package/src/app/lib/components/ui/pagination/pagination.component.ts +48 -0
- package/src/app/lib/components/ui/popover/index.ts +14 -0
- package/src/app/lib/components/ui/popover/popover-anchor.component.ts +64 -0
- package/src/app/lib/components/ui/popover/popover-content.component.ts +231 -0
- package/src/app/lib/components/ui/popover/popover-context.ts +29 -0
- package/src/app/lib/components/ui/popover/popover-trigger.component.ts +100 -0
- package/src/app/lib/components/ui/popover/popover.component.ts +163 -0
- package/src/app/lib/components/ui/progress/index.ts +6 -0
- package/src/app/lib/components/ui/progress/progress.component.ts +212 -0
- package/src/app/lib/components/ui/radio-group/index.ts +10 -0
- package/src/app/lib/components/ui/radio-group/radio-group-context.ts +38 -0
- package/src/app/lib/components/ui/radio-group/radio-group-item.component.ts +298 -0
- package/src/app/lib/components/ui/radio-group/radio-group.component.ts +275 -0
- package/src/app/lib/components/ui/resizable/index.ts +5 -0
- package/src/app/lib/components/ui/resizable/resizable-context.ts +14 -0
- package/src/app/lib/components/ui/resizable/resizable-handle.component.ts +232 -0
- package/src/app/lib/components/ui/resizable/resizable-panel-group.component.ts +140 -0
- package/src/app/lib/components/ui/resizable/resizable-panel.component.ts +77 -0
- package/src/app/lib/components/ui/scroll-area/index.ts +8 -0
- package/src/app/lib/components/ui/scroll-area/scroll-area.component.ts +126 -0
- package/src/app/lib/components/ui/scroll-area/scroll-bar.component.ts +93 -0
- package/src/app/lib/components/ui/segmented/index.ts +13 -0
- package/src/app/lib/components/ui/segmented/segmented-context.ts +11 -0
- package/src/app/lib/components/ui/segmented/segmented-item.component.ts +72 -0
- package/src/app/lib/components/ui/segmented/segmented-variants.ts +40 -0
- package/src/app/lib/components/ui/segmented/segmented.component.ts +99 -0
- package/src/app/lib/components/ui/select/index.ts +19 -0
- package/src/app/lib/components/ui/select/select-content.component.ts +97 -0
- package/src/app/lib/components/ui/select/select-context.ts +53 -0
- package/src/app/lib/components/ui/select/select-group.component.ts +56 -0
- package/src/app/lib/components/ui/select/select-item.component.ts +163 -0
- package/src/app/lib/components/ui/select/select-label.component.ts +32 -0
- package/src/app/lib/components/ui/select/select-separator.component.ts +34 -0
- package/src/app/lib/components/ui/select/select-trigger.component.ts +164 -0
- package/src/app/lib/components/ui/select/select-value.component.ts +49 -0
- package/src/app/lib/components/ui/select/select.component.ts +263 -0
- package/src/app/lib/components/ui/separator/index.ts +6 -0
- package/src/app/lib/components/ui/separator/separator.component.ts +128 -0
- package/src/app/lib/components/ui/sheet/index.ts +11 -0
- package/src/app/lib/components/ui/sheet/sheet-close.component.ts +32 -0
- package/src/app/lib/components/ui/sheet/sheet-content.component.ts +157 -0
- package/src/app/lib/components/ui/sheet/sheet-context.ts +15 -0
- package/src/app/lib/components/ui/sheet/sheet-description.component.ts +34 -0
- package/src/app/lib/components/ui/sheet/sheet-footer.component.ts +28 -0
- package/src/app/lib/components/ui/sheet/sheet-header.component.ts +28 -0
- package/src/app/lib/components/ui/sheet/sheet-title.component.ts +34 -0
- package/src/app/lib/components/ui/sheet/sheet-trigger.component.ts +38 -0
- package/src/app/lib/components/ui/sheet/sheet-variants.ts +22 -0
- package/src/app/lib/components/ui/sheet/sheet.component.ts +97 -0
- package/src/app/lib/components/ui/sidebar/index.ts +41 -0
- package/src/app/lib/components/ui/sidebar/sidebar-content.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-context.ts +33 -0
- package/src/app/lib/components/ui/sidebar/sidebar-footer.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-action.component.ts +33 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-content.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group-label.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-group.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-header.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-input.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-inset.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-action.component.ts +56 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-badge.component.ts +42 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-button.component.ts +64 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-item.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-skeleton.component.ts +39 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-button.component.ts +59 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-item.component.ts +25 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu-sub.component.ts +32 -0
- package/src/app/lib/components/ui/sidebar/sidebar-menu.component.ts +31 -0
- package/src/app/lib/components/ui/sidebar/sidebar-provider.component.ts +141 -0
- package/src/app/lib/components/ui/sidebar/sidebar-rail.component.ts +47 -0
- package/src/app/lib/components/ui/sidebar/sidebar-route-active.service.ts +124 -0
- package/src/app/lib/components/ui/sidebar/sidebar-separator.component.ts +28 -0
- package/src/app/lib/components/ui/sidebar/sidebar-trigger.component.ts +57 -0
- package/src/app/lib/components/ui/sidebar/sidebar.component.ts +130 -0
- package/src/app/lib/components/ui/skeleton/index.ts +1 -0
- package/src/app/lib/components/ui/skeleton/skeleton.component.ts +52 -0
- package/src/app/lib/components/ui/slider/index.ts +6 -0
- package/src/app/lib/components/ui/slider/slider.component.ts +477 -0
- package/src/app/lib/components/ui/spinner/index.ts +3 -0
- package/src/app/lib/components/ui/spinner/spinner-variants.ts +32 -0
- package/src/app/lib/components/ui/spinner/spinner.component.ts +77 -0
- package/src/app/lib/components/ui/switch/index.ts +6 -0
- package/src/app/lib/components/ui/switch/switch.component.ts +282 -0
- package/src/app/lib/components/ui/table/index.ts +9 -0
- package/src/app/lib/components/ui/table/table-body.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-caption.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-cell.component.ts +31 -0
- package/src/app/lib/components/ui/table/table-footer.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-head.component.ts +36 -0
- package/src/app/lib/components/ui/table/table-header.component.ts +28 -0
- package/src/app/lib/components/ui/table/table-row.component.ts +34 -0
- package/src/app/lib/components/ui/table/table.component.ts +52 -0
- package/src/app/lib/components/ui/tabs/index.ts +14 -0
- package/src/app/lib/components/ui/tabs/tabs-content.component.ts +132 -0
- package/src/app/lib/components/ui/tabs/tabs-context.ts +33 -0
- package/src/app/lib/components/ui/tabs/tabs-list.component.ts +228 -0
- package/src/app/lib/components/ui/tabs/tabs-trigger.component.ts +167 -0
- package/src/app/lib/components/ui/tabs/tabs.component.ts +203 -0
- package/src/app/lib/components/ui/textarea/index.ts +1 -0
- package/src/app/lib/components/ui/textarea/textarea.component.ts +44 -0
- package/src/app/lib/components/ui/toast/index.ts +16 -0
- package/src/app/lib/components/ui/toast/toast-action.component.ts +77 -0
- package/src/app/lib/components/ui/toast/toast-description.component.ts +52 -0
- package/src/app/lib/components/ui/toast/toast-title.component.ts +52 -0
- package/src/app/lib/components/ui/toast/toast-variants.ts +24 -0
- package/src/app/lib/components/ui/toast/toast.component.ts +177 -0
- package/src/app/lib/components/ui/toast/toast.service.ts +202 -0
- package/src/app/lib/components/ui/toast/toaster.component.ts +128 -0
- package/src/app/lib/components/ui/toggle/index.ts +6 -0
- package/src/app/lib/components/ui/toggle/toggle-variants.ts +30 -0
- package/src/app/lib/components/ui/toggle/toggle.component.ts +199 -0
- package/src/app/lib/components/ui/toggle-group/index.ts +11 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group-context.ts +48 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group-item.component.ts +241 -0
- package/src/app/lib/components/ui/toggle-group/toggle-group.component.ts +288 -0
- package/src/app/lib/components/ui/tooltip/index.ts +14 -0
- package/src/app/lib/components/ui/tooltip/tooltip-content.component.ts +154 -0
- package/src/app/lib/components/ui/tooltip/tooltip-context.ts +29 -0
- package/src/app/lib/components/ui/tooltip/tooltip-provider.component.ts +95 -0
- package/src/app/lib/components/ui/tooltip/tooltip-trigger.component.ts +138 -0
- package/src/app/lib/components/ui/tooltip/tooltip.component.ts +159 -0
- package/src/app/lib/components/ui/typography/index.ts +13 -0
- package/src/app/lib/components/ui/typography/typography-blockquote.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-h1.component.ts +32 -0
- package/src/app/lib/components/ui/typography/typography-h2.component.ts +32 -0
- package/src/app/lib/components/ui/typography/typography-h3.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-h4.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-inline-code.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-large.component.ts +28 -0
- package/src/app/lib/components/ui/typography/typography-lead.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-list.component.ts +31 -0
- package/src/app/lib/components/ui/typography/typography-muted.component.ts +28 -0
- package/src/app/lib/components/ui/typography/typography-p.component.ts +29 -0
- package/src/app/lib/components/ui/typography/typography-small.component.ts +28 -0
- package/src/app/lib/index.ts +7 -0
- package/src/app/lib/utils/accessibility/aria-id.service.ts +118 -0
- package/src/app/lib/utils/accessibility/click-outside.directive.ts +85 -0
- package/src/app/lib/utils/accessibility/focus-management.service.ts +231 -0
- package/src/app/lib/utils/accessibility/focus-trap.directive.ts +203 -0
- package/src/app/lib/utils/accessibility/index.ts +23 -0
- package/src/app/lib/utils/accessibility/keyboard-navigation.directive.ts +440 -0
- package/src/app/lib/utils/accessibility/live-region.directive.ts +260 -0
- package/src/app/lib/utils/accessibility/touch-target.directive.ts +81 -0
- package/src/app/lib/utils/accessibility/visually-hidden.component.ts +79 -0
- package/src/app/lib/utils/animation/animated.directive.ts +191 -0
- package/src/app/lib/utils/animation/animation-tokens.service.ts +88 -0
- package/src/app/lib/utils/animation/animation.types.ts +55 -0
- package/src/app/lib/utils/animation/animation.utils.ts +158 -0
- package/src/app/lib/utils/animation/index.ts +17 -0
- package/src/app/lib/utils/animation/presence.component.ts +168 -0
- package/src/app/lib/utils/animation/presence.directive.ts +169 -0
- package/src/app/lib/utils/cn.ts +15 -0
- package/src/app/lib/utils/index.ts +11 -0
- package/src/app/lib/utils/positioning/index.ts +218 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { Align, cn, computePosition, getTransformOrigin, Presence, Side } from '@/lib/utils';
|
|
2
|
+
import {
|
|
3
|
+
afterNextRender,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
Component,
|
|
6
|
+
computed,
|
|
7
|
+
effect,
|
|
8
|
+
ElementRef,
|
|
9
|
+
inject,
|
|
10
|
+
Injector,
|
|
11
|
+
input,
|
|
12
|
+
signal,
|
|
13
|
+
} from '@angular/core';
|
|
14
|
+
import { POPOVER_CONTEXT, PopoverAlign, PopoverSide } from './popover-context';
|
|
15
|
+
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Types
|
|
18
|
+
// ============================================================================
|
|
19
|
+
|
|
20
|
+
export type PopoverContentState = 'open' | 'closed';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Props for the PopoverContent component
|
|
24
|
+
*/
|
|
25
|
+
export interface PopoverContentProps {
|
|
26
|
+
/** The preferred side of the anchor to render against.
|
|
27
|
+
* @default 'bottom' */
|
|
28
|
+
side?: PopoverSide;
|
|
29
|
+
/** The distance in pixels from the anchor.
|
|
30
|
+
* @default 4 */
|
|
31
|
+
sideOffset?: number;
|
|
32
|
+
/** The preferred alignment against the anchor.
|
|
33
|
+
* @default 'center' */
|
|
34
|
+
align?: PopoverAlign;
|
|
35
|
+
/** An offset in pixels from the "start" or "end" alignment options.
|
|
36
|
+
* @default 0 */
|
|
37
|
+
alignOffset?: number;
|
|
38
|
+
/** Whether to avoid collisions with viewport boundaries.
|
|
39
|
+
* @default true */
|
|
40
|
+
avoidCollisions?: boolean;
|
|
41
|
+
/** The padding in pixels between the boundary edges and content.
|
|
42
|
+
* @default 8 */
|
|
43
|
+
collisionPadding?: number;
|
|
44
|
+
/** Additional CSS classes */
|
|
45
|
+
class?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Component
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @component PopoverContent
|
|
54
|
+
*
|
|
55
|
+
* The component that pops out when the popover is open.
|
|
56
|
+
*
|
|
57
|
+
* @description
|
|
58
|
+
* PopoverContent displays the floating content. It handles positioning,
|
|
59
|
+
* collision detection, and animations.
|
|
60
|
+
*
|
|
61
|
+
* ## Features
|
|
62
|
+
* - Configurable side (top, right, bottom, left)
|
|
63
|
+
* - Configurable alignment (start, center, end)
|
|
64
|
+
* - Collision detection and avoidance
|
|
65
|
+
* - Smooth enter/exit animations
|
|
66
|
+
* - Click outside to close
|
|
67
|
+
* - Escape key to close
|
|
68
|
+
*
|
|
69
|
+
* ## Accessibility
|
|
70
|
+
* - `role="dialog"` on the content
|
|
71
|
+
* - Focus management when opened
|
|
72
|
+
* - Escape key dismisses popover
|
|
73
|
+
*
|
|
74
|
+
* ## Keyboard Navigation
|
|
75
|
+
* - `Escape` - Close the popover
|
|
76
|
+
*
|
|
77
|
+
* @example Basic usage
|
|
78
|
+
* ```html
|
|
79
|
+
* <PopoverContent>
|
|
80
|
+
* <p>Popover content</p>
|
|
81
|
+
* </PopoverContent>
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example With custom positioning
|
|
85
|
+
* ```html
|
|
86
|
+
* <PopoverContent side="right" align="start" [sideOffset]="8">
|
|
87
|
+
* <p>Right-aligned popover</p>
|
|
88
|
+
* </PopoverContent>
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @data-attributes
|
|
92
|
+
* - `data-state` - 'open' | 'closed'
|
|
93
|
+
* - `data-side` - 'top' | 'right' | 'bottom' | 'left'
|
|
94
|
+
* - `data-align` - 'start' | 'center' | 'end'
|
|
95
|
+
*/
|
|
96
|
+
@Component({
|
|
97
|
+
selector: 'PopoverContent',
|
|
98
|
+
imports: [Presence],
|
|
99
|
+
template: `
|
|
100
|
+
<Presence [present]="context.open()">
|
|
101
|
+
<div
|
|
102
|
+
#contentRef
|
|
103
|
+
[class]="computedClass()"
|
|
104
|
+
[attr.data-state]="state()"
|
|
105
|
+
[attr.data-side]="computedSide()"
|
|
106
|
+
[attr.data-align]="computedAlign()"
|
|
107
|
+
[style]="positionStyles()"
|
|
108
|
+
role="dialog"
|
|
109
|
+
[attr.aria-modal]="context.modal() || null"
|
|
110
|
+
>
|
|
111
|
+
<ng-content />
|
|
112
|
+
</div>
|
|
113
|
+
</Presence>
|
|
114
|
+
`,
|
|
115
|
+
host: {
|
|
116
|
+
class: 'contents',
|
|
117
|
+
'(document:click)': 'onDocumentClick($event)',
|
|
118
|
+
'(document:keydown.escape)': 'onEscapeKey()',
|
|
119
|
+
},
|
|
120
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
121
|
+
})
|
|
122
|
+
export class PopoverContent {
|
|
123
|
+
protected readonly context = inject(POPOVER_CONTEXT);
|
|
124
|
+
private readonly elementRef = inject(ElementRef);
|
|
125
|
+
private readonly injector = inject(Injector);
|
|
126
|
+
|
|
127
|
+
/** The preferred side of the anchor to render against */
|
|
128
|
+
readonly side = input<Side>('bottom');
|
|
129
|
+
|
|
130
|
+
/** The distance in pixels from the anchor */
|
|
131
|
+
readonly sideOffset = input<number>(4);
|
|
132
|
+
|
|
133
|
+
/** The preferred alignment against the anchor */
|
|
134
|
+
readonly align = input<Align>('center');
|
|
135
|
+
|
|
136
|
+
/** An offset in pixels from the alignment options */
|
|
137
|
+
readonly alignOffset = input<number>(0);
|
|
138
|
+
|
|
139
|
+
/** Whether to avoid collisions with viewport boundaries */
|
|
140
|
+
readonly avoidCollisions = input<boolean>(true);
|
|
141
|
+
|
|
142
|
+
/** The padding in pixels between the boundary edges and content */
|
|
143
|
+
readonly collisionPadding = input<number>(8);
|
|
144
|
+
|
|
145
|
+
/** Additional CSS classes */
|
|
146
|
+
readonly class = input<string>('');
|
|
147
|
+
|
|
148
|
+
/** Current state: open or closed */
|
|
149
|
+
protected readonly state = computed<PopoverContentState>(() =>
|
|
150
|
+
this.context.open() ? 'open' : 'closed'
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
/** Computed position after collision detection */
|
|
154
|
+
protected readonly computedSide = signal<Side>('bottom');
|
|
155
|
+
protected readonly computedAlign = signal<Align>('center');
|
|
156
|
+
protected readonly positionStyles = signal<Record<string, string>>({});
|
|
157
|
+
|
|
158
|
+
constructor() {
|
|
159
|
+
// Recalculate position when open state changes (browser-only via afterNextRender)
|
|
160
|
+
effect(() => {
|
|
161
|
+
const isOpen = this.context.open();
|
|
162
|
+
if (isOpen) {
|
|
163
|
+
afterNextRender(() => {
|
|
164
|
+
this.updatePosition();
|
|
165
|
+
}, { injector: this.injector });
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private updatePosition(): void {
|
|
171
|
+
const triggerElement = this.context.triggerRef?.();
|
|
172
|
+
const contentElement = this.elementRef.nativeElement.querySelector('[role="dialog"]') as HTMLElement;
|
|
173
|
+
|
|
174
|
+
if (!triggerElement || !contentElement) return;
|
|
175
|
+
|
|
176
|
+
const triggerRect = triggerElement.getBoundingClientRect();
|
|
177
|
+
const contentRect = contentElement.getBoundingClientRect();
|
|
178
|
+
|
|
179
|
+
const result = computePosition(
|
|
180
|
+
triggerRect,
|
|
181
|
+
{ width: contentRect.width || 288, height: contentRect.height || 100 },
|
|
182
|
+
{
|
|
183
|
+
side: this.side(),
|
|
184
|
+
align: this.align(),
|
|
185
|
+
sideOffset: this.sideOffset(),
|
|
186
|
+
alignOffset: this.alignOffset(),
|
|
187
|
+
avoidCollisions: this.avoidCollisions(),
|
|
188
|
+
collisionPadding: this.collisionPadding(),
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
this.computedSide.set(result.side);
|
|
193
|
+
this.computedAlign.set(result.align);
|
|
194
|
+
|
|
195
|
+
// Set position styles with transform origin for animations
|
|
196
|
+
const transformOrigin = getTransformOrigin(result.side, result.align);
|
|
197
|
+
this.positionStyles.set({
|
|
198
|
+
position: 'fixed',
|
|
199
|
+
top: result.styles.top || '',
|
|
200
|
+
left: result.styles.left || '',
|
|
201
|
+
'--radix-popover-content-transform-origin': transformOrigin,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected readonly computedClass = computed(() =>
|
|
206
|
+
cn(
|
|
207
|
+
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
|
208
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
209
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
210
|
+
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
211
|
+
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
|
|
212
|
+
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
213
|
+
this.class()
|
|
214
|
+
)
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
onDocumentClick(event: Event): void {
|
|
218
|
+
const target = event.target as HTMLElement;
|
|
219
|
+
if (!this.elementRef.nativeElement.contains(target)) {
|
|
220
|
+
// Check if click is outside the popover
|
|
221
|
+
const popoverContent = this.elementRef.nativeElement.querySelector('[role="dialog"]');
|
|
222
|
+
if (popoverContent && !popoverContent.contains(target)) {
|
|
223
|
+
this.context.setOpen(false);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
onEscapeKey(): void {
|
|
229
|
+
this.context.setOpen(false);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { InjectionToken, Signal, WritableSignal } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Types
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
export type PopoverSide = 'top' | 'right' | 'bottom' | 'left';
|
|
8
|
+
export type PopoverAlign = 'start' | 'center' | 'end';
|
|
9
|
+
|
|
10
|
+
export interface PopoverContextValue {
|
|
11
|
+
/** Signal for open state */
|
|
12
|
+
open: WritableSignal<boolean>;
|
|
13
|
+
/** Set open state */
|
|
14
|
+
setOpen: (open: boolean) => void;
|
|
15
|
+
/** Toggle open state */
|
|
16
|
+
toggle: () => void;
|
|
17
|
+
/** Whether the popover is modal */
|
|
18
|
+
modal: () => boolean;
|
|
19
|
+
/** Reference to the trigger element for positioning */
|
|
20
|
+
triggerRef?: Signal<HTMLElement | null>;
|
|
21
|
+
/** Set the trigger element reference */
|
|
22
|
+
setTriggerRef?: (element: HTMLElement | null) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Injection Tokens
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
export const POPOVER_CONTEXT = new InjectionToken<PopoverContextValue>('POPOVER_CONTEXT');
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
afterNextRender,
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
Component,
|
|
5
|
+
ElementRef,
|
|
6
|
+
inject,
|
|
7
|
+
input,
|
|
8
|
+
OnDestroy,
|
|
9
|
+
} from '@angular/core';
|
|
10
|
+
import { POPOVER_CONTEXT } from './popover-context';
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Types
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props for the PopoverTrigger component
|
|
18
|
+
*/
|
|
19
|
+
export interface PopoverTriggerProps {
|
|
20
|
+
/** Change the default rendered element for the one passed as a child.
|
|
21
|
+
* @default false */
|
|
22
|
+
asChild?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Component
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @component PopoverTrigger
|
|
31
|
+
*
|
|
32
|
+
* The button that toggles the popover.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* PopoverTrigger wraps the element that opens/closes the popover when clicked.
|
|
36
|
+
* It registers itself as the positioning anchor for the popover content.
|
|
37
|
+
*
|
|
38
|
+
* ## Features
|
|
39
|
+
* - Click to toggle popover
|
|
40
|
+
* - Registers as positioning anchor
|
|
41
|
+
* - Proper ARIA attributes
|
|
42
|
+
*
|
|
43
|
+
* ## Accessibility
|
|
44
|
+
* - `aria-expanded` reflects open state
|
|
45
|
+
* - `aria-haspopup="dialog"` indicates popover type
|
|
46
|
+
*
|
|
47
|
+
* @example Basic usage
|
|
48
|
+
* ```html
|
|
49
|
+
* <PopoverTrigger>
|
|
50
|
+
* <Button variant="outline">Open</Button>
|
|
51
|
+
* </PopoverTrigger>
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example With icon button
|
|
55
|
+
* ```html
|
|
56
|
+
* <PopoverTrigger>
|
|
57
|
+
* <Button variant="ghost" size="icon">
|
|
58
|
+
* <SettingsIcon />
|
|
59
|
+
* </Button>
|
|
60
|
+
* </PopoverTrigger>
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @data-attributes
|
|
64
|
+
* - `data-state` - 'open' | 'closed'
|
|
65
|
+
*/
|
|
66
|
+
@Component({
|
|
67
|
+
selector: 'PopoverTrigger',
|
|
68
|
+
template: `<ng-content />`,
|
|
69
|
+
host: {
|
|
70
|
+
'(click)': 'onClick($event)',
|
|
71
|
+
'[attr.aria-expanded]': 'context.open()',
|
|
72
|
+
'[attr.aria-haspopup]': '"dialog"',
|
|
73
|
+
'[attr.data-state]': 'context.open() ? "open" : "closed"',
|
|
74
|
+
},
|
|
75
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
76
|
+
})
|
|
77
|
+
export class PopoverTrigger implements OnDestroy {
|
|
78
|
+
protected readonly context = inject(POPOVER_CONTEXT);
|
|
79
|
+
private readonly elementRef = inject(ElementRef);
|
|
80
|
+
|
|
81
|
+
/** Change the default rendered element for the one passed as a child */
|
|
82
|
+
readonly asChild = input<boolean>(false);
|
|
83
|
+
|
|
84
|
+
constructor() {
|
|
85
|
+
// Register this element as the trigger reference (browser-only)
|
|
86
|
+
afterNextRender(() => {
|
|
87
|
+
this.context.setTriggerRef?.(this.elementRef.nativeElement);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
ngOnDestroy(): void {
|
|
92
|
+
// Clean up trigger reference
|
|
93
|
+
this.context.setTriggerRef?.(null);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
onClick(event: Event): void {
|
|
97
|
+
event.stopPropagation();
|
|
98
|
+
this.context.toggle();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
forwardRef,
|
|
5
|
+
input,
|
|
6
|
+
output,
|
|
7
|
+
signal,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { POPOVER_CONTEXT, type PopoverContextValue } from './popover-context';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Types
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export type PopoverState = 'open' | 'closed';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the Popover component
|
|
19
|
+
*/
|
|
20
|
+
export interface PopoverProps {
|
|
21
|
+
/** The open state of the popover when initially rendered.
|
|
22
|
+
* Use when you do not need to control its open state.
|
|
23
|
+
* @default false */
|
|
24
|
+
defaultOpen?: boolean;
|
|
25
|
+
/** The controlled open state of the popover.
|
|
26
|
+
* Must be used in conjunction with onOpenChange. */
|
|
27
|
+
open?: boolean;
|
|
28
|
+
/** The modality of the popover. When set to true,
|
|
29
|
+
* interaction with outside elements will be disabled and only popover content will be visible to screen readers.
|
|
30
|
+
* @default false */
|
|
31
|
+
modal?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Component
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @component Popover
|
|
40
|
+
*
|
|
41
|
+
* Displays rich content in a portal, triggered by a button.
|
|
42
|
+
*
|
|
43
|
+
* @description
|
|
44
|
+
* Popover provides a container for displaying floating content triggered by
|
|
45
|
+
* a button. It manages open/closed state and provides context for positioning.
|
|
46
|
+
*
|
|
47
|
+
* ## Features
|
|
48
|
+
* - Click to toggle open/close
|
|
49
|
+
* - Modal and non-modal modes
|
|
50
|
+
* - Click outside to close
|
|
51
|
+
* - Escape key to close
|
|
52
|
+
* - Controlled and uncontrolled usage
|
|
53
|
+
* - Collision-aware positioning
|
|
54
|
+
*
|
|
55
|
+
* ## Accessibility
|
|
56
|
+
* - `aria-expanded` on trigger
|
|
57
|
+
* - `aria-haspopup="dialog"` on trigger
|
|
58
|
+
* - `role="dialog"` on content
|
|
59
|
+
* - Focus management in modal mode
|
|
60
|
+
* - Escape key dismisses popover
|
|
61
|
+
*
|
|
62
|
+
* ## Keyboard Navigation
|
|
63
|
+
* - `Enter` / `Space` - Toggle popover (on trigger)
|
|
64
|
+
* - `Escape` - Close popover
|
|
65
|
+
*
|
|
66
|
+
* @example Basic usage
|
|
67
|
+
* ```html
|
|
68
|
+
* <Popover>
|
|
69
|
+
* <PopoverTrigger>
|
|
70
|
+
* <Button variant="outline">Open</Button>
|
|
71
|
+
* </PopoverTrigger>
|
|
72
|
+
* <PopoverContent>
|
|
73
|
+
* <p>Content here</p>
|
|
74
|
+
* </PopoverContent>
|
|
75
|
+
* </Popover>
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example Controlled
|
|
79
|
+
* ```html
|
|
80
|
+
* <Popover [open]="isOpen" (openChange)="isOpen = $event">
|
|
81
|
+
* <PopoverTrigger>
|
|
82
|
+
* <Button>Settings</Button>
|
|
83
|
+
* </PopoverTrigger>
|
|
84
|
+
* <PopoverContent>
|
|
85
|
+
* Settings panel content
|
|
86
|
+
* </PopoverContent>
|
|
87
|
+
* </Popover>
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @example Modal mode
|
|
91
|
+
* ```html
|
|
92
|
+
* <Popover [modal]="true">
|
|
93
|
+
* <PopoverTrigger>
|
|
94
|
+
* <Button>Modal Popover</Button>
|
|
95
|
+
* </PopoverTrigger>
|
|
96
|
+
* <PopoverContent>
|
|
97
|
+
* Focus is trapped here
|
|
98
|
+
* </PopoverContent>
|
|
99
|
+
* </Popover>
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @data-attributes
|
|
103
|
+
* - `data-state` - 'open' | 'closed' (on content)
|
|
104
|
+
*/
|
|
105
|
+
@Component({
|
|
106
|
+
selector: 'Popover',
|
|
107
|
+
template: `<ng-content />`,
|
|
108
|
+
host: {
|
|
109
|
+
class: 'relative inline-block',
|
|
110
|
+
},
|
|
111
|
+
providers: [
|
|
112
|
+
{
|
|
113
|
+
provide: POPOVER_CONTEXT,
|
|
114
|
+
useExisting: forwardRef(() => Popover),
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
118
|
+
})
|
|
119
|
+
export class Popover implements PopoverContextValue {
|
|
120
|
+
/** The open state of the popover when initially rendered */
|
|
121
|
+
readonly defaultOpen = input<boolean>(false);
|
|
122
|
+
|
|
123
|
+
/** The controlled open state of the popover */
|
|
124
|
+
readonly controlledOpen = input<boolean | undefined>(undefined, { alias: 'open' });
|
|
125
|
+
|
|
126
|
+
/** The modality of the popover */
|
|
127
|
+
readonly modal = input<boolean>(false);
|
|
128
|
+
|
|
129
|
+
/** Event handler called when the open state changes */
|
|
130
|
+
readonly openChange = output<boolean>();
|
|
131
|
+
|
|
132
|
+
readonly open = signal(false);
|
|
133
|
+
|
|
134
|
+
/** Reference to the trigger element for positioning */
|
|
135
|
+
readonly triggerRef = signal<HTMLElement | null>(null);
|
|
136
|
+
|
|
137
|
+
constructor() {
|
|
138
|
+
// Initialize from defaultOpen
|
|
139
|
+
if (this.defaultOpen()) {
|
|
140
|
+
this.open.set(true);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setOpen(open: boolean): void {
|
|
145
|
+
if (this.controlledOpen() === undefined) {
|
|
146
|
+
this.open.set(open);
|
|
147
|
+
}
|
|
148
|
+
this.openChange.emit(open);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
toggle(): void {
|
|
152
|
+
this.setOpen(!this.open());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Set the trigger element reference */
|
|
156
|
+
setTriggerRef(element: HTMLElement | null): void {
|
|
157
|
+
this.triggerRef.set(element);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
isOpen(): boolean {
|
|
161
|
+
return this.controlledOpen() !== undefined ? this.controlledOpen()! : this.open();
|
|
162
|
+
}
|
|
163
|
+
}
|