noph-ui 0.32.9 → 0.33.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.
@@ -168,9 +168,9 @@
168
168
  text-decoration: none;
169
169
  --np-icon-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
170
170
  transition:
171
- background-color 150ms linear,
172
- border-radius 100ms linear,
173
- box-shadow 150ms linear;
171
+ background-color var(--np-motion-expressive-default-effects),
172
+ border-radius var(--np-motion-expressive-default-effects),
173
+ box-shadow var(--np-motion-expressive-default-effects);
174
174
  }
175
175
  .xs {
176
176
  font-size: 0.875rem;
@@ -143,8 +143,8 @@
143
143
  justify-content: center;
144
144
  --np-icon-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
145
145
  transition:
146
- background-color 150ms linear,
147
- border-radius 100ms linear;
146
+ background-color var(--np-motion-expressive-default-effects),
147
+ border-radius var(--np-motion-expressive-default-effects);
148
148
  }
149
149
 
150
150
  :global(.np-icon-button svg) {
@@ -113,7 +113,7 @@
113
113
  --np-icon-size: 1.125rem;
114
114
  --np-ripple-pressed-opacity: 0.1;
115
115
  min-width: 0;
116
- transition: box-shadow 150ms linear;
116
+ transition: box-shadow var(--np-motion-expressive-slow-effects);
117
117
  }
118
118
  .np-filter-chip-label input {
119
119
  opacity: 0;
@@ -132,7 +132,7 @@
132
132
  z-index: 1;
133
133
  padding-inline: 1rem;
134
134
  overflow: hidden;
135
- transition: padding 200ms ease;
135
+ transition: padding var(--np-motion-expressive-default-effects);
136
136
  }
137
137
  .np-chip-icon-checked {
138
138
  display: flex;
@@ -141,8 +141,8 @@
141
141
  margin-inline-end: -0.5rem;
142
142
  overflow: hidden;
143
143
  transition:
144
- width 200ms ease,
145
- margin 200ms ease;
144
+ width var(--np-motion-expressive-default-effects),
145
+ margin var(--np-motion-expressive-default-effects);
146
146
  }
