@kubex/zinc 1.0.25 → 1.0.99
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/.claude/project.md +556 -0
- package/.github/workflows/js_build_and_deploy.yaml +9 -10
- package/dist/custom-elements.json +13575 -8856
- package/dist/vscode.html-custom-data.json +583 -48
- package/dist/web-types.json +1441 -181
- package/dist/zn.d.ts +1645 -660
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +1412 -893
- package/docs/_utilities/code-previews.cjs +10 -1
- package/docs/assets/scripts/docs.js +42 -18
- package/docs/data/data-table.json +229 -66
- package/docs/data/empty.json +6 -0
- package/docs/data/products-table.json +41 -193
- package/docs/pages/components/action-bar.md +121 -6
- package/docs/pages/components/alert.md +118 -15
- package/docs/pages/components/animated-button.md +299 -0
- package/docs/pages/components/audio-select.md +534 -0
- package/docs/pages/components/bulk-actions.md +79 -5
- package/docs/pages/components/button-group.md +235 -27
- package/docs/pages/components/button.md +139 -1
- package/docs/pages/components/chart.md +365 -9
- package/docs/pages/components/checkbox.md +387 -58
- package/docs/pages/components/chip.md +253 -33
- package/docs/pages/components/collapsible.md +393 -46
- package/docs/pages/components/cols.md +152 -30
- package/docs/pages/components/confirm.md +182 -16
- package/docs/pages/components/copy-button.md +169 -6
- package/docs/pages/components/data-select.md +194 -15
- package/docs/pages/components/data-table-filter.md +96 -5
- package/docs/pages/components/data-table-search.md +451 -0
- package/docs/pages/components/data-table-sort.md +66 -5
- package/docs/pages/components/data-table.md +727 -66
- package/docs/pages/components/datepicker.md +402 -7
- package/docs/pages/components/defined-label.md +120 -5
- package/docs/pages/components/dialog.md +339 -59
- package/docs/pages/components/dropdown.md +366 -11
- package/docs/pages/components/editor.md +604 -7
- package/docs/pages/components/empty-state.md +315 -16
- package/docs/pages/components/expanding-action.md +212 -28
- package/docs/pages/components/file.md +421 -12
- package/docs/pages/components/filter-container.md +158 -5
- package/docs/pages/components/filter-wrapper.md +167 -6
- package/docs/pages/components/form-group.md +383 -6
- package/docs/pages/components/hover-container.md +237 -6
- package/docs/pages/components/icon-picker.md +121 -0
- package/docs/pages/components/icon.md +454 -48
- package/docs/pages/components/inline-edit.md +787 -19
- package/docs/pages/components/input-group.md +207 -13
- package/docs/pages/components/input.md +194 -0
- package/docs/pages/components/item.md +18 -0
- package/docs/pages/components/key-container.md +115 -0
- package/docs/pages/components/key.md +101 -0
- package/docs/pages/components/menu.md +512 -6
- package/docs/pages/components/note.md +239 -36
- package/docs/pages/components/opt-group.md +107 -0
- package/docs/pages/components/pagination.md +332 -6
- package/docs/pages/components/pane.md +222 -6
- package/docs/pages/components/panel.md +213 -26
- package/docs/pages/components/popup.md +1354 -6
- package/docs/pages/components/priority-list.md +233 -0
- package/docs/pages/components/progress-bar.md +387 -6
- package/docs/pages/components/radio-group.md +242 -5
- package/docs/pages/components/radio.md +474 -6
- package/docs/pages/components/rating.md +331 -7
- package/docs/pages/components/reveal.md +524 -6
- package/docs/pages/components/scroll-container.md +552 -6
- package/docs/pages/components/select.md +762 -160
- package/docs/pages/components/skeleton.md +473 -30
- package/docs/pages/components/slideout.md +261 -5
- package/docs/pages/components/sp.md +99 -41
- package/docs/pages/components/split-button.md +347 -9
- package/docs/pages/components/split-pane.md +445 -6
- package/docs/pages/components/stat.md +549 -9
- package/docs/pages/components/status-indicator.md +230 -1
- package/docs/pages/components/stepper.md +563 -6
- package/docs/pages/components/tabs.md +439 -13
- package/docs/pages/components/textarea.md +415 -17
- package/docs/pages/components/tile.md +385 -26
- package/docs/pages/components/toggle.md +424 -6
- package/docs/pages/components/tooltip.md +367 -0
- package/docs/pages/components/translation-group.md +210 -0
- package/docs/pages/components/translations.md +319 -19
- package/docs/pages/components/vertical-stepper.md +401 -8
- package/docs/pages/components/well.md +300 -3
- package/docs/pages/getting-started/form-controls.md +162 -0
- package/docs/pages/index.md +116 -15
- package/package.json +5 -6
- package/scss/_global-spacing.scss +4 -0
- package/scss/_root.scss +2 -2
- package/scss/boot.scss +19 -0
- package/scss/shared/layout.scss +5 -0
- package/scss/themes/_light.scss +3 -3
- package/src/components/alert/alert.scss +1 -0
- package/src/components/animated-button/README.md +306 -0
- package/src/components/animated-button/animated-button.component.ts +229 -0
- package/src/components/animated-button/animated-button.scss +228 -0
- package/src/components/animated-button/animated-button.test.ts +143 -0
- package/src/components/animated-button/index.ts +12 -0
- package/src/components/button/button.component.ts +5 -0
- package/src/components/button-group/button-group.component.ts +25 -13
- package/src/components/button-group/button-group.scss +6 -0
- package/src/components/checkbox/checkbox.component.ts +4 -0
- package/src/components/checkbox/checkbox.scss +7 -4
- package/src/components/checkbox-group/checkbox-group.scss +7 -0
- package/src/components/chip/chip.component.ts +7 -2
- package/src/components/chip/chip.scss +16 -2
- package/src/components/collapsible/collapsible.component.ts +27 -20
- package/src/components/cols/cols.component.ts +14 -2
- package/src/components/cols/cols.scss +6 -12
- package/src/components/confirm/confirm.component.ts +7 -0
- package/src/components/copy-button/copy-button.component.ts +12 -11
- package/src/components/data-select/data-select.component.ts +215 -44
- package/src/components/data-select/data-select.scss +66 -6
- package/src/components/data-select/providers/currency-data-provider.ts +20 -6
- package/src/components/data-select/providers/provider.ts +1 -0
- package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
- package/src/components/data-table/data-table.component.ts +81 -22
- package/src/components/data-table-search/data-table-search.component.ts +184 -0
- package/src/components/data-table-search/data-table-search.scss +17 -0
- package/src/components/data-table-search/data-table-search.test.ts +11 -0
- package/src/components/data-table-search/index.ts +12 -0
- package/src/components/datepicker/datepicker.component.ts +347 -13
- package/src/components/dialog/dialog.component.ts +1 -1
- package/src/components/empty-state/empty-state.scss +6 -1
- package/src/components/header/header.scss +3 -3
- package/src/components/icon/icon.component.ts +23 -1
- package/src/components/icon/icon.scss +23 -0
- package/src/components/icon-picker/brand-icons.ts +24 -0
- package/src/components/icon-picker/icon-picker.component.ts +407 -0
- package/src/components/icon-picker/icon-picker.scss +205 -0
- package/src/components/icon-picker/index.ts +12 -0
- package/src/components/icon-picker/line-icons.ts +612 -0
- package/src/components/icon-picker/material-icons.ts +14543 -0
- package/src/components/inline-edit/inline-edit.component.ts +190 -46
- package/src/components/inline-edit/inline-edit.scss +29 -0
- package/src/components/inline-edit/inline-edit.test.ts +314 -1
- package/src/components/input/input.component.ts +324 -5
- package/src/components/input/input.scss +87 -0
- package/src/components/input-group/input-group.component.ts +28 -7
- package/src/components/input-group/input-group.scss +48 -10
- package/src/components/item/item.component.ts +24 -3
- package/src/components/item/item.scss +18 -0
- package/src/components/key/index.ts +12 -0
- package/src/components/key/key.component.ts +47 -0
- package/src/components/key/key.scss +38 -0
- package/src/components/key-container/index.ts +12 -0
- package/src/components/key-container/key-container.component.ts +142 -0
- package/src/components/key-container/key-container.scss +33 -0
- package/src/components/menu-item/menu-item.component.ts +20 -0
- package/src/components/menu-item/menu-item.scss +69 -2
- package/src/components/navbar/navbar.component.ts +103 -11
- package/src/components/navbar/navbar.scss +6 -1
- package/src/components/opt-group/index.ts +12 -0
- package/src/components/opt-group/opt-group.component.ts +74 -0
- package/src/components/opt-group/opt-group.scss +37 -0
- package/src/components/opt-group/opt-group.test.ts +27 -0
- package/src/components/option/option.component.ts +1 -16
- package/src/components/option/option.scss +4 -0
- package/src/components/panel/panel.component.ts +10 -8
- package/src/components/panel/panel.scss +20 -0
- package/src/components/priority-list/index.ts +12 -0
- package/src/components/priority-list/priority-list.component.ts +611 -0
- package/src/components/priority-list/priority-list.scss +185 -0
- package/src/components/priority-list/priority-list.test.ts +139 -0
- package/src/components/progress-bar/progress-bar.component.ts +22 -16
- package/src/components/radio/radio.scss +10 -3
- package/src/components/select/select.component.ts +812 -72
- package/src/components/select/select.scss +108 -2
- package/src/components/select/select.test.ts +147 -2
- package/src/components/settings-container/settings-container.component.ts +44 -19
- package/src/components/settings-container/settings-container.scss +1 -1
- package/src/components/skeleton/skeleton.component.ts +6 -1
- package/src/components/slideout/slideout.scss +8 -3
- package/src/components/sp/sp.component.ts +3 -1
- package/src/components/sp/sp.scss +19 -0
- package/src/components/stepper/stepper.component.ts +16 -10
- package/src/components/textarea/textarea.scss +0 -4
- package/src/components/tile/tile.component.ts +12 -3
- package/src/components/tile/tile.scss +1 -1
- package/src/components/timer/timer.component.ts +15 -2
- package/src/components/toggle/toggle.component.ts +29 -26
- package/src/components/toggle/toggle.scss +13 -1
- package/src/components/translation-group/index.ts +12 -0
- package/src/components/translation-group/translation-group.component.ts +207 -0
- package/src/components/translation-group/translation-group.scss +8 -0
- package/src/components/translations/translations.component.ts +90 -44
- package/src/components/translations/translations.scss +4 -0
- package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
- package/src/events/events.ts +12 -7
- package/src/events/zn-language-change.ts +7 -0
- package/src/events/zn-purchase.ts +11 -0
- package/src/events/zn-redirect.ts +7 -0
- package/src/events/zn-reorder.ts +7 -0
- package/src/events/zn-search-change.ts +11 -0
- package/src/events/zn-submit.ts +1 -1
- package/src/form-control.scss +4 -0
- package/src/internal/form-navigation.ts +510 -0
- package/src/internal/form.ts +6 -0
- package/src/zinc.ts +91 -83
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Audio Select
|
|
4
|
+
description: Audio select allows you to choose audio files from a menu with built-in preview playback functionality.
|
|
5
|
+
layout: component
|
|
6
|
+
status: experimental
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Basic Audio Select
|
|
12
|
+
|
|
13
|
+
The audio select component combines a standard select dropdown with an integrated audio preview player. Use the `label` attribute to give the select an accessible label, provide an array of audio files via the `files` property, and control the selected value with the `value` attribute.
|
|
14
|
+
|
|
15
|
+
```html:preview
|
|
16
|
+
<zn-audio-select
|
|
17
|
+
id="basic-audio-select"
|
|
18
|
+
label="Select an audio file"
|
|
19
|
+
placeholder="Choose a sound"
|
|
20
|
+
>
|
|
21
|
+
</zn-audio-select>
|
|
22
|
+
|
|
23
|
+
<script type="module">
|
|
24
|
+
const audioSelect = document.getElementById('basic-audio-select');
|
|
25
|
+
|
|
26
|
+
audioSelect.files = [
|
|
27
|
+
{ name: 'Notification Sound', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
28
|
+
{ name: 'Alert Tone', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
29
|
+
{ name: 'Chime', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
30
|
+
];
|
|
31
|
+
</script>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
:::tip
|
|
35
|
+
The play/pause button in the prefix slot allows users to preview the selected audio file before confirming their choice. The audio automatically stops when a new selection is made or when the component is disconnected.
|
|
36
|
+
:::
|
|
37
|
+
|
|
38
|
+
### Initial Value
|
|
39
|
+
|
|
40
|
+
Use the `value` attribute to set an initial selection. The value should match one of the URLs in your files array.
|
|
41
|
+
|
|
42
|
+
```html:preview
|
|
43
|
+
<zn-audio-select
|
|
44
|
+
id="initial-value-audio"
|
|
45
|
+
label="Select notification sound"
|
|
46
|
+
placeholder="Choose a sound"
|
|
47
|
+
>
|
|
48
|
+
</zn-audio-select>
|
|
49
|
+
|
|
50
|
+
<script type="module">
|
|
51
|
+
const audioSelect = document.getElementById('initial-value-audio');
|
|
52
|
+
|
|
53
|
+
audioSelect.files = [
|
|
54
|
+
{ name: 'Notification Sound', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
55
|
+
{ name: 'Alert Tone', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
56
|
+
{ name: 'Chime', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
// Set initial value
|
|
60
|
+
audioSelect.value = 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3';
|
|
61
|
+
</script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Custom Placeholder
|
|
65
|
+
|
|
66
|
+
Customize the placeholder text shown when no audio file is selected using the `placeholder` attribute.
|
|
67
|
+
|
|
68
|
+
```html:preview
|
|
69
|
+
<zn-audio-select
|
|
70
|
+
id="custom-placeholder-audio"
|
|
71
|
+
label="Ringtone"
|
|
72
|
+
placeholder="Pick your ringtone"
|
|
73
|
+
>
|
|
74
|
+
</zn-audio-select>
|
|
75
|
+
|
|
76
|
+
<script type="module">
|
|
77
|
+
const audioSelect = document.getElementById('custom-placeholder-audio');
|
|
78
|
+
|
|
79
|
+
audioSelect.files = [
|
|
80
|
+
{ name: 'Classic Ring', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
81
|
+
{ name: 'Modern Tone', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
82
|
+
{ name: 'Gentle Chime', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
83
|
+
];
|
|
84
|
+
</script>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Interactive Preview Controls
|
|
88
|
+
|
|
89
|
+
The audio select includes an integrated play/pause checkbox in the prefix slot. Click the play button to preview the currently selected audio. The button automatically changes to a pause icon while audio is playing.
|
|
90
|
+
|
|
91
|
+
```html:preview
|
|
92
|
+
<zn-audio-select
|
|
93
|
+
id="preview-demo-audio"
|
|
94
|
+
label="Test audio playback"
|
|
95
|
+
placeholder="Select to preview"
|
|
96
|
+
>
|
|
97
|
+
</zn-audio-select>
|
|
98
|
+
|
|
99
|
+
<div style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-100); border-radius: 4px;">
|
|
100
|
+
<strong>Instructions:</strong>
|
|
101
|
+
<ol style="margin: 0.5rem 0 0 1.5rem; padding: 0;">
|
|
102
|
+
<li>Select an audio file from the dropdown</li>
|
|
103
|
+
<li>Click the play button (arrow icon) to start playback</li>
|
|
104
|
+
<li>Click the pause button to stop playback</li>
|
|
105
|
+
<li>Select a different file to automatically stop current playback</li>
|
|
106
|
+
</ol>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<script type="module">
|
|
110
|
+
const audioSelect = document.getElementById('preview-demo-audio');
|
|
111
|
+
|
|
112
|
+
audioSelect.files = [
|
|
113
|
+
{ name: 'Short Beep', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
114
|
+
{ name: 'Notification Ping', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
115
|
+
{ name: 'Alert Sound', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
116
|
+
];
|
|
117
|
+
</script>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
:::tip
|
|
121
|
+
Audio playback is prevented when no file is selected. The play/pause button becomes functional only after selecting an audio file from the dropdown.
|
|
122
|
+
:::
|
|
123
|
+
|
|
124
|
+
### Listening for Changes
|
|
125
|
+
|
|
126
|
+
The audio select emits a `zn-change` event when the selection changes. Access the selected URL through the `value` property.
|
|
127
|
+
|
|
128
|
+
```html:preview
|
|
129
|
+
<zn-audio-select
|
|
130
|
+
id="event-audio-select"
|
|
131
|
+
label="Select your notification"
|
|
132
|
+
placeholder="Choose one"
|
|
133
|
+
>
|
|
134
|
+
</zn-audio-select>
|
|
135
|
+
|
|
136
|
+
<div style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-100); border-radius: 4px;">
|
|
137
|
+
<strong>Selection:</strong>
|
|
138
|
+
<div id="audio-selection-log" style="margin-top: 0.5rem; font-family: monospace; font-size: 0.875rem;">
|
|
139
|
+
No selection yet
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<script type="module">
|
|
144
|
+
const audioSelect = document.getElementById('event-audio-select');
|
|
145
|
+
const selectionLog = document.getElementById('audio-selection-log');
|
|
146
|
+
|
|
147
|
+
audioSelect.files = [
|
|
148
|
+
{ name: 'Notification 1', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
149
|
+
{ name: 'Notification 2', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
150
|
+
{ name: 'Notification 3', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
audioSelect.addEventListener('zn-change', (e) => {
|
|
154
|
+
const selectedFile = audioSelect.files.find(f => f.url === e.target.value);
|
|
155
|
+
if (selectedFile) {
|
|
156
|
+
selectionLog.textContent = `Selected: ${selectedFile.name}\nURL: ${selectedFile.url}`;
|
|
157
|
+
} else {
|
|
158
|
+
selectionLog.textContent = 'No selection';
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
</script>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Programmatic Control
|
|
165
|
+
|
|
166
|
+
Control the audio select programmatically by setting the `value` property or manipulating the `files` array.
|
|
167
|
+
|
|
168
|
+
```html:preview
|
|
169
|
+
<zn-audio-select
|
|
170
|
+
id="programmatic-audio"
|
|
171
|
+
label="Programmable audio select"
|
|
172
|
+
placeholder="Select a sound"
|
|
173
|
+
>
|
|
174
|
+
</zn-audio-select>
|
|
175
|
+
|
|
176
|
+
<div style="margin-top: 1rem; display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
|
177
|
+
<zn-button id="select-first" size="small">Select First</zn-button>
|
|
178
|
+
<zn-button id="select-second" size="small">Select Second</zn-button>
|
|
179
|
+
<zn-button id="clear-selection" size="small">Clear</zn-button>
|
|
180
|
+
<zn-button id="add-file" size="small">Add File</zn-button>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<script type="module">
|
|
184
|
+
const audioSelect = document.getElementById('programmatic-audio');
|
|
185
|
+
|
|
186
|
+
const initialFiles = [
|
|
187
|
+
{ name: 'Sound A', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
188
|
+
{ name: 'Sound B', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' }
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
audioSelect.files = [...initialFiles];
|
|
192
|
+
|
|
193
|
+
document.getElementById('select-first').addEventListener('click', () => {
|
|
194
|
+
audioSelect.value = audioSelect.files[0]?.url || '';
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
document.getElementById('select-second').addEventListener('click', () => {
|
|
198
|
+
audioSelect.value = audioSelect.files[1]?.url || '';
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
document.getElementById('clear-selection').addEventListener('click', () => {
|
|
202
|
+
audioSelect.value = '';
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
document.getElementById('add-file').addEventListener('click', () => {
|
|
206
|
+
const newFile = {
|
|
207
|
+
name: `Sound ${audioSelect.files.length + 1}`,
|
|
208
|
+
url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3'
|
|
209
|
+
};
|
|
210
|
+
audioSelect.files = [...audioSelect.files, newFile];
|
|
211
|
+
});
|
|
212
|
+
</script>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Dynamic File Lists
|
|
216
|
+
|
|
217
|
+
Update the available audio files dynamically by setting the `files` property. This is useful for loading files from an API or updating based on user actions.
|
|
218
|
+
|
|
219
|
+
```html:preview
|
|
220
|
+
<div class="form-spacing">
|
|
221
|
+
<zn-select id="category-selector" label="Audio category">
|
|
222
|
+
<zn-option value="">Select a category</zn-option>
|
|
223
|
+
<zn-option value="notifications">Notifications</zn-option>
|
|
224
|
+
<zn-option value="alarms">Alarms</zn-option>
|
|
225
|
+
<zn-option value="ringtones">Ringtones</zn-option>
|
|
226
|
+
</zn-select>
|
|
227
|
+
|
|
228
|
+
<zn-audio-select
|
|
229
|
+
id="dynamic-audio-select"
|
|
230
|
+
label="Available sounds"
|
|
231
|
+
placeholder="First select a category"
|
|
232
|
+
>
|
|
233
|
+
</zn-audio-select>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<script type="module">
|
|
237
|
+
const categorySelector = document.getElementById('category-selector');
|
|
238
|
+
const audioSelect = document.getElementById('dynamic-audio-select');
|
|
239
|
+
|
|
240
|
+
const audioCategories = {
|
|
241
|
+
notifications: [
|
|
242
|
+
{ name: 'Gentle Ping', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
243
|
+
{ name: 'Quick Beep', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' }
|
|
244
|
+
],
|
|
245
|
+
alarms: [
|
|
246
|
+
{ name: 'Wake Up Call', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' },
|
|
247
|
+
{ name: 'Morning Alert', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' }
|
|
248
|
+
],
|
|
249
|
+
ringtones: [
|
|
250
|
+
{ name: 'Classic Ring', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
251
|
+
{ name: 'Modern Tone', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
252
|
+
]
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
categorySelector.addEventListener('zn-change', (e) => {
|
|
256
|
+
const category = e.target.value;
|
|
257
|
+
if (category && audioCategories[category]) {
|
|
258
|
+
audioSelect.files = audioCategories[category];
|
|
259
|
+
audioSelect.value = '';
|
|
260
|
+
audioSelect.placeholder = 'Select a sound';
|
|
261
|
+
} else {
|
|
262
|
+
audioSelect.files = [];
|
|
263
|
+
audioSelect.value = '';
|
|
264
|
+
audioSelect.placeholder = 'First select a category';
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
</script>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Form Integration
|
|
271
|
+
|
|
272
|
+
The audio select component works with standard HTML forms. The selected audio URL is submitted as the form value.
|
|
273
|
+
|
|
274
|
+
```html:preview
|
|
275
|
+
<form id="audio-form">
|
|
276
|
+
<zn-audio-select
|
|
277
|
+
id="form-audio-select"
|
|
278
|
+
name="notificationSound"
|
|
279
|
+
label="Notification sound"
|
|
280
|
+
placeholder="Choose your notification"
|
|
281
|
+
>
|
|
282
|
+
</zn-audio-select>
|
|
283
|
+
<br />
|
|
284
|
+
<zn-button type="submit" variant="primary">Submit</zn-button>
|
|
285
|
+
<zn-button type="reset">Reset</zn-button>
|
|
286
|
+
</form>
|
|
287
|
+
|
|
288
|
+
<script type="module">
|
|
289
|
+
const form = document.getElementById('audio-form');
|
|
290
|
+
const audioSelect = document.getElementById('form-audio-select');
|
|
291
|
+
|
|
292
|
+
audioSelect.files = [
|
|
293
|
+
{ name: 'Chime', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
294
|
+
{ name: 'Bell', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
295
|
+
{ name: 'Ding', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
form.addEventListener('submit', (e) => {
|
|
299
|
+
e.preventDefault();
|
|
300
|
+
const formData = new FormData(form);
|
|
301
|
+
const data = Object.fromEntries(formData);
|
|
302
|
+
alert('Form submitted!\n\n' + JSON.stringify(data, null, 2));
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
form.addEventListener('reset', () => {
|
|
306
|
+
audioSelect.value = '';
|
|
307
|
+
});
|
|
308
|
+
</script>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Real-world Example: Audio Settings Panel
|
|
312
|
+
|
|
313
|
+
A complete example showing how to use the audio select in a settings interface for configuring notification sounds.
|
|
314
|
+
|
|
315
|
+
```html:preview
|
|
316
|
+
<div style="max-width: 600px; padding: 1.5rem; background: var(--zn-color-neutral-50); border-radius: 8px; border: 1px solid var(--zn-color-neutral-200);">
|
|
317
|
+
<h3 style="margin-top: 0;">Audio Notification Settings</h3>
|
|
318
|
+
|
|
319
|
+
<form id="notification-settings-form" class="form-spacing">
|
|
320
|
+
<zn-checkbox id="enable-notifications" checked>
|
|
321
|
+
Enable audio notifications
|
|
322
|
+
</zn-checkbox>
|
|
323
|
+
|
|
324
|
+
<zn-audio-select
|
|
325
|
+
id="new-message-sound"
|
|
326
|
+
name="newMessageSound"
|
|
327
|
+
label="New message"
|
|
328
|
+
placeholder="Select a sound"
|
|
329
|
+
>
|
|
330
|
+
</zn-audio-select>
|
|
331
|
+
|
|
332
|
+
<zn-audio-select
|
|
333
|
+
id="mention-sound"
|
|
334
|
+
name="mentionSound"
|
|
335
|
+
label="@mention"
|
|
336
|
+
placeholder="Select a sound"
|
|
337
|
+
>
|
|
338
|
+
</zn-audio-select>
|
|
339
|
+
|
|
340
|
+
<zn-audio-select
|
|
341
|
+
id="call-sound"
|
|
342
|
+
name="callSound"
|
|
343
|
+
label="Incoming call"
|
|
344
|
+
placeholder="Select a sound"
|
|
345
|
+
>
|
|
346
|
+
</zn-audio-select>
|
|
347
|
+
|
|
348
|
+
<div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
|
|
349
|
+
<zn-button type="submit" variant="primary">Save Settings</zn-button>
|
|
350
|
+
<zn-button type="reset">Reset</zn-button>
|
|
351
|
+
</div>
|
|
352
|
+
</form>
|
|
353
|
+
</div>
|
|
354
|
+
|
|
355
|
+
<script type="module">
|
|
356
|
+
const form = document.getElementById('notification-settings-form');
|
|
357
|
+
const enableNotifications = document.getElementById('enable-notifications');
|
|
358
|
+
const newMessageSound = document.getElementById('new-message-sound');
|
|
359
|
+
const mentionSound = document.getElementById('mention-sound');
|
|
360
|
+
const callSound = document.getElementById('call-sound');
|
|
361
|
+
|
|
362
|
+
// Sample audio files
|
|
363
|
+
const audioFiles = [
|
|
364
|
+
{ name: 'Gentle Ping', url: 'https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8c8e8c5a3.mp3' },
|
|
365
|
+
{ name: 'Quick Beep', url: 'https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443c.mp3' },
|
|
366
|
+
{ name: 'Soft Chime', url: 'https://cdn.pixabay.com/download/audio/2022/03/10/audio_24f0b90e18.mp3' }
|
|
367
|
+
];
|
|
368
|
+
|
|
369
|
+
// Set audio files for all selects
|
|
370
|
+
[newMessageSound, mentionSound, callSound].forEach(select => {
|
|
371
|
+
select.files = audioFiles;
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// Enable/disable audio selects based on checkbox
|
|
375
|
+
function updateAudioSelectsState() {
|
|
376
|
+
const enabled = enableNotifications.checked;
|
|
377
|
+
[newMessageSound, mentionSound, callSound].forEach(select => {
|
|
378
|
+
select.style.opacity = enabled ? '1' : '0.5';
|
|
379
|
+
select.style.pointerEvents = enabled ? 'auto' : 'none';
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
enableNotifications.addEventListener('zn-change', updateAudioSelectsState);
|
|
384
|
+
updateAudioSelectsState();
|
|
385
|
+
|
|
386
|
+
form.addEventListener('submit', (e) => {
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
if (!enableNotifications.checked) {
|
|
389
|
+
alert('Audio notifications are disabled');
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const formData = new FormData(form);
|
|
393
|
+
const data = Object.fromEntries(formData);
|
|
394
|
+
alert('Settings saved!\n\n' + JSON.stringify(data, null, 2));
|
|
395
|
+
});
|
|
396
|
+
</script>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Properties
|
|
400
|
+
|
|
401
|
+
| Property | Attribute | Description | Type | Default |
|
|
402
|
+
|----------|-----------|-------------|------|---------|
|
|
403
|
+
| `value` | `value` | The currently selected audio file URL. When set, the audio player loads this URL for preview. | `string` | `''` |
|
|
404
|
+
| `label` | `label` | The label text displayed above the select control. For labels containing HTML, use the `label` slot instead. | `string` | `''` |
|
|
405
|
+
| `placeholder` | `placeholder` | Placeholder text shown in the dropdown when no audio file is selected. | `string` | `''` |
|
|
406
|
+
| `files` | `files` | Array of audio files available for selection. Each file object must have `name` (display text) and `url` (audio file URL) properties. | `AudioFile[]` | `[]` |
|
|
407
|
+
|
|
408
|
+
### AudioFile Interface
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
interface AudioFile {
|
|
412
|
+
name: string; // Display name shown in the dropdown
|
|
413
|
+
url: string; // URL to the audio file
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Events
|
|
418
|
+
|
|
419
|
+
| Event | Description | Event Detail |
|
|
420
|
+
|-------|-------------|--------------|
|
|
421
|
+
| `zn-change` | Emitted when the selected audio file changes. The event is triggered by the underlying `zn-select` component and bubbles up. Access the new value via `event.target.value`. | Inherited from `zn-select` |
|
|
422
|
+
| `zn-input` | Emitted when the select receives input. Inherited from the underlying `zn-select` component. | Inherited from `zn-select` |
|
|
423
|
+
| `zn-focus` | Emitted when the select gains focus. | Inherited from `zn-select` |
|
|
424
|
+
| `zn-blur` | Emitted when the select loses focus. | Inherited from `zn-select` |
|
|
425
|
+
|
|
426
|
+
:::tip
|
|
427
|
+
The audio select inherits all events from the `zn-select` component. Refer to the [select documentation](/components/select#events) for complete event details.
|
|
428
|
+
:::
|
|
429
|
+
|
|
430
|
+
## Slots
|
|
431
|
+
|
|
432
|
+
| Name | Description |
|
|
433
|
+
|------|-------------|
|
|
434
|
+
| (default) | The default slot is not used in the audio select component. Options are generated automatically from the `files` property. |
|
|
435
|
+
| `actions` | Optional slot for action buttons or controls. Inherited from `zn-select`. |
|
|
436
|
+
| `footer` | Optional slot for footer content. Inherited from `zn-select`. |
|
|
437
|
+
|
|
438
|
+
:::warning
|
|
439
|
+
**Note:** Unlike the standard `zn-select`, the audio select component auto-generates its options from the `files` property. Manual `zn-option` elements in the default slot will be overwritten.
|
|
440
|
+
:::
|
|
441
|
+
|
|
442
|
+
## CSS Parts
|
|
443
|
+
|
|
444
|
+
| Part | Description |
|
|
445
|
+
|------|-------------|
|
|
446
|
+
| `base` | The component's base wrapper element. |
|
|
447
|
+
|
|
448
|
+
:::tip
|
|
449
|
+
The audio select wraps a `zn-select` component internally, so all CSS parts from `zn-select` are also available. See the [select component CSS parts](/components/select#css-parts) for additional customization options.
|
|
450
|
+
:::
|
|
451
|
+
|
|
452
|
+
## CSS Custom Properties
|
|
453
|
+
|
|
454
|
+
| Name | Description |
|
|
455
|
+
|------|-------------|
|
|
456
|
+
| `--example` | An example CSS custom property (inherited from base component). |
|
|
457
|
+
|
|
458
|
+
:::tip
|
|
459
|
+
The audio select inherits custom properties from the underlying `zn-select` component. See the [select documentation](/components/select) for available custom properties.
|
|
460
|
+
:::
|
|
461
|
+
|
|
462
|
+
## Methods
|
|
463
|
+
|
|
464
|
+
The audio select component provides these methods:
|
|
465
|
+
|
|
466
|
+
| Method | Description | Arguments | Returns |
|
|
467
|
+
|--------|-------------|-----------|---------|
|
|
468
|
+
| `stopAudio()` | Stops any currently playing audio, resets playback to the beginning, and updates the play/pause button state. | None | `void` |
|
|
469
|
+
|
|
470
|
+
:::tip
|
|
471
|
+
Additional methods are available through the underlying `zn-select` component. Use standard DOM methods like `querySelector()` to access the internal select and call its methods (e.g., `focus()`, `blur()`, `show()`, `hide()`).
|
|
472
|
+
:::
|
|
473
|
+
|
|
474
|
+
## Behavior Details
|
|
475
|
+
|
|
476
|
+
### Audio Playback
|
|
477
|
+
|
|
478
|
+
- The audio preview player is implemented using the HTML5 `Audio` API
|
|
479
|
+
- Clicking play loads and plays the currently selected audio file
|
|
480
|
+
- Audio automatically stops when:
|
|
481
|
+
- The user clicks the pause button
|
|
482
|
+
- A different audio file is selected
|
|
483
|
+
- The component is disconnected from the DOM
|
|
484
|
+
- If audio playback fails (e.g., invalid URL, network error), an error is logged to the console and the button returns to the play state
|
|
485
|
+
- Attempting to play without selecting a file is prevented
|
|
486
|
+
|
|
487
|
+
### Selection Behavior
|
|
488
|
+
|
|
489
|
+
- The component automatically creates a disabled placeholder option from the `placeholder` property
|
|
490
|
+
- Each file in the `files` array generates a corresponding `zn-option` element
|
|
491
|
+
- When `value` changes, any playing audio is automatically stopped and the new audio URL is loaded
|
|
492
|
+
- The internal `zn-select` handles all dropdown behavior, keyboard navigation, and accessibility features
|
|
493
|
+
|
|
494
|
+
### Play/Pause Button
|
|
495
|
+
|
|
496
|
+
- Implemented as a `zn-checkbox` in the prefix slot
|
|
497
|
+
- Shows a play icon (arrow) when audio is not playing
|
|
498
|
+
- Shows a pause icon when audio is playing
|
|
499
|
+
- Uses primary color when checked (playing) and secondary color when unchecked (stopped)
|
|
500
|
+
- Button state is synchronized with audio playback state
|
|
501
|
+
|
|
502
|
+
## Accessibility
|
|
503
|
+
|
|
504
|
+
The audio select component inherits all accessibility features from the underlying `zn-select` component:
|
|
505
|
+
|
|
506
|
+
- Proper ARIA labels and roles for screen readers
|
|
507
|
+
- Full keyboard navigation support
|
|
508
|
+
- Focus management
|
|
509
|
+
- High contrast mode support
|
|
510
|
+
|
|
511
|
+
The play/pause checkbox should include an `aria-label` for screen reader users (this is implemented by default in the component).
|
|
512
|
+
|
|
513
|
+
## Best Practices
|
|
514
|
+
|
|
515
|
+
1. **File URLs**: Ensure all audio file URLs are accessible and use HTTPS for security
|
|
516
|
+
2. **File Formats**: Use widely supported audio formats (MP3, OGG, WAV) for maximum browser compatibility
|
|
517
|
+
3. **File Names**: Provide clear, descriptive names in the `name` property for better user experience
|
|
518
|
+
4. **File Size**: Keep audio files small for quick preview loading (notification sounds should typically be under 5 seconds)
|
|
519
|
+
5. **Error Handling**: Audio playback errors are logged to the console but not shown to users; consider adding custom error handling for production use
|
|
520
|
+
6. **Performance**: The component stops audio when disconnected, preventing memory leaks
|
|
521
|
+
7. **Accessibility**: Always provide a meaningful `label` attribute for screen reader users
|
|
522
|
+
|
|
523
|
+
## Browser Compatibility
|
|
524
|
+
|
|
525
|
+
The audio select component requires:
|
|
526
|
+
- Modern browser with Web Components support
|
|
527
|
+
- HTML5 Audio API support
|
|
528
|
+
- All browsers supported by the base Zinc component library
|
|
529
|
+
|
|
530
|
+
## Related Components
|
|
531
|
+
|
|
532
|
+
- [Select](/components/select) - The underlying select component
|
|
533
|
+
- [Checkbox](/components/checkbox) - Used for the play/pause button
|
|
534
|
+
- [Option](/components/option) - Used for dropdown options
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
meta:
|
|
3
3
|
title: Bulk Actions
|
|
4
|
-
description:
|
|
4
|
+
description: A dynamic form builder component that allows users to create multiple field-value pairs for bulk operations. Supports various input types including text, select options, numbers, dates, and booleans.
|
|
5
5
|
layout: component
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -15,12 +15,86 @@ layout: component
|
|
|
15
15
|
|
|
16
16
|
## Examples
|
|
17
17
|
|
|
18
|
-
###
|
|
18
|
+
### Basic Usage with Options
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Create a bulk actions component with predefined dropdown options for each action.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
```html:preview
|
|
23
|
+
<zn-bulk-actions
|
|
24
|
+
actions="[{"id":"status","name":"status","options":{"open":"Open","in_progress":"In Progress","closed":"Closed"}},{"id":"assignee","name":"assignee","options":{"john":"John Doe","jane":"Jane Smith","bob":"Bob Johnson"}}]"
|
|
25
|
+
name="ticket-actions">
|
|
26
|
+
</zn-bulk-actions>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Text Input Fields
|
|
30
|
+
|
|
31
|
+
Use text input fields for free-form data entry by omitting the `options` property.
|
|
32
|
+
|
|
33
|
+
```html:preview
|
|
34
|
+
<zn-bulk-actions
|
|
35
|
+
actions="[{"id":"tag","name":"tag"},{"id":"note","name":"note"},{"id":"reference","name":"reference"}]"
|
|
36
|
+
name="text-actions">
|
|
37
|
+
</zn-bulk-actions>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Number Input Fields
|
|
41
|
+
|
|
42
|
+
Use the `type: "number"` property to create number input fields.
|
|
43
|
+
|
|
44
|
+
```html:preview
|
|
45
|
+
<zn-bulk-actions
|
|
46
|
+
actions="[{"id":"quantity","name":"quantity","type":"number"},{"id":"price","name":"price","type":"number"},{"id":"discount","name":"discount","type":"number"}]"
|
|
47
|
+
name="number-actions">
|
|
48
|
+
</zn-bulk-actions>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Date Input Fields
|
|
52
|
+
|
|
53
|
+
Use the `type: "date"` property to create date picker fields.
|
|
54
|
+
|
|
55
|
+
```html:preview
|
|
56
|
+
<zn-bulk-actions
|
|
57
|
+
actions="[{"id":"start_date","name":"start date","type":"date"},{"id":"end_date","name":"end date","type":"date"},{"id":"due_date","name":"due date","type":"date"}]"
|
|
58
|
+
name="date-actions">
|
|
59
|
+
</zn-bulk-actions>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Boolean Input Fields
|
|
63
|
+
|
|
64
|
+
Use the `type: "bool"` or `type: "boolean"` property to create true/false dropdown fields.
|
|
65
|
+
|
|
66
|
+
```html:preview
|
|
67
|
+
<zn-bulk-actions
|
|
68
|
+
actions="[{"id":"active","name":"active","type":"bool"},{"id":"featured","name":"featured","type":"boolean"},{"id":"visible","name":"visible","type":"bool"}]"
|
|
69
|
+
name="boolean-actions">
|
|
70
|
+
</zn-bulk-actions>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Mixed Input Types
|
|
74
|
+
|
|
75
|
+
Combine different input types in a single bulk actions component.
|
|
23
76
|
|
|
24
|
-
|
|
77
|
+
```html:preview
|
|
78
|
+
<zn-bulk-actions
|
|
79
|
+
actions="[{"id":"category","name":"category","options":{"bug":"Bug","feature":"Feature","improvement":"Improvement"}},{"id":"effort","name":"effort (hours)","type":"number"},{"id":"blocked","name":"blocked","type":"bool"},{"id":"deadline","name":"deadline","type":"date"},{"id":"description","name":"description"}]"
|
|
80
|
+
name="mixed-actions">
|
|
81
|
+
</zn-bulk-actions>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### In a Form Context
|
|
85
|
+
|
|
86
|
+
Use bulk actions within a form to collect structured data for submission.
|
|
87
|
+
|
|
88
|
+
```html:preview
|
|
89
|
+
<form>
|
|
90
|
+
<h3>Update Multiple Items</h3>
|
|
91
|
+
<zn-bulk-actions
|
|
92
|
+
actions="[{"id":"priority","name":"priority","options":{"low":"Low","medium":"Medium","high":"High","critical":"Critical"}},{"id":"department","name":"department","options":{"eng":"Engineering","sales":"Sales","support":"Support"}}]"
|
|
93
|
+
name="bulk-update">
|
|
94
|
+
</zn-bulk-actions>
|
|
95
|
+
<br />
|
|
96
|
+
<zn-button type="submit" color="success">Apply Changes</zn-button>
|
|
97
|
+
</form>
|
|
98
|
+
```
|
|
25
99
|
|
|
26
100
|
|