noph-ui 0.44.0 → 0.45.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 (135) hide show
  1. package/README.md +10 -1
  2. package/dist/animation.d.ts +17 -0
  3. package/dist/animation.js +48 -0
  4. package/dist/app-bar/AppBar.svelte +280 -0
  5. package/dist/app-bar/AppBar.svelte.d.ts +4 -0
  6. package/dist/app-bar/index.d.ts +1 -0
  7. package/dist/app-bar/index.js +1 -0
  8. package/dist/app-bar/types.d.ts +35 -0
  9. package/dist/app-bar/types.js +1 -0
  10. package/dist/autocomplete/AutoComplete.svelte +10 -11
  11. package/dist/autocomplete/AutoComplete.svelte.d.ts +1 -1
  12. package/dist/autocomplete/types.d.ts +1 -1
  13. package/dist/badge/Badge.svelte +6 -1
  14. package/dist/badge/types.d.ts +0 -1
  15. package/dist/button/Button.svelte +5 -15
  16. package/dist/button/IconButton.svelte +5 -15
  17. package/dist/button/SegmentedButton.svelte +15 -1
  18. package/dist/button/SplitButton.svelte +92 -0
  19. package/dist/button/SplitButton.svelte.d.ts +4 -0
  20. package/dist/button/index.d.ts +1 -0
  21. package/dist/button/index.js +1 -0
  22. package/dist/button/types.d.ts +23 -4
  23. package/dist/card/types.d.ts +1 -1
  24. package/dist/checkbox/Checkbox.svelte +49 -58
  25. package/dist/chip/AssistChip.svelte +5 -5
  26. package/dist/chip/ChipSet.svelte +3 -11
  27. package/dist/chip/FilterChip.svelte +35 -27
  28. package/dist/chip/InputChip.svelte +13 -2
  29. package/dist/chip/SuggestionChip.svelte +29 -0
  30. package/dist/chip/SuggestionChip.svelte.d.ts +4 -0
  31. package/dist/chip/index.d.ts +1 -0
  32. package/dist/chip/index.js +1 -0
  33. package/dist/chip/types.d.ts +24 -9
  34. package/dist/date-picker/Calendar.svelte +1 -1
  35. package/dist/date-picker/DatePickerDialog.svelte +30 -8
  36. package/dist/date-picker/DatePickerDialog.svelte.d.ts +4 -1
  37. package/dist/date-picker/DateRangePicker.svelte +45 -10
  38. package/dist/date-picker/DateRangePicker.svelte.d.ts +4 -1
  39. package/dist/date-picker/DockedDatePicker.svelte +18 -4
  40. package/dist/date-picker/DockedDatePicker.svelte.d.ts +4 -1
  41. package/dist/date-picker/DockedDateTimePicker.svelte +18 -4
  42. package/dist/date-picker/DockedDateTimePicker.svelte.d.ts +4 -1
  43. package/dist/date-picker/SelectionList.svelte +6 -32
  44. package/dist/date-picker/SelectionList.svelte.d.ts +2 -12
  45. package/dist/date-picker/TimeColumn.svelte +4 -29
  46. package/dist/date-picker/exitVisibility.svelte.d.ts +10 -0
  47. package/dist/date-picker/exitVisibility.svelte.js +30 -0
  48. package/dist/date-picker/optionList.d.ts +16 -0
  49. package/dist/date-picker/optionList.js +43 -0
  50. package/dist/date-picker/types.d.ts +11 -4
  51. package/dist/dialog/Dialog.svelte +77 -68
  52. package/dist/dialog/Dialog.svelte.d.ts +3 -3
  53. package/dist/dialog/types.d.ts +5 -3
  54. package/dist/fab/ExtendedFab.svelte +281 -0
  55. package/dist/fab/ExtendedFab.svelte.d.ts +5 -0
  56. package/dist/fab/Fab.svelte +239 -0
  57. package/dist/fab/Fab.svelte.d.ts +5 -0
  58. package/dist/fab/FabMenu.svelte +255 -0
  59. package/dist/fab/FabMenu.svelte.d.ts +7 -0
  60. package/dist/fab/index.d.ts +3 -0
  61. package/dist/fab/index.js +3 -0
  62. package/dist/fab/types.d.ts +58 -0
  63. package/dist/fab/types.js +1 -0
  64. package/dist/icons/ArrowBackIcon.svelte +13 -0
  65. package/dist/icons/ArrowBackIcon.svelte.d.ts +7 -0
  66. package/dist/icons/ChevronDownIcon.svelte +3 -0
  67. package/dist/icons/ChevronDownIcon.svelte.d.ts +26 -0
  68. package/dist/icons/SearchIcon.svelte +15 -0
  69. package/dist/icons/SearchIcon.svelte.d.ts +7 -0
  70. package/dist/icons/index.d.ts +3 -0
  71. package/dist/icons/index.js +3 -0
  72. package/dist/index.d.ts +6 -0
  73. package/dist/index.js +6 -0
  74. package/dist/internal/focus-ring.css +12 -0
  75. package/dist/menu/Menu.svelte +12 -7
  76. package/dist/menu/Menu.svelte.d.ts +2 -2
  77. package/dist/menu/types.d.ts +0 -2
  78. package/dist/navigation-bar/NavigationBar.svelte +66 -0
  79. package/dist/navigation-bar/NavigationBar.svelte.d.ts +4 -0
  80. package/dist/navigation-bar/NavigationBarItem.svelte +261 -0
  81. package/dist/navigation-bar/NavigationBarItem.svelte.d.ts +5 -0
  82. package/dist/navigation-bar/index.d.ts +2 -0
  83. package/dist/navigation-bar/index.js +2 -0
  84. package/dist/navigation-bar/types.d.ts +29 -0
  85. package/dist/navigation-bar/types.js +1 -0
  86. package/dist/navigation-drawer/NavigationDrawer.svelte +128 -76
  87. package/dist/navigation-drawer/NavigationDrawer.svelte.d.ts +4 -1
  88. package/dist/navigation-drawer/NavigationDrawerItem.svelte +10 -3
  89. package/dist/navigation-drawer/types.d.ts +6 -1
  90. package/dist/navigation-rail/NavigationRailItem.svelte +16 -0
  91. package/dist/navigation-rail/types.d.ts +3 -0
  92. package/dist/popover.svelte.d.ts +14 -0
  93. package/dist/popover.svelte.js +31 -0
  94. package/dist/press.svelte.d.ts +19 -0
  95. package/dist/press.svelte.js +45 -0
  96. package/dist/radio/Radio.svelte +26 -7
  97. package/dist/radio/types.d.ts +3 -0
  98. package/dist/search/Search.svelte +472 -0
  99. package/dist/search/Search.svelte.d.ts +5 -0
  100. package/dist/search/index.d.ts +1 -0
  101. package/dist/search/index.js +1 -0
  102. package/dist/search/types.d.ts +39 -0
  103. package/dist/search/types.js +1 -0
  104. package/dist/select/Select.svelte +48 -87
  105. package/dist/sheet/Sheet.svelte +260 -0
  106. package/dist/sheet/Sheet.svelte.d.ts +7 -0
  107. package/dist/sheet/index.d.ts +1 -0
  108. package/dist/sheet/index.js +1 -0
  109. package/dist/sheet/types.d.ts +19 -0
  110. package/dist/sheet/types.js +1 -0
  111. package/dist/slider/Slider.svelte +154 -30
  112. package/dist/slider/types.d.ts +3 -0
  113. package/dist/snackbar/Snackbar.svelte +48 -37
  114. package/dist/snackbar/Snackbar.svelte.d.ts +2 -2
  115. package/dist/snackbar/types.d.ts +3 -2
  116. package/dist/switch/Switch.svelte +51 -20
  117. package/dist/switch/types.d.ts +3 -0
  118. package/dist/tabs/Tab.svelte +8 -12
  119. package/dist/tabs/Tabs.svelte +3 -3
  120. package/dist/text-field/TextField.svelte +2 -2
  121. package/dist/toolbar/Toolbar.svelte +133 -0
  122. package/dist/toolbar/Toolbar.svelte.d.ts +4 -0
  123. package/dist/toolbar/index.d.ts +1 -0
  124. package/dist/toolbar/index.js +1 -0
  125. package/dist/toolbar/types.d.ts +15 -0
  126. package/dist/toolbar/types.js +1 -0
  127. package/dist/tooltip/RichTooltip.svelte +25 -12
  128. package/dist/tooltip/RichTooltip.svelte.d.ts +2 -2
  129. package/dist/tooltip/Tooltip.svelte +22 -11
  130. package/dist/tooltip/Tooltip.svelte.d.ts +4 -1
  131. package/dist/types.d.ts +6 -0
  132. package/dist/types.js +6 -0
  133. package/package.json +13 -13
  134. package/dist/date-picker/enterAnimation.d.ts +0 -1
  135. package/dist/date-picker/enterAnimation.js +0 -10
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './app-bar/index.js';
1
2
  export * from './autocomplete/index.js';
