noph-ui 0.34.3 → 0.35.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.
Files changed (44) hide show
  1. package/dist/badge/Badge.svelte +4 -2
  2. package/dist/badge/Badge.svelte.d.ts +1 -0
  3. package/dist/button/Button.svelte +3 -5
  4. package/dist/button/IconButton.svelte +7 -7
  5. package/dist/button/SegmentedButton.svelte +22 -25
  6. package/dist/card/Card.svelte +11 -35
  7. package/dist/checkbox/Checkbox.svelte +68 -32
  8. package/dist/checkbox/types.d.ts +1 -0
  9. package/dist/chip/ChipSet.svelte +10 -2
  10. package/dist/chip/FilterChip.svelte +48 -52
  11. package/dist/chip/InputChip.svelte +32 -31
  12. package/dist/chip/InputChip.svelte.d.ts +1 -1
  13. package/dist/chip/types.d.ts +3 -1
  14. package/dist/dialog/Dialog.svelte +53 -10
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +1 -0
  17. package/dist/keyboard-nav.js +12 -4
  18. package/dist/list/Item.svelte +39 -66
  19. package/dist/menu/Menu.svelte +10 -1
  20. package/dist/menu/MenuItem.svelte +4 -4
  21. package/dist/navigation-drawer/NavigationDrawer.svelte +35 -1
  22. package/dist/navigation-rail/NavigationRailItem.svelte +2 -2
  23. package/dist/progress/CircularProgress.svelte +214 -117
  24. package/dist/progress/LinearProgress.svelte +382 -102
  25. package/dist/progress/types.d.ts +2 -0
  26. package/dist/ripple/Ripple.svelte +6 -7
  27. package/dist/select/Select.svelte +41 -20
  28. package/dist/slider/Slider.svelte +555 -0
  29. package/dist/slider/Slider.svelte.d.ts +4 -0
  30. package/dist/slider/index.d.ts +1 -0
  31. package/dist/slider/index.js +1 -0
  32. package/dist/slider/types.d.ts +23 -0
  33. package/dist/slider/types.js +1 -0
  34. package/dist/snackbar/Snackbar.svelte +21 -10
  35. package/dist/switch/Switch.svelte +1 -1
  36. package/dist/tabs/Tab.svelte +18 -16
  37. package/dist/tabs/Tabs.svelte +4 -2
  38. package/dist/tabs/types.d.ts +2 -0
  39. package/dist/text-field/TextField.svelte +3 -1
  40. package/dist/themes/defaultTheme.css +3 -9
  41. package/dist/tooltip/Tooltip.svelte +53 -10
  42. package/dist/types.d.ts +1 -0
  43. package/dist/types.js +1 -0
  44. package/package.json +11 -11
@@ -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="true"
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',
@@ -1,5 +1,6 @@
1
1
  type $$ComponentProps = {
2
2
  label?: string | number;
3
+ ariaLabel?: string;
3
4
  };
4
5
  declare const Badge: import("svelte").Component<$$ComponentProps, {}, "">;
5
6
  type Badge = ReturnType<typeof Badge>;
@@ -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
- :global(.np-button .button-icon svg) {
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 : undefined}
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 forceHover={i === hoverState} />
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={typeof option.label === 'function' ? `${name}-${i}` : option.label}
59
- value={option.label}
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={typeof option.label === 'function' ? `${name}-${i}` : option.label}
74
- value={option.label}
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={option.label ?? `${name}-${i}`}
89
- value={option.label}
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 2rem;
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.5;
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 1rem;
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-buttons:has(input:focus-visible) {
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: 2px;
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
  }
