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
@@ -10,22 +10,20 @@
10
10
  label = '',
11
11
  icon,
12
12
  element = $bindable(),
13
+ actionElement = $bindable(),
13
14
  ariaLabelRemove = 'Remove',
15
+ onclick,
14
16
  onremove,
15
17
  name,
16
18
  value,
17
19
  ...attributes
18
20
  }: InputChipProps = $props()
19
-
20
- let chipLabel: HTMLDivElement | undefined = $state()
21
21
  </script>
22
22
 
23
23
  <div
24
24
  {...attributes}
25
25
  bind:this={element}
26
- tabindex={disabled ? -1 : 0}
27
26
  aria-disabled={disabled}
28
- role="button"
29
27
  class={[
30
28
  'np-input-chip',
31
29
  icon ? 'np-input-chip-icon' : '',
@@ -34,17 +32,24 @@
34
32
  attributes.class,
35
33
  ]}
36
34
  >
37
- <div bind:this={chipLabel} class={['np-input-chip-label']}>
35
+ <button
36
+ bind:this={actionElement}
37
+ type="button"
38
+ class="np-input-chip-label"
39
+ aria-pressed={selected === undefined ? undefined : selected}
40
+ {disabled}
41
+ {onclick}
42
+ >
38
43
  {#if icon}
39
44
  <div class="np-chip-icon">
40
45
  {@render icon()}
41
46
  </div>
42
47
  {/if}
43
48
  <div class="np-chip-label">{label || value}</div>
44
- <input type="hidden" {value} {name} {disabled} />
45
- </div>
49
+ </button>
50
+ <input type="hidden" {value} {name} {disabled} />
46
51
  {#if !disabled}
47
- <Ripple forElement={chipLabel} />
52
+ <Ripple forElement={actionElement} />
48
53
  {/if}
49
54
  <IconButton
50
55
  {disabled}
@@ -71,12 +76,14 @@
71
76
  padding-inline-end: 1px;
72
77
  min-width: 0;
73
78
  }
74
- .np-input-chip-label input {
75
- opacity: 0;
76
- position: absolute;
77
- pointer-events: none;
78
- }
79
79
  .np-input-chip-label {
80
+ appearance: none;
81
+ background: none;
82
+ border-width: 0;
83
+ font: inherit;
84
+ margin: 0;
85
+ padding-block: 0;
86
+ padding-inline-end: 0;
80
87
  cursor: pointer;
81
88
  display: inline-flex;
82
89
  align-items: center;
@@ -88,6 +95,12 @@
88
95
  z-index: 1;
89
96
  padding-inline-start: 0.75rem;
90
97
  overflow: hidden;
98
+ min-width: 0;
99
+ }
100
+ /* The chip container draws the focus ring, so the body keeps none of its own.
101
+ `outline-width: 0` would not do, the UA ring is `outline-style: auto`. */
102
+ .np-input-chip-label:focus-visible {
103
+ outline: none;
91
104
  }
92
105
  .np-chip-icon {
93
106
  color: var(--np-color-on-surface-variant);
@@ -133,7 +146,7 @@
133
146
  .np-input-chip-selected .np-input-chip-label {
134
147
  color: var(--np-color-on-secondary-container);
135
148
  }
136
- .np-input-chip:focus-visible {
149
+ .np-input-chip:has(:focus-visible) {
137
150
  outline-style: solid;
138
151
  outline-color: var(--np-color-secondary);
139
152
  outline-width: 3px;
@@ -157,24 +170,12 @@
157
170
  color: var(--np-color-on-surface);
158
171
  opacity: 0.38;
159
172
  }
160
- .np-input-chip-disabled.np-input-chip-selected::before {
161
- opacity: 0.12;
162
- }
163
- .np-input-chip-disabled:not(.np-input-chip-selected).np-input-chip::after {
164
- content: '';
165
- position: absolute;
166
- inset: 0;
167
- border-radius: inherit;
168
- pointer-events: none;
169
- border-width: 1px;
170
- border-style: solid;
171
- border-color: var(--np-color-on-surface);
172
- opacity: 0.12;
173
- }
174
- .np-input-chip-disabled::before {
175
- opacity: 0.12;
173
+ .np-input-chip-disabled:not(.np-input-chip-selected)::before {
174
+ outline-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
175
+ background-color: transparent;
176
176
  }
177
177
  .np-input-chip-selected.np-input-chip-disabled::before {
178
- background-color: var(--np-color-on-surface);
178
+ outline-color: transparent;
179
+ background-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
179
180
  }
180
181
  </style>
@@ -1,4 +1,4 @@
1
1
  import type { InputChipProps } from './types.ts';
2
- declare const InputChip: import("svelte").Component<InputChipProps, {}, "element" | "selected">;
2
+ declare const InputChip: import("svelte").Component<InputChipProps, {}, "element" | "selected" | "actionElement">;
3
3
  type InputChip = ReturnType<typeof InputChip>;
4
4
  export default InputChip;
@@ -26,15 +26,17 @@ export interface FilterChipProps extends HTMLAttributes<HTMLDivElement> {
26
26
  defaultSelected?: boolean | null;
27
27
  onremove?: MouseEventHandler<ButtonElement>;
28
28
  }
29
- export interface InputChipProps extends HTMLAttributes<HTMLDivElement> {
29
+ export interface InputChipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onclick'> {
30
30
  selected?: boolean;
31
31
  disabled?: boolean;
32
32
  label?: string;
33
33
  icon?: Snippet;
34
34
  ariaLabelRemove?: string;
35
35
  element?: HTMLDivElement;
36
+ actionElement?: HTMLButtonElement;
36
37
  name?: string;
37
38
  value?: string | number;
39
+ onclick?: MouseEventHandler<HTMLButtonElement>;
38
40
  onremove?: MouseEventHandler<ButtonElement>;
39
41
  }
40
42
  export interface ChipSetContext {
@@ -11,11 +11,16 @@
11
11
  supportingText,
12
12
  actions,
13
13
  divider,
14
+ ontoggle,
14
15
  ...attributes
15
16
  }: DialogProps = $props()
16
17
 
17
18
  const uid = $props.id()
18
19
 
20
+ let dialogEl: HTMLDivElement | undefined = $state()
21
+ let previouslyFocused: HTMLElement | undefined
22
+ let inerted: HTMLElement[] = []
23
+
19
24
  export function showPopover() {
20
25
  element?.showPopover()
21
26
  }
@@ -23,12 +28,43 @@
23
28
  export function hidePopover() {
24
29
  element?.hidePopover()
25
30
  }
31
+
32
+ const trapFocus = () => {
33
+ if (!element) return
34
+ previouslyFocused = document.activeElement as HTMLElement | undefined
35
+ for (let node: HTMLElement | null = element; node && node !== document.body;) {
36
+ const parent: HTMLElement | null = node.parentElement
37
+ if (!parent) break
38
+ for (const sibling of parent.children) {
39
+ if (sibling === node || !(sibling instanceof HTMLElement) || sibling.inert) continue
40
+ sibling.inert = true
41
+ inerted.push(sibling)
42
+ }
43
+ node = parent
44
+ }
45
+ dialogEl?.focus()
46
+ }
47
+
48
+ const releaseFocus = () => {
49
+ for (const node of inerted) node.inert = false
50
+ inerted = []
51
+ previouslyFocused?.focus?.()
52
+ previouslyFocused = undefined
53
+ }
26
54
  </script>
27
55
 
28
56
  <div
29
57
  bind:this={element}
30
58
  popover="auto"
31
59
  {...attributes}
60
+ ontoggle={(event) => {
61
+ if (event.newState === 'open') {
62
+ trapFocus()
63
+ } else {
64
+ releaseFocus()
65
+ }
66
+ ontoggle?.(event)
67
+ }}
32
68
  class={['np-dialog-container', !quick && 'np-animate', attributes.class]}
33
69
  >
34
70
  <div
@@ -39,24 +75,28 @@
39
75
  }}
40
76
  ></div>
41
77
  <div
78
+ bind:this={dialogEl}
42
79
  class="np-dialog"
43
80
  role="dialog"
81
+ tabindex="-1"
44
82
  aria-modal="true"
45
- aria-labelledby="{uid}-dialog-headline"
46
- aria-describedby={supportingText ? '{uid}-dialog-supporting-text' : undefined}
83
+ aria-labelledby={headline ? `${uid}-dialog-headline` : undefined}
84
+ aria-describedby={supportingText ? `${uid}-dialog-supporting-text` : undefined}
47
85
  >
48
86
  {#if icon}
49
87
  <div class="np-dialog-icon">
50
88
  {@render icon()}
51
89
  </div>
52
90
  {/if}
53
- <h1
54
- id="{uid}-dialog-headline"
55
- class="np-dialog-headline"
56
- style={icon ? 'text-align: center' : ''}
57
- >
58
- {headline}
59
- </h1>
91
+ {#if headline}
92
+ <h1
93
+ id="{uid}-dialog-headline"
94
+ class="np-dialog-headline"
95
+ style={icon ? 'text-align: center' : ''}
96
+ >
97
+ {headline}
98
+ </h1>
99
+ {/if}
60
100
  {#if supportingText}
61
101
  <p id="{uid}-dialog-supporting-text" class="np-dialog-supporting-text">{supportingText}</p>
62
102
  {/if}
@@ -126,7 +166,10 @@
126
166
  inset: 0;
127
167
  position: fixed;
128
168
  background-color: var(--np-color-scrim);
129
- opacity: 0.38;
169
+ opacity: 0.32;
170
+ }
171
+ .np-dialog:focus-visible {
172
+ outline: none;
130
173
  }
131
174
 
132
175
  .np-dialog-icon {
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export * from './progress/index.js';
14
14
  export * from './radio/index.js';
15
15
  export * from './ripple/index.js';
16
16
  export * from './select/index.js';
17
+ export * from './slider/index.js';
17
18
  export * from './snackbar/index.js';
18
19
  export * from './switch/index.js';
19
20
  export * from './tabs/index.js';
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export * from './progress/index.js';
14
14
  export * from './radio/index.js';
15
15
  export * from './ripple/index.js';
16
16
  export * from './select/index.js';
17
+ export * from './slider/index.js';
17
18
  export * from './snackbar/index.js';
18
19
  export * from './switch/index.js';
19
20
  export * from './tabs/index.js';
@@ -1,7 +1,15 @@
1
+ const focusable = (items) => items.filter((item) => !item.matches(':disabled'));
2
+ const focusedItem = (node, itemSelector, items) => {
3
+ const active = document.activeElement;
4
+ if (!(active instanceof HTMLElement) || !node.contains(active))
5
+ return null;
6
+ const item = active.closest(itemSelector);
7
+ return item && items.includes(item) ? item : null;
8
+ };
1
9
  export const rovingTabindex = (itemSelector, options = {}) => {
2
10
  const { currentAttr = 'aria-current', currentValue = 'page' } = options;
3
11
  return (node) => {
4
- const getItems = () => Array.from(node.querySelectorAll(itemSelector));
12
+ const getItems = () => focusable(Array.from(node.querySelectorAll(itemSelector)));
5
13
  const setTabstop = (target) => {
6
14
  for (const i of getItems()) {
7
15
  const wanted = i === target ? 0 : -1;
@@ -13,7 +21,7 @@ export const rovingTabindex = (itemSelector, options = {}) => {
13
21
  const items = getItems();
14
22
  if (items.length === 0)
15
23
  return;
16
- const focused = node.querySelector(`${itemSelector}:focus`);
24
+ const focused = focusedItem(node, itemSelector, items);
17
25
  const current = items.find((i) => i.getAttribute(currentAttr) === currentValue);
18
26
  setTabstop(focused ?? current ?? items[0]);
19
27
  };
@@ -45,10 +53,10 @@ export const arrowKeyNav = (itemSelector, orientation = 'vertical') => (event) =
45
53
  const { key } = event;
46
54
  if (key !== prev && key !== next && key !== 'Home' && key !== 'End')
47
55
  return;
48
- const items = Array.from(event.currentTarget.querySelectorAll(itemSelector));
56
+ const items = focusable(Array.from(event.currentTarget.querySelectorAll(itemSelector)));
49
57
  if (items.length === 0)
50
58
  return;
51
- const focused = event.currentTarget.querySelector(`${itemSelector}:focus`);
59
+ const focused = focusedItem(event.currentTarget, itemSelector, items);
52
60
  if (!focused)
53
61
  return;
54
62
  const currentIndex = items.indexOf(focused);
@@ -1,6 +1,5 @@
1
1
  <script lang="ts">
2
2
  import Ripple from '../ripple/Ripple.svelte'
3
- import { onMount } from 'svelte'
4
3
  import type { ItemProps } from './types.ts'
5
4
 
6
5
  let {
@@ -10,37 +9,11 @@
10
9
  children,
11
10
  supportingText,
12
11
  disabled = false,
13
- onfocus,
14
- onblur,
15
12
  softFocus = false,
16
13
  lazy = false,
14
+ variant,
17
15
  ...attributes
18
16
  }: ItemProps = $props()
19
-
20
- let focused = $derived(softFocus)
21
- let visible = $derived(!lazy)
22
- let element: HTMLButtonElement | HTMLAnchorElement | HTMLDivElement | undefined = $state()
23
- let observer: IntersectionObserver | undefined
24
- onMount(() => {
25
- if (!lazy) {
26
- return
27
- }
28
- observer = new IntersectionObserver((entries) => {
29
- entries.forEach((entry) => {
30
- if (entry.isIntersecting) {
31
- visible = true
32
- observer?.disconnect()
33
- }
34
- })
35
- })
36
-
37
- return () => observer?.disconnect()
38
- })
39
- $effect(() => {
40
- if (element && lazy) {
41
- observer?.observe(element)
42
- }
43
- })
44
17
  </script>
45
18
 
46
19
  {#snippet content()}
@@ -70,53 +43,36 @@
70
43
  {/snippet}
71
44
 
72
45
  {#if disabled}
73
- <div bind:this={element} aria-disabled="true" class={['np-item disabled', attributes.class]}>
74
- {#if visible}
75
- {@render content()}
76
- {/if}
46
+ <div
47
+ {...attributes}
48
+ aria-disabled="true"
49
+ class={['np-item disabled', lazy && 'np-item-lazy', attributes.class]}
50
+ >
51
+ {@render content()}
77
52
  </div>
78
- {:else if attributes.variant === 'text' || attributes.variant === undefined}
79
- <div {...attributes} class={['np-item', selected && 'selected', attributes.class]}>
53
+ {:else if variant === 'text' || variant === undefined}
54
+ <div
55
+ {...attributes}
56
+ class={['np-item', selected && 'selected', lazy && 'np-item-lazy', attributes.class]}
57
+ >
80
58
  {@render content()}
81
59
  </div>
82
- {:else if attributes.variant === 'button'}
60
+ {:else if variant === 'button'}
83
61
  <button
84
62
  {...attributes}
85
63
  type={attributes.type ?? 'button'}
86
- onfocus={(event) => {
87
- focused = true
88
- onfocus?.(event)
89
- }}
90
- onblur={(event) => {
91
- focused = false
92
- onblur?.(event)
93
- }}
94
- class={['np-item', selected && 'selected', attributes.class]}
95
- bind:this={element}
64
+ class={['np-item', selected && 'selected', lazy && 'np-item-lazy', attributes.class]}
96
65
  >
97
- {#if visible}
98
- {@render content()}
99
- <Ripple forceHover={focused} />
100
- {/if}
66
+ {@render content()}
67
+ <Ripple forceHover={softFocus} />
101
68
  </button>
102
- {:else if attributes.variant === 'link'}
69
+ {:else if variant === 'link'}
103
70
  <a
104
71
  {...attributes}
105
- onfocus={(event) => {
106
- focused = true
107
- onfocus?.(event)
108
- }}
109
- onblur={(event) => {
110
- focused = false
111
- onblur?.(event)
112
- }}
113
- class={['np-item', selected && 'selected', attributes.class]}
114
- bind:this={element}
72
+ class={['np-item', selected && 'selected', lazy && 'np-item-lazy', attributes.class]}
115
73
  >
116
- {#if visible}
117
- {@render content()}
118
- <Ripple forceHover={focused} />
119
- {/if}
74
+ {@render content()}
75
+ <Ripple forceHover={softFocus} />
120
76
  </a>
121
77
  {/if}
122
78
 
@@ -161,9 +117,9 @@
161
117
  text-align: start;
162
118
  overflow: hidden;
163
119
  width: 100%;
164
- padding-block: 0.75rem;
120
+ padding-block: 0.625rem;
165
121
  padding-inline: 1rem;
166
- min-height: 3rem;
122
+ min-height: var(--np-item-container-height, 3.5rem);
167
123
  gap: 0.75rem;
168
124
  text-decoration: none;
169
125
  -webkit-tap-highlight-color: transparent;
@@ -171,6 +127,23 @@
171
127
  box-sizing: border-box;
172
128
  }
173
129
 
130
+ .np-item:has(.np-item-supporting-text) {
131
+ min-height: var(--np-item-container-height, 4.5rem);
132
+ }
133
+
134
+ .np-item-lazy {
135
+ content-visibility: auto;
136
+ contain-intrinsic-block-size: auto var(--np-item-container-height, 3.5rem);
137
+ }
138
+
139
+ .np-item-lazy:has(.np-item-supporting-text) {
140
+ contain-intrinsic-block-size: auto var(--np-item-container-height, 4.5rem);
141
+ }
142
+
143
+ .np-item:focus-visible :global(.np-ripple-surface)::before {
144
+ opacity: var(--np-ripple-focus-opacity, 0.1);
145
+ }
146
+
174
147
  .np-item:focus-visible {
175
148
  outline-style: solid;
176
149
  outline-color: var(--np-color-secondary);
@@ -1,7 +1,12 @@
1
1
  <script lang="ts">
2
+ import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.js'
2
3
  import type { MenuProps } from './types.ts'
3
4
  import { on } from 'svelte/events'
4
5
 
6
+ const MENU_ITEM_SELECTOR = '[role="menuitem"]'
7
+ const attach = rovingTabindex(MENU_ITEM_SELECTOR)
8
+ const arrowHandler = arrowKeyNav(MENU_ITEM_SELECTOR)
9
+
5
10
  let {
6
11
  children,
7
12
  element = $bindable(),
@@ -101,8 +106,12 @@
101
106
  {popover}
102
107
  class={['np-menu-container', attributes.class]}
103
108
  {style}
109
+ onkeydown={(event) => {
110
+ attributes.onkeydown?.(event)
111
+ if (!event.defaultPrevented) arrowHandler(event)
112
+ }}
104
113
  >
105
- <div class="np-menu">
114
+ <div {@attach attach} class="np-menu" role="none">
106
115
  {@render children()}
107
116
  </div>
108
117
  </div>
@@ -5,13 +5,13 @@
5
5
  let { ...attributes }: MenuItemProps = $props()
6
6
  </script>
7
7
 
8
- <li class="np-menu-item" role="menuitem">
8
+ <div class="np-menu-item" role="none">
9
9
  {#if 'href' in attributes}
10
- <Item {...attributes} variant="link" />
10
+ <Item role="menuitem" {...attributes} variant="link" />
11
11
  {:else}
12
- <Item {...attributes} variant="button" />
12
+ <Item role="menuitem" {...attributes} variant="button" />
13
13
  {/if}
14
- </li>
14
+ </div>
15
15
 
16
16
  <style>
17
17
  .np-menu-item {
@@ -9,6 +9,7 @@
9
9
  popover,
10
10
  children,
11
11
  onkeydown: userKeydown,
12
+ ontoggle,
12
13
  ...attributes
13
14
  }: NavigationDrawerProps = $props()
14
15
 
@@ -19,6 +20,32 @@
19
20
  userKeydown?.(event)
20
21
  if (!event.defaultPrevented) arrowHandler(event)
21
22
  }
23
+
24
+ let previouslyFocused: HTMLElement | undefined
25
+ let inerted: HTMLElement[] = []
26
+
27
+ const trapFocus = () => {
28
+ if (!element) return
29
+ previouslyFocused = document.activeElement as HTMLElement | undefined
30
+ for (let node: HTMLElement | null = element; node && node !== document.body;) {
31
+ const parent: HTMLElement | null = node.parentElement
32
+ if (!parent) break
33
+ for (const sibling of parent.children) {
34
+ if (sibling === node || !(sibling instanceof HTMLElement) || sibling.inert) continue
35
+ sibling.inert = true
36
+ inerted.push(sibling)
37
+ }
38
+ node = parent
39
+ }
40
+ element.querySelector<HTMLElement>('.np-navigation-drawer-item')?.focus()
41
+ }
42
+
43
+ const releaseFocus = () => {
44
+ for (const node of inerted) node.inert = false
45
+ inerted = []
46
+ previouslyFocused?.focus?.()
47
+ previouslyFocused = undefined
48
+ }
22
49
  </script>
23
50
 
24
51
  <nav
@@ -36,6 +63,13 @@
36
63
  attributes.class,
37
64
  ]}
38
65
  onkeydown={handleKeydown}
66
+ ontoggle={(event) => {
67
+ if (modal) {
68
+ if (event.newState === 'open') trapFocus()
69
+ else releaseFocus()
70
+ }
71
+ ontoggle?.(event)
72
+ }}
39
73
  >
40
74
  {#if backdrop}
41
75
  <div
@@ -108,7 +142,7 @@
108
142
  transition: opacity 0.25s ease;
109
143
  }
110
144
  .np-navigation-drawer-backdrop[popover]:popover-open .np-backdrop {
111
- opacity: 0.38;
145
+ opacity: 0.32;
112
146
  @starting-style {
113
147
  opacity: 0;
114
148
  }
@@ -89,7 +89,7 @@
89
89
  font-size: 0.75rem;
90
90
  line-height: 1rem;
91
91
  font-weight: var(--np-navigation-rail-item-font-weight, 500);
92
- transition: all;
92
+ transition: color var(--np-motion-expressive-default-effects);
93
93
  color: var(--np-color-on-surface-variant);
94
94
  }
95
95
  .np-navigation-action-selected .np-navigation-action-icon {
@@ -117,7 +117,7 @@
117
117
 
118
118
  .np-navigation-action-selected .np-navigation-action-label {
119
119
  font-weight: var(--np-navigation-rail-item-selected-font-weight, 500);
120
- color: var(--np-color-secondary);
120
+ color: var(--np-color-on-surface);
121
121
  }
122
122
  .np-touch {
123
123
  height: 56px;