2
3
  export * from './badge/index.js';
3
4
  export * from './button/index.js';
@@ -7,18 +8,23 @@ export * from './chip/index.js';
7
8
  export * from './date-picker/index.js';
8
9
  export * from './dialog/index.js';
9
10
  export * from './divider/index.js';
11
+ export * from './fab/index.js';
10
12
  export * from './list/index.js';
11
13
  export * from './loading-indicator/index.js';
12
14
  export * from './menu/index.js';
15
+ export * from './navigation-bar/index.js';
13
16
  export * from './navigation-drawer/index.js';
14
17
  export * from './navigation-rail/index.js';
15
18
  export * from './progress/index.js';
16
19
  export * from './radio/index.js';
17
20
  export * from './ripple/index.js';
21
+ export * from './search/index.js';
18
22
  export * from './select/index.js';
23
+ export * from './sheet/index.js';
19
24
  export * from './slider/index.js';
20
25
  export * from './snackbar/index.js';
21
26
  export * from './switch/index.js';
22
27
  export * from './tabs/index.js';
23
28
  export * from './text-field/index.js';
29
+ export * from './toolbar/index.js';
24
30
  export * from './tooltip/index.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './app-bar/index.js';
1
2
  export * from './autocomplete/index.js';
2
3
  export * from './badge/index.js';
