webcoreui 1.4.0 → 1.5.0-beta.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.
Files changed (262) hide show
  1. package/README.md +15 -1
  2. package/astro.d.ts +62 -56
  3. package/astro.js +4 -0
  4. package/components/Accordion/Accordion.astro +1 -1
  5. package/components/Accordion/Accordion.svelte +60 -58
  6. package/components/Accordion/Accordion.tsx +3 -1
  7. package/components/Alert/Alert.astro +2 -1
  8. package/components/Alert/Alert.svelte +12 -5
  9. package/components/Alert/Alert.tsx +10 -3
  10. package/components/Alert/alert.ts +2 -18
  11. package/components/AspectRatio/AspectRatio.astro +1 -1
  12. package/components/AspectRatio/AspectRatio.svelte +27 -22
  13. package/components/AspectRatio/AspectRatio.tsx +6 -3
  14. package/components/AspectRatio/aspectratio.ts +0 -10
  15. package/components/Avatar/Avatar.astro +1 -1
  16. package/components/Avatar/Avatar.svelte +7 -5
  17. package/components/Avatar/Avatar.tsx +3 -2
  18. package/components/Avatar/avatar.module.scss +3 -5
  19. package/components/Badge/Badge.astro +2 -1
  20. package/components/Badge/Badge.svelte +11 -4
  21. package/components/Badge/Badge.tsx +8 -3
  22. package/components/Badge/badge.module.scss +5 -6
  23. package/components/Badge/badge.ts +11 -13
  24. package/components/Banner/Banner.astro +1 -1
  25. package/components/Banner/Banner.svelte +11 -5
  26. package/components/Banner/Banner.tsx +6 -2
  27. package/components/Banner/banner.module.scss +4 -6
  28. package/components/Banner/banner.ts +0 -10
  29. package/components/BottomNavigation/BottomNavigation.astro +1 -1
  30. package/components/BottomNavigation/BottomNavigation.svelte +7 -4
  31. package/components/BottomNavigation/BottomNavigation.tsx +3 -2
  32. package/components/BottomNavigation/bottomnavigation.module.scss +68 -70
  33. package/components/Breadcrumb/Breadcrumb.astro +1 -1
  34. package/components/Breadcrumb/Breadcrumb.svelte +5 -3
  35. package/components/Breadcrumb/Breadcrumb.tsx +3 -1
  36. package/components/Button/Button.astro +2 -1
  37. package/components/Button/Button.svelte +11 -4
  38. package/components/Button/Button.tsx +7 -2
  39. package/components/Button/button.module.scss +9 -12
  40. package/components/Button/button.ts +23 -20
  41. package/components/Card/Card.astro +9 -2
  42. package/components/Card/Card.svelte +21 -8
  43. package/components/Card/Card.tsx +23 -6
  44. package/components/Card/card.module.scss +12 -9
  45. package/components/Card/card.ts +3 -16
  46. package/components/Carousel/Carousel.astro +3 -3
  47. package/components/Carousel/Carousel.svelte +24 -19
  48. package/components/Carousel/Carousel.tsx +9 -4
  49. package/components/Carousel/carousel.module.scss +3 -5
  50. package/components/Carousel/carousel.ts +0 -12
  51. package/components/CarouselItem/CarouselItem.astro +14 -0
  52. package/components/CarouselItem/CarouselItem.svelte +18 -0
  53. package/components/CarouselItem/CarouselItem.tsx +18 -0
  54. package/components/CarouselItem/carouselItem.ts +4 -0
  55. package/components/Checkbox/Checkbox.astro +3 -6
  56. package/components/Checkbox/Checkbox.svelte +13 -10
  57. package/components/Checkbox/Checkbox.tsx +8 -5
  58. package/components/Checkbox/checkbox.module.scss +4 -6
  59. package/components/Checkbox/checkbox.ts +2 -17
  60. package/components/Collapsible/Collapsible.astro +1 -1
  61. package/components/Collapsible/Collapsible.svelte +13 -6
  62. package/components/Collapsible/Collapsible.tsx +8 -2
  63. package/components/Collapsible/collapsible.module.scss +5 -5
  64. package/components/Collapsible/collapsible.ts +0 -15
  65. package/components/ConditionalWrapper/ConditionalWrapper.astro +1 -1
  66. package/components/ConditionalWrapper/ConditionalWrapper.svelte +8 -2
  67. package/components/ConditionalWrapper/ConditionalWrapper.tsx +7 -2
  68. package/components/ConditionalWrapper/conditionalwrapper.ts +2 -14
  69. package/components/ContextMenu/ContextMenu.astro +2 -1
  70. package/components/ContextMenu/ContextMenu.svelte +17 -9
  71. package/components/ContextMenu/ContextMenu.tsx +8 -2
  72. package/components/ContextMenu/contextmenu.ts +2 -17
  73. package/components/Copy/Copy.astro +2 -2
  74. package/components/Copy/Copy.svelte +10 -5
  75. package/components/Copy/Copy.tsx +7 -3
  76. package/components/Copy/copy.ts +2 -12
  77. package/components/Counter/Counter.astro +3 -2
  78. package/components/Counter/Counter.svelte +16 -10
  79. package/components/Counter/Counter.tsx +11 -7
  80. package/components/Counter/counter.module.scss +3 -5
  81. package/components/Counter/counter.ts +2 -11
  82. package/components/DataTable/DataTable.astro +1 -1
  83. package/components/DataTable/DataTable.svelte +23 -15
  84. package/components/DataTable/DataTable.tsx +7 -2
  85. package/components/DataTable/datatable.ts +0 -12
  86. package/components/Flex/Flex.astro +2 -1
  87. package/components/Flex/Flex.svelte +12 -6
  88. package/components/Flex/Flex.tsx +8 -3
  89. package/components/Flex/flex.ts +2 -15
  90. package/components/Footer/Footer.astro +1 -1
  91. package/components/Footer/Footer.svelte +13 -8
  92. package/components/Footer/Footer.tsx +6 -2
  93. package/components/Footer/footer.ts +0 -10
  94. package/components/Grid/Grid.astro +2 -1
  95. package/components/Grid/Grid.svelte +12 -6
  96. package/components/Grid/Grid.tsx +8 -3
  97. package/components/Grid/grid.ts +2 -15
  98. package/components/Group/Group.astro +1 -1
  99. package/components/Group/Group.svelte +9 -4
  100. package/components/Group/Group.tsx +6 -2
  101. package/components/Group/group.ts +0 -10
  102. package/components/Icon/Icon.astro +1 -1
  103. package/components/Icon/Icon.svelte +16 -9
  104. package/components/Icon/Icon.tsx +3 -2
  105. package/components/Image/Image.astro +2 -1
  106. package/components/Image/Image.svelte +54 -51
  107. package/components/Image/Image.tsx +3 -1
  108. package/components/Image/image.ts +2 -3
  109. package/components/ImageLoader/ImageLoader.astro +1 -1
  110. package/components/ImageLoader/ImageLoader.svelte +5 -3
  111. package/components/ImageLoader/ImageLoader.tsx +3 -1
  112. package/components/Input/Input.astro +3 -2
  113. package/components/Input/Input.svelte +19 -9
  114. package/components/Input/Input.tsx +11 -3
  115. package/components/Input/input.ts +26 -53
  116. package/components/Kbd/Kbd.astro +1 -1
  117. package/components/Kbd/Kbd.svelte +9 -4
  118. package/components/Kbd/Kbd.tsx +6 -2
  119. package/components/Kbd/kbd.ts +0 -10
  120. package/components/List/List.astro +1 -1
  121. package/components/List/List.svelte +13 -9
  122. package/components/List/List.tsx +10 -6
  123. package/components/List/list.ts +0 -8
  124. package/components/Masonry/Masonry.astro +1 -1
  125. package/components/Masonry/Masonry.svelte +14 -9
  126. package/components/Masonry/Masonry.tsx +7 -3
  127. package/components/Masonry/masonry.module.scss +4 -6
  128. package/components/Masonry/masonry.ts +2 -13
  129. package/components/Menu/Menu.astro +1 -1
  130. package/components/Menu/Menu.svelte +13 -7
  131. package/components/Menu/Menu.tsx +6 -2
  132. package/components/Menu/menu.ts +0 -10
  133. package/components/Modal/Modal.astro +2 -3
  134. package/components/Modal/Modal.svelte +12 -8
  135. package/components/Modal/Modal.tsx +6 -4
  136. package/components/Modal/modal.module.scss +5 -5
  137. package/components/Modal/modal.ts +2 -14
  138. package/components/OTPInput/OTPInput.astro +3 -5
  139. package/components/OTPInput/OTPInput.svelte +10 -10
  140. package/components/OTPInput/OTPInput.tsx +10 -8
  141. package/components/OTPInput/otpinput.module.scss +0 -12
  142. package/components/OTPInput/otpinput.ts +2 -4
  143. package/components/Pagination/Pagination.astro +1 -1
  144. package/components/Pagination/Pagination.svelte +8 -4
  145. package/components/Pagination/Pagination.tsx +6 -2
  146. package/components/Pagination/pagination.ts +0 -8
  147. package/components/Popover/Popover.astro +3 -7
  148. package/components/Popover/Popover.svelte +11 -10
  149. package/components/Popover/Popover.tsx +9 -12
  150. package/components/Popover/popover.ts +2 -15
  151. package/components/Progress/Progress.astro +1 -1
  152. package/components/Progress/Progress.svelte +8 -6
  153. package/components/Progress/Progress.tsx +3 -1
  154. package/components/Progress/progress.module.scss +15 -17
  155. package/components/Radio/Radio.astro +4 -4
  156. package/components/Radio/Radio.svelte +15 -8
  157. package/components/Radio/Radio.tsx +8 -5
  158. package/components/Radio/radio.module.scss +4 -6
  159. package/components/Radio/radio.ts +3 -14
  160. package/components/RangeSlider/RangeSlider.astro +5 -2
  161. package/components/RangeSlider/RangeSlider.svelte +20 -35
  162. package/components/RangeSlider/RangeSlider.tsx +11 -4
  163. package/components/RangeSlider/rangeslider.module.scss +14 -16
  164. package/components/RangeSlider/rangeslider.ts +1 -9
  165. package/components/Rating/Rating.astro +1 -1
  166. package/components/Rating/Rating.svelte +10 -7
  167. package/components/Rating/Rating.tsx +3 -1
  168. package/components/Rating/rating.module.scss +13 -15
  169. package/components/Ribbon/Ribbon.astro +1 -1
  170. package/components/Ribbon/Ribbon.svelte +9 -4
  171. package/components/Ribbon/Ribbon.tsx +6 -2
  172. package/components/Ribbon/ribbon.module.scss +9 -11
  173. package/components/Ribbon/ribbon.ts +0 -10
  174. package/components/Select/Select.astro +3 -1
  175. package/components/Select/Select.svelte +179 -171
  176. package/components/Select/Select.tsx +11 -4
  177. package/components/Select/select.ts +2 -12
  178. package/components/Sheet/Sheet.astro +2 -1
  179. package/components/Sheet/Sheet.svelte +7 -5
  180. package/components/Sheet/Sheet.tsx +5 -4
  181. package/components/Sheet/sheet.ts +3 -10
  182. package/components/Sidebar/Sidebar.astro +1 -1
  183. package/components/Sidebar/Sidebar.svelte +9 -4
  184. package/components/Sidebar/Sidebar.tsx +6 -2
  185. package/components/Sidebar/sidebar.ts +0 -10
  186. package/components/Skeleton/Skeleton.astro +1 -1
  187. package/components/Skeleton/Skeleton.svelte +7 -5
  188. package/components/Skeleton/Skeleton.tsx +3 -1
  189. package/components/Skeleton/skeleton.module.scss +6 -9
  190. package/components/Slider/Slider.astro +7 -5
  191. package/components/Slider/Slider.svelte +18 -10
  192. package/components/Slider/Slider.tsx +12 -6
  193. package/components/Slider/slider.module.scss +12 -14
  194. package/components/Slider/slider.ts +3 -12
  195. package/components/SpeedDial/SpeedDial.astro +1 -1
  196. package/components/SpeedDial/SpeedDial.svelte +6 -4
  197. package/components/SpeedDial/SpeedDial.tsx +4 -2
  198. package/components/SpeedDial/speeddial.module.scss +4 -6
  199. package/components/Spinner/Spinner.astro +1 -1
  200. package/components/Spinner/Spinner.svelte +7 -5
  201. package/components/Spinner/Spinner.tsx +3 -1
  202. package/components/Spinner/spinner.module.scss +13 -14
  203. package/components/Spoiler/Spoiler.astro +1 -1
  204. package/components/Spoiler/Spoiler.svelte +11 -5
  205. package/components/Spoiler/Spoiler.tsx +6 -2
  206. package/components/Spoiler/spoiler.module.scss +3 -5
  207. package/components/Spoiler/spoiler.ts +0 -10
  208. package/components/Stepper/Stepper.astro +1 -1
  209. package/components/Stepper/Stepper.svelte +7 -5
  210. package/components/Stepper/Stepper.tsx +3 -1
  211. package/components/Stepper/stepper.defaults.scss +5 -0
  212. package/components/Stepper/stepper.module.scss +11 -13
  213. package/components/Switch/Switch.astro +7 -2
  214. package/components/Switch/Switch.svelte +17 -8
  215. package/components/Switch/Switch.tsx +8 -4
  216. package/components/Switch/switch.module.scss +5 -7
  217. package/components/Switch/switch.ts +2 -16
  218. package/components/Tab/Tab.astro +25 -0
  219. package/components/Tab/Tab.svelte +28 -0
  220. package/components/Tab/Tab.tsx +30 -0
  221. package/components/Tab/tab.ts +6 -0
  222. package/components/Table/Table.astro +1 -1
  223. package/components/Table/Table.svelte +5 -3
  224. package/components/Table/Table.tsx +3 -1
  225. package/components/Tabs/Tabs.astro +58 -25
  226. package/components/Tabs/Tabs.svelte +47 -14
  227. package/components/Tabs/Tabs.tsx +42 -11
  228. package/components/Tabs/tabs.module.scss +7 -6
  229. package/components/Tabs/tabs.ts +0 -10
  230. package/components/Textarea/Textarea.astro +3 -6
  231. package/components/Textarea/Textarea.svelte +13 -10
  232. package/components/Textarea/Textarea.tsx +9 -7
  233. package/components/Textarea/textarea.ts +2 -17
  234. package/components/ThemeSwitcher/ThemeSwitcher.astro +1 -1
  235. package/components/ThemeSwitcher/ThemeSwitcher.svelte +14 -8
  236. package/components/ThemeSwitcher/ThemeSwitcher.tsx +7 -2
  237. package/components/ThemeSwitcher/themeswitcher.module.scss +10 -12
  238. package/components/ThemeSwitcher/themeswitcher.ts +0 -13
  239. package/components/Timeline/Timeline.astro +1 -1
  240. package/components/Timeline/Timeline.svelte +11 -6
  241. package/components/Timeline/Timeline.tsx +6 -2
  242. package/components/Timeline/timeline.module.scss +6 -8
  243. package/components/Timeline/timeline.ts +0 -10
  244. package/components/TimelineItem/TimelineItem.astro +1 -1
  245. package/components/TimelineItem/TimelineItem.svelte +9 -4
  246. package/components/TimelineItem/TimelineItem.tsx +8 -3
  247. package/components/TimelineItem/timelineitem.module.scss +4 -4
  248. package/components/TimelineItem/timelineitem.ts +0 -12
  249. package/components/Toast/Toast.astro +2 -1
  250. package/components/Toast/Toast.svelte +9 -7
  251. package/components/Toast/Toast.tsx +5 -4
  252. package/components/Toast/toast.ts +3 -11
  253. package/package.json +19 -19
  254. package/react.d.ts +145 -138
  255. package/react.js +4 -0
  256. package/scss/config/functions.scss +41 -0
  257. package/scss/config/mixins.scss +65 -0
  258. package/scss/config.scss +1 -0
  259. package/scss/global/theme.scss +209 -194
  260. package/scss/setup.scss +6 -3
  261. package/svelte.d.ts +145 -138
  262. package/svelte.js +4 -0
