noph-ui 0.34.4 → 0.36.1
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 +13 -13
- package/dist/badge/Badge.svelte +4 -2
- package/dist/badge/Badge.svelte.d.ts +1 -0
- package/dist/button/Button.svelte +3 -5
- package/dist/button/IconButton.svelte +7 -7
- package/dist/button/SegmentedButton.svelte +22 -25
- package/dist/card/Card.svelte +11 -35
- package/dist/checkbox/Checkbox.svelte +68 -32
- package/dist/checkbox/types.d.ts +1 -0
- package/dist/chip/ChipSet.svelte +10 -2
- package/dist/chip/FilterChip.svelte +48 -52
- package/dist/chip/InputChip.svelte +32 -31
- package/dist/chip/InputChip.svelte.d.ts +1 -1
- package/dist/chip/types.d.ts +3 -1
- package/dist/dialog/Dialog.svelte +53 -10
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/keyboard-nav.js +12 -4
- package/dist/list/Item.svelte +39 -66
- package/dist/loading-indicator/LoadingIndicator.svelte +135 -0
- package/dist/loading-indicator/LoadingIndicator.svelte.d.ts +4 -0
- package/dist/loading-indicator/index.d.ts +1 -0
- package/dist/loading-indicator/index.js +1 -0
- package/dist/loading-indicator/shapes.d.ts +6 -0
- package/dist/loading-indicator/shapes.js +49 -0
- package/dist/loading-indicator/types.d.ts +7 -0
- package/dist/loading-indicator/types.js +1 -0
- package/dist/menu/Menu.svelte +10 -1
- package/dist/menu/MenuItem.svelte +4 -4
- package/dist/navigation-drawer/NavigationDrawer.svelte +35 -1
- package/dist/navigation-drawer/NavigationDrawerItem.svelte +1 -1
- package/dist/navigation-rail/NavigationRailItem.svelte +2 -2
- package/dist/progress/CircularProgress.svelte +214 -117
- package/dist/progress/LinearProgress.svelte +402 -102
- package/dist/progress/types.d.ts +2 -0
- package/dist/ripple/Ripple.svelte +6 -7
- package/dist/select/Option.svelte +0 -1
- package/dist/select/Select.svelte +41 -20
- package/dist/slider/Slider.svelte +623 -0
- package/dist/slider/Slider.svelte.d.ts +4 -0
- package/dist/slider/index.d.ts +1 -0
- package/dist/slider/index.js +1 -0
- package/dist/slider/types.d.ts +23 -0
- package/dist/slider/types.js +1 -0
- package/dist/snackbar/Snackbar.svelte +21 -10
- package/dist/switch/Switch.svelte +1 -1
- package/dist/tabs/Tab.svelte +18 -16
- package/dist/tabs/Tabs.svelte +4 -2
- package/dist/tabs/types.d.ts +2 -0
- package/dist/text-field/TextField.svelte +2 -0
- package/dist/themes/defaultTheme.css +3 -9
- package/dist/tooltip/Tooltip.svelte +53 -10
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -52,30 +52,30 @@ body {
|
|
|
52
52
|
|
|
53
53
|
## Roadmap
|
|
54
54
|
|
|
55
|
-
Beta
|
|
55
|
+
Beta
|
|
56
56
|
|
|
57
|
+
- Auto complete
|
|
58
|
+
- Badges
|
|
57
59
|
- Buttons
|
|
58
60
|
- Cards
|
|
59
61
|
- Checkbox
|
|
62
|
+
- Chips
|
|
63
|
+
- Dialogs
|
|
60
64
|
- Divider
|
|
61
65
|
- Icon buttons
|
|
62
|
-
- Lists
|
|
66
|
+
- Lists
|
|
67
|
+
- Loading indicator
|
|
68
|
+
- Menus
|
|
69
|
+
- Navigation Drawer
|
|
70
|
+
- Navigation Rail
|
|
63
71
|
- Progress indicators
|
|
64
72
|
- Radio
|
|
65
73
|
- Ripple
|
|
66
74
|
- Segmented buttons
|
|
67
75
|
- Select
|
|
76
|
+
- Slider
|
|
68
77
|
- Snackbar
|
|
69
78
|
- Switch
|
|
70
|
-
- Text fields
|
|
71
79
|
- Tabs
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Auto complete
|
|
76
|
-
- Chips (Docs missing)
|
|
77
|
-
- Dialogs (Fullscreen + Docs missing)
|
|
78
|
-
- Menus (Positioning missing + Docs missing)
|
|
79
|
-
- Navigation Drawer (Docs missing)
|
|
80
|
-
- Navigation Rail (Badge is missing + Docs missing)
|
|
81
|
-
- Tooltips (Positioning missing)
|
|
80
|
+
- Text fields
|
|
81
|
+
- Tooltips
|
package/dist/badge/Badge.svelte
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
let { label }: { label?: string | number } = $props()
|
|
2
|
+
let { label, ariaLabel }: { label?: string | number; ariaLabel?: string } = $props()
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<div
|
|
6
|
-
aria-hidden=
|
|
6
|
+
aria-hidden={ariaLabel ? undefined : 'true'}
|
|
7
|
+
role={ariaLabel ? 'status' : undefined}
|
|
8
|
+
aria-label={ariaLabel}
|
|
7
9
|
class={[
|
|
8
10
|
'np-badge-container',
|
|
9
11
|
label === undefined ? 'np-badge-container-no-label' : 'np-badge-container-label',
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
{/if}
|
|
50
50
|
{#if loading}
|
|
51
51
|
<div class="circular-progress">
|
|
52
|
-
<CircularProgress aria-label={loadingAriaLabel} indeterminate />
|
|
52
|
+
<CircularProgress aria-label={loadingAriaLabel} indeterminate track={false} />
|
|
53
53
|
</div>
|
|
54
54
|
{/if}
|
|
55
55
|
{#if start}
|
|
@@ -417,10 +417,8 @@
|
|
|
417
417
|
:global(.np-button .button-icon svg) {
|
|
418
418
|
fill: currentColor;
|
|
419
419
|
display: block;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
width: calc((var(--button-height) - 0.375rem) / 2);
|
|
423
|
-
height: calc((var(--button-height) - 0.375rem) / 2);
|
|
420
|
+
width: var(--_icon-size);
|
|
421
|
+
height: var(--_icon-size);
|
|
424
422
|
}
|
|
425
423
|
|
|
426
424
|
@media (forced-colors: active) {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
{/if}
|
|
51
51
|
{#if loading}
|
|
52
52
|
<div class="np-icon-button-circular-progress">
|
|
53
|
-
<CircularProgress aria-label={loadingAriaLabel} indeterminate />
|
|
53
|
+
<CircularProgress aria-label={loadingAriaLabel} indeterminate track={false} />
|
|
54
54
|
</div>
|
|
55
55
|
{/if}
|
|
56
56
|
{#if selectedIcon && selected}
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
}
|
|
70
70
|
attributes.onclick?.(event)
|
|
71
71
|
}}
|
|
72
|
-
aria-describedby={title ? uid :
|
|
73
|
-
aria-label={title}
|
|
72
|
+
aria-describedby={title ? uid : attributes['aria-describedby']}
|
|
73
|
+
aria-label={title || attributes['aria-label']}
|
|
74
74
|
bind:this={element}
|
|
75
75
|
class={[
|
|
76
76
|
'np-icon-button',
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
border-radius: 1.25rem;
|
|
185
185
|
}
|
|
186
186
|
.s.square {
|
|
187
|
-
border-radius: var(--np-button-shape, 0.75rem);
|
|
187
|
+
border-radius: var(--np-icon-button-shape, 0.75rem);
|
|
188
188
|
}
|
|
189
189
|
.s.narrow {
|
|
190
190
|
width: 2rem;
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
border-radius: 1.75rem;
|
|
207
207
|
}
|
|
208
208
|
.m.square {
|
|
209
|
-
border-radius: var(--np-button-shape, 1rem);
|
|
209
|
+
border-radius: var(--np-icon-button-shape, 1rem);
|
|
210
210
|
}
|
|
211
211
|
.m.narrow {
|
|
212
212
|
width: 3rem;
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
border-radius: 3rem;
|
|
229
229
|
}
|
|
230
230
|
.l.square {
|
|
231
|
-
border-radius: var(--np-button-shape, 1.75rem);
|
|
231
|
+
border-radius: var(--np-icon-button-shape, 1.75rem);
|
|
232
232
|
}
|
|
233
233
|
.l.narrow {
|
|
234
234
|
width: 4rem;
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
border-radius: 4.25rem;
|
|
251
251
|
}
|
|
252
252
|
.xl.square {
|
|
253
|
-
border-radius: var(--np-button-shape, 1.75rem);
|
|
253
|
+
border-radius: var(--np-icon-button-shape, 1.75rem);
|
|
254
254
|
}
|
|
255
255
|
.xl.narrow {
|
|
256
256
|
width: 6.5rem;
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
group = $bindable(),
|
|
12
12
|
...attributes
|
|
13
13
|
}: SegmentedButtonProps = $props()
|
|
14
|
-
let hoverState = $state(-1)
|
|
15
14
|
</script>
|
|
16
15
|
|
|
17
16
|
<div
|
|
@@ -21,6 +20,7 @@
|
|
|
21
20
|
style="{attributes.style};grid-template-columns: repeat({options.length}, minmax(max-content, 1fr));"
|
|
22
21
|
>
|
|
23
22
|
{#each options as option, i (i)}
|
|
23
|
+
{@const optionLabel = option.label ?? `${name}-${i}`}
|
|
24
24
|
<label class={['np-segmented-button', option.icon && 'width-icon']}>
|
|
25
25
|
<div class="check-icon-wrapper">
|
|
26
26
|
<div class="check-icon">
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
{option.label}
|
|
43
43
|
{/if}
|
|
44
44
|
{#if !option.disabled}
|
|
45
|
-
<Ripple
|
|
45
|
+
<Ripple />
|
|
46
46
|
{/if}
|
|
47
47
|
{#if group !== undefined}
|
|
48
48
|
{#if multiSelect}
|
|
@@ -50,13 +50,9 @@
|
|
|
50
50
|
type="checkbox"
|
|
51
51
|
onclick={option.onclick}
|
|
52
52
|
bind:group
|
|
53
|
-
onfocus={(event) => {
|
|
54
|
-
if (event) hoverState = i
|
|
55
|
-
}}
|
|
56
|
-
onblur={() => (hoverState = -1)}
|
|
57
53
|
{name}
|
|
58
|
-
aria-label={
|
|
59
|
-
value={
|
|
54
|
+
aria-label={optionLabel}
|
|
55
|
+
value={optionLabel}
|
|
60
56
|
disabled={option.disabled}
|
|
61
57
|
checked={option.selected}
|
|
62
58
|
/>
|
|
@@ -65,13 +61,9 @@
|
|
|
65
61
|
type="radio"
|
|
66
62
|
onclick={option.onclick}
|
|
67
63
|
bind:group
|
|
68
|
-
onfocus={(event) => {
|
|
69
|
-
if (event) hoverState = i
|
|
70
|
-
}}
|
|
71
|
-
onblur={() => (hoverState = -1)}
|
|
72
64
|
{name}
|
|
73
|
-
aria-label={
|
|
74
|
-
value={
|
|
65
|
+
aria-label={optionLabel}
|
|
66
|
+
value={optionLabel}
|
|
75
67
|
disabled={option.disabled}
|
|
76
68
|
checked={option.selected}
|
|
77
69
|
/>
|
|
@@ -80,13 +72,9 @@
|
|
|
80
72
|
<input
|
|
81
73
|
type={multiSelect ? 'checkbox' : 'radio'}
|
|
82
74
|
onclick={option.onclick}
|
|
83
|
-
onfocus={(event) => {
|
|
84
|
-
if (event) hoverState = i
|
|
85
|
-
}}
|
|
86
|
-
onblur={() => (hoverState = -1)}
|
|
87
75
|
{name}
|
|
88
|
-
aria-label={
|
|
89
|
-
value={
|
|
76
|
+
aria-label={optionLabel}
|
|
77
|
+
value={optionLabel}
|
|
90
78
|
disabled={option.disabled}
|
|
91
79
|
checked={option.selected}
|
|
92
80
|
/>
|
|
@@ -108,7 +96,7 @@
|
|
|
108
96
|
|
|
109
97
|
.np-segmented-button {
|
|
110
98
|
flex: 1;
|
|
111
|
-
padding: 0.5rem
|
|
99
|
+
padding: 0.5rem 1.75rem;
|
|
112
100
|
text-align: center;
|
|
113
101
|
cursor: pointer;
|
|
114
102
|
font-size: 0.875rem;
|
|
@@ -136,7 +124,7 @@
|
|
|
136
124
|
|
|
137
125
|
.np-segmented-button:has(input:disabled) {
|
|
138
126
|
cursor: unset;
|
|
139
|
-
opacity: 0.
|
|
127
|
+
opacity: 0.38;
|
|
140
128
|
}
|
|
141
129
|
|
|
142
130
|
.np-segmented-button:last-child {
|
|
@@ -159,7 +147,7 @@
|
|
|
159
147
|
}
|
|
160
148
|
.width-icon,
|
|
161
149
|
.np-segmented-button:has(input:checked) {
|
|
162
|
-
padding: 0.5rem
|
|
150
|
+
padding: 0.5rem 0.75rem;
|
|
163
151
|
}
|
|
164
152
|
.np-segmented-button:has(input:checked) {
|
|
165
153
|
color: var(--np-color-on-secondary-container);
|
|
@@ -168,6 +156,7 @@
|
|
|
168
156
|
opacity: 1;
|
|
169
157
|
}
|
|
170
158
|
.check-icon {
|
|
159
|
+
display: flex;
|
|
171
160
|
width: 0;
|
|
172
161
|
overflow: hidden;
|
|
173
162
|
fill: currentColor;
|
|
@@ -182,6 +171,7 @@
|
|
|
182
171
|
transition: width 0.15s linear;
|
|
183
172
|
}
|
|
184
173
|
.alternate-icon {
|
|
174
|
+
display: flex;
|
|
185
175
|
width: 1.5rem;
|
|
186
176
|
overflow: hidden;
|
|
187
177
|
fill: currentColor;
|
|
@@ -213,21 +203,28 @@
|
|
|
213
203
|
width: 1.5rem;
|
|
214
204
|
}
|
|
215
205
|
|
|
216
|
-
.np-segmented-
|
|
206
|
+
.np-segmented-button:has(input:focus-visible) :global(.np-ripple-surface)::before {
|
|
207
|
+
opacity: var(--np-ripple-focus-opacity, 0.1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.np-segmented-button:has(input:focus-visible) {
|
|
217
211
|
outline-style: solid;
|
|
218
212
|
outline-color: var(--np-color-secondary);
|
|
219
213
|
outline-width: 3px;
|
|
220
|
-
outline-offset:
|
|
214
|
+
outline-offset: -3px;
|
|
221
215
|
animation: focusAnimation 0.3s ease forwards;
|
|
222
216
|
}
|
|
223
217
|
@keyframes focusAnimation {
|
|
224
218
|
0% {
|
|
219
|
+
outline-offset: -3px;
|
|
225
220
|
outline-width: 3px;
|
|
226
221
|
}
|
|
227
222
|
50% {
|
|
223
|
+
outline-offset: -6px;
|
|
228
224
|
outline-width: 6px;
|
|
229
225
|
}
|
|
230
226
|
100% {
|
|
227
|
+
outline-offset: -3px;
|
|
231
228
|
outline-width: 3px;
|
|
232
229
|
}
|
|
233
230
|
}
|
package/dist/card/Card.svelte
CHANGED
|
@@ -12,25 +12,9 @@
|
|
|
12
12
|
supportingText,
|
|
13
13
|
action,
|
|
14
14
|
children,
|
|
15
|
-
onfocus,
|
|
16
|
-
onblur,
|
|
17
15
|
type,
|
|
18
16
|
...attributes
|
|
19
17
|
}: CardProps = $props()
|
|
20
|
-
|
|
21
|
-
let focused = $state(false)
|
|
22
|
-
|
|
23
|
-
$effect(() => {
|
|
24
|
-
if (!element) return
|
|
25
|
-
// eslint-disable-next-line no-undef
|
|
26
|
-
const formElements: NodeListOf<
|
|
27
|
-
HTMLButtonElement | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
|
|
28
|
-
> = element.querySelectorAll('input, button, select, textarea')
|
|
29
|
-
|
|
30
|
-
formElements.forEach((el) => {
|
|
31
|
-
el.disabled = disabled
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
18
|
</script>
|
|
35
19
|
|
|
36
20
|
{#snippet content()}
|
|
@@ -61,7 +45,7 @@
|
|
|
61
45
|
{/if}
|
|
62
46
|
</div>
|
|
63
47
|
{#if !disabled && type !== 'text'}
|
|
64
|
-
<Ripple
|
|
48
|
+
<Ripple />
|
|
65
49
|
{/if}
|
|
66
50
|
{/snippet}
|
|
67
51
|
|
|
@@ -85,14 +69,6 @@
|
|
|
85
69
|
{...attributes}
|
|
86
70
|
type="button"
|
|
87
71
|
bind:this={element}
|
|
88
|
-
onfocus={(event) => {
|
|
89
|
-
focused = true
|
|
90
|
-
onfocus?.(event)
|
|
91
|
-
}}
|
|
92
|
-
onblur={(event) => {
|
|
93
|
-
focused = false
|
|
94
|
-
onblur?.(event)
|
|
95
|
-
}}
|
|
96
72
|
{disabled}
|
|
97
73
|
class={[
|
|
98
74
|
'np-card-container',
|
|
@@ -110,14 +86,6 @@
|
|
|
110
86
|
aria-disabled={disabled}
|
|
111
87
|
tabindex={disabled ? -1 : undefined}
|
|
112
88
|
role="link"
|
|
113
|
-
onfocus={(event) => {
|
|
114
|
-
focused = true
|
|
115
|
-
onfocus?.(event)
|
|
116
|
-
}}
|
|
117
|
-
onblur={(event) => {
|
|
118
|
-
focused = false
|
|
119
|
-
onblur?.(event)
|
|
120
|
-
}}
|
|
121
89
|
class={[
|
|
122
90
|
'np-card-container',
|
|
123
91
|
`np-card-${variant}`,
|
|
@@ -162,8 +130,8 @@
|
|
|
162
130
|
--border-radius: var(--np-outlined-card-container-shape, var(--np-shape-corner-medium));
|
|
163
131
|
}
|
|
164
132
|
.np-card-outlined.np-card-disabled {
|
|
165
|
-
border-color: color-mix(in srgb, var(--np-color-outline)
|
|
166
|
-
--background-color:
|
|
133
|
+
border-color: color-mix(in srgb, var(--np-color-outline) 12%, transparent);
|
|
134
|
+
--background-color: transparent;
|
|
167
135
|
}
|
|
168
136
|
.np-card-container {
|
|
169
137
|
font: inherit;
|
|
@@ -181,6 +149,10 @@
|
|
|
181
149
|
cursor: pointer;
|
|
182
150
|
}
|
|
183
151
|
|
|
152
|
+
.np-card-container:focus-visible :global(.np-ripple-surface)::before {
|
|
153
|
+
opacity: var(--np-ripple-focus-opacity, 0.1);
|
|
154
|
+
}
|
|
155
|
+
|
|
184
156
|
.np-card-container:focus-visible {
|
|
185
157
|
outline-style: solid;
|
|
186
158
|
outline-color: var(--np-color-secondary);
|
|
@@ -211,6 +183,10 @@
|
|
|
211
183
|
overflow: hidden;
|
|
212
184
|
background-size: cover;
|
|
213
185
|
background-position: 50%;
|
|
186
|
+
border-start-start-radius: var(--border-radius);
|
|
187
|
+
border-start-end-radius: var(--border-radius);
|
|
188
|
+
}
|
|
189
|
+
.np-card-container:not(:has(.np-card-content:not(:empty))) .np-card-image {
|
|
214
190
|
border-radius: var(--border-radius);
|
|
215
191
|
}
|
|
216
192
|
.np-card-content {
|
|
@@ -7,37 +7,41 @@
|
|
|
7
7
|
checked = $bindable(),
|
|
8
8
|
element = $bindable(),
|
|
9
9
|
group = $bindable(),
|
|
10
|
+
error = false,
|
|
10
11
|
style,
|
|
11
12
|
value,
|
|
12
13
|
...attributes
|
|
13
14
|
}: CheckboxProps = $props()
|
|
14
15
|
|
|
15
|
-
$
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
let inputEl: HTMLInputElement | undefined = $state()
|
|
17
|
+
|
|
18
|
+
let groupValue = $derived(
|
|
19
|
+
typeof value === 'string' || typeof value === 'number' ? value : undefined,
|
|
20
|
+
)
|
|
21
|
+
let grouped = $derived(Array.isArray(group) && groupValue !== undefined)
|
|
22
|
+
let groupChecked = $derived(
|
|
23
|
+
Array.isArray(group) && groupValue !== undefined ? group.includes(groupValue) : false,
|
|
24
|
+
)
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
group
|
|
27
|
-
group
|
|
28
|
-
|
|
29
|
-
} else {
|
|
30
|
-
if (index >= 0) {
|
|
31
|
-
group.splice(index, 1)
|
|
32
|
-
group = group
|
|
33
|
-
}
|
|
34
|
-
}
|
|
26
|
+
const onchange = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
|
27
|
+
const next = event.currentTarget.checked
|
|
28
|
+
if (Array.isArray(group) && groupValue !== undefined) {
|
|
29
|
+
group = next
|
|
30
|
+
? group.includes(groupValue)
|
|
31
|
+
? group
|
|
32
|
+
: [...group, groupValue]
|
|
33
|
+
: group.filter((entry) => entry !== groupValue)
|
|
35
34
|
}
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
checked = next
|
|
36
|
+
attributes.onchange?.(event)
|
|
37
|
+
}
|
|
38
38
|
</script>
|
|
39
39
|
|
|
40
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
{style}
|
|
42
|
+
class={['np-container', error && !attributes.disabled && 'np-error', attributes.class]}
|
|
43
|
+
bind:this={element}
|
|
44
|
+
>
|
|
41
45
|
<div class="np-outline"></div>
|
|
42
46
|
<div class="np-background"></div>
|
|
43
47
|
<svg class="np-icon" viewBox="0 0 18 18" aria-hidden="true">
|
|
@@ -48,16 +52,32 @@
|
|
|
48
52
|
{#if !attributes.disabled}
|
|
49
53
|
<Ripple forElement={inputEl} />
|
|
50
54
|
{/if}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
{#if grouped}
|
|
56
|
+
<input
|
|
57
|
+
{...attributes}
|
|
58
|
+
{value}
|
|
59
|
+
class="np-input"
|
|
60
|
+
type="checkbox"
|
|
61
|
+
bind:indeterminate
|
|
62
|
+
bind:this={inputEl}
|
|
63
|
+
checked={groupChecked}
|
|
64
|
+
{onchange}
|
|
65
|
+
aria-invalid={error ? 'true' : undefined}
|
|
66
|
+
aria-checked={indeterminate ? 'mixed' : undefined}
|
|
67
|
+
/>
|
|
68
|
+
{:else}
|
|
69
|
+
<input
|
|
70
|
+
{...attributes}
|
|
71
|
+
{value}
|
|
72
|
+
class="np-input"
|
|
73
|
+
type="checkbox"
|
|
74
|
+
bind:indeterminate
|
|
75
|
+
bind:checked
|
|
76
|
+
bind:this={inputEl}
|
|
77
|
+
aria-invalid={error ? 'true' : undefined}
|
|
78
|
+
aria-checked={indeterminate ? 'mixed' : undefined}
|
|
79
|
+
/>
|
|
80
|
+
{/if}
|
|
61
81
|
</div>
|
|
62
82
|
</div>
|
|
63
83
|
|
|
@@ -172,6 +192,22 @@
|
|
|
172
192
|
background: var(--np-color-on-surface);
|
|
173
193
|
opacity: 0.38;
|
|
174
194
|
}
|
|
195
|
+
|
|
196
|
+
.np-error .np-outline,
|
|
197
|
+
.np-error:hover .np-outline,
|
|
198
|
+
.np-error:focus-within .np-outline {
|
|
199
|
+
border-color: var(--np-color-error);
|
|
200
|
+
}
|
|
201
|
+
.np-error .np-background {
|
|
202
|
+
background-color: var(--np-color-error);
|
|
203
|
+
}
|
|
204
|
+
.np-error .np-icon {
|
|
205
|
+
fill: var(--np-color-on-error);
|
|
206
|
+
}
|
|
207
|
+
.np-error {
|
|
208
|
+
--np-ripple-hover-color: var(--np-color-error);
|
|
209
|
+
--np-ripple-pressed-color: var(--np-color-error);
|
|
210
|
+
}
|
|
175
211
|
.np-icon {
|
|
176
212
|
fill: var(--np-checkbox-selected-icon-color, var(--np-color-on-primary));
|
|
177
213
|
height: 18px;
|
package/dist/checkbox/types.d.ts
CHANGED
package/dist/chip/ChipSet.svelte
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.js'
|
|
2
3
|
import type { ChipSetProps } from './types.ts'
|
|
3
4
|
|
|
4
5
|
let { children, chipsCount, ...attributes }: ChipSetProps = $props()
|
|
6
|
+
|
|
7
|
+
const CHIP_SELECTOR = "input:not([type='hidden']), button, a[href]"
|
|
8
|
+
const attach = rovingTabindex(CHIP_SELECTOR, {
|
|
9
|
+
currentAttr: 'aria-current',
|
|
10
|
+
currentValue: 'true',
|
|
11
|
+
})
|
|
12
|
+
const onkeydown = arrowKeyNav(CHIP_SELECTOR, 'horizontal')
|
|
5
13
|
</script>
|
|
6
14
|
|
|
7
15
|
<div
|
|
@@ -13,7 +21,7 @@
|
|
|
13
21
|
style={attributes.style}
|
|
14
22
|
>
|
|
15
23
|
{#if children}
|
|
16
|
-
<div class={['np-chip-set']} role="toolbar">
|
|
24
|
+
<div {@attach attach} class={['np-chip-set']} role="toolbar" tabindex="-1" {onkeydown}>
|
|
17
25
|
{@render children()}
|
|
18
26
|
</div>
|
|
19
27
|
{/if}
|
|
@@ -26,7 +34,7 @@
|
|
|
26
34
|
margin: -0.5rem;
|
|
27
35
|
}
|
|
28
36
|
.np-chip-set-has-chips {
|
|
29
|
-
margin-
|
|
37
|
+
margin-inline-end: 0;
|
|
30
38
|
}
|
|
31
39
|
.np-chip-set {
|
|
32
40
|
display: flex;
|