3
4
  export * from './button/index.js';
@@ -7,18 +8,23 @@ export * from './chip/index.js';
7
8
  export * from './date-picker/index.js';
8
9
  export * from './dialog/index.js';
9
10
  export * from './divider/index.js';
11
+ export * from './fab/index.js';
10
12
  export * from './list/index.js';
11
13
  export * from './loading-indicator/index.js';
12
14
  export * from './menu/index.js';
15
+ export * from './navigation-bar/index.js';
13
16
  export * from './navigation-drawer/index.js';
14
17
  export * from './navigation-rail/index.js';
15
18
  export * from './progress/index.js';
16
19
  export * from './radio/index.js';
17
20
  export * from './ripple/index.js';
21
+ export * from './search/index.js';
18
22
  export * from './select/index.js';
23
+ export * from './sheet/index.js';
19
24
  export * from './slider/index.js';
20
25
  export * from './snackbar/index.js';
21
26
  export * from './switch/index.js';
22
27
  export * from './tabs/index.js';
23
28
  export * from './text-field/index.js';
29
+ export * from './toolbar/index.js';
24
30
  export * from './tooltip/index.js';
@@ -24,3 +24,15 @@
24
24
  outline-width: 3px;
25
25
  }
26
26
  }
27
+
28
+ .np-focus-ring:focus-visible {
29
+ outline-style: solid;
30
+ outline-color: var(--np-color-secondary);
31
+ outline-width: 3px;
32
+ outline-offset: 2px;
33
+ }
34
+ @media (prefers-reduced-motion: no-preference) {
35
+ .np-focus-ring:focus-visible {
36
+ animation: focusAnimation var(--np-motion-expressive-slow-effects) forwards;
37
+ }
38
+ }
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.js'
3
+ import { popoverController, syncOpenEffect } from '../popover.svelte.js'
3
4
  import type { MenuProps } from './types.js'
4
5
 
5
6
  const MENU_ITEM_SELECTOR = '[role="menuitem"]'
@@ -21,13 +22,17 @@
21
22
  let contentHeight = $state(0)
22
23
  let innerHeight = $state(0)
23
24
 
24
- export const showPopover = () => {
25
- element?.showPopover()
26
- }
25
+ const controller = popoverController(() => element)
27
26
 
