snice 2.5.4 → 3.1.0
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 +501 -882
- package/bin/templates/base/src/components/counter-button.ts +13 -26
- package/bin/templates/base/src/controllers/counter-controller.ts +3 -3
- package/dist/components/accordion/snice-accordion-item.d.ts +4 -5
- package/dist/components/accordion/snice-accordion-item.js +37 -39
- package/dist/components/accordion/snice-accordion-item.js.map +1 -1
- package/dist/components/accordion/snice-accordion.d.ts +5 -11
- package/dist/components/accordion/snice-accordion.js +51 -52
- package/dist/components/accordion/snice-accordion.js.map +1 -1
- package/dist/components/alert/snice-alert.d.ts +2 -6
- package/dist/components/alert/snice-alert.js +41 -56
- package/dist/components/alert/snice-alert.js.map +1 -1
- package/dist/components/avatar/snice-avatar.d.ts +2 -6
- package/dist/components/avatar/snice-avatar.js +64 -71
- package/dist/components/avatar/snice-avatar.js.map +1 -1
- package/dist/components/badge/snice-badge.d.ts +2 -3
- package/dist/components/badge/snice-badge.js +22 -23
- package/dist/components/badge/snice-badge.js.map +1 -1
- package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +5 -12
- package/dist/components/breadcrumbs/snice-breadcrumbs.js +88 -89
- package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
- package/dist/components/button/snice-button.d.ts +3 -7
- package/dist/components/button/snice-button.js +37 -58
- package/dist/components/button/snice-button.js.map +1 -1
- package/dist/components/card/snice-card.d.ts +5 -8
- package/dist/components/card/snice-card.js +71 -56
- package/dist/components/card/snice-card.js.map +1 -1
- package/dist/components/checkbox/snice-checkbox.d.ts +4 -13
- package/dist/components/checkbox/snice-checkbox.js +66 -137
- package/dist/components/checkbox/snice-checkbox.js.map +1 -1
- package/dist/components/chip/snice-chip.d.ts +5 -11
- package/dist/components/chip/snice-chip.js +44 -47
- package/dist/components/chip/snice-chip.js.map +1 -1
- package/dist/components/date-picker/snice-date-picker.d.ts +11 -11
- package/dist/components/date-picker/snice-date-picker.js +134 -133
- package/dist/components/date-picker/snice-date-picker.js.map +1 -1
- package/dist/components/divider/snice-divider.d.ts +2 -4
- package/dist/components/divider/snice-divider.js +14 -22
- package/dist/components/divider/snice-divider.js.map +1 -1
- package/dist/components/drawer/snice-drawer.d.ts +4 -4
- package/dist/components/drawer/snice-drawer.js +25 -19
- package/dist/components/drawer/snice-drawer.js.map +1 -1
- package/dist/components/input/snice-input.d.ts +8 -6
- package/dist/components/input/snice-input.js +122 -105
- package/dist/components/input/snice-input.js.map +1 -1
- package/dist/components/layout/snice-layout-blog.d.ts +4 -4
- package/dist/components/layout/snice-layout-blog.js +21 -19
- package/dist/components/layout/snice-layout-blog.js.map +1 -1
- package/dist/components/layout/snice-layout-card.d.ts +2 -2
- package/dist/components/layout/snice-layout-card.js +16 -9
- package/dist/components/layout/snice-layout-card.js.map +1 -1
- package/dist/components/layout/snice-layout-centered.d.ts +2 -2
- package/dist/components/layout/snice-layout-centered.js +14 -7
- package/dist/components/layout/snice-layout-centered.js.map +1 -1
- package/dist/components/layout/snice-layout-dashboard.d.ts +5 -5
- package/dist/components/layout/snice-layout-dashboard.js +38 -30
- package/dist/components/layout/snice-layout-dashboard.js.map +1 -1
- package/dist/components/layout/snice-layout-fullscreen.d.ts +2 -2
- package/dist/components/layout/snice-layout-fullscreen.js +17 -10
- package/dist/components/layout/snice-layout-fullscreen.js.map +1 -1
- package/dist/components/layout/snice-layout-landing.d.ts +4 -4
- package/dist/components/layout/snice-layout-landing.js +21 -19
- package/dist/components/layout/snice-layout-landing.js.map +1 -1
- package/dist/components/layout/snice-layout-minimal.d.ts +2 -2
- package/dist/components/layout/snice-layout-minimal.js +17 -6
- package/dist/components/layout/snice-layout-minimal.js.map +1 -1
- package/dist/components/layout/snice-layout-sidebar.d.ts +5 -4
- package/dist/components/layout/snice-layout-sidebar.js +42 -20
- package/dist/components/layout/snice-layout-sidebar.js.map +1 -1
- package/dist/components/layout/snice-layout-split.d.ts +2 -2
- package/dist/components/layout/snice-layout-split.js +14 -7
- package/dist/components/layout/snice-layout-split.js.map +1 -1
- package/dist/components/layout/snice-layout.d.ts +4 -4
- package/dist/components/layout/snice-layout.js +16 -10
- package/dist/components/layout/snice-layout.js.map +1 -1
- package/dist/components/login/snice-login.d.ts +6 -11
- package/dist/components/login/snice-login.js +97 -71
- package/dist/components/login/snice-login.js.map +1 -1
- package/dist/components/modal/snice-modal.d.ts +5 -9
- package/dist/components/modal/snice-modal.js +47 -78
- package/dist/components/modal/snice-modal.js.map +1 -1
- package/dist/components/nav/snice-nav.d.ts +13 -7
- package/dist/components/nav/snice-nav.js +191 -100
- package/dist/components/nav/snice-nav.js.map +1 -1
- package/dist/components/nav/snice-nav.types.d.ts +3 -3
- package/dist/components/pagination/snice-pagination.d.ts +6 -7
- package/dist/components/pagination/snice-pagination.js +94 -81
- package/dist/components/pagination/snice-pagination.js.map +1 -1
- package/dist/components/progress/snice-progress.d.ts +2 -7
- package/dist/components/progress/snice-progress.js +41 -98
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/radio/snice-radio.d.ts +4 -4
- package/dist/components/radio/snice-radio.js +52 -44
- package/dist/components/radio/snice-radio.js.map +1 -1
- package/dist/components/select/snice-option.d.ts +2 -1
- package/dist/components/select/snice-option.js +12 -5
- package/dist/components/select/snice-option.js.map +1 -1
- package/dist/components/select/snice-select.d.ts +9 -21
- package/dist/components/select/snice-select.js +98 -170
- package/dist/components/select/snice-select.js.map +1 -1
- package/dist/components/skeleton/snice-skeleton.d.ts +2 -6
- package/dist/components/skeleton/snice-skeleton.js +18 -49
- package/dist/components/skeleton/snice-skeleton.js.map +1 -1
- package/dist/components/snice-cell-BLFVdxPp.js +4 -0
- package/dist/components/snice-cell-BLFVdxPp.js.map +1 -0
- package/dist/components/switch/snice-switch.d.ts +2 -2
- package/dist/components/switch/snice-switch.js +38 -26
- package/dist/components/switch/snice-switch.js.map +1 -1
- package/dist/components/table/snice-cell-actions.d.ts +24 -0
- package/dist/components/table/snice-cell-actions.js +149 -0
- package/dist/components/table/snice-cell-actions.js.map +1 -0
- package/dist/components/table/snice-cell-boolean.d.ts +2 -2
- package/dist/components/table/snice-cell-boolean.js +13 -7
- package/dist/components/table/snice-cell-boolean.js.map +1 -1
- package/dist/components/table/snice-cell-color.d.ts +18 -0
- package/dist/components/table/snice-cell-color.js +149 -0
- package/dist/components/table/snice-cell-color.js.map +1 -0
- package/dist/components/table/snice-cell-currency.d.ts +24 -0
- package/dist/components/table/snice-cell-currency.js +235 -0
- package/dist/components/table/snice-cell-currency.js.map +1 -0
- package/dist/components/table/snice-cell-date.d.ts +2 -2
- package/dist/components/table/snice-cell-date.js +14 -8
- package/dist/components/table/snice-cell-date.js.map +1 -1
- package/dist/components/table/snice-cell-duration.d.ts +2 -2
- package/dist/components/table/snice-cell-duration.js +12 -6
- package/dist/components/table/snice-cell-duration.js.map +1 -1
- package/dist/components/table/snice-cell-email.d.ts +15 -0
- package/dist/components/table/snice-cell-email.js +125 -0
- package/dist/components/table/snice-cell-email.js.map +1 -0
- package/dist/components/table/snice-cell-filesize.d.ts +2 -2
- package/dist/components/table/snice-cell-filesize.js +12 -6
- package/dist/components/table/snice-cell-filesize.js.map +1 -1
- package/dist/components/table/snice-cell-image.d.ts +20 -0
- package/dist/components/table/snice-cell-image.js +162 -0
- package/dist/components/table/snice-cell-image.js.map +1 -0
- package/dist/components/table/snice-cell-json.d.ts +20 -0
- package/dist/components/table/snice-cell-json.js +186 -0
- package/dist/components/table/snice-cell-json.js.map +1 -0
- package/dist/components/table/snice-cell-link.d.ts +17 -0
- package/dist/components/table/snice-cell-link.js +142 -0
- package/dist/components/table/snice-cell-link.js.map +1 -0
- package/dist/components/table/snice-cell-location.d.ts +19 -0
- package/dist/components/table/snice-cell-location.js +185 -0
- package/dist/components/table/snice-cell-location.js.map +1 -0
- package/dist/components/table/snice-cell-number.d.ts +2 -2
- package/dist/components/table/snice-cell-number.js +12 -6
- package/dist/components/table/snice-cell-number.js.map +1 -1
- package/dist/components/table/snice-cell-percentage.d.ts +22 -0
- package/dist/components/table/snice-cell-percentage.js +208 -0
- package/dist/components/table/snice-cell-percentage.js.map +1 -0
- package/dist/components/table/snice-cell-phone.d.ts +18 -0
- package/dist/components/table/snice-cell-phone.js +153 -0
- package/dist/components/table/snice-cell-phone.js.map +1 -0
- package/dist/components/table/snice-cell-progress.d.ts +2 -2
- package/dist/components/table/snice-cell-progress.js +12 -6
- package/dist/components/table/snice-cell-progress.js.map +1 -1
- package/dist/components/table/snice-cell-rating.d.ts +2 -2
- package/dist/components/table/snice-cell-rating.js +12 -6
- package/dist/components/table/snice-cell-rating.js.map +1 -1
- package/dist/components/table/snice-cell-sparkline.d.ts +2 -2
- package/dist/components/table/snice-cell-sparkline.js +13 -7
- package/dist/components/table/snice-cell-sparkline.js.map +1 -1
- package/dist/components/table/snice-cell-status.d.ts +17 -0
- package/dist/components/table/snice-cell-status.js +144 -0
- package/dist/components/table/snice-cell-status.js.map +1 -0
- package/dist/components/table/snice-cell-tag.d.ts +16 -0
- package/dist/components/table/snice-cell-tag.js +131 -0
- package/dist/components/table/snice-cell-tag.js.map +1 -0
- package/dist/components/table/snice-cell-text.d.ts +2 -2
- package/dist/components/table/snice-cell-text.js +14 -8
- package/dist/components/table/snice-cell-text.js.map +1 -1
- package/dist/components/table/snice-cell.d.ts +2 -2
- package/dist/components/table/snice-cell.js +12 -6
- package/dist/components/table/snice-cell.js.map +1 -1
- package/dist/components/table/snice-column.d.ts +1 -1
- package/dist/components/table/snice-column.js +6 -3
- package/dist/components/table/snice-column.js.map +1 -1
- package/dist/components/table/snice-header.d.ts +5 -5
- package/dist/components/table/snice-header.js +60 -50
- package/dist/components/table/snice-header.js.map +1 -1
- package/dist/components/table/snice-progress.d.ts +2 -2
- package/dist/components/table/snice-progress.js +18 -11
- package/dist/components/table/snice-progress.js.map +1 -1
- package/dist/components/table/snice-rating.d.ts +2 -2
- package/dist/components/table/snice-rating.js +15 -8
- package/dist/components/table/snice-rating.js.map +1 -1
- package/dist/components/table/snice-row.d.ts +17 -6
- package/dist/components/table/snice-row.js +95 -44
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +18 -10
- package/dist/components/table/snice-table.js +355 -173
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/snice-table.types.d.ts +101 -2
- package/dist/components/tabs/snice-tab-panel.d.ts +2 -2
- package/dist/components/tabs/snice-tab-panel.js +12 -6
- package/dist/components/tabs/snice-tab-panel.js.map +1 -1
- package/dist/components/tabs/snice-tab.d.ts +6 -5
- package/dist/components/tabs/snice-tab.js +36 -19
- package/dist/components/tabs/snice-tab.js.map +1 -1
- package/dist/components/tabs/snice-tabs.d.ts +5 -5
- package/dist/components/tabs/snice-tabs.js +38 -28
- package/dist/components/tabs/snice-tabs.js.map +1 -1
- package/dist/components/toast/snice-toast-container.d.ts +7 -7
- package/dist/components/toast/snice-toast-container.js +19 -12
- package/dist/components/toast/snice-toast-container.js.map +1 -1
- package/dist/components/toast/snice-toast.d.ts +3 -15
- package/dist/components/toast/snice-toast.js +49 -108
- package/dist/components/toast/snice-toast.js.map +1 -1
- package/dist/components/tooltip/snice-tooltip.d.ts +2 -2
- package/dist/components/tooltip/snice-tooltip.js +14 -7
- package/dist/components/tooltip/snice-tooltip.js.map +1 -1
- package/dist/context.d.ts +44 -0
- package/dist/element-ready.d.ts +40 -0
- package/dist/{types/element.d.ts → element.d.ts} +2 -8
- package/dist/{types/events.d.ts → events.d.ts} +0 -4
- package/dist/index.cjs +2589 -605
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.esm.js +2568 -604
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +2589 -605
- package/dist/index.iife.js.map +1 -1
- package/dist/method-decorators.d.ts +121 -0
- package/dist/on.d.ts +59 -0
- package/dist/parts.d.ts +159 -0
- package/dist/render-debug.d.ts +27 -0
- package/dist/render-tracker.d.ts +14 -0
- package/dist/render.d.ts +96 -0
- package/dist/symbols.cjs +163 -0
- package/dist/symbols.cjs.map +1 -1
- package/dist/{types/symbols.d.ts → symbols.d.ts} +22 -0
- package/dist/symbols.esm.js +27 -3
- package/dist/symbols.esm.js.map +1 -1
- package/dist/template.d.ts +100 -0
- package/dist/transitions.cjs +219 -0
- package/dist/transitions.esm.js +2 -2
- package/dist/types/context.d.ts +48 -0
- package/dist/types/element-options.d.ts +26 -0
- package/dist/types/index.d.ts +25 -9
- package/dist/types/nav-context.d.ts +19 -0
- package/dist/types/{types/on-options.d.ts → on-options.d.ts} +2 -0
- package/dist/types/{types/placard.d.ts → placard.d.ts} +0 -1
- package/docs/ai/README.md +17 -0
- package/docs/ai/api.md +175 -0
- package/docs/ai/architecture.md +160 -0
- package/docs/ai/components/accordion.md +174 -0
- package/docs/ai/components/alert.md +77 -0
- package/docs/ai/components/avatar.md +61 -0
- package/docs/ai/components/badge.md +69 -0
- package/docs/ai/components/breadcrumbs.md +74 -0
- package/docs/ai/components/button.md +75 -0
- package/docs/ai/components/card.md +61 -0
- package/docs/ai/components/checkbox.md +74 -0
- package/docs/ai/components/chip.md +73 -0
- package/docs/ai/components/date-picker.md +75 -0
- package/docs/ai/components/divider.md +66 -0
- package/docs/ai/components/drawer.md +80 -0
- package/docs/ai/components/input.md +111 -0
- package/docs/ai/components/login.md +109 -0
- package/docs/ai/components/modal.md +67 -0
- package/docs/ai/components/nav.md +76 -0
- package/docs/ai/components/pagination.md +55 -0
- package/docs/ai/components/progress.md +72 -0
- package/docs/ai/components/radio.md +79 -0
- package/docs/ai/components/select.md +92 -0
- package/docs/ai/components/skeleton.md +57 -0
- package/docs/ai/components/switch.md +53 -0
- package/docs/ai/components/table.md +227 -0
- package/docs/ai/components/tabs.md +83 -0
- package/docs/ai/components/toast.md +140 -0
- package/docs/ai/components/tooltip.md +146 -0
- package/docs/ai/patterns.md +244 -0
- package/docs/components/accordion.md +558 -0
- package/docs/components/drawer.md +602 -0
- package/docs/components/modal.md +558 -0
- package/docs/components/nav.md +239 -0
- package/docs/components/pagination.md +289 -0
- package/docs/components/select.md +599 -0
- package/docs/components/switch.md +354 -0
- package/docs/components/tabs.md +546 -0
- package/docs/components/toast.md +506 -0
- package/docs/components/tooltip.md +523 -0
- package/docs/controllers.md +744 -0
- package/docs/elements.md +855 -0
- package/docs/events.md +807 -0
- package/docs/migration-v2-to-v3.md +569 -0
- package/docs/observe.md +588 -0
- package/docs/placards.md +401 -0
- package/docs/request-response.md +852 -0
- package/docs/routing.md +1186 -0
- package/package.json +10 -11
- package/dist/components/snice-cell-C9N6yGxQ.js +0 -4
- package/dist/components/snice-cell-C9N6yGxQ.js.map +0 -1
- package/dist/types/types/index.d.ts +0 -23
- /package/dist/{types/controller.d.ts → controller.d.ts} +0 -0
- /package/dist/{types/global.d.ts → global.d.ts} +0 -0
- /package/dist/{types/observe.d.ts → observe.d.ts} +0 -0
- /package/dist/{types/request-response.d.ts → request-response.d.ts} +0 -0
- /package/dist/{types/router.d.ts → router.d.ts} +0 -0
- /package/dist/{types/testing.d.ts → testing.d.ts} +0 -0
- /package/dist/{types/transitions.d.ts → transitions.d.ts} +0 -0
- /package/dist/types/{types/adopted-options.d.ts → adopted-options.d.ts} +0 -0
- /package/dist/types/{types/app-context.d.ts → app-context.d.ts} +0 -0
- /package/dist/types/{types/dispatch-options.d.ts → dispatch-options.d.ts} +0 -0
- /package/dist/types/{types/guard.d.ts → guard.d.ts} +0 -0
- /package/dist/types/{types/i-controller.d.ts → i-controller.d.ts} +0 -0
- /package/dist/types/{types/moved-options.d.ts → moved-options.d.ts} +0 -0
- /package/dist/types/{types/observe-options.d.ts → observe-options.d.ts} +0 -0
- /package/dist/types/{types/page-options.d.ts → page-options.d.ts} +0 -0
- /package/dist/types/{types/part-options.d.ts → part-options.d.ts} +0 -0
- /package/dist/types/{types/property-converter.d.ts → property-converter.d.ts} +0 -0
- /package/dist/types/{types/property-options.d.ts → property-options.d.ts} +0 -0
- /package/dist/types/{types/query-options.d.ts → query-options.d.ts} +0 -0
- /package/dist/types/{types/request-options.d.ts → request-options.d.ts} +0 -0
- /package/dist/types/{types/respond-options.d.ts → respond-options.d.ts} +0 -0
- /package/dist/types/{types/route-params.d.ts → route-params.d.ts} +0 -0
- /package/dist/types/{types/router-instance.d.ts → router-instance.d.ts} +0 -0
- /package/dist/types/{types/router-options.d.ts → router-options.d.ts} +0 -0
- /package/dist/types/{types/simple-array.d.ts → simple-array.d.ts} +0 -0
- /package/dist/types/{types/snice-element.d.ts → snice-element.d.ts} +0 -0
- /package/dist/types/{types/snice-global.d.ts → snice-global.d.ts} +0 -0
- /package/dist/types/{types/transition.d.ts → transition.d.ts} +0 -0
- /package/dist/{types/utils.d.ts → utils.d.ts} +0 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
# Modal Component
|
|
2
|
+
|
|
3
|
+
The `<snice-modal>` component provides a dialog overlay for displaying content on top of the main page. It includes features like focus trapping, backdrop dismiss, keyboard navigation, and accessibility support.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [Basic Usage](#basic-usage)
|
|
7
|
+
- [Properties](#properties)
|
|
8
|
+
- [Methods](#methods)
|
|
9
|
+
- [Events](#events)
|
|
10
|
+
- [Slots](#slots)
|
|
11
|
+
- [Examples](#examples)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<snice-modal label="Confirm Action">
|
|
17
|
+
<div slot="header">
|
|
18
|
+
<h2>Confirm</h2>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<p>Are you sure you want to proceed?</p>
|
|
22
|
+
|
|
23
|
+
<div slot="footer">
|
|
24
|
+
<button>Cancel</button>
|
|
25
|
+
<button>Confirm</button>
|
|
26
|
+
</div>
|
|
27
|
+
</snice-modal>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import 'snice/components/modal/snice-modal';
|
|
32
|
+
|
|
33
|
+
const modal = document.querySelector('snice-modal');
|
|
34
|
+
|
|
35
|
+
// Open the modal
|
|
36
|
+
modal.show();
|
|
37
|
+
|
|
38
|
+
// Listen for events
|
|
39
|
+
modal.addEventListener('@snice/modal-close', () => {
|
|
40
|
+
console.log('Modal closed');
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Properties
|
|
45
|
+
|
|
46
|
+
| Property | Type | Default | Description |
|
|
47
|
+
|----------|------|---------|-------------|
|
|
48
|
+
| `open` | `boolean` | `false` | Whether the modal is visible |
|
|
49
|
+
| `size` | `'small' \| 'medium' \| 'large' \| 'fullscreen'` | `'medium'` | Size variant of the modal |
|
|
50
|
+
| `noBackdropDismiss` | `boolean` | `false` | Prevent closing when clicking backdrop |
|
|
51
|
+
| `noEscapeDismiss` | `boolean` | `false` | Prevent closing with Escape key |
|
|
52
|
+
| `noFocusTrap` | `boolean` | `false` | Disable focus trapping |
|
|
53
|
+
| `noCloseButton` | `boolean` | `false` | Hide the close button in header |
|
|
54
|
+
| `label` | `string` | `''` | Accessible label for the modal |
|
|
55
|
+
|
|
56
|
+
## Methods
|
|
57
|
+
|
|
58
|
+
### `show(): void`
|
|
59
|
+
Open the modal.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
modal.show();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `close(): void`
|
|
66
|
+
Close the modal.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
modal.close();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Events
|
|
73
|
+
|
|
74
|
+
### `@snice/modal-open`
|
|
75
|
+
Fired when the modal opens.
|
|
76
|
+
|
|
77
|
+
**Event Detail:**
|
|
78
|
+
```typescript
|
|
79
|
+
{
|
|
80
|
+
modal: SniceModalElement; // Reference to the modal element
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Usage:**
|
|
85
|
+
```typescript
|
|
86
|
+
modal.addEventListener('@snice/modal-open', (e) => {
|
|
87
|
+
console.log('Modal opened:', e.detail.modal);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `@snice/modal-close`
|
|
92
|
+
Fired when the modal closes.
|
|
93
|
+
|
|
94
|
+
**Event Detail:**
|
|
95
|
+
```typescript
|
|
96
|
+
{
|
|
97
|
+
modal: SniceModalElement; // Reference to the modal element
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Usage:**
|
|
102
|
+
```typescript
|
|
103
|
+
modal.addEventListener('@snice/modal-close', (e) => {
|
|
104
|
+
console.log('Modal closed:', e.detail.modal);
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Slots
|
|
109
|
+
|
|
110
|
+
### `header` (named slot)
|
|
111
|
+
Content for the modal header. Typically used for titles.
|
|
112
|
+
|
|
113
|
+
```html
|
|
114
|
+
<snice-modal>
|
|
115
|
+
<div slot="header">
|
|
116
|
+
<h2>Modal Title</h2>
|
|
117
|
+
</div>
|
|
118
|
+
</snice-modal>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Default slot
|
|
122
|
+
Main content of the modal body.
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<snice-modal>
|
|
126
|
+
<p>This goes in the body</p>
|
|
127
|
+
</snice-modal>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `footer` (named slot)
|
|
131
|
+
Content for the modal footer. Typically used for action buttons.
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<snice-modal>
|
|
135
|
+
<div slot="footer">
|
|
136
|
+
<button>Cancel</button>
|
|
137
|
+
<button>OK</button>
|
|
138
|
+
</div>
|
|
139
|
+
</snice-modal>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Examples
|
|
143
|
+
|
|
144
|
+
### Basic Modal
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<button id="openModal">Open Modal</button>
|
|
148
|
+
|
|
149
|
+
<snice-modal id="myModal" label="Example Modal">
|
|
150
|
+
<div slot="header">
|
|
151
|
+
<h2>Hello</h2>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<p>This is a basic modal example.</p>
|
|
155
|
+
|
|
156
|
+
<div slot="footer">
|
|
157
|
+
<button id="closeModal">Close</button>
|
|
158
|
+
</div>
|
|
159
|
+
</snice-modal>
|
|
160
|
+
|
|
161
|
+
<script type="module">
|
|
162
|
+
import 'snice/components/modal/snice-modal';
|
|
163
|
+
|
|
164
|
+
const modal = document.querySelector('#myModal');
|
|
165
|
+
const openBtn = document.querySelector('#openModal');
|
|
166
|
+
const closeBtn = document.querySelector('#closeModal');
|
|
167
|
+
|
|
168
|
+
openBtn.addEventListener('click', () => modal.show());
|
|
169
|
+
closeBtn.addEventListener('click', () => modal.close());
|
|
170
|
+
</script>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Size Variants
|
|
174
|
+
|
|
175
|
+
```html
|
|
176
|
+
<!-- Small -->
|
|
177
|
+
<snice-modal size="small" label="Small Modal">
|
|
178
|
+
<div slot="header"><h2>Small</h2></div>
|
|
179
|
+
<p>This is a small modal.</p>
|
|
180
|
+
</snice-modal>
|
|
181
|
+
|
|
182
|
+
<!-- Medium (default) -->
|
|
183
|
+
<snice-modal size="medium" label="Medium Modal">
|
|
184
|
+
<div slot="header"><h2>Medium</h2></div>
|
|
185
|
+
<p>This is a medium modal.</p>
|
|
186
|
+
</snice-modal>
|
|
187
|
+
|
|
188
|
+
<!-- Large -->
|
|
189
|
+
<snice-modal size="large" label="Large Modal">
|
|
190
|
+
<div slot="header"><h2>Large</h2></div>
|
|
191
|
+
<p>This is a large modal.</p>
|
|
192
|
+
</snice-modal>
|
|
193
|
+
|
|
194
|
+
<!-- Fullscreen -->
|
|
195
|
+
<snice-modal size="fullscreen" label="Fullscreen Modal">
|
|
196
|
+
<div slot="header"><h2>Fullscreen</h2></div>
|
|
197
|
+
<p>This modal takes up the entire screen.</p>
|
|
198
|
+
</snice-modal>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Without Close Button
|
|
202
|
+
|
|
203
|
+
```html
|
|
204
|
+
<snice-modal no-close-button label="Forced Choice">
|
|
205
|
+
<div slot="header">
|
|
206
|
+
<h2>Choose an Option</h2>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<p>You must select one of the options below.</p>
|
|
210
|
+
|
|
211
|
+
<div slot="footer">
|
|
212
|
+
<button onclick="this.closest('snice-modal').close()">Option A</button>
|
|
213
|
+
<button onclick="this.closest('snice-modal').close()">Option B</button>
|
|
214
|
+
</div>
|
|
215
|
+
</snice-modal>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Prevent Backdrop Dismiss
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<snice-modal no-backdrop-dismiss label="Important">
|
|
222
|
+
<div slot="header">
|
|
223
|
+
<h2>Important Information</h2>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<p>Click the button to close, clicking outside won't work.</p>
|
|
227
|
+
|
|
228
|
+
<div slot="footer">
|
|
229
|
+
<button onclick="this.closest('snice-modal').close()">I Understand</button>
|
|
230
|
+
</div>
|
|
231
|
+
</snice-modal>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Prevent Escape Dismiss
|
|
235
|
+
|
|
236
|
+
```html
|
|
237
|
+
<snice-modal no-escape-dismiss label="Confirmation Required">
|
|
238
|
+
<div slot="header">
|
|
239
|
+
<h2>Confirm Action</h2>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<p>Press Escape won't close this modal.</p>
|
|
243
|
+
|
|
244
|
+
<div slot="footer">
|
|
245
|
+
<button onclick="this.closest('snice-modal').close()">Confirm</button>
|
|
246
|
+
</div>
|
|
247
|
+
</snice-modal>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Confirmation Dialog
|
|
251
|
+
|
|
252
|
+
```html
|
|
253
|
+
<button id="deleteBtn">Delete Item</button>
|
|
254
|
+
|
|
255
|
+
<snice-modal id="confirmModal" size="small" label="Confirm Delete">
|
|
256
|
+
<div slot="header">
|
|
257
|
+
<h2>Confirm Delete</h2>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<p>Are you sure you want to delete this item? This action cannot be undone.</p>
|
|
261
|
+
|
|
262
|
+
<div slot="footer">
|
|
263
|
+
<button id="cancelBtn">Cancel</button>
|
|
264
|
+
<button id="confirmBtn" style="background: #dc2626; color: white;">Delete</button>
|
|
265
|
+
</div>
|
|
266
|
+
</snice-modal>
|
|
267
|
+
|
|
268
|
+
<script type="module">
|
|
269
|
+
import 'snice/components/modal/snice-modal';
|
|
270
|
+
|
|
271
|
+
const deleteBtn = document.querySelector('#deleteBtn');
|
|
272
|
+
const modal = document.querySelector('#confirmModal');
|
|
273
|
+
const cancelBtn = document.querySelector('#cancelBtn');
|
|
274
|
+
const confirmBtn = document.querySelector('#confirmBtn');
|
|
275
|
+
|
|
276
|
+
deleteBtn.addEventListener('click', () => {
|
|
277
|
+
modal.show();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
cancelBtn.addEventListener('click', () => {
|
|
281
|
+
modal.close();
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
confirmBtn.addEventListener('click', () => {
|
|
285
|
+
// Perform delete action
|
|
286
|
+
console.log('Item deleted');
|
|
287
|
+
modal.close();
|
|
288
|
+
});
|
|
289
|
+
</script>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Form in Modal
|
|
293
|
+
|
|
294
|
+
```html
|
|
295
|
+
<button id="showFormModal">Edit Profile</button>
|
|
296
|
+
|
|
297
|
+
<snice-modal id="formModal" label="Edit Profile">
|
|
298
|
+
<div slot="header">
|
|
299
|
+
<h2>Edit Profile</h2>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
<form id="profileForm">
|
|
303
|
+
<div style="display: flex; flex-direction: column; gap: 1rem;">
|
|
304
|
+
<div>
|
|
305
|
+
<label for="name">Name:</label>
|
|
306
|
+
<input type="text" id="name" name="name" required>
|
|
307
|
+
</div>
|
|
308
|
+
<div>
|
|
309
|
+
<label for="email">Email:</label>
|
|
310
|
+
<input type="email" id="email" name="email" required>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</form>
|
|
314
|
+
|
|
315
|
+
<div slot="footer">
|
|
316
|
+
<button type="button" onclick="this.closest('snice-modal').close()">Cancel</button>
|
|
317
|
+
<button type="submit" form="profileForm">Save</button>
|
|
318
|
+
</div>
|
|
319
|
+
</snice-modal>
|
|
320
|
+
|
|
321
|
+
<script type="module">
|
|
322
|
+
import 'snice/components/modal/snice-modal';
|
|
323
|
+
|
|
324
|
+
const showBtn = document.querySelector('#showFormModal');
|
|
325
|
+
const modal = document.querySelector('#formModal');
|
|
326
|
+
const form = document.querySelector('#profileForm');
|
|
327
|
+
|
|
328
|
+
showBtn.addEventListener('click', () => modal.show());
|
|
329
|
+
|
|
330
|
+
form.addEventListener('submit', (e) => {
|
|
331
|
+
e.preventDefault();
|
|
332
|
+
const formData = new FormData(form);
|
|
333
|
+
console.log('Saving:', Object.fromEntries(formData));
|
|
334
|
+
modal.close();
|
|
335
|
+
});
|
|
336
|
+
</script>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### With Event Handling
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
import type { SniceModalElement } from 'snice/components/modal/snice-modal.types';
|
|
343
|
+
|
|
344
|
+
const modal = document.querySelector<SniceModalElement>('snice-modal');
|
|
345
|
+
|
|
346
|
+
modal.addEventListener('@snice/modal-open', () => {
|
|
347
|
+
console.log('Modal opened');
|
|
348
|
+
// Pause video, etc.
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
modal.addEventListener('@snice/modal-close', () => {
|
|
352
|
+
console.log('Modal closed');
|
|
353
|
+
// Resume video, etc.
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// Open programmatically
|
|
357
|
+
modal.show();
|
|
358
|
+
|
|
359
|
+
// Close programmatically
|
|
360
|
+
modal.close();
|
|
361
|
+
|
|
362
|
+
// Toggle based on state
|
|
363
|
+
if (modal.open) {
|
|
364
|
+
modal.close();
|
|
365
|
+
} else {
|
|
366
|
+
modal.show();
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Dynamic Content
|
|
371
|
+
|
|
372
|
+
```html
|
|
373
|
+
<button id="showDetails">Show Details</button>
|
|
374
|
+
|
|
375
|
+
<snice-modal id="detailsModal" label="Item Details">
|
|
376
|
+
<div slot="header">
|
|
377
|
+
<h2 id="itemTitle">Loading...</h2>
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
<div id="itemContent">
|
|
381
|
+
<p>Loading...</p>
|
|
382
|
+
</div>
|
|
383
|
+
|
|
384
|
+
<div slot="footer">
|
|
385
|
+
<button onclick="this.closest('snice-modal').close()">Close</button>
|
|
386
|
+
</div>
|
|
387
|
+
</snice-modal>
|
|
388
|
+
|
|
389
|
+
<script type="module">
|
|
390
|
+
import 'snice/components/modal/snice-modal';
|
|
391
|
+
|
|
392
|
+
const showBtn = document.querySelector('#showDetails');
|
|
393
|
+
const modal = document.querySelector('#detailsModal');
|
|
394
|
+
const title = document.querySelector('#itemTitle');
|
|
395
|
+
const content = document.querySelector('#itemContent');
|
|
396
|
+
|
|
397
|
+
showBtn.addEventListener('click', async () => {
|
|
398
|
+
modal.show();
|
|
399
|
+
|
|
400
|
+
// Fetch data
|
|
401
|
+
const response = await fetch('/api/item/123');
|
|
402
|
+
const item = await response.json();
|
|
403
|
+
|
|
404
|
+
// Update modal content
|
|
405
|
+
title.textContent = item.name;
|
|
406
|
+
content.innerHTML = `
|
|
407
|
+
<p><strong>ID:</strong> ${item.id}</p>
|
|
408
|
+
<p><strong>Description:</strong> ${item.description}</p>
|
|
409
|
+
<p><strong>Price:</strong> $${item.price}</p>
|
|
410
|
+
`;
|
|
411
|
+
});
|
|
412
|
+
</script>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Complete Example
|
|
416
|
+
|
|
417
|
+
```html
|
|
418
|
+
<!DOCTYPE html>
|
|
419
|
+
<html>
|
|
420
|
+
<head>
|
|
421
|
+
<style>
|
|
422
|
+
.demo-container {
|
|
423
|
+
padding: 2rem;
|
|
424
|
+
display: flex;
|
|
425
|
+
gap: 1rem;
|
|
426
|
+
flex-wrap: wrap;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.demo-container button {
|
|
430
|
+
padding: 0.5rem 1rem;
|
|
431
|
+
cursor: pointer;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
snice-modal h2 {
|
|
435
|
+
margin: 0;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
snice-modal [slot="footer"] {
|
|
439
|
+
display: flex;
|
|
440
|
+
gap: 0.5rem;
|
|
441
|
+
justify-content: flex-end;
|
|
442
|
+
}
|
|
443
|
+
</style>
|
|
444
|
+
|
|
445
|
+
<script type="module">
|
|
446
|
+
import 'snice/components/modal/snice-modal';
|
|
447
|
+
|
|
448
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
449
|
+
// Setup all modals
|
|
450
|
+
document.querySelectorAll('[data-modal-trigger]').forEach(btn => {
|
|
451
|
+
const modalId = btn.getAttribute('data-modal-trigger');
|
|
452
|
+
const modal = document.querySelector(`#${modalId}`);
|
|
453
|
+
|
|
454
|
+
btn.addEventListener('click', () => modal?.show());
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Setup close buttons
|
|
458
|
+
document.querySelectorAll('[data-modal-close]').forEach(btn => {
|
|
459
|
+
btn.addEventListener('click', () => {
|
|
460
|
+
btn.closest('snice-modal')?.close();
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
</script>
|
|
465
|
+
</head>
|
|
466
|
+
<body>
|
|
467
|
+
<div class="demo-container">
|
|
468
|
+
<button data-modal-trigger="modal1">Small Modal</button>
|
|
469
|
+
<button data-modal-trigger="modal2">Medium Modal</button>
|
|
470
|
+
<button data-modal-trigger="modal3">Large Modal</button>
|
|
471
|
+
<button data-modal-trigger="modal4">Fullscreen Modal</button>
|
|
472
|
+
</div>
|
|
473
|
+
|
|
474
|
+
<snice-modal id="modal1" size="small" label="Small Modal">
|
|
475
|
+
<div slot="header"><h2>Small Modal</h2></div>
|
|
476
|
+
<p>This is a small modal with minimal content.</p>
|
|
477
|
+
<div slot="footer">
|
|
478
|
+
<button data-modal-close>Close</button>
|
|
479
|
+
</div>
|
|
480
|
+
</snice-modal>
|
|
481
|
+
|
|
482
|
+
<snice-modal id="modal2" size="medium" label="Medium Modal">
|
|
483
|
+
<div slot="header"><h2>Medium Modal</h2></div>
|
|
484
|
+
<p>This is a medium-sized modal with more content.</p>
|
|
485
|
+
<p>It can hold paragraphs, images, forms, and more.</p>
|
|
486
|
+
<div slot="footer">
|
|
487
|
+
<button data-modal-close>Cancel</button>
|
|
488
|
+
<button data-modal-close>OK</button>
|
|
489
|
+
</div>
|
|
490
|
+
</snice-modal>
|
|
491
|
+
|
|
492
|
+
<snice-modal id="modal3" size="large" label="Large Modal">
|
|
493
|
+
<div slot="header"><h2>Large Modal</h2></div>
|
|
494
|
+
<p>This is a large modal for displaying lots of content.</p>
|
|
495
|
+
<p>Perfect for detailed forms or extensive information.</p>
|
|
496
|
+
<div slot="footer">
|
|
497
|
+
<button data-modal-close>Close</button>
|
|
498
|
+
</div>
|
|
499
|
+
</snice-modal>
|
|
500
|
+
|
|
501
|
+
<snice-modal id="modal4" size="fullscreen" label="Fullscreen Modal">
|
|
502
|
+
<div slot="header"><h2>Fullscreen Modal</h2></div>
|
|
503
|
+
<p>This modal takes up the entire viewport.</p>
|
|
504
|
+
<p>Ideal for immersive experiences or complex workflows.</p>
|
|
505
|
+
<div slot="footer">
|
|
506
|
+
<button data-modal-close>Close</button>
|
|
507
|
+
</div>
|
|
508
|
+
</snice-modal>
|
|
509
|
+
</body>
|
|
510
|
+
</html>
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## Accessibility
|
|
514
|
+
|
|
515
|
+
The modal component includes comprehensive accessibility features:
|
|
516
|
+
|
|
517
|
+
- `role="dialog"` on the modal container
|
|
518
|
+
- `aria-modal="true"` to indicate modal behavior
|
|
519
|
+
- `aria-label` for screen reader context
|
|
520
|
+
- `aria-hidden` reflects visibility state
|
|
521
|
+
- Focus trap keeps keyboard navigation within modal
|
|
522
|
+
- Focus restoration returns focus to trigger element on close
|
|
523
|
+
- Escape key support for closing
|
|
524
|
+
- Close button is keyboard accessible
|
|
525
|
+
|
|
526
|
+
### Keyboard Support
|
|
527
|
+
|
|
528
|
+
- **Escape**: Close modal (unless `noEscapeDismiss` is true)
|
|
529
|
+
- **Tab**: Cycle through focusable elements within modal (trapped)
|
|
530
|
+
- **Shift + Tab**: Reverse cycle through focusable elements
|
|
531
|
+
|
|
532
|
+
## Behavior
|
|
533
|
+
|
|
534
|
+
### Focus Management
|
|
535
|
+
|
|
536
|
+
When a modal opens:
|
|
537
|
+
1. Current focus is stored
|
|
538
|
+
2. Body scroll is locked
|
|
539
|
+
3. Focus moves to first focusable element in modal
|
|
540
|
+
4. Tab navigation is trapped within the modal
|
|
541
|
+
|
|
542
|
+
When a modal closes:
|
|
543
|
+
1. Body scroll is restored
|
|
544
|
+
2. Focus returns to the previously focused element
|
|
545
|
+
|
|
546
|
+
### Dismissal
|
|
547
|
+
|
|
548
|
+
By default, modals can be dismissed by:
|
|
549
|
+
- Clicking the close button
|
|
550
|
+
- Clicking the backdrop
|
|
551
|
+
- Pressing Escape
|
|
552
|
+
|
|
553
|
+
This behavior can be customized with `noBackdropDismiss`, `noEscapeDismiss`, and `noCloseButton` properties.
|
|
554
|
+
|
|
555
|
+
## Browser Support
|
|
556
|
+
|
|
557
|
+
- Modern browsers (Chrome, Firefox, Safari, Edge)
|
|
558
|
+
- Requires Custom Elements v1 and Shadow DOM support
|