147
147
  .np-filter-chip:has(input:checked) .np-chip-icon-checked {
148
148
  width: 18px;
package/dist/index.d.ts CHANGED
@@ -13,7 +13,6 @@ export * from './progress/index.js';
13
13
  export * from './radio/index.js';
14
14
  export * from './ripple/index.js';
15
15
  export * from './select/index.js';
16
- export * from './slider/index.js';
17
16
  export * from './snackbar/index.js';
18
17
  export * from './switch/index.js';
19
18
  export * from './tabs/index.js';
package/dist/index.js CHANGED
@@ -13,7 +13,6 @@ export * from './progress/index.js';
13
13
  export * from './radio/index.js';
14
14
  export * from './ripple/index.js';
15
15
  export * from './select/index.js';
16
- export * from './slider/index.js';
17
16
  export * from './snackbar/index.js';
18
17
  export * from './switch/index.js';
19
18
  export * from './tabs/index.js';
@@ -0,0 +1,8 @@
1
+ import type { Attachment } from 'svelte/attachments';
2
+ export declare const rovingTabindex: (itemSelector: string, options?: {
3
+ currentAttr?: string;
4
+ currentValue?: string;
5
+ }) => Attachment<HTMLElement>;
6
+ export declare const arrowKeyNav: (itemSelector: string, orientation?: "vertical" | "horizontal") => (event: KeyboardEvent & {
7
+ currentTarget: EventTarget & HTMLElement;
8
+ }) => void;
@@ -0,0 +1,69 @@
1
+ export const rovingTabindex = (itemSelector, options = {}) => {
2
+ const { currentAttr = 'aria-current', currentValue = 'page' } = options;
3
+ return (node) => {
4
+ const getItems = () => Array.from(node.querySelectorAll(itemSelector));
5
+ const setTabstop = (target) => {
6
+ for (const i of getItems()) {
7
+ const wanted = i === target ? 0 : -1;
8
+ if (i.tabIndex !== wanted)
9
+ i.tabIndex = wanted;
10
+ }
11
+ };
12
+ const sync = () => {
13
+ const items = getItems();
14
+ if (items.length === 0)
15
+ return;
16
+ const focused = node.querySelector(`${itemSelector}:focus`);
17
+ const current = items.find((i) => i.getAttribute(currentAttr) === currentValue);
18
+ setTabstop(focused ?? current ?? items[0]);
19
+ };
20
+ const onFocusIn = (event) => {
21
+ const target = event.target.closest(itemSelector);
22
+ if (!target || !node.contains(target) || target.tabIndex === 0)
23
+ return;
24
+ setTabstop(target);
25
+ };
26
+ sync();
27
+ node.addEventListener('focusin', onFocusIn);
28
+ const observer = new MutationObserver(sync);
29
+ observer.observe(node, {
30
+ attributes: true,
31
+ attributeFilter: [currentAttr],
32
+ subtree: true,
33
+ childList: true,
34
+ });
35
+ return () => {
36
+ node.removeEventListener('focusin', onFocusIn);
37
+ observer.disconnect();
38
+ };
39
+ };
40
+ };
41
+ export const arrowKeyNav = (itemSelector, orientation = 'vertical') => (event) => {
42
+ const [prev, next] = orientation === 'vertical'
43
+ ? ['ArrowUp', 'ArrowDown']
44
+ : ['ArrowLeft', 'ArrowRight'];
45
+ const { key } = event;
46
+ if (key !== prev && key !== next && key !== 'Home' && key !== 'End')
47
+ return;
48
+ const items = Array.from(event.currentTarget.querySelectorAll(itemSelector));
49
+ if (items.length === 0)
50
+ return;
51
+ const focused = event.currentTarget.querySelector(`${itemSelector}:focus`);
52
+ if (!focused)
53
+ return;
54
+ const currentIndex = items.indexOf(focused);
55
+ let target;
56
+ if (key === 'Home') {
57
+ target = items[0];
58
+ }
59
+ else if (key === 'End') {
60
+ target = items[items.length - 1];
61
+ }
62
+ else {
63
+ const delta = key === next ? 1 : -1;
64
+ const index = currentIndex + delta;
65
+ target = index < 0 ? items[items.length - 1] : index >= items.length ? items[0] : items[index];
66
+ }
67
+ target.focus();
68
+ event.preventDefault();
69
+ };
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.ts'
2
3
  import type { NavigationDrawerProps } from './types.ts'
3
4
  let {
4
5
  modal = false,
@@ -7,12 +8,22 @@
7
8
  direction = 'ltr',
8
9
  popover,
9
10
  children,
11
+ onkeydown: userKeydown,
10
12
  ...attributes
11
13
  }: NavigationDrawerProps = $props()
14
+
15
+ const attach = rovingTabindex('.np-navigation-drawer-item')
16
+ const arrowHandler = arrowKeyNav('.np-navigation-drawer-item')
17
+
18
+ const handleKeydown = (event: KeyboardEvent & { currentTarget: EventTarget & HTMLElement }) => {
19
+ userKeydown?.(event)
20
+ if (!event.defaultPrevented) arrowHandler(event)
21
+ }
12
22
  </script>
13
23
 
14
24
  <nav
15
25
  {...attributes}
26
+ {@attach attach}
16
27
  bind:this={element}
17
28
  popover={modal ? popover || 'auto' : undefined}
18
29
  style="--np-navigation-drawer-start: {direction === 'ltr'
@@ -24,6 +35,7 @@
24
35
  backdrop && 'np-navigation-drawer-backdrop',
25
36
  attributes.class,
26
37
  ]}
38
+ onkeydown={handleKeydown}
27
39
  >