28
- export const hidePopover = () => {
29
- element?.hidePopover()
30
- }
27
+ export const show = () => controller.show()
28
+ export const close = () => controller.close()
29
+
30
+ syncOpenEffect(
31
+ () => element,
32
+ () => open,
33
+ show,
34
+ close,
35
+ )
31
36
 
32
37
  const calculateTransformOrigin = (anchorRect: DOMRect, menuRect: DOMRect) => {
33
38
  const pivot = (anchorStart: number, anchorEnd: number, menuStart: number, menuEnd: number) => {
@@ -82,7 +87,7 @@
82
87
  }}
83
88
  >
84
89
  <div {@attach attach} bind:clientHeight={contentHeight} class="np-menu" role="none">
85
- {@render children()}
90
+ {@render children?.()}
86
91
  </div>
87
92
  </div>
88
93
 
@@ -1,7 +1,7 @@
1
1
  import type { MenuProps } from './types.ts';
2
2
  declare const Menu: import("svelte").Component<MenuProps, {
3
- showPopover: () => void;
4
- hidePopover: () => void;
3
+ show: () => void;
4
+ close: () => void;
5
5
  }, "element" | "open">;
6
6
  type Menu = ReturnType<typeof Menu>;
7
7
  export default Menu;
@@ -1,8 +1,6 @@
1
1
  import type { ItemProps } from '../list/types.js';
2
- import type { Snippet } from 'svelte';
3
2
  import type { HTMLAttributes } from 'svelte/elements';
