webcoreui 0.0.10 → 0.0.12

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 (123) hide show
  1. package/README.md +35 -7
  2. package/astro.d.ts +8 -0
  3. package/astro.js +8 -0
  4. package/components/Accordion/Accordion.astro +10 -8
  5. package/components/Accordion/Accordion.svelte +8 -8
  6. package/components/Accordion/Accordion.tsx +7 -6
  7. package/components/Accordion/{accordion.scss → accordion.module.scss} +18 -10
  8. package/components/Alert/Alert.astro +11 -7
  9. package/components/Alert/Alert.svelte +9 -7
  10. package/components/Alert/Alert.tsx +11 -7
  11. package/components/Alert/alert.module.scss +54 -0
  12. package/components/Alert/alert.ts +3 -1
  13. package/components/Avatar/Avatar.astro +4 -4
  14. package/components/Avatar/Avatar.svelte +13 -7
  15. package/components/Avatar/Avatar.tsx +11 -9
  16. package/components/Avatar/{avatar.scss → avatar.module.scss} +2 -2
  17. package/components/Badge/Badge.astro +8 -8
  18. package/components/Badge/Badge.svelte +25 -13
  19. package/components/Badge/Badge.tsx +26 -8
  20. package/components/Badge/badge.module.scss +89 -0
  21. package/components/Badge/badge.ts +8 -1
  22. package/components/Button/Button.astro +10 -6
  23. package/components/Button/Button.svelte +15 -11
  24. package/components/Button/Button.tsx +11 -7
  25. package/components/Button/button.module.scss +94 -0
  26. package/components/Button/button.ts +6 -1
  27. package/components/Card/Card.astro +7 -15
  28. package/components/Card/Card.svelte +16 -13
  29. package/components/Card/Card.tsx +15 -11
  30. package/components/Card/card.module.scss +33 -0
  31. package/components/Checkbox/Checkbox.astro +10 -10
  32. package/components/Checkbox/Checkbox.svelte +19 -18
  33. package/components/Checkbox/Checkbox.tsx +12 -11
  34. package/components/Checkbox/{checkbox.scss → checkbox.module.scss} +16 -17
  35. package/components/Checkbox/checkbox.ts +5 -1
  36. package/components/ConditionalWrapper/ConditionalWrapper.svelte +1 -1
  37. package/components/Icon/Icon.svelte +1 -8
  38. package/components/Icon/Icon.tsx +1 -8
  39. package/components/Icon/map.ts +23 -0
  40. package/components/Input/Input.astro +50 -0
  41. package/components/Input/Input.svelte +52 -0
  42. package/components/Input/Input.tsx +59 -0
  43. package/components/Input/input.module.scss +87 -0
  44. package/components/Input/input.ts +50 -0
  45. package/components/Menu/Menu.astro +107 -0
  46. package/components/Menu/Menu.svelte +88 -0
  47. package/components/Menu/Menu.tsx +107 -0
  48. package/components/Menu/menu.module.scss +144 -0
  49. package/components/Menu/menu.ts +21 -0
  50. package/components/Progress/Progress.astro +42 -40
  51. package/components/Progress/Progress.svelte +40 -38
  52. package/components/Progress/Progress.tsx +48 -47
  53. package/components/Progress/{progress.scss → progress.module.scss} +66 -66
  54. package/components/Radio/Radio.astro +57 -57
  55. package/components/Radio/Radio.svelte +58 -56
  56. package/components/Radio/Radio.tsx +69 -68
  57. package/components/Radio/{radio.scss → radio.module.scss} +92 -92
  58. package/components/Radio/radio.ts +4 -0
  59. package/components/Rating/Rating.astro +13 -10
  60. package/components/Rating/Rating.svelte +15 -15
  61. package/components/Rating/Rating.tsx +22 -11
  62. package/components/Rating/{rating.scss → rating.module.scss} +10 -9
  63. package/components/Rating/rating.ts +1 -1
  64. package/components/Spinner/Spinner.astro +44 -42
  65. package/components/Spinner/Spinner.svelte +40 -38
  66. package/components/Spinner/Spinner.tsx +45 -44
  67. package/components/Spinner/{spinner.scss → spinner.module.scss} +41 -41
  68. package/components/Switch/Switch.astro +13 -11
  69. package/components/Switch/Switch.svelte +26 -24
  70. package/components/Switch/Switch.tsx +14 -12
  71. package/components/Switch/{switch.scss → switch.module.scss} +4 -4
  72. package/components/Switch/switch.ts +8 -4
  73. package/components/Table/Table.astro +60 -0
  74. package/components/Table/Table.svelte +56 -0
  75. package/components/Table/Table.tsx +64 -0
  76. package/components/Table/table.module.scss +64 -0
  77. package/components/Table/table.ts +10 -0
  78. package/components/Tabs/Tabs.astro +77 -76
  79. package/components/Tabs/Tabs.svelte +56 -54
  80. package/components/Tabs/Tabs.tsx +70 -69
  81. package/components/Tabs/{tabs.scss → tabs.module.scss} +30 -31
  82. package/components/ThemeSwitcher/ThemeSwitcher.astro +106 -0
  83. package/components/ThemeSwitcher/ThemeSwitcher.svelte +76 -0
  84. package/components/ThemeSwitcher/ThemeSwitcher.tsx +89 -0
  85. package/components/ThemeSwitcher/themeswitcher.module.scss +74 -0
  86. package/components/ThemeSwitcher/themeswitcher.ts +13 -0
  87. package/components/Timeline/Timeline.astro +36 -34
  88. package/components/Timeline/Timeline.svelte +32 -30
  89. package/components/Timeline/Timeline.tsx +38 -37
  90. package/components/Timeline/{timeline.scss → timeline.module.scss} +71 -71
  91. package/components/TimelineItem/TimelineItem.astro +27 -26
  92. package/components/TimelineItem/TimelineItem.svelte +24 -22
  93. package/components/TimelineItem/TimelineItem.tsx +33 -32
  94. package/components/TimelineItem/{timelineitem.scss → timelineitem.module.scss} +31 -31
  95. package/components/Toast/Toast.astro +41 -30
  96. package/components/Toast/Toast.svelte +32 -21
  97. package/components/Toast/Toast.tsx +38 -28
  98. package/components/Toast/{toast.scss → toast.module.scss} +44 -43
  99. package/components/Toast/toast.ts +3 -6
  100. package/icons/moon.svg +3 -0
  101. package/icons/sun.svg +3 -0
  102. package/index.js +3 -0
  103. package/package.json +3 -1
  104. package/react.d.ts +8 -0
  105. package/react.js +8 -0
  106. package/scss/global/elements.scss +1 -1
  107. package/scss/global/scrollbar.scss +21 -0
  108. package/scss/global/theme.scss +140 -0
  109. package/scss/global/tooltip.scss +8 -5
  110. package/scss/global/utility.scss +29 -0
  111. package/scss/global.scss +2 -0
  112. package/scss/resets.scss +5 -5
  113. package/scss/setup.scss +39 -18
  114. package/svelte.d.ts +18 -10
  115. package/svelte.js +8 -0
  116. package/utils/classNames.ts +4 -0
  117. package/utils/cookies.ts +28 -0
  118. package/utils/event.ts +17 -0
  119. package/utils/toast.ts +12 -9
  120. package/components/Alert/alert.scss +0 -53
  121. package/components/Badge/badge.scss +0 -85
  122. package/components/Button/button.scss +0 -91
  123. package/components/Card/card.scss +0 -37
