webcoreui 0.9.0 → 0.10.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 (138) hide show
  1. package/README.md +20 -6
  2. package/components/Accordion/Accordion.astro +15 -10
  3. package/components/Accordion/Accordion.svelte +14 -12
  4. package/components/Accordion/Accordion.tsx +2 -2
  5. package/components/Alert/Alert.svelte +17 -12
  6. package/components/Alert/Alert.tsx +1 -1
  7. package/components/Alert/alert.ts +10 -3
  8. package/components/AspectRatio/AspectRatio.svelte +7 -4
  9. package/components/AspectRatio/aspectratio.ts +6 -0
  10. package/components/Avatar/Avatar.svelte +11 -9
  11. package/components/Badge/Badge.svelte +14 -10
  12. package/components/Badge/badge.ts +2 -1
  13. package/components/Banner/Banner.astro +10 -4
  14. package/components/Banner/Banner.svelte +14 -10
  15. package/components/Banner/Banner.tsx +1 -0
  16. package/components/Banner/banner.ts +6 -0
  17. package/components/BottomNavigation/BottomNavigation.svelte +7 -5
  18. package/components/Breadcrumb/Breadcrumb.astro +1 -1
  19. package/components/Breadcrumb/Breadcrumb.svelte +8 -6
  20. package/components/Breadcrumb/Breadcrumb.tsx +2 -2
  21. package/components/Button/Button.svelte +12 -8
  22. package/components/Button/Button.tsx +2 -2
  23. package/components/Button/button.ts +2 -3
  24. package/components/Card/Card.svelte +14 -10
  25. package/components/Card/card.ts +6 -0
  26. package/components/Carousel/Carousel.astro +46 -41
  27. package/components/Carousel/carousel.ts +3 -0
  28. package/components/Checkbox/Checkbox.svelte +12 -9
  29. package/components/Checkbox/checkbox.module.scss +4 -0
  30. package/components/Collapsible/Collapsible.astro +8 -5
  31. package/components/Collapsible/Collapsible.svelte +54 -49
  32. package/components/Collapsible/collapsible.ts +8 -0
  33. package/components/ConditionalWrapper/ConditionalWrapper.svelte +10 -6
  34. package/components/ConditionalWrapper/conditionalwrapper.ts +6 -0
  35. package/components/Copy/Copy.astro +17 -11
  36. package/components/Copy/Copy.svelte +68 -61
  37. package/components/Copy/Copy.tsx +1 -0
  38. package/components/Copy/copy.ts +8 -2
  39. package/components/DataTable/DataTable.astro +103 -93
  40. package/components/DataTable/DataTable.svelte +276 -272
  41. package/components/DataTable/datatable.ts +5 -2
  42. package/components/Flex/Flex.svelte +14 -10
  43. package/components/Flex/flex.ts +6 -0
  44. package/components/Footer/Footer.svelte +12 -9
  45. package/components/Footer/footer.ts +6 -0
  46. package/components/Grid/Grid.svelte +12 -8
  47. package/components/Grid/grid.ts +6 -0
  48. package/components/Group/Group.svelte +7 -4
  49. package/components/Group/group.ts +6 -0
  50. package/components/Icon/Icon.astro +19 -5
  51. package/components/Icon/Icon.svelte +23 -7
  52. package/components/Icon/Icon.tsx +19 -5
  53. package/components/Icon/icon.ts +9 -3
  54. package/components/Icon/map.ts +8 -10
  55. package/components/Input/Input.svelte +24 -20
  56. package/components/Input/input.ts +10 -3
  57. package/components/Kbd/Kbd.svelte +7 -4
  58. package/components/Kbd/kbd.ts +6 -0
  59. package/components/List/List.astro +65 -60
  60. package/components/List/List.svelte +149 -147
  61. package/components/List/List.tsx +1 -1
  62. package/components/Masonry/Masonry.svelte +12 -10
  63. package/components/Menu/Menu.astro +8 -3
  64. package/components/Menu/Menu.svelte +15 -10
  65. package/components/Menu/Menu.tsx +3 -1
  66. package/components/Menu/menu.ts +6 -0
  67. package/components/Modal/Modal.astro +1 -0
  68. package/components/Modal/Modal.svelte +18 -13
  69. package/components/Modal/Modal.tsx +2 -1
  70. package/components/Modal/modal.ts +6 -1
  71. package/components/Pagination/Pagination.astro +75 -69
  72. package/components/Pagination/Pagination.svelte +29 -26
  73. package/components/Pagination/Pagination.tsx +5 -4
  74. package/components/Pagination/pagination.module.scss +4 -0
  75. package/components/Popover/Popover.svelte +10 -6
  76. package/components/Popover/popover.ts +6 -0
  77. package/components/Progress/Progress.svelte +12 -10
  78. package/components/Progress/progress.ts +1 -1
  79. package/components/Radio/Radio.svelte +12 -9
  80. package/components/Radio/radio.ts +4 -2
  81. package/components/Rating/Rating.svelte +16 -14
  82. package/components/Ribbon/Ribbon.svelte +9 -6
  83. package/components/Ribbon/ribbon.ts +6 -0
  84. package/components/Select/Select.astro +73 -63
  85. package/components/Select/Select.svelte +27 -22
  86. package/components/Select/Select.tsx +8 -6
  87. package/components/Sheet/Sheet.svelte +9 -5
  88. package/components/Sheet/sheet.ts +6 -2
  89. package/components/Sidebar/Sidebar.svelte +7 -4
  90. package/components/Sidebar/sidebar.ts +6 -0
  91. package/components/Skeleton/Skeleton.svelte +9 -7
  92. package/components/Slider/Slider.svelte +15 -13
  93. package/components/Slider/slider.module.scss +4 -0
  94. package/components/Slider/slider.ts +4 -2
  95. package/components/Spinner/Spinner.svelte +7 -5
  96. package/components/Spoiler/Spoiler.astro +13 -8
  97. package/components/Spoiler/Spoiler.svelte +13 -10
  98. package/components/Spoiler/spoiler.ts +6 -0
  99. package/components/Stepper/Stepper.svelte +9 -7
  100. package/components/Switch/Switch.svelte +15 -12
  101. package/components/Table/Table.svelte +11 -9
  102. package/components/Table/table.ts +1 -1
  103. package/components/Tabs/Tabs.astro +8 -5
  104. package/components/Tabs/Tabs.svelte +14 -11
  105. package/components/Tabs/tabs.ts +7 -1
  106. package/components/Textarea/Textarea.svelte +14 -11
  107. package/components/Textarea/textarea.ts +9 -4
  108. package/components/ThemeSwitcher/ThemeSwitcher.astro +43 -37
  109. package/components/ThemeSwitcher/ThemeSwitcher.svelte +14 -10
  110. package/components/ThemeSwitcher/themeswitcher.ts +7 -0
  111. package/components/Timeline/Timeline.svelte +12 -9
  112. package/components/Timeline/timeline.ts +7 -2
  113. package/components/TimelineItem/TimelineItem.svelte +8 -5
  114. package/components/TimelineItem/timelineitem.ts +6 -0
  115. package/components/Toast/Toast.svelte +18 -10
  116. package/components/Toast/toast.ts +6 -1
  117. package/icons/alert.svg +2 -2
  118. package/icons/check.svg +2 -2
  119. package/icons/chevron-down.svg +3 -0
  120. package/icons/chevron-left.svg +3 -0
  121. package/icons/chevron-right.svg +3 -0
  122. package/icons/chevron-up.svg +3 -0
  123. package/icons/circle-check.svg +3 -3
  124. package/icons/info.svg +3 -3
  125. package/icons.d.ts +4 -5
  126. package/icons.js +4 -5
  127. package/index.d.ts +1 -0
  128. package/index.js +1 -0
  129. package/package.json +20 -20
  130. package/react.d.ts +3 -3
  131. package/svelte.d.ts +98 -98
  132. package/utils/bodyFreeze.ts +13 -0
  133. package/utils/modal.ts +12 -0
  134. package/icons/arrow-down.svg +0 -3
  135. package/icons/arrow-left.svg +0 -3
  136. package/icons/arrow-right.svg +0 -3
  137. package/icons/components.svg +0 -3
  138. package/icons/file.svg +0 -3