4
3
  export interface MenuProps extends HTMLAttributes<HTMLDivElement> {
5
- children: Snippet;
6
4
  anchor?: HTMLElement | undefined;
7
5
  element?: HTMLDivElement;
8
6
  open?: boolean;
@@ -0,0 +1,66 @@
1
+ <script lang="ts">
2
+ import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.js'
3
+ import type { NavigationBarProps } from './types.js'
4
+
5
+ let {
6
+ children,
7
+ arrangement = 'equal-weight',
8
+ element = $bindable(),
9
+ onkeydown: userKeydown,
10
+ ...attributes
11
+ }: NavigationBarProps = $props()
12
+
13
+ // The same attachments the rail uses. They read no reactive state, so they never tear down.
14
+ const attach = rovingTabindex('.np-navigation-bar-item')
15
+ const arrowHandler = arrowKeyNav('.np-navigation-bar-item', 'horizontal')
16
+
17
+ const handleKeydown = (event: KeyboardEvent & { currentTarget: EventTarget & HTMLElement }) => {
18
+ userKeydown?.(event)
19
+ if (!event.defaultPrevented) arrowHandler(event)
20
+ }
21
+ </script>
22
+
23
+ <nav
24
+ {...attributes}
25
+ {@attach attach}
26
+ bind:this={element}
27
+ class={[
28
+ 'np-navigation-bar',
29
+ arrangement === 'centered' && 'np-navigation-bar-centered',
30
+ attributes.class,
31
+ ]}
32
+ onkeydown={handleKeydown}
33
+ >
34
+ {@render children?.()}
35
+ </nav>
36
+
37
+ <style>
38
+ .np-navigation-bar {
39
+ display: flex;
40
+ justify-content: space-around;
41
+ align-items: stretch;
42
+ box-sizing: border-box;
43
+ width: 100%;
44
+ min-height: 5rem;
45
+ padding-block: 0.75rem;
46
+ padding-inline: 0.5rem;
47
+ background-color: var(--np-navigation-bar-container-color, var(--np-color-surface-container));
48
+ /* Sits above page content the way a rail does, and clears the home inset on a phone. */
49
+ padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
50
+ z-index: 8;
51
+ }
52
+
53
+ /* Items keep their own content width instead of stretching, and group in the middle. */
54
+ .np-navigation-bar-centered {
55
+ justify-content: center;
56
+ gap: 0.5rem;
57
+ }
58
+ /*
59
+ * Doubled selector to outrank the item's own `.svelte-*`-scoped `flex: 1` rule, which has the
60
+ * same specificity and would otherwise win or lose depending on CSS bundle order.
61
+ */
62
+ :global(.np-navigation-bar-centered .np-navigation-bar-item.np-navigation-bar-item) {
63
+ flex: 0 0 auto;
64
+ min-width: 0;
65
+ }
66
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { NavigationBarProps } from './types.ts';
2
+ declare const NavigationBar: import("svelte").Component<NavigationBarProps, {}, "element">;
3
+ type NavigationBar = ReturnType<typeof NavigationBar>;
4
+ export default NavigationBar;
@@ -0,0 +1,261 @@
1
+ <script lang="ts">
2
+ import '../internal/focus-ring.css'
3
+ import Badge from '../badge/Badge.svelte'
4
+ import Ripple from '../ripple/Ripple.svelte'
5
+ import type { HTMLButtonAttributes } from 'svelte/elements'
6
+ import type { NavigationBarItemProps } from './types.js'
7
+
8
+ let {
9
+ selected = false,
10
+ icon,
11
+ label,
12
+ badge = false,
13
+ badgeLabel,
14
+ badgeAriaLabel,
15
+ labelBehavior = 'always',
16
+ orientation = 'vertical',
17
+ element = $bindable(),
18
+ ...attributes
19
+ }: NavigationBarItemProps = $props()
20
+
21
+ let touchEl: HTMLSpanElement | undefined = $state()
22
+
23
+ const isLink = $derived(attributes.href != null)
24
+ const classes = $derived([
25
+ 'np-navigation-bar-item',
26
+ selected && 'np-navigation-bar-item-selected',
27
+ labelBehavior === 'selected' && 'np-navigation-bar-item-label-selected',
28
+ orientation === 'horizontal' && 'np-navigation-bar-item-horizontal',
29
+ attributes.class,
30
+ ])
31
+ </script>
32
+
33
+ {#snippet content()}
34
+ {#if orientation === 'horizontal'}
35
+ <!-- Sized off its own parent, so it has to sit on the whole pill rather than the icon alone. -->
36
+ <Ripple forElement={touchEl} />
37
+ {/if}
38
+ <span class="np-navigation-bar-item-icon">
39
+ {#if orientation === 'vertical'}
40
+ <Ripple forElement={touchEl} />
41
+ {/if}
42
+ {@render icon()}
43
+ {#if badge}
44
+ <span class="np-navigation-bar-item-badge">
45
+ <Badge label={badgeLabel} aria-label={badgeAriaLabel} />
46
+ </span>
47
+ {/if}
48
+ </span>
49
+ <span class="np-navigation-bar-item-label">{label}</span>
50
+ <span class="np-touch" bind:this={touchEl}></span>
51
+ {/snippet}
52
+
53
+ {#if isLink}
54
+ <a
55
+ {...attributes}
56
+ bind:this={element}
57
+ href={attributes.href}
58
+ class={classes}
59
+ aria-current={selected ? 'page' : undefined}
60
+ tabindex={selected ? 0 : -1}
61
+ >
62
+ {@render content()}
63
+ </a>
64
+ {:else}
65
+ <button
66
+ {...attributes as HTMLButtonAttributes}
67
+ bind:this={element}
68
+ class={classes}
69
+ aria-current={selected ? 'page' : undefined}
70
+ tabindex={selected ? 0 : -1}
71
+ >
72
+ {@render content()}
73
+ </button>
74
+ {/if}
75
+
76
+ <style>
77
+ .np-navigation-bar-item {
78
+ position: relative;
79
+ flex: 1;
80
+ min-width: 0;
81
+ cursor: pointer;
82
+ font: inherit;
83
+ border-width: 0;
84
+ background: none;
85
+ display: flex;
86
+ flex-direction: column;
87
+ align-items: center;
88
+ justify-content: flex-start;
89
+ gap: 0.25rem;
90
+ color: var(--np-color-on-surface);
91
+ text-decoration: none;
92
+ -webkit-tap-highlight-color: transparent;
93
+ }
94
+
95
+ .np-navigation-bar-item-icon {
96
+ position: relative;
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ width: 3.5rem;
101
+ height: 2rem;
102
+ border-radius: var(--np-shape-corner-full);
103
+ color: var(--np-color-on-surface-variant);
104
+ z-index: 1;
105
+ }
106
+
107
+ /* The active-indicator pill, grown from the selected class rather than measured. */
108
+ .np-navigation-bar-item-icon::before {
109
+ content: '';
110
+ position: absolute;
111
+ inset: 0;
112
+ opacity: 0;
113
+ transform: scaleX(0.32);
114
+ background-color: var(
115
+ --np-navigation-bar-item-active-indicator-color,
116
+ var(--np-color-secondary-container)
117
+ );
118
+ border-radius: inherit;
119
+ z-index: -1;
120
+ }
121
+ .np-navigation-bar-item-selected .np-navigation-bar-item-icon::before {
122
+ opacity: 1;
123
+ transform: scaleX(1);
124
+ }
125
+
126
+ .np-navigation-bar-item-selected .np-navigation-bar-item-icon {
127
+ color: var(--np-color-on-secondary-container);
128
+ --np-icon-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
129
+ }
130
+
131
+ .np-navigation-bar-item-label {
132
+ font-size: 0.75rem;
133
+ line-height: 1rem;
134
+ letter-spacing: 0.031rem;
135
+ font-weight: var(--np-navigation-bar-item-font-weight, 500);
136
+ color: var(--np-color-on-surface-variant);
137
+ max-width: 100%;
138
+ overflow: hidden;
139
+ text-overflow: ellipsis;
140
+ white-space: nowrap;
141
+ }
142
+ .np-navigation-bar-item-selected .np-navigation-bar-item-label {
143
+ font-weight: var(--np-navigation-bar-item-selected-font-weight, 500);
144
+ color: var(--np-color-on-surface);
145
+ }
146
+
147
+ /*
148
+ * `labelBehavior="selected"` keeps the label in the layout but hides it, so the row does not
149
+ * reflow as the selection moves.
150
+ */
151
+ .np-navigation-bar-item-label-selected .np-navigation-bar-item-label {
152
+ visibility: hidden;
153
+ }
154
+ .np-navigation-bar-item-label-selected.np-navigation-bar-item-selected
155
+ .np-navigation-bar-item-label {
156
+ visibility: visible;
157
+ }
158
+
159
+ /*
160
+ * The icon sits beside the label instead of above it, for a bar with room to spare. Unlike the
161
+ * stacked layout, the active-indicator pill wraps the icon and label together, like a chip,
162
+ * rather than just the icon.
163
+ */
164
+ .np-navigation-bar-item-horizontal {
165
+ flex-direction: row;
166
+ justify-content: center;
167
+ /* M3's "icon label space" token: 4dp between the icon and the label. */
168
+ gap: 0.25rem;
169
+ /*
170
+ * M3's "leading/trailing space" token (16dp) sets the inline padding, and the block padding
171
+ * is picked so a 1.5rem icon plus padding adds up to the "active indicator height" token
172
+ * (40dp).
173
+ */
174
+ padding: 0.5rem 1rem;
175
+ border-radius: var(--np-shape-corner-full);
176
+ /* The bar stretches items to its own height by default; a pill sizes to its own content and
177
+ * centers in the bar instead. */
178
+ align-self: center;
179
+ /* Gives the item its own stacking context, so the pill's z-index: -1 stays behind the icon
180
+ * and label instead of escaping to sit behind the bar's own background. */
181
+ z-index: 0;
182
+ }
183
+ .np-navigation-bar-item-horizontal::before {
184
+ content: '';
185
+ position: absolute;
186
+ inset: 0;
187
+ opacity: 0;
188
+ transform: scaleX(0.32);
189
+ background-color: var(
190
+ --np-navigation-bar-item-active-indicator-color,
191
+ var(--np-color-secondary-container)
192
+ );
193
+ border-radius: inherit;
194
+ z-index: -1;
195
+ }
196
+ .np-navigation-bar-item-horizontal.np-navigation-bar-item-selected::before {
197
+ opacity: 1;
198
+ transform: scaleX(1);
199
+ }
200
+ /* The wrapping item now supplies the pill, so the icon's own is switched off. */
201
+ .np-navigation-bar-item-horizontal .np-navigation-bar-item-icon {
202
+ width: 1.5rem;
203
+ height: 1.5rem;
204
+ }
205
+ .np-navigation-bar-item-horizontal .np-navigation-bar-item-icon::before {
206
+ content: none;
207
+ }
208
+ .np-navigation-bar-item-horizontal .np-navigation-bar-item-badge {
209
+ --np-badge-top: -0.25rem;
210
+ --np-badge-end: -0.25rem;
211
+ }
212
+ .np-navigation-bar-item-horizontal .np-touch {
213
+ inset: 0;
214
+ width: 100%;
215
+ height: 100%;
216
+ }
217
+ @media (prefers-reduced-motion: no-preference) {
218
+ .np-navigation-bar-item-horizontal::before {
219
+ transition:
220
+ transform var(--np-motion-expressive-default-spatial),
221
+ opacity var(--np-motion-expressive-fast-effects);
222
+ }
223
+ }
224
+
225
+ .np-navigation-bar-item-badge {
226
+ --np-badge-top: 0;
227
+ --np-badge-end: 1rem;
228
+ position: absolute;
229
+ inset: 0;
230
+ pointer-events: none;
231
+ }
232
+
233
+ .np-touch {
234
+ position: absolute;
235
+ inset-block-start: 0;
236
+ height: 3.5rem;
237
+ width: 4rem;
238
+ }
239
+
240
+ .np-navigation-bar-item:focus-visible {
241
+ outline-style: solid;
242
+ outline-color: var(--np-color-secondary);
243
+ outline-width: 3px;
244
+ outline-offset: 2px;
245
+ border-radius: 1rem;
246
+ }
247
+
248
+ @media (prefers-reduced-motion: no-preference) {
249
+ .np-navigation-bar-item-icon::before {
250
+ transition:
251
+ transform var(--np-motion-expressive-default-spatial),
252
+ opacity var(--np-motion-expressive-fast-effects);
253
+ }
254
+ .np-navigation-bar-item-label {
255
+ transition: color var(--np-motion-expressive-default-effects);
256
+ }
257
+ .np-navigation-bar-item:focus-visible {
258
+ animation: focusAnimation var(--np-motion-expressive-slow-effects) forwards;
259
+ }
260
+ }
261
+ </style>
@@ -0,0 +1,5 @@
1
+ import '../internal/focus-ring.css';
2
+ import type { NavigationBarItemProps } from './types.ts';
3
+ declare const NavigationBarItem: import("svelte").Component<NavigationBarItemProps, {}, "element">;
4
+ type NavigationBarItem = ReturnType<typeof NavigationBarItem>;
5
+ export default NavigationBarItem;
@@ -0,0 +1,2 @@
1
+ export { default as NavigationBar } from './NavigationBar.svelte';
2
+ export { default as NavigationBarItem } from './NavigationBarItem.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as NavigationBar } from './NavigationBar.svelte';
2
+ export { default as NavigationBarItem } from './NavigationBarItem.svelte';
@@ -0,0 +1,29 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ export interface NavigationBarProps extends HTMLAttributes<HTMLElement> {
4
+ /**
5
+ * `'equal-weight'` stretches every item to the same width, which M3 recommends for compact
6
+ * screens. `'centered'` sizes each item to its content and groups them in the middle, which M3
7
+ * recommends once the bar has room to spare on a medium-width screen.
8
+ */
9
+ arrangement?: 'equal-weight' | 'centered';
10
+ element?: HTMLElement;
11
+ }
12
+ export type NavigationBarItemElement = HTMLButtonElement | HTMLAnchorElement;
13
+ export interface NavigationBarItemProps extends HTMLAttributes<NavigationBarItemElement>, Omit<HTMLButtonAttributes, keyof HTMLAttributes<HTMLButtonElement> | 'type'>, Omit<HTMLAnchorAttributes, keyof HTMLAttributes<HTMLAnchorElement> | 'type'> {
14
+ icon: Snippet;
15
+ label: string;
16
+ selected?: boolean;
17
+ badge?: boolean;
18
+ badgeLabel?: string | number;
19
+ badgeAriaLabel?: string;
20
+ /** Hides the label until the item is selected, which M3 allows for four or five items. */
21
+ labelBehavior?: 'always' | 'selected';
22
+ /**
23
+ * `'vertical'` stacks the icon above the label. `'horizontal'` puts it beside the label instead,
24
+ * which M3 pairs with `arrangement="centered"` once a bar has room to spare.
25
+ */
26
+ orientation?: 'vertical' | 'horizontal';
27
+ type?: 'submit' | 'reset' | 'button' | (string & {}) | null;
28
+ element?: NavigationBarItemElement;
29
+ }
@@ -0,0 +1 @@
1
+ export {};