@@ -1,76 +1,77 @@
1
- ---
2
- import type { TabsProps } from './tabs'
3
- import './tabs.scss'
4
-
5
- interface Props extends TabsProps {}
6
-
7
- const {
8
- items,
9
- theme,
10
- vertical,
11
- even,
12
- className
13
- } = Astro.props
14
-
15
- const classes = [
16
- 'w-tabs',
17
- theme && theme,
18
- vertical && 'vertical',
19
- even && 'even',
20
- className
21
- ]
22
- ---
23
-
24
- <section class:list={classes} data-id="w-tabs">
25
- <div class="tabs-wrapper">
26
- <div class="tabs">
27
- {items.map(item => (
28
- <button
29
- data-value={item.value}
30
- class:list={[item.active && 'active']}
31
- disabled={item.disabled}
32
- >
33
- <Fragment set:html={item.label} />
34
- </button>
35
- ))}
36
- </div>
37
- </div>
38
- <div class="tab-content">
39
- <slot />
40
- </div>
41
- </section>
42
-
43
- <script>
44
- const tabs = document.querySelectorAll('[data-id="w-tabs"]')
45
-
46
- Array.from(tabs).forEach(element => {
47
- element.addEventListener('click', event => {
48
- const target = event.target as HTMLDivElement
49
-
50
- if (target.dataset.value) {
51
- const tabContent = target.parentElement
52
- ?.parentElement
53
- ?.nextElementSibling as HTMLDivElement
54
-
55
- Array.from(tabContent.children)
56
- .forEach((element: any) => {
57
- if (element.dataset.tab === target.dataset.value) {
58
- element.dataset.active = true
59
- } else {
60
- element.dataset.active = false
61
- }
62
- })
63
-
64
- const tabs = target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>
65
-
66
- Array.from(tabs).forEach((tab: any) => {
67
- tab.classList.remove('active')
68
-
69
- if (tab.dataset.value === target.dataset.value) {
70
- tab.classList.add('active')
71
- }
72
- })
73
- }
74
- })
75
- })
76
- </script>
1
+ ---
2
+ import type { TabsProps } from './tabs'
3
+ import styles from './tabs.module.scss'
4
+
5
+ interface Props extends TabsProps {}
6
+
7
+ const {
8
+ items,
9
+ theme,
10
+ vertical,
11
+ even,
12
+ className
13
+ } = Astro.props
14
+
15
+ const classes = [
16
+ styles.tabs,
17
+ theme && styles[theme],
18
+ vertical && styles.vertical,
19
+ even && styles.even,
20
+ className
21
+ ]
22
+ ---
23
+
24
+ <section class:list={classes} data-id="w-tabs">
25
+ <div class={styles.wrapper}>
26
+ <div class={styles.items}>
27
+ {items.map(item => (
28
+ <button
29
+ data-value={item.value}
30
+ data-active={item.active ? 'true' : null}
31
+ disabled={item.disabled}
32
+ >
33
+ <Fragment set:html={item.label} />
34
+ </button>
35
+ ))}
36
+ </div>
37
+ </div>
38
+ <div class={styles.content}>
39
+ <slot />
40
+ </div>
41
+ </section>
42
+
43
+ <script>
44
+ const tabs = document.querySelectorAll('[data-id="w-tabs"]')
45
+
46
+ Array.from(tabs).forEach(element => {
47
+ element.addEventListener('click', event => {
48
+ const target = event.target as HTMLDivElement
49
+
50
+ if (target.dataset.value) {
51
+ const tabContent = target.parentElement
52
+ ?.parentElement
53
+ ?.nextElementSibling as HTMLDivElement
54
+
55
+ Array.from(tabContent.children)
56
+ .forEach((element: any) => {
57
+ if (element.dataset.tab === target.dataset.value) {
58
+ element.dataset.active = true
59
+ } else {
60
+ element.dataset.active = false
61
+ }
62
+ })
63
+
64
+ const tabs = target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>
65
+
66
+ // TODO - update logic
67
+ Array.from(tabs).forEach((tab: any) => {
68
+ tab.dataset.active = 'false'
69
+
70
+ if (tab.dataset.value === target.dataset.value) {
71
+ tab.dataset.active = 'true'
72
+ }
73
+ })
74
+ }
75
+ })
76
+ })
77
+ </script>
@@ -1,54 +1,56 @@
1
- <script lang="ts">
2
- import type { TabsProps } from './tabs'
3
- import './tabs.scss'
4
-
5
- export let items: TabsProps['items'] = []
6
- export let theme: TabsProps['theme'] = null
7
- export let vertical: TabsProps['vertical'] = false
8
- export let even: TabsProps['even'] = false
9
- export let className: TabsProps['className'] = ''
10
-
11
- let active = ''
12
- let tabContainer: HTMLDivElement
13
-
14
- const classes = [
15
- 'w-tabs',
16
- theme && theme,
17
- vertical && 'vertical',
18
- even && 'even',
19
- className
20
- ].filter(Boolean).join(' ')
21
-
22
- const setTab = (tab: string) => {
23
- const tabs = tabContainer.querySelectorAll('[data-tab]')
24
-
25
- active = tab
26
-
27
- Array.from(tabs).forEach((item: any) => {
28
- item.dataset.active = false
29
-
30
- if (item.dataset.tab === active) {
31
- item.dataset.active = true
32
- }
33
- })
34
- }
35
- </script>
36
-
37
- <section class={classes}>
38
- <div class="tabs-wrapper">
39
- <div class="tabs">
40
- {#each items as item}
41
- <button
42
- class:active={active ? active === item.value : item.active}
43
- disabled={item.disabled}
44
- on:click={() => setTab(item.value)}
45
- >
46
- {@html item.label}
47
- </button>
48
- {/each}
49
- </div>
50
- </div>
51
- <div class="tab-content" bind:this={tabContainer}>
52
- <slot />
53
- </div>
54
- </section>
1
+ <script lang="ts">
2
+ import type { TabsProps } from './tabs'
3
+
4
+ import styles from './tabs.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ export let items: TabsProps['items'] = []
8
+ export let theme: TabsProps['theme'] = null
9
+ export let vertical: TabsProps['vertical'] = false
10
+ export let even: TabsProps['even'] = false
11
+ export let className: TabsProps['className'] = ''
12
+
13
+ let active = ''
14
+ let tabContainer: HTMLDivElement
15
+
16
+ const classes = classNames([
17
+ styles.tabs,
18
+ theme && styles[theme],
19
+ vertical && styles.vertical,
20
+ even && styles.even,
21
+ className
22
+ ])
23
+
24
+ const setTab = (tab: string) => {
25
+ const tabs = tabContainer.querySelectorAll('[data-tab]')
26
+
27
+ active = tab
28
+
29
+ Array.from(tabs).forEach((item: any) => {
30
+ item.dataset.active = false
31
+
32
+ if (item.dataset.tab === active) {
33
+ item.dataset.active = true
34
+ }
35
+ })
36
+ }
37
+ </script>
38
+
39
+ <section class={classes}>
40
+ <div class={styles.wrapper}>
41
+ <div class={styles.items}>
42
+ {#each items as item}
43
+ <button
44
+ data-active={active ? active === item.value : item.active}
45
+ disabled={item.disabled}
46
+ on:click={() => setTab(item.value)}
47
+ >
48
+ {@html item.label}
49
+ </button>
50
+ {/each}
51
+ </div>
52
+ </div>
53
+ <div class={styles.content} bind:this={tabContainer}>
54
+ <slot />
55
+ </div>
56
+ </section>
@@ -1,69 +1,70 @@
1
- import React, { useState, useRef } from 'react'
2
- import type { ReactTabsProps } from './tabs'
3
-
4
- import './tabs.scss'
5
-
6
- const Tabs = ({
7
- items,
8
- theme,
9
- vertical,
10
- even,
11
- className,
12
- children
13
- }: ReactTabsProps) => {
14
- const tabContainer = useRef<HTMLDivElement>(null)
15
- const [active, setActive] = useState('')
16
-
17
- const classes = [
18
- 'w-tabs',
19
- theme && theme,
20
- vertical && 'vertical',
21
- even && 'even',
22
- className
23
- ].filter(Boolean).join(' ')
24
-
25
- const setTab = (tab: string) => {
26
- const tabs = tabContainer.current!.querySelectorAll('[data-tab]')
27
-
28
- Array.from(tabs).forEach((item: any) => {
29
- item.dataset.active = false
30
-
31
- if (item.dataset.tab === tab) {
32
- item.dataset.active = true
33
- }
34
- })
35
-
36
- setActive(tab)
37
- }
38
-
39
- const isActive = (item: ReactTabsProps['items'][0]) => {
40
- if (!active) {
41
- return item.active ? 'active' : undefined
42
- }
43
-
44
- return active === item.value ? 'active' : undefined
45
- }
46
-
47
- return (
48
- <section className={classes}>
49
- <div className="tabs-wrapper">
50
- <div className="tabs">
51
- {items.map((item, index) => (
52
- <button
53
- key={index}
54
- disabled={item.disabled}
55
- dangerouslySetInnerHTML={{ __html: item.label }}
56
- onClick={() => setTab(item.value)}
57
- className={isActive(item)}
58
- />
59
- ))}
60
- </div>
61
- </div>
62
- <div className="tab-content" ref={tabContainer}>
63
- {children}
64
- </div>
65
- </section>
66
- )
67
- }
68
-
69
- export default Tabs
1
+ import React, { useState, useRef } from 'react'
2
+ import type { ReactTabsProps } from './tabs'
3
+
4
+ import styles from './tabs.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ const Tabs = ({
8
+ items,
9
+ theme,
10
+ vertical,
11
+ even,
12
+ className,
13
+ children
14
+ }: ReactTabsProps) => {
15
+ const tabContainer = useRef<HTMLDivElement>(null)
16
+ const [active, setActive] = useState('')
17
+
18
+ const classes = classNames([
19
+ styles.tabs,
20
+ theme && styles[theme],
21
+ vertical && styles.vertical,
22
+ even && styles.even,
23
+ className
24
+ ])
25
+
26
+ const setTab = (tab: string) => {
27
+ const tabs = tabContainer.current!.querySelectorAll('[data-tab]')
28
+
29
+ Array.from(tabs).forEach((item: any) => {
30
+ item.dataset.active = false
31
+
32
+ if (item.dataset.tab === tab) {
33
+ item.dataset.active = true
34
+ }
35
+ })
36
+
37
+ setActive(tab)
38
+ }
39
+
40
+ const isActive = (item: ReactTabsProps['items'][0]) => {
41
+ if (!active) {
42
+ return item.active ? 'true' : undefined
43
+ }
44
+
45
+ return active === item.value ? 'true' : undefined
46
+ }
47
+
48
+ return (
49
+ <section className={classes}>
50
+ <div className={styles.wrapper}>
51
+ <div className={styles.items}>
52
+ {items.map((item, index) => (
53
+ <button
54
+ key={index}
55
+ disabled={item.disabled}
56
+ dangerouslySetInnerHTML={{ __html: item.label }}
57
+ onClick={() => setTab(item.value)}
58
+ data-active={isActive(item)}
59
+ />
60
+ ))}
61
+ </div>
62
+ </div>
63
+ <div className={styles.content} ref={tabContainer}>
64
+ {children}
65
+ </div>
66
+ </section>
67
+ )
68
+ }
69
+
70
+ export default Tabs
@@ -1,41 +1,40 @@
1
1
  @import '../../scss/config.scss';