@@ -1,14 +1,12 @@
1
1
  @use '../../scss/config.scss' as *;
2
2
 
3
- body {
4
- --w-stepper-color-border: var(--w-color-primary-50);
5
- --w-stepper-color-active: var(--w-color-info);
6
- --w-stepper-color-complete: var(--w-color-success);
7
- }
8
-
9
3
  $size: 20px;
10
4
 
11
5
  .stepper {
6
+ --border: var(--w-stepper-color-border, var(--w-color-primary-50));
7
+ --active: var(--w-stepper-color-active, var(--w-color-info));
8
+ --complete: var(--w-stepper-color-complete, var(--w-color-success));
9
+
12
10
  @include layout(flex, default, column);
13
11
  @include spacing(0);
14
12
  @include size('w100%');
@@ -16,7 +14,7 @@ $size: 20px;
16
14
  list-style-type: none;
17
15
 
18
16
  &:not(.borderless) .number {
19
- border: 2px solid var(--w-stepper-color-border);
17
+ border: 2px solid var(--border);
20
18
  }
21
19
 
22
20
  li {
@@ -31,7 +29,7 @@ $size: 20px;
31
29
 
32
30
  &::before {
33
31
  @include position(absolute, l16px);
34
- @include background(var(--w-stepper-color-border));
32
+ @include background(var(--border));
35
33
  @include size(w2px);
36
34
 
37
35
  top: -50%;
@@ -42,18 +40,18 @@ $size: 20px;
42
40
 
43
41
  &.completed::before,
44
42
  &.active::before {
45
- @include background(var(--w-stepper-color-complete));
43
+ @include background(var(--complete));
46
44
  }
47
45
  }
48
46
 
49
47
  &.active .number {
50
- border-color: var(--w-stepper-color-active);
51
- color: var(--w-stepper-color-active);
48
+ border-color: var(--active);
49
+ color: var(--active);
52
50
  }
53
51
 
54
52
  &.completed .number {
55
- border-color: var(--w-stepper-color-complete);
56
- color: var(--w-stepper-color-complete);
53
+ border-color: var(--complete);
54
+ color: var(--complete);
57
55
  }
58
56
 
59
57
  .number {
@@ -1,11 +1,12 @@
1
1
  ---
2
+ import type { HTMLAttributes } from 'astro/types'
2
3
  import type { SwitchProps } from './switch'
3
4
 
4
5
  import { classNames } from '../../utils/classNames'
5
6
 
6
7
  import styles from './switch.module.scss'
7
8
 
8
- interface Props extends SwitchProps {}
9
+ export type Props = SwitchProps<HTMLAttributes<'textarea'>>
9
10
 
10
11
  const {
11
12
  label,
@@ -36,7 +37,11 @@ const styleVariables = classNames([
36
37
  ---
37
38
 
38
39
  <label class:list={classes} style={styleVariables}>
39
- <input type="checkbox" checked={toggled} disabled={disabled} {...rest} />
40
+ <input
41
+ {...rest}
42
+ type="checkbox"
43
+ checked={toggled}
44
+ />
40
45
  <span class={styles.toggle}></span>
41
46
  {label && <span class={styles.label} set:html={label} />}
42
47
  </label>
@@ -1,10 +1,20 @@
1
1
  <script lang="ts">
2
- import type { SvelteSwitchProps } from './switch'
2
+ import type {
3
+ ChangeEventHandler,
4
+ HTMLInputAttributes,
5
+ MouseEventHandler
6
+ } from 'svelte/elements'
7
+ import type { SwitchProps } from './switch'
3
8
 
4
9
  import { classNames } from '../../utils/classNames'
5
10
 
6
11
  import styles from './switch.module.scss'
7
12
 
13
+ export type Props = SwitchProps<HTMLInputAttributes> & {
14
+ onChange?: ChangeEventHandler<HTMLInputElement>
15
+ onClick?: MouseEventHandler<HTMLInputElement>
16
+ }
17
+
8
18
  const {
9
19
  label,
10
20
  toggled,
@@ -18,31 +28,30 @@
18
28
  onClick,
19
29
  onChange,
20
30
  ...rest
21
- }: SvelteSwitchProps = $props()
31
+ }: Props = $props()
22
32
 
23
- const classes = classNames([
33
+ const classes = $derived(classNames([
24
34
  styles.switch,
25
35
  reverse && styles.reverse,
26
36
  small && styles.small,
27
37
  square && styles.square,
28
38
  disabled && styles.disabled,
29
39
  className
30
- ])
40
+ ]))
31
41
 
32
- const styleVariables = classNames([
42
+ const styleVariables = $derived(classNames([
33
43
  offColor && `--w-switch-off-color: ${offColor};`,
34
44
  onColor && `--w-switch-on-color: ${onColor};`
35
- ])
45
+ ]))
36
46
  </script>
37
47
 
38
48
  <label class={classes} style={styleVariables || null}>
39
49
  <input
50
+ {...rest}
40
51
  type="checkbox"
41
52
  checked={toggled}
42
- disabled={disabled}
43
53
  onclick={onClick}
44
54
  onchange={onChange}
45
- {...rest}
46
55
  />
47
56
  <span class={styles.toggle}></span>
48
57
  {#if label}
@@ -1,10 +1,15 @@
1
1
  import React from 'react'
2
- import type { ReactSwitchProps } from './switch'
2
+ import type { SwitchProps } from './switch'
3
3
 
4
4
  import { classNames } from '../../utils/classNames'
5
5
 
6
6
  import styles from './switch.module.scss'
7
7
 
8
+ export type Props = SwitchProps<React.InputHTMLAttributes<HTMLInputElement>> & {
9
+ onChange?: React.ChangeEventHandler<HTMLInputElement>
10
+ onClick?: React.MouseEventHandler<HTMLInputElement>
11
+ }
12
+
8
13
  const Switch = ({
9
14
  label,
10
15
  toggled,
@@ -16,7 +21,7 @@ const Switch = ({
16
21
  disabled,
17
22
  className,
18
23
  ...rest
19
- }: ReactSwitchProps) => {
24
+ }: Props) => {
20
25
  const classes = classNames([
21
26
  styles.switch,
22
27
  reverse && styles.reverse,
@@ -34,10 +39,9 @@ const Switch = ({
34
39
  return (
35
40
  <label className={classes} style={styleVariables || null}>
36
41
  <input
42
+ {...rest}
37
43
  type="checkbox"
38
44
  defaultChecked={toggled}
39
- disabled={disabled}
40
- {...rest}
41
45
  />
42
46
  <span className={styles.toggle}></span>
43
47
  {label && (
@@ -1,11 +1,9 @@
1
1
  @use '../../scss/config.scss' as *;
2
2
 
3
- body {
4
- --w-switch-off-color: var(--w-color-primary-50);
5
- --w-switch-on-color: var(--w-color-primary);
6
- }
7
-
8
3
  .switch {
4
+ --off-color: var(--w-switch-off-color, var(--w-color-primary-50));
5
+ --on-color: var(--w-switch-on-color, var(--w-color-primary));
6
+
9
7
  @include layout(inline-flex, v-center, sm);
10
8
  cursor: pointer;
11
9
  user-select: none;
@@ -53,7 +51,7 @@ body {
53
51
  @include visibility(none);
54
52
 
55
53
  &:checked + span {
56
- @include background(var(--w-switch-on-color));
54
+ @include background(var(--on-color));
57
55
 
58
56
  &::before {
59
57
  transform: translateX(30px);
@@ -66,7 +64,7 @@ body {
66
64
  @include position(relative);
67
65
  @include size(w60px, h30px);
68
66
  @include border-radius(xl);
69
- @include background(var(--w-switch-off-color));
67
+ @include background(var(--off-color));
70
68
 
71
69
  &::before {
72
70
  @include transition(transform);
@@ -1,24 +1,10 @@
1
- import type { ChangeEventHandler, MouseEventHandler } from 'svelte/elements'
2
-
3
- export type SwitchProps = {
1
+ export type SwitchProps<T extends object = object> = {
4
2
  label?: string
5
3
  reverse?: boolean
6
4
  toggled?: boolean
7
- disabled?: boolean
8
5
  small?: boolean
9
6
  square?: boolean
10
7
  onColor?: string
11
8
  offColor?: string
12
9
  className?: string
13
- [key: string]: any
14
- }
15
-
16
- export type SvelteSwitchProps = {
17
- onChange?: ChangeEventHandler<HTMLInputElement>
18
- onClick?: MouseEventHandler<HTMLInputElement>
19
- } & SwitchProps
20
-
21
- export type ReactSwitchProps = {
22
- onChange?: React.ChangeEventHandler<HTMLInputElement>
23
- onClick?: React.MouseEventHandler<HTMLInputElement>
24
- } & SwitchProps
10
+ } & T
@@ -0,0 +1,25 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ import type { TabProps } from './tab'
4
+
5
+ export type Props = TabProps<HTMLAttributes<'section'>>
6
+
7
+ const {
8
+ element = 'div',
9
+ id,
10
+ active,
11
+ className,
12
+ ...rest
13
+ } = Astro.props
14
+
15
+ const Element = element
16
+
17
+ const props = {
18
+ ...rest,
19
+ 'class': className,
20
+ 'data-tab': id,
21
+ 'data-active': active
22
+ }
23
+ ---
24
+
25
+ <Element {...props}><slot /></Element>
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte'
3
+ import type { HTMLAttributes } from 'svelte/elements'
4
+ import type { TabProps } from './tab'
5
+
6
+ export type Props = TabProps<HTMLAttributes<HTMLElement>> & {
7
+ children: Snippet
8
+ }
9
+
10
+ const {
11
+ element = 'div',
12
+ id,
13
+ active,
14
+ className,
15
+ children,
16
+ ...rest
17
+ }: Props = $props()
18
+ </script>
19
+
20
+ <svelte:element
21
+ {...rest}
22
+ {...(className && { class: className })}
23
+ this={element}
24
+ data-tab={id}
25
+ data-active={active}
26
+ >
27
+ {@render children?.()}
28
+ </svelte:element>
@@ -0,0 +1,30 @@
1
+ import React from 'react'
2
+ import type { TabProps } from './tab'
3
+
4
+ export type Props = TabProps<React.HTMLAttributes<HTMLElement>> & {
5
+ children: React.ReactNode
6
+ }
7
+
8
+ const Tab = ({
9
+ element = 'div',
10
+ id,
11
+ active,
12
+ className,
13
+ children,
14
+ ...rest
15
+ }: Props) => {
16
+ const Element = element as React.ElementType<React.HTMLAttributes<HTMLElement>>
17
+
18
+ return (
19
+ <Element
20
+ {...rest}
21
+ className={className}
22
+ data-tab={id}
23
+ data-active={active}
24
+ >
25
+ {children}
26
+ </Element>
27
+ )
28
+ }
29
+
30
+ export default Tab
@@ -0,0 +1,6 @@
1
+ export type TabProps<T extends object = object> = {
2
+ element?: string
3
+ id?: string
4
+ active?: boolean
5
+ className?: string
6
+ } & T
@@ -3,7 +3,7 @@ import type { TableProps } from './table'
3
3
 
4
4
  import styles from './table.module.scss'
5
5
 
6
- interface Props extends TableProps {}
6
+ export type Props = TableProps
7
7
 
8
8
  const {
9
9
  headings,
@@ -4,6 +4,8 @@
4
4
  import { classNames } from '../../utils/classNames'
5
5
 
6
6
  import styles from './table.module.scss'
7
+
8
+ export type Props = TableProps
7
9
 
8
10
  const {
9
11
  headings,
@@ -15,9 +17,9 @@
15
17
  compact,
16
18
  maxHeight,
17
19
  className
18
- }: TableProps = $props()
20
+ }: Props = $props()
19
21
 
20
- const classes = classNames([
22
+ const classes = $derived(classNames([
21
23
  styles.table,
22
24
  hover && styles.hover,
23
25
  striped && styles[`striped-${striped}s`],
@@ -25,7 +27,7 @@
25
27
  compact && styles.compact,
26
28
  maxHeight && styles.scroll,
27
29
  className
28
- ])
30
+ ]))
29
31
  </script>
30
32
 
31
33
  <div class={classes} style={maxHeight ? `max-height:${maxHeight}` : null}>
@@ -4,6 +4,8 @@ import type { TableProps } from './table'
4
4
  import { classNames } from '../../utils/classNames'
5
5
 
6
6
  import styles from './table.module.scss'
7
+
8
+ export type Props = TableProps
7
9
 
8
10
  const Table = ({
9
11
  headings,
@@ -15,7 +17,7 @@ const Table = ({
15
17
  compact,
16
18
  maxHeight,
17
19
  className
18
- }: TableProps) => {
20
+ }: Props) => {
19
21
  const classes = classNames([
20
22
  styles.table,
21
23
  hover && styles.hover,
@@ -3,7 +3,7 @@ import type { TabsProps } from './tabs'
3
3
 
4
4
  import styles from './tabs.module.scss'
5
5
 
6
- interface Props extends TabsProps {}
6
+ export type Props = TabsProps
7
7
 
8
8
  const {
9
9
  items,
@@ -20,6 +20,12 @@ const classes = [
20
20
  even && styles.even,
21
21
  className
22
22
  ]
23
+
24
+ const hasActive = items.some(item => item.active)
25
+
26
+ if (!hasActive) {
27
+ items[0].active = true
28
+ }
23
29
  ---
24
30
 
25
31
  <section class:list={classes} data-id="w-tabs">
@@ -36,45 +42,72 @@ const classes = [
36
42
  ))}
37
43
  </div>
38
44
  </div>
39
- <div class={styles.content}>
45
+ <div
46
+ class={styles.content}
47
+ data-id="w-tabs-content"
48
+ data-active-index={items.findIndex(item => item.active)}
49
+ >
40
50
  <slot />
41
51
  </div>
42
52
  </section>
43
53
 
44
54
  <script>
45
- import { on } from '../../utils/DOMUtils'
55
+ import { get, on } from '../../utils/DOMUtils'
56
+
57
+ const setActiveTab = () => {
58
+ const tabContents = get('[data-id="w-tabs-content"]', true) as NodeListOf<HTMLDivElement>
59
+
60
+ tabContents.forEach((tabContent) => {
61
+ const contentChildren = Array.from(tabContent.children) as HTMLElement[]
62
+
63
+ if (!contentChildren.some(element => element.dataset.active === 'true')) {
64
+ const index = Number(tabContent.dataset.activeIndex)
65
+
66
+ if (contentChildren[index]) {
67
+ contentChildren[index].dataset.active = 'true'
68
+ }
69
+ }
70
+ })
71
+ }
46
72
 
47
73
  const addEventListeners = () => {
48
74
  on('[data-id="w-tabs"]', 'click', (event: Event) => {
49
- const target = event.target as HTMLDivElement
75
+ const target = event.target as HTMLButtonElement
76
+
77
+ if (!target.dataset.value) {
78
+ return
79
+ }
50
80
 
51
- if (target.dataset.value) {
52
- const tabContent = target.parentElement
53
- ?.parentElement
54
- ?.nextElementSibling as HTMLDivElement
81
+ const tabContent = target.parentElement
82
+ ?.parentElement
83
+ ?.nextElementSibling as HTMLDivElement
55
84
 
56
- Array.from(tabContent.children)
57
- .forEach((element: any) => {
58
- if (element.dataset.tab === target.dataset.value) {
59
- element.dataset.active = true
60
- } else {
61
- element.dataset.active = false
62
- }
63
- })
85
+ const btns = Array.from(target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>)
86
+ const clickedIndex = btns.indexOf(target)
87
+ const contentChildren = Array.from(tabContent.children) as HTMLElement[]
88
+ const hasExplicitTabs = contentChildren.some((element: HTMLElement) => element.dataset.tab)
64
89
 
65
- const tabs = target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>
90
+ btns.forEach((tab: HTMLElement, index: number) => {
91
+ tab.dataset.active = index === clickedIndex ? 'true' : 'false'
66
92
 
67
- Array.from(tabs).forEach((tab: any) => {
68
- tab.dataset.active = 'false'
93
+ if (contentChildren[index]) {
94
+ const content = contentChildren[index]
69
95
 
70
- if (tab.dataset.value === target.dataset.value) {
71
- tab.dataset.active = 'true'
96
+ if (hasExplicitTabs) {
97
+ content.dataset.active = content.dataset.tab === target.dataset.value ? 'true' : 'false'
98
+ } else {
99
+ content.dataset.active = index === clickedIndex ? 'true' : 'false'
72
100
  }
73
- })
74
- }
101
+ }
102
+ })
75
103
  }, true)
76
104
  }
77
105
 
78
- on(document, 'astro:after-swap', addEventListeners)
79
- addEventListeners()
106
+ const initTabs = () => {
107
+ setActiveTab()
108
+ addEventListeners()
109
+ }
110
+
111
+ on(document, 'astro:after-swap', initTabs)
112
+ initTabs()
80
113
  </script>
@@ -1,10 +1,15 @@
1
1
  <script lang="ts">
2
- import type { SvelteTabsProps } from './tabs'
2
+ import { onMount, type Snippet } from 'svelte'
3
+ import type { TabsProps } from './tabs'
3
4
 
4
5
  import { classNames } from '../../utils/classNames'
5
6
 
6
7
  import styles from './tabs.module.scss'
7
8
 
9
+ export type Props = TabsProps & {
10
+ children: Snippet
11
+ }
12
+
8
13
  const {
9
14
  items,
10
15
  theme,
@@ -12,42 +17,70 @@
12
17
  even,
13
18
  className,
14
19
  children
15
- }: SvelteTabsProps = $props()
20
+ }: Props = $props()
16
21
 
17
22
  let active = $state('')
18
23
  let tabContainer: HTMLDivElement | undefined = $state()
19
24
 
20
- const classes = classNames([
25
+ const usedInAstro = $derived(tabContainer?.children[0]?.nodeName === 'ASTRO-SLOT')
26
+ const hasActive = $derived(items.some(item => item.active))
27
+ const itemsState = $derived.by(() => {
28
+ if (!hasActive) {
29
+ items[0].active = true
30
+ }
31
+
32
+ return items
33
+ })
34
+
35
+ const classes = $derived(classNames([
21
36
  styles.tabs,
22
37
  theme && styles[theme],
23
38
  vertical && styles.vertical,
24
39
  even && styles.even,
25
40
  className
26
- ])
27
-
28
- const setTab = (tab: string) => {
29
- const tabs = tabContainer!.querySelectorAll('[data-tab]')
41
+ ]))
30
42
 
31
- active = tab
43
+ const setTab = (tab: string, index: number) => {
44
+ const contentChildren = usedInAstro
45
+ ? Array.from(tabContainer!.children[0].children) as HTMLElement[]
46
+ : Array.from(tabContainer!.children) as HTMLElement[]
32
47
 
33
- Array.from(tabs).forEach((item: any) => {
34
- item.dataset.active = false
48
+ const hasExplicitTabs = contentChildren.some((el: HTMLElement) => el.dataset.tab)
35
49
 
36
- if (item.dataset.tab === active) {
37
- item.dataset.active = true
50
+ contentChildren.forEach((item: HTMLElement, i: number) => {
51
+ if (hasExplicitTabs) {
52
+ item.dataset.active = item.dataset.tab === tab ? 'true' : 'false'
53
+ } else {
54
+ item.dataset.active = i === index ? 'true' : 'false'
38
55
  }
39
56
  })
57
+
58
+ active = tab
40
59
  }
60
+
61
+ onMount(() => {
62
+ const contentChildren = usedInAstro
63
+ ? Array.from(tabContainer!.children[0].children) as HTMLElement[]
64
+ : Array.from(tabContainer!.children) as HTMLElement[]
65
+
66
+ if (!contentChildren.some(element => element.dataset.active === 'true')) {
67
+ const index = itemsState.findIndex(item => item.active)
68
+
69
+ if (contentChildren[index]) {
70
+ contentChildren[index].dataset.active = 'true'
71
+ }
72
+ }
73
+ })
41
74
  </script>
42
75
 
43
76
  <section class={classes}>
44
77
  <div class={styles.wrapper}>
45
78
  <div class={styles.items}>
46
- {#each items as item}
79
+ {#each itemsState as item, i}
47
80
  <button
48
81
  data-active={active ? active === item.value : item.active}
49
82
  disabled={item.disabled}
50
- onclick={() => setTab(item.value)}
83
+ onclick={() => setTab(item.value, i)}
51
84
  >
52
85
  {@html item.label}
53
86
  </button>