noph-ui 0.23.0 → 0.23.2

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.
@@ -53,6 +53,11 @@
53
53
  onkeydown(event)
54
54
  }
55
55
  }
56
+ const setCheckInitialState = () => {
57
+ if (parentElement?.getAttribute('data-value') === value) {
58
+ selected = true
59
+ }
60
+ }
56
61
  </script>
57
62
 
58
63
  {#snippet content()}
@@ -97,6 +102,7 @@
97
102
 
98
103
  {#if href}
99
104
  <a
105
+ {@attach setCheckInitialState}
100
106
  {...attributes}
101
107
  {id}
102
108
  tabindex={selected ? 0 : -1}
@@ -118,6 +124,7 @@
118
124
  </a>
119
125
  {:else}
120
126
  <div
127
+ {@attach setCheckInitialState}
121
128
  {...attributes}
122
129
  {id}
123
130
  tabindex={selected ? 0 : -1}
@@ -4,65 +4,98 @@
4
4
  import type { TabsProps } from './types.ts'
5
5
 
6
6
  let { children, element = $bindable(), value = $bindable(), ...attributes }: TabsProps = $props()
7
- let tabs = $derived(
8
- element ? Array.from(element.querySelectorAll<HTMLElement>('.np-tab')) : undefined,
9
- )
10
- let activeTab = $derived(
11
- tabs && tabs.length > 0
12
- ? (tabs.find((t) => {
13
- return t.getAttribute('data-value') === value
14
- }) ?? tabs[0])
15
- : undefined,
16
- )
7
+ const initialValue = value
8
+
9
+ const getCurrentTabs = () => {
10
+ if (!element) {
11
+ return []
12
+ }
13
+ return Array.from(element.querySelectorAll<HTMLElement>('.np-tab'))
14
+ }
17
15
 
18
16
  $effect(() => {
19
- if (value === undefined) {
20
- value = activeTab?.getAttribute('data-value') ?? undefined
17
+ if (value) {
18
+ const tabs = getCurrentTabs()
19
+ const newTab = tabs?.find((tab) => tab.getAttribute('data-value') === value)
20
+ if (newTab) {
21
+ selectTab(newTab, tabs, { id: newTab.id, value })
22
+ }
21
23
  }
22
24
  })
23
25
 
24
- onMount(() => {
25
- element?.addEventListener('change', (event) => {
26
- const { detail } = event as CustomEvent<{ id: string; value: string | number }>
27
- const oldTab = activeTab
28
- const newTab = tabs?.find((tab) => tab.id === detail.id)
29
- if (newTab && oldTab) {
30
- const oldIndicator = oldTab.querySelector('.np-indicator') as HTMLElement
31
- const oldIndicatorRect = oldIndicator.getBoundingClientRect()
32
- if (oldIndicatorRect) {
33
- const newIndicator = newTab.querySelector<HTMLElement>('.np-indicator')
34
- if (newIndicator) {
35
- newIndicator.style.setProperty(
36
- '--np-tab-indicator-start',
37
- `${oldIndicatorRect.x - newIndicator.getBoundingClientRect().x}px`,
38
- )
39
- newIndicator.style.setProperty(
40
- '--np-tab-indicator-scale',
41
- `${oldIndicatorRect.width / newIndicator.clientWidth}`,
42
- )
43
- }
44
- }
45
- value = detail.value
46
- activeTab = newTab
47
- tabs?.forEach((tab) => {
48
- tab.dispatchEvent(new CustomEvent('change', { detail }))
49
- })
26
+ const selectTab = (
27
+ newTab: HTMLElement,
28
+ tabs: HTMLElement[],
29
+ detail: { id: string; value: string | number },
30
+ ) => {
31
+ const oldTab = tabs.find((tab) => tab.getAttribute('aria-selected') === 'true')
32
+ if (!oldTab || oldTab === newTab) {
33
+ return
34
+ }
35
+ const oldIndicator = oldTab.querySelector<HTMLElement>('.np-indicator')
36
+ const oldIndicatorRect = oldIndicator?.getBoundingClientRect()
37
+ if (oldIndicatorRect) {
38
+ const newIndicator = newTab.querySelector<HTMLElement>('.np-indicator')
39
+ if (newIndicator) {
40
+ newIndicator.style.setProperty(
41
+ '--np-tab-indicator-start',
42
+ `${oldIndicatorRect.x - newIndicator.getBoundingClientRect().x}px`,
43
+ )
44
+ newIndicator.style.setProperty(
45
+ '--np-tab-indicator-scale',
46
+ `${oldIndicatorRect.width / newIndicator.clientWidth}`,
47
+ )
50
48
  }
49
+ }
50
+ value = detail.value
51
+ tabs?.forEach((tab) => {
52
+ tab.dispatchEvent(new CustomEvent('change', { detail }))
51
53
  })
52
- activeTab?.dispatchEvent(new CustomEvent('change', { detail: { id: activeTab.id } }))
54
+ }
55
+
56
+ const onChange = (event: Event) => {
57
+ const { detail } = event as CustomEvent<{ id: string; value: string | number }>
58
+ const tabs = getCurrentTabs()
59
+ const newTab = tabs?.find((tab) => tab.id === detail.id)
60
+ if (newTab) {
61
+ selectTab(newTab, tabs, detail)
62
+ }
63
+ }
64
+
65
+ onMount(() => {
66
+ element?.addEventListener('change', onChange)
67
+ return () => {
68
+ element?.removeEventListener('change', onChange)
69
+ }
53
70
  })
71
+ const initialSetup = (el: HTMLElement) => {
72
+ const tabs = Array.from(el.querySelectorAll<HTMLElement>('.np-tab'))
73
+ const activeTab =
74
+ tabs && tabs.length > 0
75
+ ? (tabs.find((t) => {
76
+ return t.getAttribute('data-value') === initialValue
77
+ }) ?? tabs[0])
78
+ : undefined
79
+ if (initialValue === undefined) {
80
+ value = activeTab?.getAttribute('data-value') ?? undefined
81
+ } else {
82
+ value = initialValue
83
+ }
84
+ }
54
85
  </script>
55
86
 
56
- <div {...attributes} class={[attributes.class]}>
87
+ <div {@attach initialSetup} {...attributes} class={[attributes.class]}>
57
88
  <div
58
89
  class={['np-tabs']}
59
90
  role="tablist"
91
+ data-value={value}
60
92
  tabindex="-1"
61
93
  bind:this={element}
62
94
  onkeydown={(event) => {
95
+ const tabs = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('.np-tab'))
63
96
  if (tabs && tabs.length > 0 && (event.key === 'ArrowRight' || event.key === 'ArrowLeft')) {
64
- const focusedTab = event.currentTarget.querySelector('.np-tab:focus') as HTMLElement
65
- const currentIndex = tabs.indexOf(focusedTab)
97
+ const focusedTab = event.currentTarget.querySelector<HTMLElement>('.np-tab:focus')
98
+ const currentIndex = focusedTab ? tabs.indexOf(focusedTab) : 0
66
99
  const index = currentIndex + (event.key === 'ArrowRight' ? 1 : -1)
67
100
  const newTab =
68
101
  index < 0 ? tabs[tabs.length - 1] : index >= tabs.length ? tabs[0] : tabs[index]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.23.0",
3
+ "version": "0.23.2",
4
4
  "license": "MIT",
5
5
  "homepage": "https://noph.dev",
6
6
  "repository": {