2
2
 
3
- .w-tabs {
4
-
5
- &.boxed .tabs,
6
- &.outline .tabs {
7
- background: #252525;
3
+ .tabs {
4
+ &.boxed .items,
5
+ &.outline .items {
6
+ background: var(--w-color-primary-50);
8
7
  border-radius: 5px;
9
8
  padding: 5px;
10
- width: fit-content;
9
+ width: max-content;
11
10
 
12
11
  button {
13
12
  @include Transition();
14
13
  border-radius: 5px;
15
14
  padding: 10px;
16
15
 
17
- &.active {
16
+ &[data-active="true"] {
18
17
  border: 0;
19
- background: #000;
18
+ background: var(--w-color-primary-70);
20
19
  padding-bottom: 10px;
21
20
  }
22
21
  }
23
22
  }
24
23
 
25
- &.outline .tabs {
24
+ &.outline .items {
26
25
  background: transparent;
27
- border: 1px solid #252525;
26
+ border: 1px solid var(--w-color-primary-50);
28
27
 
29
28
  button {
30
29
  margin-bottom: 0;
31
30
 
32
- &.active {
33
- background: #252525;
31
+ &[data-active="true"] {
32
+ background: var(--w-color-primary-50);
34
33
  }
35
34
  }
36
35
  }
37
36
 
38
- &.even .tabs button {
37
+ &.even .items button {
39
38
  flex: 1;
40
39
  justify-content: center;
41
40
  }
@@ -44,36 +43,36 @@
44
43
  display: flex;
45
44
  gap: 20px;
46
45
 
47
- &.boxed .tabs button,
48
- &.outline .tabs button {
46
+ &.boxed .items button,
47
+ &.outline .items button {
49
48
  border-bottom: 0;
50
49
  }
51
50
 
52
- .tabs {
51
+ .items {
53
52
  flex-direction: column;
54
53
  gap: 5px;
55
54
 
56
55
  button {
57
56
  padding: 10px;
58
- border-bottom: 2px solid #252525;
57
+ border-bottom: 2px solid var(--w-color-primary-50);
59
58
 
60
- &.active {
59
+ &[data-active="true"] {
61
60
  padding-bottom: 10px;
62
61
  }
63
62
  }
64
63
  }
65
64
 
66
- .tab-content {
65
+ .content {
67
66
  margin-top: 0;
68
67
  }
69
68
  }
70
69
 
71
- .tabs-wrapper {
70
+ .wrapper {
72
71
  overflow: auto;
73
72
  }
74
73
 
75
- .tabs {
76
- border-bottom: 2px solid #252525;
74
+ .items {
75
+ border-bottom: 2px solid var(--w-color-primary-50);
77
76
  display: flex;
78
77
  gap: 10px;
79
78
 
@@ -81,13 +80,13 @@
81
80
  @include Transition(color);
82
81
  background: transparent;
83
82
  cursor: pointer;
84
- color: #FFF;
83
+ color: var(--w-color-primary);
85
84
  border: 0;
86
85
  font-size: 16px;
87
86
  padding: 0;
88
87
  margin-bottom: -2px;
89
88
  padding: 15px 15px;
90
- color: #BBB;
89
+ color: var(--w-color-primary-20);
91
90
  display: flex;
92
91
  align-items: center;
93
92
  gap: 10px;
@@ -100,19 +99,19 @@
100
99
  }
101
100
 
102
101
  &[disabled] {
103
- color: #555;
102
+ color: var(--w-color-primary-30);
104
103
  cursor: no-drop;
105
104
  }
106
105
 
107
- &.active {
108
- color: #FFF;
109
- border-bottom: 2px solid #FFF;
106
+ &[data-active="true"] {
107
+ color: var(--w-color-primary);
108
+ border-bottom: 2px solid var(--w-color-primary);
110
109
  padding-bottom: 13px;
111
110
  }
112
111
  }
113
112
  }
114
113
 
115
- .tab-content {
114
+ .content {
116
115
  margin-top: 20px;
117
116
  }
118
117
 
@@ -126,8 +125,8 @@
126
125
  }
127
126
 
128
127
  @include Media('xs') {
129
- .w-tabs {
130
- &.even .tabs {
128
+ .tabs {
129
+ &.even .items {
131
130
  width: auto;
132
131
  }
133
132
  }
@@ -0,0 +1,106 @@
1
+ ---
2
+ import type { ThemeSwitcherProps } from './themeswitcher'
3
+ import styles from './themeswitcher.module.scss'
4
+
5
+ interface Props extends ThemeSwitcherProps {}
6
+
7
+ const {
8
+ themes,
9
+ toggle,
10
+ size,
11
+ className
12
+ } = Astro.props
13
+
14
+ const classes = [
15
+ styles.switcher,
16
+ toggle && styles.toggle,
17
+ className
18
+ ]
19
+
20
+ const primaryTheme = themes[Object.keys(themes)[0]]
21
+ const secondaryTheme = themes[Object.keys(themes)[1]]
22
+ const useIcons = Astro.slots.has('primaryIcon') && Astro.slots.has('secondaryIcon')
23
+
24
+ const buttonClasses = [
25
+ styles.switch,
26
+ useIcons && styles.icons
27
+ ]
28
+ ---
29
+
30
+ <div
31
+ class:list={classes}
32
+ style={size ? `--w-theme-switcher-size: ${size}px;` : null}
33
+ data-id="w-theme-switcher"
34
+ data-primary-theme={primaryTheme}
35
+ data-secondary-theme={toggle ? secondaryTheme : undefined}
36
+ >
37
+ {Object.keys(themes as {}).map((theme, index) => (
38
+ <button
39
+ style={!useIcons ? `background:${theme};` : undefined}
40
+ data-theme={themes[theme]}
41
+ class:list={buttonClasses}
42
+ >
43
+ {index === 0 && <slot name="primaryIcon" />}
44
+ {index !== 0 && <slot name="secondaryIcon" />}
45
+ </button>
46
+ ))}
47
+ </div>
48
+
49
+ <script>
50
+ import { setCookie, getCookie } from '../../utils/cookies'
51
+ import { listen, dispatch } from '../../utils/event'
52
+
53
+ const switchers = document.querySelectorAll('[data-id="w-theme-switcher"]')
54
+
55
+ let currentTheme = localStorage.getItem('w-theme')
56
+ || getCookie('w-theme')
57
+ || (switchers[0] as HTMLDivElement).dataset.primaryTheme
58
+ || ''
59
+
60
+ const setActiveButton = (buttons: HTMLButtonElement[]) => {
61
+ buttons.forEach(button => button.dataset.active = 'false')
62
+
63
+ buttons.forEach(button => {
64
+ if (button.dataset.theme === currentTheme) {
65
+ button.dataset.active = 'true'
66
+ }
67
+ })
68
+ }
69
+
70
+ Array.from(switchers).forEach(switcher => {
71
+ const buttons = Array.from(switcher.querySelectorAll('button'))
72
+
73
+ setActiveButton(buttons)
74
+
75
+ listen('theme-switched', theme => {
76
+ currentTheme = theme
77
+
78
+ setActiveButton(buttons)
79
+ })
80
+
81
+ switcher.addEventListener('click', event => {
82
+ const target = event.target as HTMLButtonElement
83
+
84
+ if (target.nodeName === 'BUTTON') {
85
+ const toggleTheme = (switcher as HTMLDivElement).dataset.secondaryTheme
86
+
87
+ const theme = toggleTheme
88
+ ? toggleTheme === target.dataset.theme
89
+ ? (target.previousElementSibling as HTMLButtonElement).dataset.theme as string
90
+ : (target.nextElementSibling as HTMLButtonElement).dataset.theme as string
91
+ : target.dataset.theme as string
92
+
93
+ document.body.classList.replace(currentTheme, theme)
94
+
95
+ currentTheme = theme
96
+
97
+ setActiveButton(buttons)
98
+ setCookie('w-theme', currentTheme, 30)
99
+ localStorage.setItem('w-theme', currentTheme)
100
+
101
+ dispatch('theme-switched', currentTheme)
102
+ }
103
+ })
104
+ })
105
+ </script>
106
+