28
40
  {#if backdrop}
29
41
  <div
@@ -64,13 +76,13 @@
64
76
 
65
77
  .np-navigation-drawer-container[popover] .np-navigation-wrapper {
66
78
  transform: var(--np-navigation-drawer-start, translateX(-100%));
67
- transition: transform 0.25s ease;
79
+ transition: transform var(--np-motion-expressive-slow-effects);
68
80
  }
69
81
 
70
82
  .np-navigation-drawer-container[popover] {
71
83
  transition:
72
- overlay 0.25s allow-discrete,
73
- display 0.25s allow-discrete;
84
+ overlay 0.3s allow-discrete,
85
+ display 0.3s allow-discrete;
74
86
  }
75
87
 
76
88
  .np-navigation-drawer-container:popover-open .np-navigation-wrapper {
@@ -28,12 +28,14 @@
28
28
  {#if 'href' in attributes}
29
29
  <a
30
30
  {...attributes}
31
+ href={attributes.href}
31
32
  class={[
32
33
  'np-navigation-drawer-item',
33
34
  selected && 'np-navigation-drawer-item-selected',
34
35
  attributes.class,
35
36
  ]}
36
37
  aria-current={selected ? 'page' : undefined}
38
+ tabindex={selected ? 0 : -1}
37
39
  >
38
40
  {@render content()}
39
41
  </a>
@@ -46,7 +48,8 @@
46
48
  attributes.class,
47
49
  ]}
48
50
  type="button"
49
- aria-pressed={selected ? 'true' : undefined}
51
+ aria-current={selected ? 'page' : undefined}
52
+ tabindex={selected ? 0 : -1}
50
53
  >
51
54
  {@render content()}
52
55
  </button>
@@ -97,7 +100,11 @@
97
100
  outline-color: var(--np-color-secondary);
98
101
  outline-width: 3px;
99
102
  outline-offset: -3px;
100
- animation: focusAnimation 0.3s ease forwards;
103
+ }
104
+ @media (prefers-reduced-motion: no-preference) {
105
+ .np-navigation-drawer-item:focus-visible {
106
+ animation: focusAnimation 0.3s ease forwards;
107
+ }
101
108
  }
