@kubex/zinc 1.0.17 → 1.0.19
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/dist/custom-elements.json +308 -6
- package/dist/vscode.html-custom-data.json +43 -2
- package/dist/web-types.json +88 -5
- package/dist/zn.d.ts +69 -4
- package/dist/zn.min.js +568 -530
- package/docs/pages/components/select.md +23 -2
- package/package.json +1 -1
- package/src/components/audio-select/audio-select.component.ts +128 -0
- package/src/components/audio-select/audio-select.scss +4 -0
- package/src/components/audio-select/audio-select.test.ts +10 -0
- package/src/components/audio-select/index.ts +12 -0
- package/src/components/checkbox/checkbox.component.ts +53 -4
- package/src/components/checkbox/checkbox.scss +145 -11
- package/src/components/data-table/data-table.component.ts +35 -9
- package/src/components/select/select.component.ts +81 -53
- package/src/components/select/select.scss +21 -0
- package/src/components/style/style.component.ts +1 -1
- package/src/zinc.ts +1 -0
|
@@ -41,7 +41,6 @@ on [form controls](/getting-started/form-controls) to learn more about form subm
|
|
|
41
41
|
|
|
42
42
|
### Distinct Selects
|
|
43
43
|
|
|
44
|
-
|
|
45
44
|
```html:preview
|
|
46
45
|
|
|
47
46
|
<div class="form-spacing">
|
|
@@ -60,7 +59,6 @@ on [form controls](/getting-started/form-controls) to learn more about form subm
|
|
|
60
59
|
|
|
61
60
|
### Conditional Selects
|
|
62
61
|
|
|
63
|
-
|
|
64
62
|
```html:preview
|
|
65
63
|
|
|
66
64
|
<div class="form-spacing">
|
|
@@ -423,6 +421,29 @@ so that we can consider whether the pattern needs to be updated.
|
|
|
423
421
|
</zn-select>
|
|
424
422
|
```
|
|
425
423
|
|
|
424
|
+
### Checkbox Prefix
|
|
425
|
+
|
|
426
|
+
You can place a checkbox in the `prefix` slot to visually join it to the select. The checkbox will match the height of
|
|
427
|
+
the control and can be interacted with independently (clicking or toggling it won’t open the select).
|
|
428
|
+
|
|
429
|
+
```html:preview
|
|
430
|
+
<zn-select label="Notify me about" help-text="Use the checkbox to enable/disable notifications; choose a channel with the select">
|
|
431
|
+
<zn-checkbox slot="prefix" aria-label="Enable notifications"></zn-checkbox>
|
|
432
|
+
<zn-option value="email">Email</zn-option>
|
|
433
|
+
<zn-option value="sms">SMS</zn-option>
|
|
434
|
+
<zn-option value="push">Push</zn-option>
|
|
435
|
+
</zn-select>
|
|
436
|
+
|
|
437
|
+
<br />
|
|
438
|
+
|
|
439
|
+
<zn-select label="Large with checkbox" size="large" value="email">
|
|
440
|
+
<zn-checkbox slot="prefix" size="large" aria-label="Enable notifications"></zn-checkbox>
|
|
441
|
+
<zn-option value="email">Email</zn-option>
|
|
442
|
+
<zn-option value="sms">SMS</zn-option>
|
|
443
|
+
<zn-option value="push">Push</zn-option>
|
|
444
|
+
</zn-select>
|
|
445
|
+
```
|
|
446
|
+
|
|
426
447
|
### Custom Tags
|
|
427
448
|
|
|
428
449
|
When multiple options can be selected, you can provide custom tags by passing a function to the `getTag` property. Your
|
package/package.json
CHANGED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
2
|
+
import {property, state} from "lit/decorators.js";
|
|
3
|
+
import ZincElement from '../../internal/zinc-element';
|
|
4
|
+
import type {ZnChangeEvent} from "../../events/zn-change";
|
|
5
|
+
|
|
6
|
+
import styles from './audio-select.scss';
|
|
7
|
+
|
|
8
|
+
interface AudioFile {
|
|
9
|
+
name: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @summary Short summary of the component's intended use.
|
|
15
|
+
* @documentation https://zinc.style/components/audio-select
|
|
16
|
+
* @status experimental
|
|
17
|
+
* @since 1.0
|
|
18
|
+
*
|
|
19
|
+
* @slot - The default slot.
|
|
20
|
+
* @slot actions - The actions slot.
|
|
21
|
+
* @slot footer - The footer slot.
|
|
22
|
+
*
|
|
23
|
+
* @csspart base - The component's base wrapper.
|
|
24
|
+
*
|
|
25
|
+
* @cssproperty --example - An example CSS custom property.
|
|
26
|
+
*/
|
|
27
|
+
export default class ZnAudioSelect extends ZincElement {
|
|
28
|
+
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
29
|
+
|
|
30
|
+
private _selectedUrl: string = '';
|
|
31
|
+
@state() private _isPlaying: boolean = false;
|
|
32
|
+
private readonly _audio: HTMLAudioElement;
|
|
33
|
+
|
|
34
|
+
@property() label = '';
|
|
35
|
+
@property() placeholder = '';
|
|
36
|
+
@property({type: Object}) files: AudioFile[];
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
this._audio = new Audio();
|
|
41
|
+
|
|
42
|
+
// Handle audio ending naturally
|
|
43
|
+
this._audio.addEventListener('ended', () => {
|
|
44
|
+
this._isPlaying = false;
|
|
45
|
+
// Reset to start so pressing play again restarts the audio
|
|
46
|
+
this._audio.currentTime = 0;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
disconnectedCallback() {
|
|
51
|
+
super.disconnectedCallback();
|
|
52
|
+
this._stopAudio();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_stopAudio() {
|
|
56
|
+
if (this._audio) {
|
|
57
|
+
this._audio.pause();
|
|
58
|
+
this._audio.currentTime = 0;
|
|
59
|
+
}
|
|
60
|
+
this._isPlaying = false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
handleSelectChange(e: ZnChangeEvent) {
|
|
64
|
+
if (e.target !== e.currentTarget) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const url = (e.target as HTMLSelectElement).value;
|
|
69
|
+
this._selectedUrl = url;
|
|
70
|
+
|
|
71
|
+
this._stopAudio();
|
|
72
|
+
|
|
73
|
+
if (url) {
|
|
74
|
+
this._audio.src = url;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
togglePreview(e: CustomEvent) {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
|
|
81
|
+
if (!this._selectedUrl) {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
this._isPlaying = false;
|
|
84
|
+
this.requestUpdate();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (this._isPlaying) {
|
|
89
|
+
this._audio.pause();
|
|
90
|
+
this._isPlaying = false;
|
|
91
|
+
} else {
|
|
92
|
+
this._audio.play()
|
|
93
|
+
.then(() => {
|
|
94
|
+
this._isPlaying = true;
|
|
95
|
+
})
|
|
96
|
+
.catch(err => {
|
|
97
|
+
console.error("Audio playback failed:", err);
|
|
98
|
+
this._isPlaying = false;
|
|
99
|
+
this.requestUpdate();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
render() {
|
|
105
|
+
return html`
|
|
106
|
+
<div class="container">
|
|
107
|
+
<div class="select-wrapper">
|
|
108
|
+
<zn-select label="${this.label}" @zn-change="${this.handleSelectChange}">
|
|
109
|
+
<zn-checkbox
|
|
110
|
+
slot="prefix"
|
|
111
|
+
checked-icon="pause"
|
|
112
|
+
unchecked-icon="play_arrow"
|
|
113
|
+
checked-color="primary"
|
|
114
|
+
unchecked-color="secondary"
|
|
115
|
+
?checked="${this._isPlaying}"
|
|
116
|
+
@zn-change="${this.togglePreview}">
|
|
117
|
+
</zn-checkbox>
|
|
118
|
+
|
|
119
|
+
<zn-option value="" disabled selected>${this.placeholder || 'Select audio'}</zn-option>
|
|
120
|
+
${this.files.map(file => html`
|
|
121
|
+
<zn-option value="${file.url}">${file.name}</zn-option>
|
|
122
|
+
`)}
|
|
123
|
+
</zn-select>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import '../../../dist/zn.min.js';
|
|
2
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
|
3
|
+
|
|
4
|
+
describe('<zn-audio-select>', () => {
|
|
5
|
+
it('should render a component', async () => {
|
|
6
|
+
const el = await fixture(html` <zn-audio-select></zn-audio-select> `);
|
|
7
|
+
|
|
8
|
+
expect(el).to.exist;
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ZnAudioSelect from './audio-select.component';
|
|
2
|
+
|
|
3
|
+
export * from './audio-select.component';
|
|
4
|
+
export default ZnAudioSelect;
|
|
5
|
+
|
|
6
|
+
ZnAudioSelect.define('zn-audio-select');
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'zn-audio-select': ZnAudioSelect;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -7,12 +7,14 @@ import {ifDefined} from "lit/directives/if-defined.js";
|
|
|
7
7
|
import {live} from "lit/directives/live.js";
|
|
8
8
|
import {property, query, state} from 'lit/decorators.js';
|
|
9
9
|
import {watch} from '../../internal/watch';
|
|
10
|
-
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
11
10
|
import ZincElement from '../../internal/zinc-element';
|
|
12
11
|
import ZnIcon from "../icon";
|
|
12
|
+
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
13
13
|
|
|
14
14
|
import styles from './checkbox.scss';
|
|
15
15
|
|
|
16
|
+
type ColorOption = 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' | 'transparent';
|
|
17
|
+
|
|
16
18
|
/**
|
|
17
19
|
* @summary Short summary of the component's intended use.
|
|
18
20
|
* @documentation https://zinc.style/components/checkbox
|
|
@@ -23,7 +25,7 @@ import styles from './checkbox.scss';
|
|
|
23
25
|
*
|
|
24
26
|
* @slot - The checkbox's label.
|
|
25
27
|
* @slot description - A description of the checkbox's label. Serves as help text for a checkbox item. Alternatively, you can use the `description` attribute.
|
|
26
|
-
*
|
|
28
|
+
* @slot selected-content - Use to nest rich content (like an input) inside a selected checkbox item. Use only with the contained style.
|
|
27
29
|
*
|
|
28
30
|
* @event zn-blur - Emitted when the checkbox loses focus.
|
|
29
31
|
* @event zn-change - Emitted when the checked state changes.
|
|
@@ -36,6 +38,7 @@ import styles from './checkbox.scss';
|
|
|
36
38
|
* @csspart control--checked - Matches the control part when the checkbox is checked.
|
|
37
39
|
* @csspart control--indeterminate - Matches the control part when the checkbox is indeterminate.
|
|
38
40
|
* @csspart checked-icon - The checked icon, an `<zn-icon>` element.
|
|
41
|
+
* @csspart unchecked-icon - The unchecked icon, an `<zn-icon>` element.
|
|
39
42
|
* @csspart indeterminate-icon - The indeterminate icon, an `<zn-icon>` element.
|
|
40
43
|
* @csspart label - The container that wraps the checkbox's label.
|
|
41
44
|
* @csspart description - The container that wraps the checkbox's description.
|
|
@@ -105,6 +108,21 @@ export default class ZnCheckbox extends ZincElement implements ZincFormControl {
|
|
|
105
108
|
|
|
106
109
|
@property({attribute: 'label-tooltip'}) labelTooltip: string;
|
|
107
110
|
|
|
111
|
+
/** The icon to show when the checkbox is checked. */
|
|
112
|
+
@property({attribute: 'checked-icon'}) checkedIcon = '';
|
|
113
|
+
|
|
114
|
+
/** The icon to show when the checkbox is unchecked. */
|
|
115
|
+
@property({attribute: 'unchecked-icon'}) uncheckedIcon = '';
|
|
116
|
+
|
|
117
|
+
/** The color of the checkbox. */
|
|
118
|
+
@property({reflect: true}) color: ColorOption = 'default';
|
|
119
|
+
|
|
120
|
+
/** The color of the checkbox when checked. Overrides `color`. */
|
|
121
|
+
@property({attribute: 'checked-color'}) checkedColor: ColorOption;
|
|
122
|
+
|
|
123
|
+
/** The color of the checkbox when unchecked. Overrides `color`. */
|
|
124
|
+
@property({attribute: 'unchecked-color'}) uncheckedColor: ColorOption;
|
|
125
|
+
|
|
108
126
|
/** Gets the validity state object */
|
|
109
127
|
get validity() {
|
|
110
128
|
return this.input?.validity;
|
|
@@ -216,6 +234,11 @@ export default class ZnCheckbox extends ZincElement implements ZincFormControl {
|
|
|
216
234
|
const hasLabelTooltip = this.hasSlotController.test('label-tooltip');
|
|
217
235
|
const hasLabel = this.label || hasLabelSlot;
|
|
218
236
|
|
|
237
|
+
// Determine the effective color
|
|
238
|
+
const effectiveColor = (this.checked || this.indeterminate)
|
|
239
|
+
? (this.checkedColor || this.color)
|
|
240
|
+
: (this.uncheckedColor || this.color);
|
|
241
|
+
|
|
219
242
|
//
|
|
220
243
|
// NOTE: we use a <div> around the label slot because of this Chrome bug.
|
|
221
244
|
//
|
|
@@ -262,6 +285,14 @@ export default class ZnCheckbox extends ZincElement implements ZincFormControl {
|
|
|
262
285
|
'checkbox--small': this.size === 'small',
|
|
263
286
|
'checkbox--medium': this.size === 'medium',
|
|
264
287
|
'checkbox--large': this.size === 'large',
|
|
288
|
+
'checkbox--default': effectiveColor === 'default',
|
|
289
|
+
'checkbox--primary': effectiveColor === 'primary',
|
|
290
|
+
'checkbox--secondary': effectiveColor === 'secondary',
|
|
291
|
+
'checkbox--error': effectiveColor === 'error',
|
|
292
|
+
'checkbox--info': effectiveColor === 'info',
|
|
293
|
+
'checkbox--success': effectiveColor === 'success',
|
|
294
|
+
'checkbox--warning': effectiveColor === 'warning',
|
|
295
|
+
'checkbox--transparent': effectiveColor === 'transparent',
|
|
265
296
|
'checkbox--has-description': hasDescription,
|
|
266
297
|
'checkbox--has-selected-content': this.hasSlotController.test('selected-content')
|
|
267
298
|
})}>
|
|
@@ -289,10 +320,28 @@ export default class ZnCheckbox extends ZincElement implements ZincFormControl {
|
|
|
289
320
|
? ' control--indeterminate'
|
|
290
321
|
: ''}"
|
|
291
322
|
class="checkbox__control">
|
|
292
|
-
|
|
323
|
+
|
|
324
|
+
${this.checked && !this.indeterminate
|
|
325
|
+
? this.checkedIcon
|
|
326
|
+
? html`
|
|
327
|
+
<zn-icon part="checked-icon" class="checkbox__icon" src="${this.checkedIcon}"></zn-icon>`
|
|
328
|
+
: html`
|
|
329
|
+
<svg viewBox="0 0 24 24"
|
|
330
|
+
fill="none"
|
|
331
|
+
stroke="currentColor"
|
|
332
|
+
stroke-width="4"
|
|
333
|
+
stroke-linecap="round"
|
|
334
|
+
stroke-linejoin="round"
|
|
335
|
+
class="svg-icon">
|
|
336
|
+
<polyline class="checkbox__checked-icon" points="20 6 9 17 4 12"></polyline>
|
|
337
|
+
</svg>`
|
|
338
|
+
: ''}
|
|
339
|
+
|
|
340
|
+
${!this.checked && !this.indeterminate && this.uncheckedIcon
|
|
293
341
|
? html`
|
|
294
|
-
<zn-icon part="
|
|
342
|
+
<zn-icon part="unchecked-icon" class="checkbox__icon" src="${this.uncheckedIcon}"></zn-icon>`
|
|
295
343
|
: ''}
|
|
344
|
+
|
|
296
345
|
${!this.checked && this.indeterminate
|
|
297
346
|
? html`
|
|
298
347
|
<zn-icon
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
.form-control {
|
|
9
9
|
display: flex;
|
|
10
10
|
flex-direction: column;
|
|
11
|
+
height: 100%;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
.form-control .form-control__label {
|
|
@@ -23,6 +24,61 @@
|
|
|
23
24
|
color: var(--zn-input-label-color);
|
|
24
25
|
vertical-align: middle;
|
|
25
26
|
cursor: pointer;
|
|
27
|
+
height: 100%;
|
|
28
|
+
|
|
29
|
+
--checkbox-color: var(--zn-color-primary-600);
|
|
30
|
+
--checkbox-color-hover: var(--zn-color-primary-500);
|
|
31
|
+
--checkbox-icon-color: var(--zn-color-neutral-0);
|
|
32
|
+
--checkbox-border-color: var(--zn-input-border-color);
|
|
33
|
+
--checkbox-bg-color: var(--zn-input-background-color);
|
|
34
|
+
|
|
35
|
+
&.checkbox--default {
|
|
36
|
+
--checkbox-color: var(--zn-color-primary-600);
|
|
37
|
+
--checkbox-color-hover: var(--zn-color-primary-500);
|
|
38
|
+
--checkbox-border-color: var(--zn-input-border-color);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.checkbox--primary {
|
|
42
|
+
--checkbox-color: var(--zn-color-primary-600);
|
|
43
|
+
--checkbox-color-hover: var(--zn-color-primary-500);
|
|
44
|
+
--checkbox-border-color: var(--zn-color-primary-600);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&.checkbox--secondary {
|
|
48
|
+
--checkbox-color: var(--zn-color-neutral-600);
|
|
49
|
+
--checkbox-color-hover: var(--zn-color-neutral-500);
|
|
50
|
+
--checkbox-border-color: var(--zn-color-neutral-300);
|
|
51
|
+
--checkbox-bg-color: var(--zn-color-neutral-50);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.checkbox--info {
|
|
55
|
+
--checkbox-color: var(--zn-color-info-600);
|
|
56
|
+
--checkbox-color-hover: var(--zn-color-info-500);
|
|
57
|
+
--checkbox-border-color: var(--zn-color-info-600);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&.checkbox--success {
|
|
61
|
+
--checkbox-color: var(--zn-color-success-600);
|
|
62
|
+
--checkbox-color-hover: var(--zn-color-success-500);
|
|
63
|
+
--checkbox-border-color: var(--zn-color-success-600);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&.checkbox--warning {
|
|
67
|
+
--checkbox-color: var(--zn-color-warning-600);
|
|
68
|
+
--checkbox-color-hover: var(--zn-color-warning-500);
|
|
69
|
+
--checkbox-border-color: var(--zn-color-warning-600);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&.checkbox--error {
|
|
73
|
+
--checkbox-color: var(--zn-color-danger-600);
|
|
74
|
+
--checkbox-color-hover: var(--zn-color-danger-500);
|
|
75
|
+
--checkbox-border-color: var(--zn-color-danger-600);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&.checkbox--transparent {
|
|
79
|
+
--checkbox-bg-color: transparent;
|
|
80
|
+
--checkbox-border-color: transparent;
|
|
81
|
+
}
|
|
26
82
|
}
|
|
27
83
|
|
|
28
84
|
.checkbox--small {
|
|
@@ -58,10 +114,10 @@
|
|
|
58
114
|
width: var(--toggle-size);
|
|
59
115
|
height: var(--toggle-size);
|
|
60
116
|
box-shadow: var(--zn-shadow-x-small);
|
|
61
|
-
border: solid var(--zn-input-border-width) var(--
|
|
117
|
+
border: solid var(--zn-input-border-width) var(--checkbox-border-color);
|
|
118
|
+
background-color: var(--checkbox-bg-color);
|
|
62
119
|
border-radius: 2px;
|
|
63
|
-
|
|
64
|
-
color: var(--zn-color-neutral-0);
|
|
120
|
+
color: var(--checkbox-icon-color);
|
|
65
121
|
transition: var(--zn-transition-fast) border-color,
|
|
66
122
|
var(--zn-transition-fast) background-color,
|
|
67
123
|
var(--zn-transition-fast) color,
|
|
@@ -76,25 +132,50 @@
|
|
|
76
132
|
pointer-events: none;
|
|
77
133
|
}
|
|
78
134
|
|
|
79
|
-
.checkbox__checked-icon,
|
|
80
135
|
.checkbox__indeterminate-icon {
|
|
81
136
|
--icon-size: var(--toggle-size);
|
|
82
|
-
--icon-color: var(--
|
|
137
|
+
--icon-color: var(--checkbox-icon-color);
|
|
83
138
|
|
|
84
139
|
display: inline-flex;
|
|
85
140
|
width: var(--toggle-size);
|
|
86
141
|
height: var(--toggle-size);
|
|
87
142
|
}
|
|
88
143
|
|
|
144
|
+
.svg-icon {
|
|
145
|
+
width: max(16px, 70%);
|
|
146
|
+
height: max(16px, 70%);
|
|
147
|
+
--icon-color: var(--checkbox-icon-color);
|
|
148
|
+
|
|
149
|
+
.checkbox__checked-icon {
|
|
150
|
+
stroke-dasharray: 24;
|
|
151
|
+
stroke-dashoffset: 24;
|
|
152
|
+
transition: stroke-dashoffset 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.checkbox--indeterminate .svg-icon {
|
|
157
|
+
color: transparent;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.checkbox--checked {
|
|
161
|
+
.svg-icon {
|
|
162
|
+
color: var(--checkbox-icon-color);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.checkbox__checked-icon {
|
|
166
|
+
stroke-dashoffset: 0;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
89
170
|
/* Hover */
|
|
90
171
|
.checkbox:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover {
|
|
91
|
-
border-color: var(--zn-input-border-color-hover);
|
|
172
|
+
border-color: var(--checkbox-color-hover, var(--zn-input-border-color-hover));
|
|
92
173
|
background-color: var(--zn-input-background-color-hover);
|
|
93
174
|
}
|
|
94
175
|
|
|
95
176
|
/* Focus */
|
|
96
177
|
.checkbox:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__input:focus-visible ~ .checkbox__control {
|
|
97
|
-
border-color: var(--
|
|
178
|
+
border-color: var(--checkbox-color);
|
|
98
179
|
outline: var(--zn-focus-ring);
|
|
99
180
|
outline-offset: var(--zn-focus-ring-offset);
|
|
100
181
|
}
|
|
@@ -102,15 +183,16 @@
|
|
|
102
183
|
/* Checked/indeterminate */
|
|
103
184
|
.checkbox--checked .checkbox__control,
|
|
104
185
|
.checkbox--indeterminate .checkbox__control {
|
|
105
|
-
border-color: var(--
|
|
106
|
-
background-color: var(--
|
|
186
|
+
border-color: var(--checkbox-color);
|
|
187
|
+
background-color: var(--checkbox-color);
|
|
188
|
+
color: var(--checkbox-icon-color);
|
|
107
189
|
}
|
|
108
190
|
|
|
109
191
|
/* Checked/indeterminate + hover */
|
|
110
192
|
.checkbox.checkbox--checked:not(.checkbox--disabled) .checkbox__control:hover,
|
|
111
193
|
.checkbox.checkbox--indeterminate:not(.checkbox--disabled) .checkbox__control:hover {
|
|
112
|
-
border-color: var(--
|
|
113
|
-
background-color: var(--
|
|
194
|
+
border-color: var(--checkbox-color-hover);
|
|
195
|
+
background-color: var(--checkbox-color-hover);
|
|
114
196
|
}
|
|
115
197
|
|
|
116
198
|
/* Checked/indeterminate + focus */
|
|
@@ -200,3 +282,55 @@
|
|
|
200
282
|
outline: 1px solid var(--zn-color-purple-600);
|
|
201
283
|
transition: var(--zn-transition-medium) all;
|
|
202
284
|
}
|
|
285
|
+
|
|
286
|
+
/** Select prefix slot */
|
|
287
|
+
:host([slot="prefix"]) {
|
|
288
|
+
height: 100%;
|
|
289
|
+
aspect-ratio: 1;
|
|
290
|
+
|
|
291
|
+
.checkbox__control {
|
|
292
|
+
height: 100%;
|
|
293
|
+
width: 100%;
|
|
294
|
+
border-left: unset;
|
|
295
|
+
border-top: unset;
|
|
296
|
+
border-bottom: unset;
|
|
297
|
+
box-shadow: unset;
|
|
298
|
+
background-color: var(--zn-color-purple-50);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.checkbox--primary .checkbox__control,
|
|
302
|
+
.checkbox--success .checkbox__control,
|
|
303
|
+
.checkbox--warning .checkbox__control,
|
|
304
|
+
.checkbox--error .checkbox__control,
|
|
305
|
+
.checkbox--info .checkbox__control {
|
|
306
|
+
background-color: var(--checkbox-color);
|
|
307
|
+
color: var(--zn-color-neutral-0);
|
|
308
|
+
border-color: var(--checkbox-color);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.checkbox--primary:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover,
|
|
312
|
+
.checkbox--success:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover,
|
|
313
|
+
.checkbox--warning:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover,
|
|
314
|
+
.checkbox--error:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover,
|
|
315
|
+
.checkbox--info:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover {
|
|
316
|
+
background-color: var(--checkbox-color-hover);
|
|
317
|
+
border-color: var(--checkbox-color-hover);
|
|
318
|
+
color: var(--zn-color-neutral-0);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.checkbox--secondary .checkbox__control {
|
|
322
|
+
background-color: var(--zn-color-neutral-200);
|
|
323
|
+
color: var(--zn-color-neutral-700);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.checkbox--secondary:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover {
|
|
327
|
+
background-color: var(--zn-color-neutral-300);
|
|
328
|
+
border-color: var(--zn-color-neutral-300);
|
|
329
|
+
color: var(--zn-color-neutral-800);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.checkbox--checked .checkbox__control {
|
|
333
|
+
background-color: var(--checkbox-color);
|
|
334
|
+
color: var(--zn-color-neutral-0);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -417,21 +417,47 @@ export default class ZnDataTable extends ZincElement {
|
|
|
417
417
|
|
|
418
418
|
// add groups to the current rows
|
|
419
419
|
const toAdd = this.groups.split(',').map(g => g.trim()).filter(g => g.length > 0);
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
|
|
421
|
+
const hasWildcard = toAdd.includes('*');
|
|
422
|
+
const explicitGroups = new Set(
|
|
423
|
+
toAdd
|
|
424
|
+
.filter(g => g !== '*')
|
|
425
|
+
.map(g => this.humanize(g))
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
// pre-create explicit groups
|
|
429
|
+
explicitGroups.forEach((group) => {
|
|
430
|
+
if (!groupedRows[group]) {
|
|
431
|
+
groupedRows[group] = [];
|
|
423
432
|
}
|
|
424
433
|
});
|
|
425
434
|
|
|
435
|
+
// pre-create wildcard grouping if requested
|
|
436
|
+
if (hasWildcard) {
|
|
437
|
+
groupedRows['*'] = [];
|
|
438
|
+
}
|
|
439
|
+
|
|
426
440
|
this._rows.forEach((row: Row) => {
|
|
427
441
|
const groupCell = row.cells.find((cell: Cell) => cell.column === this.groupBy);
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
442
|
+
const rawGroupValue = groupCell ? groupCell.text : 'Ungrouped';
|
|
443
|
+
const groupValue = this.humanize(rawGroupValue);
|
|
444
|
+
|
|
445
|
+
if (explicitGroups.has(groupValue)) {
|
|
446
|
+
groupedRows[groupValue].push(row);
|
|
447
|
+
return;
|
|
431
448
|
}
|
|
432
449
|
|
|
433
|
-
if (
|
|
434
|
-
groupedRows[
|
|
450
|
+
if (hasWildcard) {
|
|
451
|
+
groupedRows['*'].push(row);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// If no groups specified, or handling ungrouped fallback, create groups dynamically
|
|
456
|
+
if (!this.groups || groupValue === 'Ungrouped') {
|
|
457
|
+
if (!groupedRows[groupValue]) {
|
|
458
|
+
groupedRows[groupValue] = [];
|
|
459
|
+
}
|
|
460
|
+
groupedRows[groupValue].push(row);
|
|
435
461
|
}
|
|
436
462
|
});
|
|
437
463
|
|
|
@@ -447,7 +473,7 @@ export default class ZnDataTable extends ZincElement {
|
|
|
447
473
|
<zn-sp flush>
|
|
448
474
|
${Object.keys(groupedRows).map((groupKey) => html`
|
|
449
475
|
<div class="table-group">
|
|
450
|
-
<h3 class="table-group__title">${groupKey === "Ungrouped" ? "" : groupKey}</h3>
|
|
476
|
+
<h3 class="table-group__title">${(groupKey === "Ungrouped" || groupKey === "*") ? "" : groupKey}</h3>
|
|
451
477
|
${this.renderTableData(groupedRows[groupKey])}
|
|
452
478
|
</div>`
|
|
453
479
|
)}
|