webcoreui 0.8.1 → 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.
- package/README.md +36 -6
- package/astro.d.ts +23 -0
- package/astro.js +8 -0
- package/components/Accordion/Accordion.astro +15 -10
- package/components/Accordion/Accordion.svelte +14 -12
- package/components/Accordion/Accordion.tsx +2 -2
- package/components/Accordion/accordion.module.scss +1 -0
- package/components/Alert/Alert.svelte +17 -12
- package/components/Alert/Alert.tsx +1 -1
- package/components/Alert/alert.ts +10 -3
- package/components/AspectRatio/AspectRatio.svelte +7 -4
- package/components/AspectRatio/aspectratio.ts +6 -0
- package/components/Avatar/Avatar.svelte +11 -9
- package/components/Badge/Badge.svelte +14 -10
- package/components/Badge/badge.ts +3 -2
- package/components/Banner/Banner.astro +10 -4
- package/components/Banner/Banner.svelte +14 -10
- package/components/Banner/Banner.tsx +1 -0
- package/components/Banner/banner.ts +6 -0
- package/components/BottomNavigation/BottomNavigation.astro +51 -0
- package/components/BottomNavigation/BottomNavigation.svelte +47 -0
- package/components/BottomNavigation/BottomNavigation.tsx +63 -0
- package/components/BottomNavigation/bottomnavigation.module.scss +70 -0
- package/components/BottomNavigation/bottomnavigation.ts +16 -0
- package/components/Breadcrumb/Breadcrumb.astro +1 -1
- package/components/Breadcrumb/Breadcrumb.svelte +8 -6
- package/components/Breadcrumb/Breadcrumb.tsx +2 -2
- package/components/Button/Button.svelte +12 -8
- package/components/Button/Button.tsx +2 -2
- package/components/Button/button.ts +2 -3
- package/components/Card/Card.svelte +14 -10
- package/components/Card/card.module.scss +1 -0
- package/components/Card/card.ts +6 -0
- package/components/Carousel/Carousel.astro +46 -41
- package/components/Carousel/carousel.ts +3 -0
- package/components/Checkbox/Checkbox.astro +8 -2
- package/components/Checkbox/Checkbox.svelte +12 -8
- package/components/Checkbox/Checkbox.tsx +3 -1
- package/components/Checkbox/checkbox.module.scss +4 -0
- package/components/Checkbox/checkbox.ts +1 -0
- package/components/Collapsible/Collapsible.astro +8 -5
- package/components/Collapsible/Collapsible.svelte +54 -49
- package/components/Collapsible/collapsible.ts +8 -0
- package/components/ConditionalWrapper/ConditionalWrapper.svelte +10 -6
- package/components/ConditionalWrapper/conditionalwrapper.ts +6 -0
- package/components/Copy/Copy.astro +80 -0
- package/components/Copy/Copy.svelte +68 -0
- package/components/Copy/Copy.tsx +74 -0
- package/components/Copy/copy.module.scss +37 -0
- package/components/Copy/copy.ts +20 -0
- package/components/DataTable/DataTable.astro +103 -93
- package/components/DataTable/DataTable.svelte +276 -272
- package/components/DataTable/datatable.ts +5 -2
- package/components/Flex/Flex.astro +34 -0
- package/components/Flex/Flex.svelte +31 -0
- package/components/Flex/Flex.tsx +30 -0
- package/components/Flex/flex.ts +28 -0
- package/components/Footer/Footer.svelte +12 -9
- package/components/Footer/footer.ts +6 -0
- package/components/Grid/Grid.astro +32 -0
- package/components/Grid/Grid.svelte +29 -0
- package/components/Grid/Grid.tsx +28 -0
- package/components/Grid/grid.ts +24 -0
- package/components/Group/Group.svelte +7 -4
- package/components/Group/group.ts +6 -0
- package/components/Icon/Icon.astro +19 -5
- package/components/Icon/Icon.svelte +23 -7
- package/components/Icon/Icon.tsx +19 -5
- package/components/Icon/icon.ts +10 -3
- package/components/Icon/map.ts +10 -10
- package/components/Input/Input.astro +1 -1
- package/components/Input/Input.svelte +26 -20
- package/components/Input/Input.tsx +4 -1
- package/components/Input/input.ts +10 -3
- package/components/Kbd/Kbd.svelte +7 -4
- package/components/Kbd/kbd.ts +6 -0
- package/components/List/List.astro +65 -60
- package/components/List/List.svelte +149 -147
- package/components/List/List.tsx +1 -1
- package/components/List/list.module.scss +3 -0
- package/components/Masonry/Masonry.svelte +12 -10
- package/components/Menu/Menu.astro +8 -3
- package/components/Menu/Menu.svelte +19 -10
- package/components/Menu/Menu.tsx +3 -1
- package/components/Menu/menu.ts +6 -0
- package/components/Modal/Modal.astro +1 -0
- package/components/Modal/Modal.svelte +18 -13
- package/components/Modal/Modal.tsx +2 -1
- package/components/Modal/modal.ts +6 -1
- package/components/Pagination/Pagination.astro +75 -69
- package/components/Pagination/Pagination.svelte +30 -26
- package/components/Pagination/Pagination.tsx +5 -4
- package/components/Pagination/pagination.module.scss +4 -0
- package/components/Popover/Popover.svelte +10 -6
- package/components/Popover/popover.ts +6 -0
- package/components/Progress/Progress.svelte +12 -10
- package/components/Progress/progress.ts +1 -1
- package/components/Radio/Radio.astro +3 -1
- package/components/Radio/Radio.svelte +14 -10
- package/components/Radio/Radio.tsx +5 -3
- package/components/Radio/radio.ts +5 -2
- package/components/Rating/Rating.svelte +16 -14
- package/components/Ribbon/Ribbon.svelte +9 -6
- package/components/Ribbon/ribbon.ts +6 -0
- package/components/Select/Select.astro +85 -42
- package/components/Select/Select.svelte +62 -21
- package/components/Select/Select.tsx +41 -7
- package/components/Select/select.ts +4 -1
- package/components/Sheet/Sheet.svelte +9 -5
- package/components/Sheet/sheet.ts +6 -2
- package/components/Sidebar/Sidebar.svelte +7 -4
- package/components/Sidebar/sidebar.ts +6 -0
- package/components/Skeleton/Skeleton.astro +2 -2
- package/components/Skeleton/Skeleton.svelte +11 -9
- package/components/Skeleton/Skeleton.tsx +2 -2
- package/components/Slider/Slider.svelte +15 -13
- package/components/Slider/slider.module.scss +4 -0
- package/components/Slider/slider.ts +4 -2
- package/components/Spinner/Spinner.svelte +7 -5
- package/components/Spoiler/Spoiler.astro +13 -8
- package/components/Spoiler/Spoiler.svelte +13 -10
- package/components/Spoiler/spoiler.ts +6 -0
- package/components/Stepper/Stepper.svelte +9 -7
- package/components/Switch/Switch.astro +3 -2
- package/components/Switch/Switch.svelte +15 -11
- package/components/Switch/Switch.tsx +3 -1
- package/components/Switch/switch.ts +1 -0
- package/components/Table/Table.svelte +11 -9
- package/components/Table/table.ts +1 -1
- package/components/Tabs/Tabs.astro +8 -5
- package/components/Tabs/Tabs.svelte +14 -11
- package/components/Tabs/tabs.ts +7 -1
- package/components/Textarea/Textarea.astro +3 -1
- package/components/Textarea/Textarea.svelte +51 -47
- package/components/Textarea/textarea.ts +24 -18
- package/components/ThemeSwitcher/ThemeSwitcher.astro +43 -37
- package/components/ThemeSwitcher/ThemeSwitcher.svelte +14 -10
- package/components/ThemeSwitcher/themeswitcher.ts +7 -0
- package/components/Timeline/Timeline.svelte +12 -9
- package/components/Timeline/timeline.ts +7 -2
- package/components/TimelineItem/TimelineItem.svelte +8 -5
- package/components/TimelineItem/timelineitem.ts +6 -0
- package/components/Toast/Toast.svelte +18 -10
- package/components/Toast/toast.ts +6 -1
- package/icons/alert.svg +2 -2
- package/icons/check.svg +2 -2
- package/icons/chevron-down.svg +3 -0
- package/icons/chevron-left.svg +3 -0
- package/icons/chevron-right.svg +3 -0
- package/icons/chevron-up.svg +3 -0
- package/icons/circle-check.svg +3 -3
- package/icons/copy.svg +3 -0
- package/icons/info.svg +3 -3
- package/icons.d.ts +5 -5
- package/icons.js +5 -5
- package/index.d.ts +75 -2
- package/index.js +2 -0
- package/package.json +31 -22
- package/react.d.ts +23 -0
- package/react.js +8 -0
- package/scss/global/utility.scss +48 -3
- package/svelte.d.ts +111 -88
- package/svelte.js +8 -0
- package/utils/DOMUtils.ts +2 -2
- package/utils/bodyFreeze.ts +13 -0
- package/utils/classNames.ts +1 -1
- package/utils/getLayoutClasses.ts +141 -0
- package/utils/modal.ts +16 -4
- package/utils/popover.ts +30 -4
- package/icons/arrow-down.svg +0 -3
- package/icons/arrow-left.svg +0 -3
- package/icons/arrow-right.svg +0 -3
- package/icons/components.svg +0 -3
- package/icons/file.svg +0 -3
- package/scss/webcore.config.scss +0 -0
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
import styles from './checkbox.module.scss'
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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,7 +41,8 @@
|
|
|
38
41
|
type="checkbox"
|
|
39
42
|
checked={checked}
|
|
40
43
|
disabled={disabled}
|
|
41
|
-
|
|
44
|
+
onclick={onClick}
|
|
45
|
+
{...rest}
|
|
42
46
|
/>
|
|
43
47
|
<span class={styles.check}>
|
|
44
48
|
{@html check}
|
|
@@ -16,7 +16,8 @@ const Checkbox = ({
|
|
|
16
16
|
disabled,
|
|
17
17
|
color,
|
|
18
18
|
className,
|
|
19
|
-
onClick
|
|
19
|
+
onClick,
|
|
20
|
+
...rest
|
|
20
21
|
}: ReactCheckboxProps) => {
|
|
21
22
|
const classes = classNames([
|
|
22
23
|
styles.checkbox,
|
|
@@ -43,6 +44,7 @@ const Checkbox = ({
|
|
|
43
44
|
defaultChecked={checked}
|
|
44
45
|
disabled={disabled}
|
|
45
46
|
onClick={onClick}
|
|
47
|
+
{...rest}
|
|
46
48
|
/>
|
|
47
49
|
<span
|
|
48
50
|
className={styles.check}
|
|
@@ -45,10 +45,10 @@ const styleVariables = classNames([
|
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
<script>
|
|
48
|
-
|
|
48
|
+
import { on } from '../../utils/DOMUtils'
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
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 {
|
|
3
|
-
|
|
4
|
-
import { classNames } from '../../utils/classNames'
|
|
5
|
-
|
|
6
|
-
import styles from './collapsible.module.scss'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
])
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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 {
|
|
2
|
+
import type { SvelteConditionalWrapperProps } from './conditionalwrapper'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
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} {
|
|
10
|
-
|
|
13
|
+
<svelte:element this={element} {...rest}>
|
|
14
|
+
{@render children?.()}
|
|
11
15
|
</svelte:element>
|
|
12
16
|
{:else}
|
|
13
|
-
|
|
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
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { CopyProps } from './copy'
|
|
3
|
+
|
|
4
|
+
import Badge from '../Badge/Badge.astro'
|
|
5
|
+
import Icon from '../Icon/Icon.astro'
|
|
6
|
+
|
|
7
|
+
import { classNames } from '../../utils/classNames'
|
|
8
|
+
|
|
9
|
+
import styles from './copy.module.scss'
|
|
10
|
+
|
|
11
|
+
import type { IconProps } from '../Icon/icon'
|
|
12
|
+
|
|
13
|
+
interface Props extends CopyProps {}
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
tooltip,
|
|
17
|
+
tooltipPosition,
|
|
18
|
+
copyIcon = 'copy',
|
|
19
|
+
copiedIcon = 'circle-check',
|
|
20
|
+
className,
|
|
21
|
+
...rest
|
|
22
|
+
} = Astro.props
|
|
23
|
+
|
|
24
|
+
const classes = classNames([
|
|
25
|
+
styles.copy,
|
|
26
|
+
className
|
|
27
|
+
])
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<Badge
|
|
31
|
+
{...rest}
|
|
32
|
+
className={classes}
|
|
33
|
+
data-tooltip={tooltip}
|
|
34
|
+
data-position={tooltipPosition}
|
|
35
|
+
>
|
|
36
|
+
<slot />
|
|
37
|
+
<div class={styles.icons}>
|
|
38
|
+
<button
|
|
39
|
+
class={styles['copy-icon']}
|
|
40
|
+
data-id="w-copy"
|
|
41
|
+
aria-label="copy"
|
|
42
|
+
>
|
|
43
|
+
{copyIcon?.startsWith('<svg')
|
|
44
|
+
? <Fragment set:html={copyIcon} />
|
|
45
|
+
: <Icon type={copyIcon as IconProps['type']} />
|
|
46
|
+
}
|
|
47
|
+
</button>
|
|
48
|
+
<span class={styles.copied}>
|
|
49
|
+
{copiedIcon?.startsWith('<svg')
|
|
50
|
+
? <Fragment set:html={copiedIcon} />
|
|
51
|
+
: <Icon type={copiedIcon as IconProps['type']} />
|
|
52
|
+
}
|
|
53
|
+
</span>
|
|
54
|
+
</div>
|
|
55
|
+
</Badge>
|
|
56
|
+
|
|
57
|
+
<script>
|
|
58
|
+
import { on } from '../../utils/DOMUtils'
|
|
59
|
+
|
|
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
|
|
65
|
+
|
|
66
|
+
const text = copy.parentElement?.previousSibling?.textContent?.trim()
|
|
67
|
+
|
|
68
|
+
copy.style.opacity = '0'
|
|
69
|
+
copy.style.pointerEvents = 'none'
|
|
70
|
+
|
|
71
|
+
copied.style.opacity = '1'
|
|
72
|
+
badge.removeAttribute('data-tooltip')
|
|
73
|
+
|
|
74
|
+
navigator.clipboard.writeText(text as string)
|
|
75
|
+
}, true)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
on(document, 'astro:after-swap', addEventListeners)
|
|
79
|
+
addEventListeners()
|
|
80
|
+
</script>
|
|
@@ -0,0 +1,68 @@
|
|
|
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>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react'
|
|
2
|
+
import type { ReactCopyProps } from './copy'
|
|
3
|
+
|
|
4
|
+
import Badge from '../Badge/Badge.tsx'
|
|
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
|
+
const Copy = ({
|
|
14
|
+
tooltip,
|
|
15
|
+
tooltipPosition,
|
|
16
|
+
copyIcon,
|
|
17
|
+
copiedIcon,
|
|
18
|
+
className,
|
|
19
|
+
children,
|
|
20
|
+
...rest
|
|
21
|
+
}: ReactCopyProps) => {
|
|
22
|
+
const copyButton = useRef<HTMLButtonElement>(null)
|
|
23
|
+
const copiedButton = useRef<HTMLSpanElement>(null)
|
|
24
|
+
const [tooltipText, setTooltipText] = useState(tooltip)
|
|
25
|
+
|
|
26
|
+
const classes = classNames([
|
|
27
|
+
styles.copy,
|
|
28
|
+
className
|
|
29
|
+
])
|
|
30
|
+
|
|
31
|
+
const copyText = () => {
|
|
32
|
+
const copyButtonElement = copyButton.current as HTMLButtonElement
|
|
33
|
+
const copiedButtonElement = copiedButton.current as HTMLSpanElement
|
|
34
|
+
|
|
35
|
+
const text = copyButtonElement.parentElement?.previousSibling?.textContent?.trim()
|
|
36
|
+
|| copyButtonElement.parentElement?.previousElementSibling?.textContent?.trim()
|
|
37
|
+
|
|
38
|
+
copyButtonElement.style.opacity = '0'
|
|
39
|
+
copyButtonElement.style.pointerEvents = 'none'
|
|
40
|
+
|
|
41
|
+
copiedButtonElement.style.opacity = '1'
|
|
42
|
+
|
|
43
|
+
setTooltipText('')
|
|
44
|
+
|
|
45
|
+
navigator.clipboard.writeText(text as string)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Badge
|
|
50
|
+
{...rest}
|
|
51
|
+
className={classes}
|
|
52
|
+
data-tooltip={tooltipText || undefined}
|
|
53
|
+
data-position={tooltipPosition}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
<div className={styles.icons}>
|
|
57
|
+
<button
|
|
58
|
+
className={styles['copy-icon']}
|
|
59
|
+
ref={copyButton}
|
|
60
|
+
onClick={copyText}
|
|
61
|
+
aria-label="copy"
|
|
62
|
+
dangerouslySetInnerHTML={{ __html: copyIcon || copy }}
|
|
63
|
+
/>
|
|
64
|
+
<span
|
|
65
|
+
className={styles.copied}
|
|
66
|
+
ref={copiedButton}
|
|
67
|
+
dangerouslySetInnerHTML={{ __html: copiedIcon || circleCheck }}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</Badge>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default Copy
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
.copy {
|
|
4
|
+
@include typography(md);
|
|
5
|
+
|
|
6
|
+
svg {
|
|
7
|
+
@include size(18px);
|
|
8
|
+
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.icons {
|
|
13
|
+
@include position(relative);
|
|
14
|
+
@include size(18px);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.copy-icon,
|
|
18
|
+
.copied {
|
|
19
|
+
@include position(absolute, t0, l0);
|
|
20
|
+
@include transition(opacity);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.copy-icon {
|
|
24
|
+
@include background(transparent);
|
|
25
|
+
@include border(0);
|
|
26
|
+
@include spacing(p0);
|
|
27
|
+
|
|
28
|
+
color: inherit;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.copied {
|
|
32
|
+
@include visibility(0);
|
|
33
|
+
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
cursor: auto;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte'
|
|
2
|
+
|
|
3
|
+
import type { BadgeProps } from '../Badge/badge'
|
|
4
|
+
import type { IconProps } from '../Icon/icon'
|
|
5
|
+
|
|
6
|
+
export type CopyProps = {
|
|
7
|
+
tooltip?: string
|
|
8
|
+
tooltipPosition?: 'left' | 'right' | 'bottom' | null
|
|
9
|
+
copyIcon?: IconProps['type'] | string
|
|
10
|
+
copiedIcon?: IconProps['type'] | string
|
|
11
|
+
className?: string
|
|
12
|
+
} & BadgeProps
|
|
13
|
+
|
|
14
|
+
export type SvelteCopyProps = {
|
|
15
|
+
children: Snippet
|
|
16
|
+
} & CopyProps
|
|
17
|
+
|
|
18
|
+
export type ReactCopyProps = {
|
|
19
|
+
children: React.ReactNode
|
|
20
|
+
} & CopyProps
|