@@ -1,3 +1,4 @@
1
+ import type { Snippet } from 'svelte'
1
2
  import type { MouseEventHandler } from 'svelte/elements'
2
3
 
3
4
  export type ButtonProps = {
@@ -8,15 +9,12 @@ export type ButtonProps = {
8
9
  | 'success'
9
10
  | 'warning'
10
11
  | 'alert'
11
- | null
12
- | undefined
13
12
  target?: '_self'
14
13
  | '_blank'
15
14
  | '_parent'
16
15
  | '_top'
17
16
  | '_unfencedTop'
18
17
  | ''
19
- | undefined
20
18
  href?: string
21
19
  className?: string
22
20
  [key: string]: any
@@ -24,6 +22,7 @@ export type ButtonProps = {
24
22
 
25
23
  export type SvelteButtonProps = {
26
24
  onClick?: MouseEventHandler<HTMLButtonElement>
25
+ children: Snippet
27
26
  } & ButtonProps
28
27
 
29
28
  export type ReactButtonProps = {
@@ -1,17 +1,21 @@
1
1
  <script lang="ts">
2
- import type { CardProps } from './card'
2
+ import type { SvelteCardProps } from './card'
3
3
 
4
4
  import { classNames } from '../../utils/classNames'
5
5
 
6
6
  import styles from './card.module.scss'
7
7
 
8
- export let element: CardProps['element'] = 'section'
9
- export let title: CardProps['title'] = ''
10
- export let titleTag: CardProps['titleTag'] = 'span'
11
- export let compact: CardProps['compact'] = false
12
- export let className: CardProps['className'] = ''
13
- export let bodyClassName: CardProps['bodyClassName'] = ''
14
- export let secondary: CardProps['secondary'] = false
8
+ const {
9
+ element = 'section',
10
+ title,
11
+ titleTag = 'span',
12
+ compact,
13
+ className,
14
+ bodyClassName,
15
+ secondary,
16
+ children,
17
+ ...rest
18
+ }: SvelteCardProps = $props()
15
19
 
16
20
  const classes = classNames([
17
21
  styles.card,
@@ -26,13 +30,13 @@
26
30
  ])
27
31
  </script>
28
32
 
29
- <svelte:element this={element} class={classes} {...$$restProps}>
33
+ <svelte:element this={element} class={classes} {...rest}>
30
34
  {#if title}
31
35
  <svelte:element this={titleTag} class={styles.title}>
32
36
  {title}
33
37
  </svelte:element>
34
38
  {/if}
35
39
  <div class={bodyClasses}>
36
- <slot />
40
+ {@render children?.()}
37
41
  </div>
38
42
  </svelte:element>
@@ -1,3 +1,5 @@
1
+ import type { Snippet } from 'svelte'
2
+
1
3
  export type CardProps = {
2
4
  element?: string
3
5
  title?: string
@@ -9,6 +11,10 @@ export type CardProps = {
9
11
  [key: string]: any
10
12
  }
11
13
 
14
+ export type SvelteCardProps = {
15
+ children: Snippet
16
+ } & CardProps
17
+
12
18
  export type ReactCardProps = {
13
19
  Element?: keyof JSX.IntrinsicElements
14
20
  TitleTag?: keyof JSX.IntrinsicElements
@@ -102,53 +102,55 @@ const style = itemsPerSlide > 1
102
102
  import { debounce } from '../../utils/debounce'
103
103
  import { listen } from '../../utils/event'
104
104
 
105
- const carousels = Array.from(document.querySelectorAll('[data-id="w-carousel"]'))
106
-
107
- const scroll = (event: Event) => {
108
- const target = event.target as HTMLDivElement
109
-
110
- if (!target.dataset.paginated) {
111
- const scrollLeft = target.scrollLeft
112
- const itemWidth = target.children[0].clientWidth
113
- const page = Math.round(scrollLeft / itemWidth) + 1
114
- const carouselElement = target.children[0]
115
- const paginationElement = target.parentElement
116
- ?.querySelector('[data-id="w-pagination"]') as HTMLUListElement
117
- const currentPage = Number(paginationElement.dataset.currentPage)
118
- const diff = Math.abs(currentPage - page)
119
-
120
- let triggerButton = currentPage > page
121
- ? paginationElement.querySelector('[data-page="prev"]') as HTMLButtonElement
122
- : paginationElement.querySelector('[data-page="next"]') as HTMLButtonElement
123
-
124
- if (!triggerButton) {
125
- triggerButton = paginationElement.querySelector(`[data-page="${page}"]`) as HTMLButtonElement
126
- }
105
+ const addEventListeners = () => {
106
+ const carousels = Array.from(document.querySelectorAll('[data-id="w-carousel"]'))
107
+
108
+ const scroll = (event: Event) => {
109
+ const target = event.target as HTMLDivElement
110
+
111
+ if (!target.dataset.paginated) {
112
+ const scrollLeft = target.scrollLeft
113
+ const itemWidth = target.children[0].clientWidth
114
+ const page = Math.round(scrollLeft / itemWidth) + 1
115
+ const carouselElement = target.children[0]
116
+ const paginationElement = target.parentElement
117
+ ?.querySelector('[data-id="w-pagination"]') as HTMLUListElement
118
+ const currentPage = Number(paginationElement.dataset.currentPage)
119
+ const diff = Math.abs(currentPage - page)
120
+
121
+ let triggerButton = currentPage > page
122
+ ? paginationElement.querySelector('[data-page="prev"]') as HTMLButtonElement
123
+ : paginationElement.querySelector('[data-page="next"]') as HTMLButtonElement
124
+
125
+ if (!triggerButton) {
126
+ triggerButton = paginationElement.querySelector(`[data-page="${page}"]`) as HTMLButtonElement
127
+ }
127
128
 
128
- for (let i = 0; i < diff; i++) {
129
- triggerButton.click()
130
- }
129
+ for (let i = 0; i < diff; i++) {
130
+ triggerButton.click()
131
+ }
131
132
 
132
- Array.from(carouselElement.children).forEach(li => {
133
- (li as HTMLLIElement).removeAttribute('data-active')
134
- })
133
+ Array.from(carouselElement.children).forEach(li => {
134
+ (li as HTMLLIElement).removeAttribute('data-active')
135
+ })
135
136
 
136
- const activeElement = carouselElement.children[page - 1] as HTMLLIElement
137
+ const activeElement = carouselElement.children[page - 1] as HTMLLIElement
137
138
 
138
- activeElement.dataset.active = 'true'
139
+ activeElement.dataset.active = 'true'
140
+ }
139
141
  }
140
- }
141
142
 
142
- carousels.forEach(carousel => {
143
- const carouselElement = carousel as HTMLDivElement
144
- const debounceAmount = carouselElement.dataset.debounce
145
- ? Number(carouselElement.dataset.debounce)
146
- : 20
143
+ carousels.forEach(carousel => {
144
+ const carouselElement = carousel as HTMLDivElement
145
+ const debounceAmount = carouselElement.dataset.debounce
146
+ ? Number(carouselElement.dataset.debounce)
147
+ : 20
147
148
 
148
- carousel.addEventListener('scroll', debounce((event: Event) => {
149
- scroll(event)
150
- }, debounceAmount))
151
- })
149
+ carousel.addEventListener('scroll', debounce((event: Event) => {
150
+ scroll(event)
151
+ }, debounceAmount))
152
+ })
153
+ }
152
154
 
153
155
  listen('paginate', event => {
154
156
  const target = event.target
@@ -172,7 +174,7 @@ const style = itemsPerSlide > 1
172
174
  : indexes[event.page - 1][indexes[event.page - 1].length - 1]
173
175
 
174
176
  const liElement = carousel.children[pageIndex]
175
- const subText = event.target.nextElementSibling
177
+ const subText = event.target.parentElement.querySelector('span')
176
178
 
177
179
  Array.from(carousel.children).forEach(li => {
178
180
  (li as HTMLLIElement).removeAttribute('data-active')
@@ -204,4 +206,7 @@ const style = itemsPerSlide > 1
204
206
  }, 300)
205
207
  }
206
208
  })
209
+
210
+ document.addEventListener('astro:after-swap', addEventListeners)
211
+ addEventListeners()
207
212
  </script>
@@ -1,3 +1,5 @@
1
+ import type { Snippet } from 'svelte'
2
+
1
3
  import type { PaginationProps } from '../Pagination/pagination'
2
4
 
3
5
  export type CarouselProps = {
@@ -18,6 +20,7 @@ export type CarouselProps = {
18
20
 
19
21
  export type SvelteCarouselProps = {
20
22
  onScroll?: (event: number) => void
23
+ children: Snippet
21
24
  } & CarouselProps
22
25
 
23
26
  export type ReactCarouselProps = {
@@ -9,13 +9,16 @@
9
9
 
10
10
  import styles from './checkbox.module.scss'
11
11
 
12
- export let checked: SvelteCheckboxProps['checked'] = false
13
- export let label: SvelteCheckboxProps['label'] = ''
14
- export let subText: SvelteCheckboxProps['subText'] = ''
15
- export let disabled: SvelteCheckboxProps['disabled'] = false
16
- export let color: SvelteCheckboxProps['color'] = ''
17
- export let className: SvelteCheckboxProps['className'] = ''
18
- export let onClick: SvelteCheckboxProps['onClick'] = () => {}
12
+ const {
13
+ checked,
14
+ label,
15
+ subText,
16
+ disabled,
17
+ color,
18
+ className,
19
+ onClick,
20
+ ...rest
21
+ }: SvelteCheckboxProps = $props()
19
22
 
20
23
  const classes = classNames([
21
24
  styles.checkbox,
@@ -38,8 +41,8 @@
38
41
  type="checkbox"
39
42
  checked={checked}
40
43
  disabled={disabled}
41
- on:click={onClick}
42
- {...$$restProps}
44
+ onclick={onClick}
45
+ {...rest}
43
46
  />
44
47
  <span class={styles.check}>
45
48
  {@html check}
@@ -52,6 +52,10 @@ body {
52
52
 
53
53
  svg {
54
54
  @include visibility(none);
55
+
56
+ path {
57
+ stroke-width: 4px;
58
+ }
55
59
  }
56
60
  }
57
61
 
@@ -45,10 +45,10 @@ const styleVariables = classNames([
45
45
  </div>
46
46
 
47
47
  <script>
48
- const collapsibles = document.querySelectorAll('[data-id="w-collapsible"]')
48
+ import { on } from '../../utils/DOMUtils'
49
49
 
50
- Array.from(collapsibles).forEach(element => {
51
- element.addEventListener('click', event => {
50
+ const addEventListeners = () => {
51
+ on('[data-id="w-collapsible"]', 'click', (event: Event) => {
52
52
  const collapsible = event.currentTarget as HTMLDivElement
53
53
  const target = event.target as HTMLDivElement
54
54
 
@@ -59,6 +59,9 @@ const styleVariables = classNames([
59
59
  if (target.parentElement?.dataset.toggleOff) {
60
60
  collapsible.dataset.toggled = 'false'
61
61
  }
62
- })
63
- })
62
+ }, true)
63
+ }
64
+
65
+ on(document, 'astro:after-swap', addEventListeners)
66
+ addEventListeners()
64
67
  </script>
@@ -1,49 +1,54 @@
1
- <script lang="ts">
2
- import type { CollapsibleProps } from './collapsible'
3
-
4
- import { classNames } from '../../utils/classNames'
5
-
6
- import styles from './collapsible.module.scss'
7
-
8
- export let initialHeight: CollapsibleProps['initialHeight'] = ''
9
- export let maxHeight: CollapsibleProps['maxHeight'] = ''
10
- export let toggled: CollapsibleProps['toggled'] = false
11
- export let className: CollapsibleProps['className'] = ''
12
- export let togglesClassName: CollapsibleProps['togglesClassName'] = ''
13
-
14
- const classes = classNames([
15
- styles.collapsible,
16
- maxHeight && styles.animated,
17
- className
18
- ])
19
-
20
- const styleVariables = classNames([
21
- initialHeight && `--w-collapsible-initial-height: ${initialHeight};`,
22
- maxHeight && `--w-collapsible-max-height: ${maxHeight};`
23
- ])
24
- </script>
25
-
26
- <div
27
- class={classes}
28
- data-toggled={toggled ? 'true' : undefined}
29
- >
30
- <div
31
- class={styles.wrapper}
32
- style={styleVariables}
33
- >
34
- <slot />
35
- </div>
36
- <div
37
- on:click={() => toggled = !toggled}
38
- on:keyup={() => toggled = !toggled}
39
- role="button"
40
- tabindex={0}
41
- class={togglesClassName}
42
- >
43
- {#if toggled}
44
- <slot name="off" />
45
- {:else}
46
- <slot name="on" />
47
- {/if}
48
- </div>
49
- </div>
1
+ <script lang="ts">
2
+ import type { SvelteCollapsibleProps } from './collapsible'
3
+
4
+ import { classNames } from '../../utils/classNames'
5
+
6
+ import styles from './collapsible.module.scss'
7
+
8
+ let {
9
+ initialHeight,
10
+ maxHeight,
11
+ toggled = $bindable(),
12
+ className,
13
+ togglesClassName,
14
+ children,
15
+ off,
16
+ on
17
+ }: SvelteCollapsibleProps = $props()
18
+
19
+ const classes = classNames([
20
+ styles.collapsible,
21
+ maxHeight && styles.animated,
22
+ className
23
+ ])
24
+
25
+ const styleVariables = classNames([
26
+ initialHeight && `--w-collapsible-initial-height: ${initialHeight};`,
27
+ maxHeight && `--w-collapsible-max-height: ${maxHeight};`
28
+ ])
29
+ </script>
30
+
31
+ <div
32
+ class={classes}
33
+ data-toggled={toggled ? 'true' : undefined}
34
+ >
35
+ <div
36
+ class={styles.wrapper}
37
+ style={styleVariables}
38
+ >
39
+ {@render children?.()}
40
+ </div>
41
+ <div
42
+ onclick={() => toggled = !toggled}
43
+ onkeyup={() => toggled = !toggled}
44
+ role="button"
45
+ tabindex={0}
46
+ class={togglesClassName}
47
+ >
48
+ {#if toggled}
49
+ {@render off?.()}
50
+ {:else}
51
+ {@render on?.()}
52
+ {/if}
53
+ </div>
54
+ </div>
@@ -1,3 +1,5 @@
1
+ import type { Snippet } from 'svelte'
2
+
1
3
  export type CollapsibleProps = {
2
4
  initialHeight?: string
3
5
  maxHeight?: string
@@ -6,6 +8,12 @@ export type CollapsibleProps = {
6
8
  togglesClassName?: string
7
9
  }
8
10
 
11
+ export type SvelteCollapsibleProps = {
12
+ on: Snippet
13
+ off: Snippet
14
+ children: Snippet
15
+ } & CollapsibleProps
16
+
9
17
  export type ReactCollapsibleProps = {
10
18
  on: React.ReactNode
11
19
  off: React.ReactNode
@@ -1,14 +1,18 @@
1
1
  <script lang="ts">
2
- import type { ConditionalWrapperProps } from './conditionalwrapper'
2
+ import type { SvelteConditionalWrapperProps } from './conditionalwrapper'
3
3
 
4
- export let condition: ConditionalWrapperProps['condition']
5
- export let element: string = 'div'
4
+ const {
5
+ condition,
6
+ element = 'div',
7
+ children,
8
+ ...rest
9
+ }: SvelteConditionalWrapperProps = $props()
6
10
  </script>
7
11
 
8
12
  {#if condition}
9
- <svelte:element this={element} {...$$restProps}>
10
- <slot />
13
+ <svelte:element this={element} {...rest}>
14
+ {@render children?.()}
11
15
  </svelte:element>
12
16
  {:else}
13
- <slot />
17
+ {@render children?.()}
14
18
  {/if}
@@ -1,8 +1,14 @@
1
+ import type { Snippet } from 'svelte'
2
+
1
3
  export type ConditionalWrapperProps = {
2
4
  condition: boolean
3
5
  [key: string]: any
4
6
  }
5
7
 
8
+ export type SvelteConditionalWrapperProps = {
9
+ children: Snippet
10
+ } & ConditionalWrapperProps
11
+
6
12
  export type ReactConditionalWrapperProps = {
7
13
  wrapper: (_: React.ReactNode) => any
8
14
  children: React.ReactNode
@@ -38,6 +38,7 @@ const classes = classNames([
38
38
  <button
39
39
  class={styles['copy-icon']}
40
40
  data-id="w-copy"
41
+ aria-label="copy"
41
42
  >
42
43
  {copyIcon?.startsWith('<svg')
43
44
  ? <Fragment set:html={copyIcon} />
@@ -56,19 +57,24 @@ const classes = classNames([
56
57
  <script>
57
58
  import { on } from '../../utils/DOMUtils'
58
59
 
59
- on('[data-id="w-copy"]', 'click', (event: Event) => {
60
- const copy = event.currentTarget as HTMLButtonElement
61
- const copied = copy.nextElementSibling as HTMLSpanElement
62
- const badge = copy.parentElement?.parentElement as HTMLElement
60
+ const addEventListeners = () => {
61
+ on('[data-id="w-copy"]', 'click', (event: Event) => {
62
+ const copy = event.currentTarget as HTMLButtonElement
63
+ const copied = copy.nextElementSibling as HTMLSpanElement
64
+ const badge = copy.parentElement?.parentElement as HTMLElement
63
65
 
64
- const text = copy.parentElement?.previousSibling?.textContent?.trim()
66
+ const text = copy.parentElement?.previousSibling?.textContent?.trim()
65
67
 
66
- copy.style.opacity = '0'
67
- copy.style.pointerEvents = 'none'
68
+ copy.style.opacity = '0'
69
+ copy.style.pointerEvents = 'none'
68
70
 
69
- copied.style.opacity = '1'
70
- badge.removeAttribute('data-tooltip')
71
+ copied.style.opacity = '1'
72
+ badge.removeAttribute('data-tooltip')
71
73
 
72
- navigator.clipboard.writeText(text as string)
73
- }, true)
74
+ navigator.clipboard.writeText(text as string)
75
+ }, true)
76
+ }
77
+
78
+ on(document, 'astro:after-swap', addEventListeners)
79
+ addEventListeners()
74
80
  </script>
@@ -1,61 +1,68 @@
1
- <script lang="ts">
2
- import type { CopyProps } from './copy'
3
-
4
- import Badge from '../Badge/Badge.svelte'
5
-
6
- import { classNames } from '../../utils/classNames'
7
-
8
- import circleCheck from '../../icons/circle-check.svg?raw'
9
- import copy from '../../icons/copy.svg?raw'
10
-
11
- import styles from './copy.module.scss'
12
-
13
- export let tooltip: CopyProps['tooltip'] = ''
14
- export let tooltipPosition: CopyProps['tooltipPosition'] = null
15
- export let copyIcon: CopyProps['copyIcon'] = ''
16
- export let copiedIcon: CopyProps['copiedIcon'] = ''
17
- export let className: CopyProps['className'] = ''
18
-
19
- const classes = classNames([
20
- styles.copy,
21
- className
22
- ])
23
-
24
- let copyButton: HTMLButtonElement
25
- let copiedButton: HTMLSpanElement
26
-
27
- const copyText = () => {
28
- const text = copyButton.parentElement?.previousSibling?.textContent?.trim()
29
- || (copyButton.parentElement?.previousSibling as Text)?.wholeText?.trim()
30
- || copyButton.parentElement?.previousElementSibling?.textContent?.trim()
31
-
32
- copyButton.style.opacity = '0'
33
- copyButton.style.pointerEvents = 'none'
34
-
35
- copiedButton.style.opacity = '1'
36
- tooltip = ''
37
-
38
- navigator.clipboard.writeText(text as string)
39
- }
40
- </script>
41
-
42
- <Badge
43
- {...$$restProps}
44
- className={classes}
45
- data-tooltip={tooltip || undefined}
46
- data-position={tooltipPosition}
47
- >
48
- <slot />
49
- <div class={styles.icons}>
50
- <button
51
- class={styles['copy-icon']}
52
- bind:this={copyButton}
53
- on:click={copyText}
54
- >
55
- {@html copyIcon || copy}
56
- </button>
57
- <span class={styles.copied} bind:this={copiedButton}>
58
- {@html copiedIcon || circleCheck}
59
- </span>
60
- </div>
61
- </Badge>
1
+ <script lang="ts">
2
+ import type { SvelteCopyProps } from './copy'
3
+
4
+ import Badge from '../Badge/Badge.svelte'
5
+
6
+ import { classNames } from '../../utils/classNames'
7
+
8
+ import circleCheck from '../../icons/circle-check.svg?raw'
9
+ import copy from '../../icons/copy.svg?raw'
10
+
11
+ import styles from './copy.module.scss'
12
+
13
+ let {
14
+ tooltip = $bindable(''),
15
+ tooltipPosition,
16
+ copyIcon,
17
+ copiedIcon,
18
+ className,
19
+ children,
20
+ ...rest
21
+ }: SvelteCopyProps = $props()
22
+
23
+ const classes = classNames([
24
+ styles.copy,
25
+ className
26
+ ])
27
+
28
+ let copyButton: HTMLButtonElement | undefined = $state()
29
+ let copiedButton: HTMLSpanElement | undefined = $state()
30
+
31
+ const copyText = () => {
32
+ const text = copyButton
33
+ ?.parentElement
34
+ ?.parentElement
35
+ ?.querySelector('[data-id="text"]')
36
+ ?.textContent?.trim()
37
+
38
+ copyButton!.style.opacity = '0'
39
+ copyButton!.style.pointerEvents = 'none'
40
+
41
+ copiedButton!.style.opacity = '1'
42
+ tooltip = ''
43
+
44
+ navigator.clipboard.writeText(text as string)
45
+ }
46
+ </script>
47
+
48
+ <Badge
49
+ {...rest}
50
+ className={classes}
51
+ data-tooltip={tooltip || undefined}
52
+ data-position={tooltipPosition}
53
+ >
54
+ <span data-id="text">{@render children?.()}</span>
55
+ <div class={styles.icons}>
56
+ <button
57
+ bind:this={copyButton}
58
+ class={styles['copy-icon']}
59
+ onclick={copyText}
60
+ aria-label="copy"
61
+ >
62
+ {@html copyIcon || copy}
63
+ </button>
64
+ <span class={styles.copied} bind:this={copiedButton}>
65
+ {@html copiedIcon || circleCheck}
66
+ </span>
67
+ </div>
68
+ </Badge>
@@ -58,6 +58,7 @@ const Copy = ({
58
58
  className={styles['copy-icon']}
59
59
  ref={copyButton}
60
60
  onClick={copyText}
61
+ aria-label="copy"
61
62
  dangerouslySetInnerHTML={{ __html: copyIcon || copy }}
62
63
  />
63
64
  <span