@ojiepermana/angular 22.1.11 → 22.1.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/README.md +32 -26
- package/chart/README.md +272 -0
- package/component/README.md +89 -0
- package/component/accordion/README.md +195 -0
- package/component/alert/README.md +184 -0
- package/component/alert-dialog/README.md +255 -0
- package/component/aspect-ratio/README.md +116 -0
- package/component/avatar/README.md +182 -0
- package/component/badge/README.md +143 -0
- package/component/breadcrumb/README.md +223 -0
- package/component/button/README.md +141 -0
- package/component/button-group/README.md +214 -0
- package/component/calendar/README.md +137 -0
- package/component/card/README.md +232 -0
- package/component/carousel/README.md +276 -0
- package/component/checkbox/README.md +153 -0
- package/component/collapsible/README.md +216 -0
- package/component/combobox/README.md +202 -0
- package/component/command/README.md +287 -0
- package/component/composer/README.md +241 -0
- package/component/context-menu/README.md +268 -0
- package/component/date-picker/README.md +202 -0
- package/component/dialog/README.md +276 -0
- package/component/drawer/README.md +147 -0
- package/component/dropdown-menu/README.md +336 -0
- package/component/editor/README.md +152 -0
- package/component/empty/README.md +193 -0
- package/component/form/README.md +216 -0
- package/component/hover-card/README.md +150 -0
- package/component/icon/README.md +25 -0
- package/component/input/README.md +160 -0
- package/component/input-group/README.md +245 -0
- package/component/input-otp/README.md +331 -0
- package/component/item/README.md +254 -0
- package/component/kanban/README.md +81 -0
- package/component/kbd/README.md +141 -0
- package/component/label/README.md +137 -0
- package/component/menubar/README.md +270 -0
- package/component/native-select/README.md +176 -0
- package/component/navigation-menu/README.md +165 -0
- package/component/pagination/README.md +151 -0
- package/component/pillbox/README.md +68 -0
- package/component/popover/README.md +54 -0
- package/component/progress/README.md +160 -0
- package/component/radio/README.md +212 -0
- package/component/resizable/README.md +178 -0
- package/component/scroll-area/README.md +150 -0
- package/component/select/README.md +228 -0
- package/component/separator/README.md +175 -0
- package/component/sheet/README.md +190 -0
- package/component/skeleton/README.md +158 -0
- package/component/slider/README.md +207 -0
- package/component/spinner/README.md +160 -0
- package/component/switch/README.md +170 -0
- package/component/table/README.md +292 -0
- package/component/tabs/README.md +220 -0
- package/component/textarea/README.md +169 -0
- package/component/timeline/README.md +94 -0
- package/component/toast/README.md +173 -0
- package/component/toggle/README.md +133 -0
- package/component/toggle-group/README.md +234 -0
- package/component/tooltip/README.md +230 -0
- package/fesm2022/ojiepermana-angular-chart-area.mjs +289 -3
- package/fesm2022/ojiepermana-angular-chart-bar.mjs +722 -3
- package/fesm2022/ojiepermana-angular-chart-core.mjs +1482 -3
- package/fesm2022/ojiepermana-angular-chart-line.mjs +294 -3
- package/fesm2022/ojiepermana-angular-chart-pie.mjs +291 -3
- package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1301 -3
- package/fesm2022/ojiepermana-angular-chart-radar.mjs +421 -3
- package/fesm2022/ojiepermana-angular-chart-radial.mjs +295 -3
- package/fesm2022/ojiepermana-angular-chart-scatter.mjs +306 -3
- package/fesm2022/ojiepermana-angular-chart.mjs +12 -3
- package/fesm2022/ojiepermana-angular-component-accordion.mjs +267 -3
- package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +359 -3
- package/fesm2022/ojiepermana-angular-component-alert.mjs +101 -3
- package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +31 -3
- package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -3
- package/fesm2022/ojiepermana-angular-component-badge.mjs +57 -3
- package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +192 -3
- package/fesm2022/ojiepermana-angular-component-button-group.mjs +95 -3
- package/fesm2022/ojiepermana-angular-component-button.mjs +73 -3
- package/fesm2022/ojiepermana-angular-component-calendar.mjs +718 -3
- package/fesm2022/ojiepermana-angular-component-card.mjs +167 -3
- package/fesm2022/ojiepermana-angular-component-carousel.mjs +326 -3
- package/fesm2022/ojiepermana-angular-component-checkbox.mjs +190 -3
- package/fesm2022/ojiepermana-angular-component-collapsible.mjs +117 -3
- package/fesm2022/ojiepermana-angular-component-combobox.mjs +327 -3
- package/fesm2022/ojiepermana-angular-component-command.mjs +351 -3
- package/fesm2022/ojiepermana-angular-component-composer.mjs +359 -3
- package/fesm2022/ojiepermana-angular-component-context-menu.mjs +158 -3
- package/fesm2022/ojiepermana-angular-component-date-picker.mjs +482 -3
- package/fesm2022/ojiepermana-angular-component-dialog.mjs +400 -3
- package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -3
- package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +689 -3
- package/fesm2022/ojiepermana-angular-component-editor.mjs +511 -3
- package/fesm2022/ojiepermana-angular-component-empty.mjs +134 -3
- package/fesm2022/ojiepermana-angular-component-form.mjs +438 -3
- package/fesm2022/ojiepermana-angular-component-hover-card.mjs +273 -3
- package/fesm2022/ojiepermana-angular-component-icon.mjs +139 -3
- package/fesm2022/ojiepermana-angular-component-input-group.mjs +176 -3
- package/fesm2022/ojiepermana-angular-component-input-otp.mjs +550 -3
- package/fesm2022/ojiepermana-angular-component-input.mjs +52 -3
- package/fesm2022/ojiepermana-angular-component-item.mjs +264 -3
- package/fesm2022/ojiepermana-angular-component-kanban.mjs +310 -3
- package/fesm2022/ojiepermana-angular-component-kbd.mjs +48 -3
- package/fesm2022/ojiepermana-angular-component-label.mjs +27 -3
- package/fesm2022/ojiepermana-angular-component-menubar.mjs +327 -3
- package/fesm2022/ojiepermana-angular-component-native-select.mjs +62 -3
- package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +378 -3
- package/fesm2022/ojiepermana-angular-component-pagination.mjs +238 -3
- package/fesm2022/ojiepermana-angular-component-pillbox.mjs +999 -3
- package/fesm2022/ojiepermana-angular-component-popover.mjs +201 -3
- package/fesm2022/ojiepermana-angular-component-progress.mjs +57 -3
- package/fesm2022/ojiepermana-angular-component-radio.mjs +180 -3
- package/fesm2022/ojiepermana-angular-component-resizable.mjs +493 -3
- package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +51 -3
- package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +227 -3
- package/fesm2022/ojiepermana-angular-component-select.mjs +609 -3
- package/fesm2022/ojiepermana-angular-component-separator.mjs +31 -3
- package/fesm2022/ojiepermana-angular-component-sheet.mjs +407 -3
- package/fesm2022/ojiepermana-angular-component-skeleton.mjs +25 -3
- package/fesm2022/ojiepermana-angular-component-slider.mjs +456 -3
- package/fesm2022/ojiepermana-angular-component-spinner.mjs +56 -3
- package/fesm2022/ojiepermana-angular-component-switch.mjs +145 -3
- package/fesm2022/ojiepermana-angular-component-table.mjs +155 -3
- package/fesm2022/ojiepermana-angular-component-tabs.mjs +315 -3
- package/fesm2022/ojiepermana-angular-component-textarea.mjs +46 -3
- package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -3
- package/fesm2022/ojiepermana-angular-component-toast.mjs +241 -3
- package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +290 -3
- package/fesm2022/ojiepermana-angular-component-toggle.mjs +76 -3
- package/fesm2022/ojiepermana-angular-component-tooltip.mjs +519 -3
- package/fesm2022/ojiepermana-angular-component-utils-core.mjs +310 -3
- package/fesm2022/ojiepermana-angular-component-utils-overlay.mjs +62 -3
- package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +34 -3
- package/fesm2022/ojiepermana-angular-component-utils.mjs +3 -2
- package/fesm2022/ojiepermana-angular-component.mjs +4 -4
- package/fesm2022/ojiepermana-angular-navigation-core.mjs +21 -3
- package/fesm2022/ojiepermana-angular-navigation-icon.mjs +20 -3
- package/fesm2022/ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs +91 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs +512 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-Cd-jh6tg.mjs +623 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs +404 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs +466 -0
- package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-DNKU6viC.mjs +2642 -0
- package/fesm2022/ojiepermana-angular-navigation-service.mjs +725 -3
- package/fesm2022/ojiepermana-angular-navigation-types.mjs +65 -4
- package/fesm2022/ojiepermana-angular-navigation.mjs +4 -10
- package/fesm2022/ojiepermana-angular-sdk.mjs +204 -4
- package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +1387 -3
- package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +331 -3
- package/fesm2022/ojiepermana-angular-theme-layout-types.mjs +45 -4
- package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +1044 -3
- package/fesm2022/ojiepermana-angular-theme-layout.mjs +729 -3
- package/fesm2022/ojiepermana-angular-theme-page-core.mjs +381 -3
- package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +267 -3
- package/fesm2022/ojiepermana-angular-theme-page-root.mjs +361 -3
- package/fesm2022/ojiepermana-angular-theme-page-side.mjs +198 -3
- package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +110 -3
- package/fesm2022/ojiepermana-angular-theme-page.mjs +7 -2
- package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +338 -3
- package/fesm2022/ojiepermana-angular-theme-shell-types.mjs +160 -4
- package/fesm2022/ojiepermana-angular-theme-shell.mjs +811 -3
- package/fesm2022/ojiepermana-angular-theme-styles.mjs +783 -3
- package/fesm2022/ojiepermana-angular-theme.mjs +4 -4
- package/fesm2022/ojiepermana-angular.mjs +6 -11
- package/navigation/README.md +374 -0
- package/package.json +81 -20
- package/sdk/README.md +212 -0
- package/sdk/schematics/collection.json +20 -0
- package/sdk/schematics/init/index.js +83 -0
- package/sdk/schematics/init/schema.json +19 -0
- package/sdk/schematics/ng-add/index.js +147 -0
- package/sdk/schematics/ng-add/schema.json +14 -0
- package/sdk/schematics/package.json +3 -0
- package/sdk/schematics/sdk/index.js +175 -0
- package/sdk/schematics/sdk/schema.json +19 -0
- package/sdk/sdk.config.example.json +24 -0
- package/sdk/src/config/loader.js +43 -0
- package/sdk/src/config/schema.js +59 -0
- package/sdk/src/emit/client.js +251 -0
- package/sdk/src/emit/metadata.js +310 -0
- package/sdk/src/emit/models.js +104 -0
- package/sdk/src/emit/navigation.js +56 -0
- package/sdk/src/emit/operations.js +118 -0
- package/sdk/src/emit/public-api.js +54 -0
- package/sdk/src/emit/services.js +110 -0
- package/sdk/src/engine.js +67 -0
- package/sdk/src/layout/per-domain.js +360 -0
- package/sdk/src/package.json +3 -0
- package/sdk/src/parser/bundle.js +25 -0
- package/sdk/src/parser/ir.js +429 -0
- package/sdk/src/parser/types.js +7 -0
- package/sdk/src/render/template.js +152 -0
- package/sdk/src/writer/index.js +286 -0
- package/theme/README.md +126 -0
- package/theme/component/settings/README.md +135 -0
- package/theme/layout/README.md +539 -0
- package/theme/page/README.md +453 -0
- package/theme/shell/README.md +340 -0
- package/theme/styles/README.md +178 -0
- package/theme/styles/css/base/components.css +553 -0
- package/theme/styles/css/base/index.css +14 -0
- package/theme/styles/css/base/package.css +9 -0
- package/theme/styles/css/base/prefers-dark.css +86 -0
- package/theme/styles/css/base/print.css +62 -0
- package/theme/styles/css/base/status.css +38 -0
- package/theme/styles/css/base/tailwind.css +165 -0
- package/theme/styles/css/base/theme.css +373 -0
- package/theme/styles/css/base/tokens.css +361 -0
- package/theme/styles/css/color/amber.css +72 -0
- package/theme/styles/css/color/blue.css +72 -0
- package/theme/styles/css/color/brand.css +38 -0
- package/theme/styles/css/color/cyan.css +72 -0
- package/theme/styles/css/color/emerald.css +72 -0
- package/theme/styles/css/color/fuchsia.css +72 -0
- package/theme/styles/css/color/green.css +72 -0
- package/theme/styles/css/color/index.css +19 -0
- package/theme/styles/css/color/indigo.css +72 -0
- package/theme/styles/css/color/lime.css +72 -0
- package/theme/styles/css/color/orange.css +72 -0
- package/theme/styles/css/color/pink.css +72 -0
- package/theme/styles/css/color/purple.css +72 -0
- package/theme/styles/css/color/red.css +72 -0
- package/theme/styles/css/color/rose.css +72 -0
- package/theme/styles/css/color/sky.css +72 -0
- package/theme/styles/css/color/teal.css +72 -0
- package/theme/styles/css/color/violet.css +72 -0
- package/theme/styles/css/color/yellow.css +72 -0
- package/theme/styles/css/index.css +18 -0
- package/theme/styles/css/neutral/gray.css +63 -0
- package/theme/styles/css/neutral/index.css +11 -0
- package/theme/styles/css/neutral/mauve.css +63 -0
- package/theme/styles/css/neutral/mist.css +63 -0
- package/theme/styles/css/neutral/neutral.css +63 -0
- package/theme/styles/css/neutral/olive.css +63 -0
- package/theme/styles/css/neutral/slate.css +63 -0
- package/theme/styles/css/neutral/stone.css +63 -0
- package/theme/styles/css/neutral/taupe.css +63 -0
- package/theme/styles/css/neutral/zinc.css +63 -0
- package/theme/styles/css/radius/index.css +30 -0
- package/theme/styles/css/space/index.css +20 -0
- package/types/ojiepermana-angular-chart-area.d.ts +76 -1
- package/types/ojiepermana-angular-chart-bar.d.ts +201 -1
- package/types/ojiepermana-angular-chart-core.d.ts +811 -1
- package/types/ojiepermana-angular-chart-line.d.ts +75 -1
- package/types/ojiepermana-angular-chart-pie.d.ts +131 -1
- package/types/ojiepermana-angular-chart-primitives.d.ts +291 -1
- package/types/ojiepermana-angular-chart-radar.d.ts +116 -1
- package/types/ojiepermana-angular-chart-radial.d.ts +116 -1
- package/types/ojiepermana-angular-chart-scatter.d.ts +125 -1
- package/types/ojiepermana-angular-chart.d.ts +2 -1
- package/types/ojiepermana-angular-component-accordion.d.ts +85 -1
- package/types/ojiepermana-angular-component-alert-dialog.d.ts +140 -1
- package/types/ojiepermana-angular-component-alert.d.ts +42 -1
- package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -1
- package/types/ojiepermana-angular-component-avatar.d.ts +56 -1
- package/types/ojiepermana-angular-component-badge.d.ts +24 -1
- package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -1
- package/types/ojiepermana-angular-component-button-group.d.ts +26 -1
- package/types/ojiepermana-angular-component-button.d.ts +27 -1
- package/types/ojiepermana-angular-component-calendar.d.ts +111 -1
- package/types/ojiepermana-angular-component-card.d.ts +69 -1
- package/types/ojiepermana-angular-component-carousel.d.ts +86 -1
- package/types/ojiepermana-angular-component-checkbox.d.ts +42 -1
- package/types/ojiepermana-angular-component-collapsible.d.ts +42 -1
- package/types/ojiepermana-angular-component-combobox.d.ts +60 -1
- package/types/ojiepermana-angular-component-command.d.ts +130 -1
- package/types/ojiepermana-angular-component-composer.d.ts +90 -1
- package/types/ojiepermana-angular-component-context-menu.d.ts +54 -1
- package/types/ojiepermana-angular-component-date-picker.d.ts +109 -1
- package/types/ojiepermana-angular-component-dialog.d.ts +136 -1
- package/types/ojiepermana-angular-component-drawer.d.ts +1 -1
- package/types/ojiepermana-angular-component-dropdown-menu.d.ts +248 -1
- package/types/ojiepermana-angular-component-editor.d.ts +135 -1
- package/types/ojiepermana-angular-component-empty.d.ts +50 -1
- package/types/ojiepermana-angular-component-form.d.ts +159 -1
- package/types/ojiepermana-angular-component-hover-card.d.ts +75 -1
- package/types/ojiepermana-angular-component-icon.d.ts +89 -1
- package/types/ojiepermana-angular-component-input-group.d.ts +51 -1
- package/types/ojiepermana-angular-component-input-otp.d.ts +155 -1
- package/types/ojiepermana-angular-component-input.d.ts +21 -1
- package/types/ojiepermana-angular-component-item.d.ts +93 -1
- package/types/ojiepermana-angular-component-kanban.d.ts +70 -1
- package/types/ojiepermana-angular-component-kbd.d.ts +16 -1
- package/types/ojiepermana-angular-component-label.d.ts +11 -1
- package/types/ojiepermana-angular-component-menubar.d.ts +93 -1
- package/types/ojiepermana-angular-component-native-select.d.ts +26 -1
- package/types/ojiepermana-angular-component-navigation-menu.d.ts +104 -1
- package/types/ojiepermana-angular-component-pagination.d.ts +33 -1
- package/types/ojiepermana-angular-component-pillbox.d.ts +222 -1
- package/types/ojiepermana-angular-component-popover.d.ts +66 -1
- package/types/ojiepermana-angular-component-progress.d.ts +17 -1
- package/types/ojiepermana-angular-component-radio.d.ts +60 -1
- package/types/ojiepermana-angular-component-resizable.d.ts +117 -1
- package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -1
- package/types/ojiepermana-angular-component-segmented-control.d.ts +58 -1
- package/types/ojiepermana-angular-component-select.d.ts +122 -1
- package/types/ojiepermana-angular-component-separator.d.ts +14 -1
- package/types/ojiepermana-angular-component-sheet.d.ts +130 -1
- package/types/ojiepermana-angular-component-skeleton.d.ts +10 -1
- package/types/ojiepermana-angular-component-slider.d.ts +83 -1
- package/types/ojiepermana-angular-component-spinner.d.ts +13 -1
- package/types/ojiepermana-angular-component-switch.d.ts +44 -1
- package/types/ojiepermana-angular-component-table.d.ts +57 -1
- package/types/ojiepermana-angular-component-tabs.d.ts +124 -1
- package/types/ojiepermana-angular-component-textarea.d.ts +17 -1
- package/types/ojiepermana-angular-component-timeline.d.ts +64 -1
- package/types/ojiepermana-angular-component-toast.d.ts +64 -1
- package/types/ojiepermana-angular-component-toggle-group.d.ts +90 -1
- package/types/ojiepermana-angular-component-toggle.d.ts +25 -1
- package/types/ojiepermana-angular-component-tooltip.d.ts +143 -1
- package/types/ojiepermana-angular-component-utils-core.d.ts +184 -1
- package/types/ojiepermana-angular-component-utils-overlay.d.ts +21 -1
- package/types/ojiepermana-angular-component-utils-scale.d.ts +19 -1
- package/types/ojiepermana-angular-component-utils.d.ts +2 -1
- package/types/ojiepermana-angular-component.d.ts +2 -1
- package/types/ojiepermana-angular-navigation-core.d.ts +59 -1
- package/types/ojiepermana-angular-navigation-icon.d.ts +12 -1
- package/types/ojiepermana-angular-navigation-service.d.ts +116 -1
- package/types/ojiepermana-angular-navigation-types.d.ts +144 -1
- package/types/ojiepermana-angular-navigation.d.ts +507 -1
- package/types/ojiepermana-angular-sdk.d.ts +89 -1
- package/types/ojiepermana-angular-theme-component-settings.d.ts +154 -1
- package/types/ojiepermana-angular-theme-layout-services.d.ts +147 -1
- package/types/ojiepermana-angular-theme-layout-types.d.ts +40 -1
- package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +299 -1
- package/types/ojiepermana-angular-theme-layout.d.ts +129 -1
- package/types/ojiepermana-angular-theme-page-core.d.ts +157 -1
- package/types/ojiepermana-angular-theme-page-filter.d.ts +77 -1
- package/types/ojiepermana-angular-theme-page-root.d.ts +88 -1
- package/types/ojiepermana-angular-theme-page-side.d.ts +50 -1
- package/types/ojiepermana-angular-theme-page-slots.d.ts +40 -1
- package/types/ojiepermana-angular-theme-page.d.ts +5 -1
- package/types/ojiepermana-angular-theme-shell-services.d.ts +193 -1
- package/types/ojiepermana-angular-theme-shell-types.d.ts +105 -1
- package/types/ojiepermana-angular-theme-shell.d.ts +100 -1
- package/types/ojiepermana-angular-theme-styles.d.ts +319 -1
- package/types/ojiepermana-angular-theme.d.ts +2 -1
- package/types/ojiepermana-angular.d.ts +5 -5
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Carousel
|
|
2
|
+
|
|
3
|
+
A carousel with motion, drag gestures, keyboard navigation, and Embla-powered slide state.
|
|
4
|
+
|
|
5
|
+
Use Carousel for image galleries, card reels, onboarding panels, and compact item pickers where adjacent content should be discoverable without leaving the current view.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
CarouselComponent,
|
|
12
|
+
CarouselContentComponent,
|
|
13
|
+
CarouselItemComponent,
|
|
14
|
+
CarouselNextComponent,
|
|
15
|
+
CarouselPreviousComponent,
|
|
16
|
+
type CarouselApi,
|
|
17
|
+
type CarouselOptions,
|
|
18
|
+
} from '@ojiepermana/angular/component/carousel';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Compose the carousel from a root, content track, items, and optional previous/next buttons.
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<Carousel class="w-full max-w-xs">
|
|
27
|
+
<CarouselContent>
|
|
28
|
+
<CarouselItem>...</CarouselItem>
|
|
29
|
+
<CarouselItem>...</CarouselItem>
|
|
30
|
+
<CarouselItem>...</CarouselItem>
|
|
31
|
+
</CarouselContent>
|
|
32
|
+
<button CarouselPrevious></button>
|
|
33
|
+
<button CarouselNext></button>
|
|
34
|
+
</Carousel>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Composition
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
Carousel
|
|
41
|
+
├── CarouselContent
|
|
42
|
+
│ ├── CarouselItem
|
|
43
|
+
│ └── CarouselItem
|
|
44
|
+
├── button[CarouselPrevious]
|
|
45
|
+
└── button[CarouselNext]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Common patterns
|
|
49
|
+
|
|
50
|
+
### Card slides
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<Carousel class="mx-auto w-full max-w-xs">
|
|
54
|
+
<CarouselContent>
|
|
55
|
+
@for (slide of slides; track slide.id) {
|
|
56
|
+
<CarouselItem [ariaLabel]="slide.label">
|
|
57
|
+
<div class="p-1">
|
|
58
|
+
<Card>
|
|
59
|
+
<CardContent class="flex aspect-square items-center justify-center p-6">
|
|
60
|
+
<span class="text-4xl font-semibold">{{ slide.value }}</span>
|
|
61
|
+
</CardContent>
|
|
62
|
+
</Card>
|
|
63
|
+
</div>
|
|
64
|
+
</CarouselItem>
|
|
65
|
+
}
|
|
66
|
+
</CarouselContent>
|
|
67
|
+
<button CarouselPrevious></button>
|
|
68
|
+
<button CarouselNext></button>
|
|
69
|
+
</Carousel>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Sizes
|
|
73
|
+
|
|
74
|
+
Use basis utilities on each `CarouselItem` when multiple slides should be partially visible.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
readonly startOptions: CarouselOptions = { align: 'start' };
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<Carousel [opts]="startOptions" class="w-full max-w-sm">
|
|
82
|
+
<CarouselContent>
|
|
83
|
+
<CarouselItem class="basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
84
|
+
<CarouselItem class="basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
85
|
+
<CarouselItem class="basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
86
|
+
</CarouselContent>
|
|
87
|
+
</Carousel>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Spacing
|
|
91
|
+
|
|
92
|
+
Match shadcn spacing by pairing a negative margin on `CarouselContent` with padding on `CarouselItem`.
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<Carousel class="w-full max-w-sm">
|
|
96
|
+
<CarouselContent class="-ml-2 md:-ml-4">
|
|
97
|
+
<CarouselItem class="basis-1/2 pl-2 md:pl-4 lg:basis-1/3">...</CarouselItem>
|
|
98
|
+
<CarouselItem class="basis-1/2 pl-2 md:pl-4 lg:basis-1/3">...</CarouselItem>
|
|
99
|
+
<CarouselItem class="basis-1/2 pl-2 md:pl-4 lg:basis-1/3">...</CarouselItem>
|
|
100
|
+
</CarouselContent>
|
|
101
|
+
</Carousel>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Vertical orientation
|
|
105
|
+
|
|
106
|
+
Set `orientation="vertical"` and give the content viewport a height so Embla can measure the track.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
readonly verticalOptions: CarouselOptions = { align: 'start' };
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<Carousel orientation="vertical" [opts]="verticalOptions" class="w-full max-w-xs">
|
|
114
|
+
<CarouselContent class="-mt-1 h-67.5">
|
|
115
|
+
<CarouselItem class="basis-1/2 pt-1">...</CarouselItem>
|
|
116
|
+
<CarouselItem class="basis-1/2 pt-1">...</CarouselItem>
|
|
117
|
+
<CarouselItem class="basis-1/2 pt-1">...</CarouselItem>
|
|
118
|
+
</CarouselContent>
|
|
119
|
+
</Carousel>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Options
|
|
123
|
+
|
|
124
|
+
Pass Embla options through `[opts]`. Keep the object as a class property so Angular does not create a new object every change detection pass.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
readonly loopOptions: CarouselOptions = {
|
|
128
|
+
align: 'start',
|
|
129
|
+
loop: true,
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<Carousel [opts]="loopOptions">
|
|
135
|
+
<CarouselContent>
|
|
136
|
+
<CarouselItem>...</CarouselItem>
|
|
137
|
+
<CarouselItem>...</CarouselItem>
|
|
138
|
+
<CarouselItem>...</CarouselItem>
|
|
139
|
+
</CarouselContent>
|
|
140
|
+
</Carousel>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### API and events
|
|
144
|
+
|
|
145
|
+
The root component exposes `selectedIndex`, `slideCount`, `canScrollPrev`, and `canScrollNext` as signals. Use a template reference for simple status UI.
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<Carousel #carouselRef class="w-full max-w-xs">
|
|
149
|
+
<CarouselContent>
|
|
150
|
+
<CarouselItem>...</CarouselItem>
|
|
151
|
+
<CarouselItem>...</CarouselItem>
|
|
152
|
+
<CarouselItem>...</CarouselItem>
|
|
153
|
+
</CarouselContent>
|
|
154
|
+
</Carousel>
|
|
155
|
+
|
|
156
|
+
<p>Slide {{ carouselRef.selectedIndex() + 1 }} of {{ carouselRef.slideCount() }}</p>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Use `(apiReady)` when you need the lower-level Embla API.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
connectCarousel(api: CarouselApi): void {
|
|
163
|
+
api.on('select', () => {
|
|
164
|
+
this.currentSlide.set(api.selectedScrollSnap() + 1);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<Carousel (apiReady)="connectCarousel($event)"> ... </Carousel>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Plugins
|
|
174
|
+
|
|
175
|
+
Optional Embla plugins are passed through `[plugins]`. Install plugin packages separately.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import Autoplay from 'embla-carousel-autoplay';
|
|
179
|
+
|
|
180
|
+
readonly plugins = [Autoplay({ delay: 2000 })];
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<Carousel [plugins]="plugins">
|
|
185
|
+
<CarouselContent>
|
|
186
|
+
<CarouselItem>...</CarouselItem>
|
|
187
|
+
</CarouselContent>
|
|
188
|
+
</Carousel>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### RTL
|
|
192
|
+
|
|
193
|
+
Set both `dir="rtl"` and `opts.direction` so layout direction and Embla motion agree.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
readonly rtlOptions: CarouselOptions = { direction: 'rtl' };
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```html
|
|
200
|
+
<section dir="rtl">
|
|
201
|
+
<Carousel dir="rtl" [opts]="rtlOptions" class="w-full max-w-xs">
|
|
202
|
+
<CarouselContent>
|
|
203
|
+
<CarouselItem>...</CarouselItem>
|
|
204
|
+
<CarouselItem>...</CarouselItem>
|
|
205
|
+
<CarouselItem>...</CarouselItem>
|
|
206
|
+
</CarouselContent>
|
|
207
|
+
<button CarouselPrevious class="rtl:rotate-180"></button>
|
|
208
|
+
<button CarouselNext class="rtl:rotate-180"></button>
|
|
209
|
+
</Carousel>
|
|
210
|
+
</section>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## API reference
|
|
214
|
+
|
|
215
|
+
### `CarouselComponent`
|
|
216
|
+
|
|
217
|
+
| Input or output | Type | Default |
|
|
218
|
+
| --------------- | ---------------------------- | ---------------------------------------------- |
|
|
219
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |
|
|
220
|
+
| `opts` | `CarouselOptions` | `{}` |
|
|
221
|
+
| `plugins` | `readonly CarouselPlugin[]` | `[]` |
|
|
222
|
+
| `keyboard` | `boolean` | `true` |
|
|
223
|
+
| `label` | `string` | `'Carousel'` |
|
|
224
|
+
| `class` | `string` | `''` |
|
|
225
|
+
| `apiReady` | `CarouselApi` output | emitted after Embla initializes |
|
|
226
|
+
| `apiChange` | `CarouselApi \| null` output | emitted when Embla initializes or is destroyed |
|
|
227
|
+
|
|
228
|
+
### Root signals
|
|
229
|
+
|
|
230
|
+
| Signal | Type |
|
|
231
|
+
| --------------- | ----------------- |
|
|
232
|
+
| `selectedIndex` | `Signal<number>` |
|
|
233
|
+
| `slideCount` | `Signal<number>` |
|
|
234
|
+
| `canScrollPrev` | `Signal<boolean>` |
|
|
235
|
+
| `canScrollNext` | `Signal<boolean>` |
|
|
236
|
+
|
|
237
|
+
### Parts
|
|
238
|
+
|
|
239
|
+
| Part | Inputs |
|
|
240
|
+
| -------------------------- | -------------------- |
|
|
241
|
+
| `CarouselContent` | `class` |
|
|
242
|
+
| `CarouselItem` | `ariaLabel`, `class` |
|
|
243
|
+
| `button[CarouselPrevious]` | `label`, `class` |
|
|
244
|
+
| `button[CarouselNext]` | `label`, `class` |
|
|
245
|
+
|
|
246
|
+
## Styling and theming
|
|
247
|
+
|
|
248
|
+
The primitive follows the shadcn layout recipe: root is `relative`, content owns the overflow-hidden viewport, and items are `basis-full` by default. Pass `class` to tune width, item basis, spacing, and control placement.
|
|
249
|
+
|
|
250
|
+
Use theme-aware classes such as `border-border`, `bg-card`, `text-foreground`, `bg-background`, `hover:bg-accent`, and `focus-visible:ring-ring` for custom slide and control styling.
|
|
251
|
+
|
|
252
|
+
## Accessibility
|
|
253
|
+
|
|
254
|
+
- The root renders as a labelled `region` with `aria-roledescription="carousel"`.
|
|
255
|
+
- Previous and next controls are native buttons with descriptive labels and disabled states.
|
|
256
|
+
- Each item renders as a `group` with `aria-roledescription="slide"`; pass `ariaLabel` when the slide needs an explicit spoken label.
|
|
257
|
+
- Keep interactive controls inside slides reachable by normal tab order and avoid hiding focus outlines.
|
|
258
|
+
|
|
259
|
+
## Keyboard interactions
|
|
260
|
+
|
|
261
|
+
- The root is focusable when `keyboard` is `true`.
|
|
262
|
+
- Horizontal carousels use ArrowLeft and ArrowRight to move between slides.
|
|
263
|
+
- Vertical carousels use ArrowUp and ArrowDown to move between slides.
|
|
264
|
+
- Home moves to the first slide and End moves to the last slide.
|
|
265
|
+
- Previous and next buttons also support native Enter and Space activation.
|
|
266
|
+
|
|
267
|
+
## Angular notes
|
|
268
|
+
|
|
269
|
+
- This implementation uses vanilla Embla Carousel rather than `embla-carousel-react`.
|
|
270
|
+
- Embla initializes only in the browser, so server rendering can produce the static slide markup without touching the DOM API.
|
|
271
|
+
- `orientation` controls Embla axis; if `opts.axis` is provided, the Angular `orientation` input wins.
|
|
272
|
+
- Define `opts` and `plugins` as class properties to avoid unnecessary Embla reinitialization.
|
|
273
|
+
|
|
274
|
+
## Source parity
|
|
275
|
+
|
|
276
|
+
This Angular implementation follows the shadcn Carousel anatomy, options, API, events, plugins, and RTL guidance while translating React props into Angular inputs, outputs, signals, and standalone component imports.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
A shadcn-style checkbox primitive built on a native `<input type="checkbox">`, with full `ControlValueAccessor` support for `ngModel` and reactive forms.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { CheckboxComponent } from '@ojiepermana/angular/component/checkbox';
|
|
9
|
+
import { LabelComponent } from '@ojiepermana/angular/component/label';
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
Wrap the control and copy in `label[Label]` when the text should toggle the checkbox. This is the closest Angular equivalent to the upstream shadcn `Field` + `FieldLabel` composition.
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<label Label class="flex items-start gap-3">
|
|
18
|
+
<Checkbox [(ngModel)]="accepted" name="terms-checkbox" class="mt-0.5" />
|
|
19
|
+
<span class="grid gap-1 leading-none">
|
|
20
|
+
<span>Accept terms and conditions</span>
|
|
21
|
+
<span class="text-sm font-normal leading-5 text-muted-foreground">
|
|
22
|
+
By clicking this checkbox, you agree to the terms.
|
|
23
|
+
</span>
|
|
24
|
+
</span>
|
|
25
|
+
</label>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Reactive forms continue to work through the component's value accessor.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<Checkbox [formControl]="form.controls.marketingOptIn" aria-label="Receive product updates" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Common patterns
|
|
35
|
+
|
|
36
|
+
### Controlled checked state
|
|
37
|
+
|
|
38
|
+
Use `checkedChange` when the parent owns the signal and you want to keep the checkbox controlled without wrapping a form model.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const marketingOptIn = signal(false);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<Checkbox
|
|
46
|
+
[ngModel]="marketingOptIn()"
|
|
47
|
+
(checkedChange)="marketingOptIn.set($event)"
|
|
48
|
+
aria-label="Receive product updates"
|
|
49
|
+
/>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Invalid state
|
|
53
|
+
|
|
54
|
+
Forward `aria-invalid="true"` to switch the control into the destructive invalid treatment.
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
<label Label class="flex items-start gap-3 text-destructive">
|
|
58
|
+
<Checkbox aria-invalid="true" name="terms-checkbox-invalid" class="mt-0.5" />
|
|
59
|
+
<span class="grid gap-1 leading-none">
|
|
60
|
+
<span>Accept terms and conditions</span>
|
|
61
|
+
<span class="text-sm font-normal leading-5 text-muted-foreground">
|
|
62
|
+
Choose this before continuing to checkout.
|
|
63
|
+
</span>
|
|
64
|
+
</span>
|
|
65
|
+
</label>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Grouped preferences
|
|
69
|
+
|
|
70
|
+
Use a semantic `fieldset` for a checkbox list.
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<fieldset class="space-y-3">
|
|
74
|
+
<legend class="text-sm font-semibold">Show these items on the desktop:</legend>
|
|
75
|
+
@for (item of groupOptions; track item.id) {
|
|
76
|
+
<label Label class="flex items-start gap-3">
|
|
77
|
+
<Checkbox
|
|
78
|
+
[ngModel]="desktopItems().has(item.id)"
|
|
79
|
+
(checkedChange)="toggleDesktopItem(item.id, $event)"
|
|
80
|
+
[name]="item.id"
|
|
81
|
+
class="mt-0.5"
|
|
82
|
+
/>
|
|
83
|
+
<span class="font-normal">{{ item.label }}</span>
|
|
84
|
+
</label>
|
|
85
|
+
}
|
|
86
|
+
</fieldset>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Table row selection
|
|
90
|
+
|
|
91
|
+
Use `indeterminate` for the select-all checkbox and set `data-state="selected"` on the selected row so the table highlight stays in sync.
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<Checkbox
|
|
95
|
+
[ngModel]="selectAll()"
|
|
96
|
+
[indeterminate]="someRowsSelected()"
|
|
97
|
+
aria-label="Select all team members"
|
|
98
|
+
(checkedChange)="handleSelectAll($event)"
|
|
99
|
+
/>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## API reference
|
|
103
|
+
|
|
104
|
+
| Input | Type | Default | Notes |
|
|
105
|
+
| ------------------ | --------------------------- | -------------- | ------------------------------------------------------------ |
|
|
106
|
+
| `id` | `string` | auto-generated | Set directly on the native checkbox input. |
|
|
107
|
+
| `name` | `string \| null` | `null` | Forwarded to the native checkbox input. |
|
|
108
|
+
| `indeterminate` | `boolean` | `false` | Useful for select-all patterns. |
|
|
109
|
+
| `required` | `boolean` | `false` | Forwarded to the native input. |
|
|
110
|
+
| `disabled` | `boolean` | `false` | Disables the control; forwarded to the native input. |
|
|
111
|
+
| `aria-label` | `string \| null` | `null` | Use for icon-only or table selection checkboxes. |
|
|
112
|
+
| `aria-describedby` | `string \| null` | `null` | Links helper or error text outside the checkbox. |
|
|
113
|
+
| `aria-labelledby` | `string \| null` | `null` | Alternative to projected text or wrapper labels. |
|
|
114
|
+
| `aria-invalid` | `boolean \| string \| null` | `null` | Switches the control into the destructive invalid treatment. |
|
|
115
|
+
| `class` | `string` | `''` | Adds utility classes to the checkbox host. |
|
|
116
|
+
|
|
117
|
+
| Output | Payload |
|
|
118
|
+
| --------------- | --------- |
|
|
119
|
+
| `checkedChange` | `boolean` |
|
|
120
|
+
|
|
121
|
+
Public method: `focus()`.
|
|
122
|
+
|
|
123
|
+
## Styling and theming
|
|
124
|
+
|
|
125
|
+
The component renders a native checkbox input that is restyled through the library theme tokens.
|
|
126
|
+
|
|
127
|
+
- Default borders and icon color use the shared `input` and `primary` tokens.
|
|
128
|
+
- `aria-invalid="true"` switches the control to the `destructive` token set.
|
|
129
|
+
- Pass spacing or alignment utilities through the `class` input when the checkbox needs to align with multi-line content.
|
|
130
|
+
|
|
131
|
+
Extra visual adjustments belong in the component's inline `styles` inside the library.
|
|
132
|
+
|
|
133
|
+
## Accessibility
|
|
134
|
+
|
|
135
|
+
- Always give the checkbox an accessible name via wrapper label text, projected content, `aria-label`, or `aria-labelledby`.
|
|
136
|
+
- Use `aria-describedby` to connect helper or error text rendered outside the checkbox.
|
|
137
|
+
- Use `indeterminate` for tri-state list headers and table select-all behavior.
|
|
138
|
+
- `required` and `name` are forwarded to the underlying native input.
|
|
139
|
+
|
|
140
|
+
## Keyboard interactions
|
|
141
|
+
|
|
142
|
+
- `Tab` moves focus to the checkbox in DOM order.
|
|
143
|
+
- `Space` toggles the checked state.
|
|
144
|
+
|
|
145
|
+
## Angular notes
|
|
146
|
+
|
|
147
|
+
- `ngModel`, reactive forms, and `checkedChange` all work with the same primitive.
|
|
148
|
+
- When you pass `id`, it is set directly on the native checkbox input; wrapper labels or `aria-labelledby` are usually the simplest Angular pattern.
|
|
149
|
+
- Projected text still works if you prefer `<Checkbox>Accept</Checkbox>` for compact markup.
|
|
150
|
+
|
|
151
|
+
## Source parity
|
|
152
|
+
|
|
153
|
+
This Angular implementation follows the shadcn Checkbox examples while mapping the upstream `Field` helpers to Angular-native label wrappers, `fieldset` composition, semantic table rows, and signal-friendly state handling.
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Collapsible
|
|
2
|
+
|
|
3
|
+
Displays an interactive disclosure region that expands and collapses inline content.
|
|
4
|
+
|
|
5
|
+
Use Collapsible for settings drawers, detail rows, compact status cards, and nested explorers where content should stay in the same document flow.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
CollapsibleComponent,
|
|
12
|
+
CollapsibleContentComponent,
|
|
13
|
+
CollapsibleTriggerDirective,
|
|
14
|
+
} from '@ojiepermana/angular/component/collapsible';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Composition
|
|
18
|
+
|
|
19
|
+
The Angular composition follows the shadcn and Radix structure while using a root component, a trigger directive on a native button, and a content component.
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Collapsible
|
|
23
|
+
├── button[CollapsibleTrigger]
|
|
24
|
+
└── CollapsibleContent
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Basic usage
|
|
28
|
+
|
|
29
|
+
Bind `[(open)]` when the parent should control the disclosure state or seed a default open panel.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
readonly detailsOpen = signal(false);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<Collapsible [(open)]="detailsOpen" class="w-full max-w-md rounded-lg border border-border p-3">
|
|
37
|
+
<button
|
|
38
|
+
CollapsibleTrigger
|
|
39
|
+
class="inline-flex w-full items-center justify-between gap-2 text-left text-sm font-medium"
|
|
40
|
+
>
|
|
41
|
+
Can I use this in my project?
|
|
42
|
+
<span aria-hidden="true">+</span>
|
|
43
|
+
</button>
|
|
44
|
+
|
|
45
|
+
<CollapsibleContent class="pt-3 text-sm text-muted-foreground">
|
|
46
|
+
Yes. The trigger and content follow the disclosure ARIA pattern and stay in normal layout flow.
|
|
47
|
+
</CollapsibleContent>
|
|
48
|
+
</Collapsible>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Common patterns
|
|
52
|
+
|
|
53
|
+
### Controlled state
|
|
54
|
+
|
|
55
|
+
Use a signal boolean with `[(open)]` when another control needs to observe or update the open state.
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
readonly isOpen = signal(false);
|
|
59
|
+
|
|
60
|
+
toggleFromElsewhere(): void {
|
|
61
|
+
this.isOpen.update((value) => !value);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Button composition
|
|
66
|
+
|
|
67
|
+
`button[CollapsibleTrigger]` is a directive, so it can compose with the local button primitive on the same element.
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<Collapsible [(open)]="basicOpen" class="rounded-md border border-border p-2">
|
|
71
|
+
<button Button CollapsibleTrigger variant="ghost" class="w-full justify-between px-2">
|
|
72
|
+
Product details
|
|
73
|
+
<svg
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class="h-4 w-4"
|
|
76
|
+
viewBox="0 0 24 24"
|
|
77
|
+
fill="none"
|
|
78
|
+
stroke="currentColor"
|
|
79
|
+
stroke-width="2"
|
|
80
|
+
>
|
|
81
|
+
<polyline points="6 9 12 15 18 9" />
|
|
82
|
+
</svg>
|
|
83
|
+
</button>
|
|
84
|
+
|
|
85
|
+
<CollapsibleContent class="px-2 pb-2 pt-1 text-sm text-muted-foreground">
|
|
86
|
+
This panel can reveal additional details without leaving the page.
|
|
87
|
+
</CollapsibleContent>
|
|
88
|
+
</Collapsible>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Settings drawer
|
|
92
|
+
|
|
93
|
+
Wrap the trigger and content inside a card-like surface when the disclosure belongs to a small settings editor.
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<Collapsible [(open)]="settingsOpen" class="rounded-lg border border-border p-4">
|
|
97
|
+
<div class="flex items-start gap-3">
|
|
98
|
+
<div class="grid flex-1 grid-cols-2 gap-2">
|
|
99
|
+
<input Input placeholder="Radius X" />
|
|
100
|
+
<input Input placeholder="Radius Y" />
|
|
101
|
+
<CollapsibleContent class="col-span-full grid grid-cols-2 gap-2 pt-0">
|
|
102
|
+
<input Input placeholder="Blur" />
|
|
103
|
+
<input Input placeholder="Spread" />
|
|
104
|
+
</CollapsibleContent>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<button
|
|
108
|
+
Button
|
|
109
|
+
CollapsibleTrigger
|
|
110
|
+
variant="outline"
|
|
111
|
+
size="icon"
|
|
112
|
+
aria-label="Toggle advanced fields"
|
|
113
|
+
>
|
|
114
|
+
<span aria-hidden="true">...</span>
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
</Collapsible>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Nested file tree
|
|
121
|
+
|
|
122
|
+
Nested `Collapsible` roots work well for compact explorers and outline views.
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<Collapsible [(open)]="componentsOpen">
|
|
126
|
+
<button CollapsibleTrigger class="inline-flex items-center gap-2 text-sm font-medium">
|
|
127
|
+
components
|
|
128
|
+
</button>
|
|
129
|
+
|
|
130
|
+
<CollapsibleContent class="ml-5 mt-2 flex flex-col gap-1">
|
|
131
|
+
<Collapsible [(open)]="uiOpen">
|
|
132
|
+
<button CollapsibleTrigger class="inline-flex items-center gap-2 text-sm font-medium">
|
|
133
|
+
ui
|
|
134
|
+
</button>
|
|
135
|
+
<CollapsibleContent class="ml-5 mt-2 flex flex-col gap-1 text-sm text-muted-foreground">
|
|
136
|
+
<span>button.ts</span>
|
|
137
|
+
<span>collapsible.ts</span>
|
|
138
|
+
</CollapsibleContent>
|
|
139
|
+
</Collapsible>
|
|
140
|
+
</CollapsibleContent>
|
|
141
|
+
</Collapsible>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### RTL
|
|
145
|
+
|
|
146
|
+
For right-to-left interfaces, set `dir="rtl"` on a wrapping container or the collapsible root.
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<section dir="rtl" lang="ar" class="max-w-md text-right">
|
|
150
|
+
<Collapsible [(open)]="rtlOpen" class="flex flex-col gap-2">
|
|
151
|
+
<button
|
|
152
|
+
CollapsibleTrigger
|
|
153
|
+
class="inline-flex items-center justify-between gap-2 text-sm font-medium"
|
|
154
|
+
>
|
|
155
|
+
تبديل التفاصيل
|
|
156
|
+
</button>
|
|
157
|
+
<CollapsibleContent class="flex flex-col gap-2 text-sm">
|
|
158
|
+
<div class="rounded-md border border-border px-4 py-2">عنوان الشحن</div>
|
|
159
|
+
<div class="rounded-md border border-border px-4 py-2">2x سماعات الاستوديو</div>
|
|
160
|
+
</CollapsibleContent>
|
|
161
|
+
</Collapsible>
|
|
162
|
+
</section>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## API reference
|
|
166
|
+
|
|
167
|
+
### `CollapsibleComponent`
|
|
168
|
+
|
|
169
|
+
| Input | Type | Default |
|
|
170
|
+
| -------------- | --------- | ------- |
|
|
171
|
+
| `open` (model) | `boolean` | `false` |
|
|
172
|
+
| `disabled` | `boolean` | `false` |
|
|
173
|
+
| `class` | `string` | `''` |
|
|
174
|
+
|
|
175
|
+
### `CollapsibleContentComponent`
|
|
176
|
+
|
|
177
|
+
| Input | Type | Default |
|
|
178
|
+
| ------------ | --------- | ------- |
|
|
179
|
+
| `forceMount` | `boolean` | `false` |
|
|
180
|
+
| `class` | `string` | `''` |
|
|
181
|
+
|
|
182
|
+
### Parts
|
|
183
|
+
|
|
184
|
+
- `button[CollapsibleTrigger]` is the interactive control. It manages `aria-expanded`, `aria-controls`, `data-state`, and root toggling.
|
|
185
|
+
- `CollapsibleContent` is the panel region. It applies `role="region"`, `aria-labelledby`, `data-state`, and optional persistent projection via `forceMount`.
|
|
186
|
+
- Lower-level behavior follows the Radix Collapsible model: <https://www.radix-ui.com/primitives/docs/components/collapsible#api-reference>.
|
|
187
|
+
|
|
188
|
+
## Styling and theming
|
|
189
|
+
|
|
190
|
+
Pass `class` to the root or content, and use the native `class` attribute on the trigger button. The root and content expose `data-state="open" | "closed"` so surrounding styles or transitions can react to the current disclosure state.
|
|
191
|
+
|
|
192
|
+
Use theme tokens such as `border-border`, `bg-card`, `text-muted-foreground`, and spacing utilities to match the rest of the library.
|
|
193
|
+
|
|
194
|
+
## Accessibility
|
|
195
|
+
|
|
196
|
+
- The primitive follows the disclosure WAI-ARIA pattern.
|
|
197
|
+
- Trigger is a native button, so Enter and Space work without extra key handling.
|
|
198
|
+
- Trigger receives `aria-controls` and `aria-expanded`; content receives `role="region"` and `aria-labelledby`.
|
|
199
|
+
- `disabled` keeps the control visible while preventing interaction.
|
|
200
|
+
|
|
201
|
+
## Keyboard interactions
|
|
202
|
+
|
|
203
|
+
- `Enter` toggles the collapsible.
|
|
204
|
+
- `Space` toggles the collapsible.
|
|
205
|
+
- Tab order follows the DOM order of the trigger and any focusable controls inside the content.
|
|
206
|
+
|
|
207
|
+
## Angular notes
|
|
208
|
+
|
|
209
|
+
- `[(open)]` is the Angular equivalent of shadcn's `open` and `onOpenChange` props.
|
|
210
|
+
- `button[CollapsibleTrigger]` is a directive, not a component, so it can compose with `button[Button]` on the same element.
|
|
211
|
+
- `forceMount` keeps projected content rendered even when the panel is closed, which is useful for measuring or animating content without re-creating it.
|
|
212
|
+
- The local API intentionally does not add an `asChild` prop; Angular composition is handled through selectors and host directives instead.
|
|
213
|
+
|
|
214
|
+
## Source parity
|
|
215
|
+
|
|
216
|
+
This Angular implementation follows the shadcn Collapsible structure and examples while translating the API to standalone Angular imports, signal-backed state, button-directive composition, and Angular-friendly RTL guidance.
|