@@ -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 forceHover={focused} />
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) 32%, transparent);
166
- --background-color: none;
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
- $effect(() => {
16
- if (group && value) {
17
- checked = group.includes(value)
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
- $effect(() => {
22
- if (value && group) {
23
- const index = group.indexOf(value)
24
- if (checked) {
25
- if (index < 0) {
26
- group?.push(value)
27
- group = 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
- let inputEl: HTMLInputElement | undefined = $state()
35
+ checked = next
36
+ attributes.onchange?.(event)
37
+ }
38
38
  </script>
39
39
 
40
- <div {style} class={['np-container', attributes.class]} bind:this={element}>
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
- <input
52
- {...attributes}
53
- {value}
54
- class="np-input"
55
- type="checkbox"
56
- bind:indeterminate
57
- bind:checked
58
- bind:this={inputEl}
59
- aria-checked={indeterminate ? 'mixed' : undefined}
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;
@@ -2,4 +2,5 @@ import type { HTMLInputAttributes } from 'svelte/elements';
2
2
  export interface CheckboxProps extends Omit<HTMLInputAttributes, 'type'> {
3
3
  element?: HTMLElement;
4
4
  group?: (string | number)[] | null;
5
+ error?: boolean;
5
6
  }
@@ -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-right: 0;
37
+ margin-inline-end: 0;
30
38
  }
31
39
  .np-chip-set {
32
40
  display: flex;
@@ -23,28 +23,23 @@
23
23
  }: FilterChipProps = $props()
24
24
 
25
25
  let chipLabel: HTMLLabelElement | undefined = $state()
26
- let pressed = $state(false)
27
26
 
28
- const handlePointerDown = () => {
29
- if (disabled) return
30
- pressed = true
31
- }
32
-
33
- const handlePointerUp = () => {
34
- pressed = false
35
- }
27
+ let grouped = $derived(Array.isArray(group) && value !== undefined)
28
+ let groupChecked = $derived(
29
+ Array.isArray(group) && value !== undefined ? group.includes(value) : false,
30
+ )
36
31
 
37
- $effect(() => {
38
- if (!group || !value) return
39
- const included = group.includes(value)
40
- if (selected && !included) {
41
- group = [...group, value]
42
- } else if (!selected && included) {
43
- group = group.filter((v) => v !== value)
44
- } else if (included !== selected) {
45
- selected = included
32
+ const onchange = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
33
+ const next = event.currentTarget.checked
34
+ if (Array.isArray(group) && value !== undefined) {
35
+ group = next
36
+ ? group.includes(value)
37
+ ? group
38
+ : [...group, value]
39
+ : group.filter((entry) => entry !== value)
46
40
  }
47
- })
41
+ selected = next
42
+ }
48
43
  </script>
49
44
 
50
45
  <div
@@ -56,17 +51,10 @@
56
51
  icon ? 'np-filter-chip-icon' : '',
57
52
  removable ? 'np-filter-chip-removable' : '',
58
53
  disabled ? 'np-filter-chip-disabled' : '',
59
- pressed && 'np-filter-chip-pressed',
60
54
  attributes.class,
61
55
  ]}
62
56
  >
63
- <label
64
- bind:this={chipLabel}
65
- class="np-filter-chip-label"
66
- onpointerdown={handlePointerDown}
67
- onpointerup={handlePointerUp}
68
- onpointerleave={handlePointerUp}
69
- >
57
+ <label bind:this={chipLabel} class="np-filter-chip-label">
70
58
  {#if icon}
71
59
  <div class="np-chip-icon">
72
60
  {@render icon()}
@@ -76,14 +64,26 @@
76
64
  <CheckIcon width={18} height={18} />
77
65
  </div>
78
66
  <div class="np-chip-label">{label}</div>
79
- <input
80
- type="checkbox"
81
- bind:checked={selected}
82
- {value}
83
- {name}
84
- {disabled}
85
- defaultChecked={defaultSelected}
86
- />
67
+ {#if grouped}
68
+ <input
69
+ type="checkbox"
70
+ checked={groupChecked}
71
+ {onchange}
72
+ {value}
73
+ {name}
74
+ {disabled}
75
+ defaultChecked={defaultSelected}
76
+ />
77
+ {:else}
78
+ <input
79
+ type="checkbox"
80
+ bind:checked={selected}
81
+ {value}
82
+ {name}
83
+ {disabled}
84
+ defaultChecked={defaultSelected}
85
+ />
86
+ {/if}
87
87
  </label>
88
88
  {#if !disabled}
89
89
  <Ripple forElement={chipLabel} />
@@ -155,7 +155,7 @@
155
155
  display: none;
156
156
  }
157
157
  .np-chip-icon {
158
- color: var(--np-color-primary);
158
+ color: var(--np-color-on-surface-variant);
159
159
  display: flex;
160
160
  }
161
161
 
@@ -215,10 +215,12 @@
215
215
  box-shadow: var(--np-elevation-1);
216
216
  }
217
217
  }
218
- .np-filter-chip-elevated:not(.np-filter-chip-disabled).np-filter-chip-pressed {
218
+ .np-filter-chip-elevated:not(.np-filter-chip-disabled):has(.np-filter-chip-label:active) {
219
219
  box-shadow: var(--np-elevation-1);
220
220
  }
221
- .np-filter-chip-default:not(.np-filter-chip-disabled):has(input:checked).np-filter-chip-pressed {
221
+ .np-filter-chip-default:not(.np-filter-chip-disabled):has(
222
+ .np-filter-chip-label:active input:checked
223
+ ) {
222
224
  box-shadow: none;
223
225
  }
224
226
  .np-filter-chip:has(input:checked) {
@@ -257,20 +259,14 @@
257
259
  .np-filter-chip-disabled.np-filter-chip-elevated {
258
260
  box-shadow: none;
259
261
  }
260
- .np-filter-chip-disabled:has(input:not(:checked)).np-filter-chip-default::after {
261
- content: '';
262
- position: absolute;
263
- inset: 0;
264
- border-radius: inherit;
265
- pointer-events: none;
266
- border-width: 1px;
267
- border-style: solid;
268
- border-color: var(--np-color-on-surface);
269
- opacity: 0.12;
262
+ .np-filter-chip-disabled.np-filter-chip-default:has(input:not(:checked))::before {
263
+ outline-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
264
+ background-color: transparent;
270
265
  }
271
- .np-filter-chip-disabled::before {
272
- background-color: var(--np-color-on-surface) !important;
273
- opacity: 0.12;
274
- border-width: 0;
266
+
267
+ .np-filter-chip-disabled.np-filter-chip-elevated::before,
268
+ .np-filter-chip-disabled:has(input:checked)::before {
269
+ outline-color: transparent;
270
+ background-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
275
271
  }
276
272
  </style>