102
109
  @keyframes focusAnimation {
103
110
  0% {
@@ -1,10 +1,24 @@
1
1
  <script lang="ts">
2
+ import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.ts'
2
3
  import type { NavigationRailProps } from './types.ts'
3
4
 
4
- let { children, ...attributes }: NavigationRailProps = $props()
5
+ let { children, onkeydown: userKeydown, ...attributes }: NavigationRailProps = $props()
6
+
7
+ const attach = rovingTabindex('.np-navigation-action')
8
+ const arrowHandler = arrowKeyNav('.np-navigation-action')
9
+
10
+ const handleKeydown = (event: KeyboardEvent & { currentTarget: EventTarget & HTMLElement }) => {
11
+ userKeydown?.(event)
12
+ if (!event.defaultPrevented) arrowHandler(event)
13
+ }
5
14
  </script>
6
15
 
7
- <nav {...attributes} class="navigation-rail {attributes.class}">
16
+ <nav
17
+ {...attributes}
18
+ {@attach attach}
19
+ class="navigation-rail {attributes.class}"
20
+ onkeydown={handleKeydown}
21
+ >
8
22
  {#if children}
9
23
  {@render children()}
10
24
  {/if}
@@ -19,8 +19,10 @@
19
19
  {#if 'href' in attributes}
20
20
  <a
21
21
  {...attributes}
22
+ href={attributes.href}
22
23
  class={['np-navigation-action', selected && 'np-navigation-action-selected', attributes.class]}
23
24
  aria-current={selected ? 'page' : undefined}
25
+ tabindex={selected ? 0 : -1}
24
26
  >
25
27
  {@render content()}
26
28
  </a>
@@ -28,7 +30,8 @@
28
30
  <button
29
31
  {...attributes as HTMLButtonAttributes}
30
32
  class={['np-navigation-action', selected && 'np-navigation-action-selected', attributes.class]}
31
- aria-pressed={selected ? 'true' : undefined}
33
+ aria-current={selected ? 'page' : undefined}
34
+ tabindex={selected ? 0 : -1}
32
35
  >
33
36
  {@render content()}
34
37
  </button>
@@ -54,7 +57,11 @@
54
57
  outline-width: 3px;
55
58
  outline-offset: 2px;
56
59
  border-radius: 1rem;
57
- animation: focusAnimation 0.3s ease forwards;
60
+ }
61
+ @media (prefers-reduced-motion: no-preference) {
62
+ .np-navigation-action:focus-visible {
63
+ animation: focusAnimation 0.3s ease forwards;
64
+ }
58
65
  }
59
66
  @keyframes focusAnimation {
60
67
  0% {
@@ -123,13 +123,13 @@
123
123
  transition:
124
124
  overlay 0.2s allow-discrete,
125
125
  display 0.2s allow-discrete,
126
- opacity 0.2s linear;
126
+ opacity var(--np-motion-expressive-default-effects);
127
127
  opacity: 0;
128
128
  }
129
129
 
130
130
  .np-snackbar:popover-open {
131
131
  opacity: 1;
132
- animation: slideIn 0.2s linear;
132
+ animation: slideIn var(--np-motion-expressive-default-spatial);
133
133
  }
134
134
 
135
135
  @keyframes slideIn {
@@ -98,8 +98,8 @@
98
98
  height: 1rem;
99
99
  margin: 0.5rem;
100
100
  transition:
101
- transform 0.2s,
102
- background-color 0.2s;
101
+ transform var(--np-motion-expressive-fast-spatial),
102
+ background-color var(--np-motion-expressive-default-effects);
103
103
  background-color: var(--np-comp-switch-unselected-handle-color, var(--np-color-outline));
104
104
  border-radius: var(--np-comp-switch-handle-shape, var(--np-shape-corner-full));
105
105
  }
@@ -114,7 +114,7 @@
114
114
  height: var(--np-comp-switch-state-layer-size, 2.5rem);
115
115
  margin-block-start: -0.25rem;
116
116
  margin-inline-start: -0.25rem;
117
- transition: transform 0.2s;
117
+ transition: var(--np-motion-expressive-fast-spatial);
118
118
  border-radius: var(--np-comp-switch-state-layer-shape, var(--np-shape-corner-full));
119
119
  }
120
120
 
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
- import Ripple from '../ripple/Ripple.svelte'
3
- import { onMount } from 'svelte'
4
- import type { TabProps } from './types.ts'
5
2
  import Badge from '../badge/Badge.svelte'
3
+ import Ripple from '../ripple/Ripple.svelte'
4
+ import { onMount, tick } from 'svelte'
6
5
  import { getTabsContext } from './context.js'
6
+ import type { TabProps } from './types.ts'
7
7
 
8
8
  let {
9
9
  children,
@@ -22,20 +22,17 @@
22
22
  const tabsContext = getTabsContext()
23
23
  let fallbackIndicator = $state(false)
24
24
 
25
- const handleClick = (event: MouseEvent & { currentTarget: EventTarget & HTMLElement }) => {
26
- tabsContext.value = value
27
- if (onclick) {
28
- onclick(event)
29
- }
30
- }
31
- const handleKeyDown = (event: KeyboardEvent & { currentTarget: EventTarget & HTMLElement }) => {
32
- if (event.key === 'Enter' || event.key === ' ') {
33
- tabsContext.value = value
34
- }
35
- if (onkeydown) {
36
- onkeydown(event)
25
+ $effect(() => {
26
+ if (tabsContext.value === value) {
27
+ tabsContext.indicatorValue = value
37
28
  }
29
+ })
30
+
31
+ const setIndicatorValue = async () => {
32
+ await tick()
33
+ tabsContext.indicatorValue = value
38
34
  }
35
+
39
36
  onMount(() => {
40
37
  if (!('anchorName' in document.documentElement.style)) {
41
38
  fallbackIndicator = true
@@ -69,11 +66,15 @@
69
66
  {@render children?.()}
70
67
  {/if}
71
68
  {#if tabsContext.variant === 'primary'}
72
- <div class="np-indicator"></div>
69
+ <div
70
+ class={['np-indicator', tabsContext.indicatorValue === value && 'np-indicator-anchor']}
71
+ ></div>
73
72
  {/if}
74
73
  </div>
75
74
  {#if tabsContext.variant === 'secondary'}
76
- <div class="np-indicator"></div>
75
+ <div
76
+ class={['np-indicator', tabsContext.indicatorValue === value && 'np-indicator-anchor']}
77
+ ></div>
77
78
  {/if}
78
79
  </div>
79
80
  <div class="focus-area"></div>
@@ -112,8 +113,18 @@
112
113
  tabsContext.variant === 'primary' ? 'primary' : 'secondary',
113
114
  attributes.class,
114
115
  ]}
115
- onclick={handleClick}
116
- onkeydown={handleKeyDown}
116
+ onclick={(event) => {
117
+ tabsContext.value = value
118
+ setIndicatorValue()
119
+ onclick?.(event)
120
+ }}
121
+ onkeydown={(event) => {
122
+ if (event.key === 'Enter' || event.key === ' ') {
123
+ tabsContext.value = value
124
+ setIndicatorValue()
125
+ }
126
+ onkeydown?.(event)
127
+ }}
117
128
  >
118
129
  {@render content()}
119
130
  </button>
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import Divider from '../divider/Divider.svelte'
3
+ import { arrowKeyNav, rovingTabindex } from '../keyboard-nav.ts'
3
4
  import { setTabsContext } from './context.js'
4
5
  import type { TabsContext, TabsProps } from './types.ts'
5
6
 
@@ -11,13 +12,11 @@
11
12
  ...attributes
12
13
  }: TabsProps = $props()
13
14
 
14
- let uid = $props.id()
15
-
16
15
  // svelte-ignore state_referenced_locally
17
16
  let tabsContext = $state<TabsContext>({
18
17
  value,
18
+ indicatorValue: value,
19
19
  variant,
20
- id: uid,
21
20
  })
22
21
  $effect(() => {
23
22
  value = tabsContext.value
@@ -29,35 +28,22 @@
29
28
  })
30
29
  setTabsContext(tabsContext)
31
30
 
32
- const handleKeydown = (
33
- event: KeyboardEvent & {
34
- currentTarget: EventTarget & HTMLDivElement
35
- },
36
- ) => {
37
- const tabs = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('.np-tab'))
38
- if (tabs && tabs.length > 0 && (event.key === 'ArrowRight' || event.key === 'ArrowLeft')) {
39
- const focusedTab = event.currentTarget.querySelector<HTMLElement>('.np-tab:focus')
40
- const currentIndex = focusedTab ? tabs.indexOf(focusedTab) : 0
41
- const index = currentIndex + (event.key === 'ArrowRight' ? 1 : -1)
42
- const newTab =
43
- index < 0 ? tabs[tabs.length - 1] : index >= tabs.length ? tabs[0] : tabs[index]
44
- newTab.focus()
45
- event.preventDefault()
46
- }
47
- }
31
+ const secondaryStyle = $derived(
32
+ tabsContext.variant === 'secondary' ? '--np-indicator-radius: 0;--_indicator-gap: 0' : '',
33
+ )
34
+
35
+ const attach = rovingTabindex('.np-tab', { currentAttr: 'aria-selected', currentValue: 'true' })
36
+ const onkeydown = arrowKeyNav('.np-tab', 'horizontal')
48
37
  </script>
49
38
 
50
- <nav
51
- {...attributes}
52
- bind:this={element}
53
- style={tabsContext.variant === 'secondary' ? '--np-indicator-radius: 0;--_indicator-gap: 0' : ''}
54
- >
39
+ <nav {...attributes} bind:this={element} style={secondaryStyle}>
55
40
  <div
41
+ {@attach attach}
56
42
  class={['np-tabs']}
57
43
  role="tablist"
58
44
  aria-orientation="horizontal"
59
45
  tabindex="-1"
60
- onkeydown={handleKeydown}
46
+ {onkeydown}
61
47
  >
62
48
  {@render children?.()}
63
49
  </div>
@@ -65,7 +51,7 @@
65
51
  </nav>
66
52
 
67
53
  <style>
68
- :global(.np-tabs .np-tab-content-active .np-indicator) {
54
+ :global(.np-tabs .np-indicator-anchor) {
69
55
  anchor-name: --np-tab-indicator;
70
56
  }
71
57
  .np-tabs {
@@ -92,7 +78,7 @@
92
78
  border-start-start-radius: var(--np-indicator-radius, var(--np-shape-corner-full));
93
79
  border-start-end-radius: var(--np-indicator-radius, var(--np-shape-corner-full));
94
80
  position-anchor: --np-tab-indicator;
95
- transition: cubic-bezier(0.33, 1, 0.68, 1) 0.3s;
81
+ transition: var(--np-motion-expressive-fast-spatial);
96
82
  }
97
83
  }
98
84
  </style>
@@ -16,6 +16,6 @@ export interface TabsProps extends HTMLAttributes<HTMLElement> {
16
16
  }
17
17
  export interface TabsContext {
18
18
  value: string | number;
19
+ indicatorValue: string | number;
19
20
  variant: 'primary' | 'secondary';
20
- id: string;
21
21
  }
@@ -171,7 +171,7 @@
171
171
  }
172
172
  .active-indicator::after {
173
173
  opacity: 0;
174
- transition: opacity 150ms cubic-bezier(0.2, 0, 0, 1);
174
+ transition: opacity var(--np-motion-expressive-fast-effects);
175
175
  }
176
176
  .active-indicator::before,
177
177
  .active-indicator::after {
@@ -572,9 +572,7 @@
572
572
  inset-inline-start: var(--floating-label-inline-start, 0);
573
573
  }
574
574
  .label {
575
- transition-property: all;
576
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
577
- transition-duration: 150ms;
575
+ transition: all var(--np-motion-expressive-fast-effects);
578
576
  box-sizing: border-box;
579
577
  color: var(--np-color-on-surface-variant);
580
578
  overflow: hidden;
@@ -737,7 +735,7 @@
737
735
  .outline-end::after,
738
736
  .outline-notch::after {
739
737
  opacity: 0;
740
- transition: opacity 150ms cubic-bezier(0.2, 0, 0, 1);
738
+ transition: opacity var(--np-motion-expressive-fast-effects);
741
739
  }
742
740
  .field:has(input:focus-visible) .outline-start::after,
743
741
  .field:has(input:focus-visible) .outline-end::after,
@@ -63,6 +63,27 @@
63
63
  --np-elevation-3:
64
64
  rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px,
65
65
  rgba(0, 0, 0, 0.12) 0px 3px 14px 2px;
66
+
67
+ /* Motion: Expressive spatial */
68
+ --np-motion-expressive-fast-spatial: 350ms cubic-bezier(0.42, 1.67, 0.21, 0.9);
69
+ --np-motion-expressive-default-spatial: 500ms cubic-bezier(0.38, 1.21, 0.22, 1);
70
+ --np-motion-expressive-slow-spatial: 650ms cubic-bezier(0.39, 1.29, 0.35, 0.98);
71
+
72
+ /* Motion: Expressive effects */
73
+ --np-motion-expressive-fast-effects: 150ms cubic-bezier(0.31, 0.94, 0.34, 1);
74
+ --np-motion-expressive-default-effects: 200ms cubic-bezier(0.34, 0.8, 0.34, 1);
75
+ --np-motion-expressive-slow-effects: 300ms cubic-bezier(0.34, 0.88, 0.34, 1);
76
+
77
+ /* Motion: Standard spatial */
78
+ --np-motion-standard-fast-spatial: 350ms cubic-bezier(0.27, 1.06, 0.18, 1);
79
+ --np-motion-standard-default-spatial: 500ms cubic-bezier(0.27, 1.06, 0.18, 1);
80
+ --np-motion-standard-slow-spatial: 750ms cubic-bezier(0.27, 1.06, 0.18, 1);
81
+
82
+ /* Motion: Standard effects */
83
+ --np-motion-standard-fast-effects: 150ms cubic-bezier(0.31, 0.94, 0.34, 1);
84
+ --np-motion-standard-default-effects: 200ms cubic-bezier(0.34, 0.8, 0.34, 1);
85
+ --np-motion-standard-slow-effects: 300ms cubic-bezier(0.34, 0.88, 0.34, 1);
86
+
66
87
  --np-shape-corner-full: 9999px;
67
88
  --np-shape-corner-extra-small: 0.25rem;
68
89
  --np-shape-corner-small: 0.5rem;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
- import type { TooltipProps } from './types.ts'
3
- import { MediaQuery } from 'svelte/reactivity'
4
2
  import { on } from 'svelte/events'
3
+ import { MediaQuery } from 'svelte/reactivity'
4
+ import type { TooltipProps } from './types.ts'
5
5
 
6
6
  let {
7
7
  children,
@@ -127,7 +127,7 @@
127
127
  }
128
128
  .np-tooltip:popover-open {
129
129
  opacity: 1;
130
- animation: scaleIn 0.3s ease;
130
+ animation: scaleIn var(--np-motion-expressive-fast-spatial);
131
131
  }
132
132
 
133
133
  @keyframes scaleIn {
package/dist/types.d.ts CHANGED
@@ -13,7 +13,6 @@ export * from './progress/types.ts';
13
13
  export * from './radio/types.ts';
14
14
  export * from './ripple/types.ts';
15
15
  export * from './select/types.ts';
16
- export * from './slider/types.ts';
17
16
  export * from './snackbar/types.ts';
18
17
  export * from './switch/types.ts';
19
18
  export * from './text-field/types.ts';
package/dist/types.js CHANGED
@@ -13,7 +13,6 @@ export * from './progress/types.ts';
13
13
  export * from './radio/types.ts';
14
14
  export * from './ripple/types.ts';
15
15
  export * from './select/types.ts';
16
- export * from './slider/types.ts';
17
16
  export * from './snackbar/types.ts';
18
17
  export * from './switch/types.ts';
19
18
  export * from './text-field/types.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.32.9",
3
+ "version": "0.33.1",
4
4
  "license": "MIT",
5
5
  "homepage": "https://noph.dev",
6
6
  "repository": {
@@ -70,25 +70,25 @@
70
70
  "devDependencies": {
71
71
  "@eslint/js": "^10.0.1",
72
72
  "@materialx/material-color-utilities": "^0.4.8",
73
- "@playwright/test": "^1.58.2",
73
+ "@playwright/test": "^1.59.1",
74
74
  "@sveltejs/adapter-auto": "^7.0.1",
75
- "@sveltejs/kit": "^2.55.0",
75
+ "@sveltejs/kit": "^2.57.1",
76
76
  "@sveltejs/package": "^2.5.7",
77
77
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
78
78
  "@types/eslint": "^9.6.1",
79
- "eslint": "^10.1.0",
79
+ "eslint": "^10.2.1",
80
80
  "eslint-config-prettier": "^10.1.8",
81
- "eslint-plugin-svelte": "^3.16.0",
82
- "globals": "^17.4.0",
83
- "prettier": "^3.8.1",
81
+ "eslint-plugin-svelte": "^3.17.1",
82
+ "globals": "^17.5.0",
83
+ "prettier": "^3.8.3",
84
84
  "prettier-plugin-svelte": "^3.5.1",
85
85
  "publint": "^0.3.18",
86
- "svelte": "^5.55.0",
87
- "svelte-check": "^4.4.5",
88
- "typescript": "^6.0.2",
89
- "typescript-eslint": "^8.57.2",
90
- "vite": "8.0.3",
91
- "vitest": "^4.1.2"
86
+ "svelte": "^5.55.4",
87
+ "svelte-check": "^4.4.6",
88
+ "typescript": "^6.0.3",
89
+ "typescript-eslint": "^8.59.0",
90
+ "vite": "8.0.10",
91
+ "vitest": "^4.1.5"
92
92
  },
93
93
  "svelte": "./dist/index.js",
94
94
  "types": "./dist/index.d.ts",
@@ -1,26 +0,0 @@
1
- <script lang="ts">
2
- import type { SliderProps } from './types.ts'
3
-
4
- let {
5
- type = 'standard',
6
- orientation = 'horizontal',
7
- size = 'sm',
8
- stops = false,
9
- value = $bindable(0),
10
- min = 0,
11
- max = 100,
12
- step = 1,
13
- element = $bindable(),
14
- inputElement = $bindable(),
15
- ...attributes
16
- }: SliderProps = $props()
17
- </script>
18
-
19
- <input class={[orientation]} bind:this={inputElement} type="range" />
20
-
21
- <style>
22
- .vertical {
23
- writing-mode: vertical-lr;
24
- direction: rtl;
25
- }
26
- </style>
@@ -1,4 +0,0 @@
1
- import type { SliderProps } from './types.ts';
2
- declare const Slider: import("svelte").Component<SliderProps, {}, "element" | "value" | "inputElement">;
3
- type Slider = ReturnType<typeof Slider>;
4
- export default Slider;
@@ -1 +0,0 @@
1
- export { default as Slider } from './Slider.svelte';
@@ -1 +0,0 @@
1
- export { default as Slider } from './Slider.svelte';
@@ -1,11 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- export interface SliderProps extends Omit<HTMLInputAttributes, 'type' | 'role' | 'checked' | 'indeterminate' | 'size'> {
4
- type?: 'standard' | 'centered' | 'range';
5
- orientation?: 'horizontal' | 'vertical';
6
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
7
- stops?: boolean;
8
- insetIcon?: Snippet;
9
- inputElement?: HTMLInputElement;
10
- element?: HTMLDivElement;
11
- }
@@ -1 +0,0 @@
1
- export {};