webcoreui 0.6.1 → 0.8.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 +46 -7
- package/astro.d.ts +21 -0
- package/astro.js +14 -0
- package/components/Accordion/Accordion.astro +32 -20
- package/components/Accordion/Accordion.svelte +22 -4
- package/components/Accordion/Accordion.tsx +29 -7
- package/components/Accordion/accordion.module.scss +12 -0
- package/components/Accordion/accordion.ts +4 -0
- package/components/AspectRatio/AspectRatio.astro +21 -0
- package/components/AspectRatio/AspectRatio.svelte +19 -0
- package/components/AspectRatio/AspectRatio.tsx +28 -0
- package/components/AspectRatio/aspect-ratio.module.scss +10 -0
- package/components/AspectRatio/aspectratio.ts +8 -0
- package/components/Banner/Banner.astro +56 -0
- package/components/Banner/Banner.svelte +47 -0
- package/components/Banner/Banner.tsx +54 -0
- package/components/Banner/banner.module.scss +57 -0
- package/components/Banner/banner.ts +12 -0
- package/components/Breadcrumb/breadcrumb.module.scss +26 -26
- package/components/Button/button.module.scss +4 -0
- package/components/Carousel/carousel.module.scss +1 -1
- package/components/Collapsible/collapsible.module.scss +29 -29
- package/components/ConditionalWrapper/conditionalwrapper.ts +1 -0
- package/components/DataTable/datatable.module.scss +102 -102
- package/components/Footer/footer.module.scss +61 -61
- package/components/Group/group.module.scss +43 -43
- package/components/Icon/map.ts +2 -0
- package/components/Kbd/Kbd.astro +20 -0
- package/components/Kbd/Kbd.svelte +18 -0
- package/components/Kbd/Kbd.tsx +27 -0
- package/components/Kbd/kbd.module.scss +8 -0
- package/components/Kbd/kbd.ts +26 -0
- package/components/Kbd/keyMap.ts +21 -0
- package/components/List/list.module.scss +91 -91
- package/components/Masonry/masonry.module.scss +1 -1
- package/components/Modal/modal.module.scss +110 -110
- package/components/Pagination/pagination.module.scss +1 -1
- package/components/Popover/popover.module.scss +52 -52
- package/components/Ribbon/Ribbon.astro +28 -0
- package/components/Ribbon/Ribbon.svelte +26 -0
- package/components/Ribbon/Ribbon.tsx +33 -0
- package/components/Ribbon/ribbon.module.scss +84 -0
- package/components/Ribbon/ribbon.ts +16 -0
- package/components/Select/select.module.scss +25 -25
- package/components/Sheet/sheet.module.scss +68 -68
- package/components/Sidebar/sidebar.module.scss +43 -43
- package/components/Skeleton/Skeleton.astro +35 -0
- package/components/Skeleton/Skeleton.svelte +31 -0
- package/components/Skeleton/Skeleton.tsx +34 -0
- package/components/Skeleton/skeleton.module.scss +68 -0
- package/components/Skeleton/skeleton.ts +9 -0
- package/components/Slider/slider.module.scss +68 -68
- package/components/Spoiler/Spoiler.astro +50 -0
- package/components/Spoiler/Spoiler.svelte +45 -0
- package/components/Spoiler/Spoiler.tsx +50 -0
- package/components/Spoiler/spoiler.module.scss +40 -0
- package/components/Spoiler/spoiler.ts +11 -0
- package/components/Stepper/Stepper.astro +61 -0
- package/components/Stepper/Stepper.svelte +59 -0
- package/components/Stepper/Stepper.tsx +60 -0
- package/components/Stepper/stepper.module.scss +102 -0
- package/components/Stepper/stepper.ts +17 -0
- package/components/Table/Table.tsx +1 -1
- package/components/Textarea/textarea.module.scss +36 -36
- package/icons/close.svg +1 -1
- package/icons/plus.svg +3 -0
- package/icons.d.ts +1 -0
- package/icons.js +1 -0
- package/package.json +5 -5
- package/react.d.ts +21 -0
- package/react.js +14 -0
- package/scss/config/color-palette.scss +2 -0
- package/scss/config/css-values.scss +2 -0
- package/scss/config/layout.scss +2 -0
- package/scss/config/mixins.scss +7 -0
- package/scss/config/typography.scss +2 -0
- package/scss/config/variables.scss +2 -0
- package/scss/config.scss +7 -7
- package/scss/global/utility.scss +4 -0
- package/scss/global.scss +4 -4
- package/scss/index.scss +3 -3
- package/scss/resets.scss +10 -5
- package/scss/setup.scss +7 -1
- package/svelte.d.ts +21 -0
- package/svelte.js +14 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
body {
|
|
4
|
+
--w-skeleton-color: var(--w-color-primary-60);
|
|
5
|
+
--w-skeleton-wave-color: var(--w-color-primary-50);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.skeleton {
|
|
9
|
+
@include background(var(--w-skeleton-color));
|
|
10
|
+
@include size(100%);
|
|
11
|
+
|
|
12
|
+
text-indent: -9999px;
|
|
13
|
+
|
|
14
|
+
&.wave {
|
|
15
|
+
@include position(relative);
|
|
16
|
+
@include visibility(hidden);
|
|
17
|
+
|
|
18
|
+
&::after {
|
|
19
|
+
@include position(absolute, t0);
|
|
20
|
+
@include visibility(block);
|
|
21
|
+
@include size('w200px', 'h100%');
|
|
22
|
+
|
|
23
|
+
content: '';
|
|
24
|
+
left: -200px;
|
|
25
|
+
animation: wave 1s cubic-bezier(0.4, 0.0, 0.2, 1) infinite;
|
|
26
|
+
background: linear-gradient(
|
|
27
|
+
to right,
|
|
28
|
+
transparent 0%,
|
|
29
|
+
var(--w-skeleton-wave-color) 50%,
|
|
30
|
+
transparent 100%
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.pulse {
|
|
36
|
+
animation: pulse 1.3s cubic-bezier(0.4, 0.0, 0.2, 1) infinite;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&.rounded {
|
|
40
|
+
@include border-radius();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.circle {
|
|
44
|
+
@include border-radius(max);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@keyframes wave {
|
|
49
|
+
from {
|
|
50
|
+
left: -200px;
|
|
51
|
+
}
|
|
52
|
+
to {
|
|
53
|
+
left: 100%;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@keyframes pulse {
|
|
59
|
+
0% {
|
|
60
|
+
@include visibility(1);
|
|
61
|
+
}
|
|
62
|
+
50% {
|
|
63
|
+
@include visibility(.7);
|
|
64
|
+
}
|
|
65
|
+
100% {
|
|
66
|
+
@include visibility(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
@
|
|
2
|
-
|
|
3
|
-
body {
|
|
4
|
-
--w-slider-background: var(--w-color-primary-50);
|
|
5
|
-
--w-slider-color: var(--w-color-primary);
|
|
6
|
-
--w-slider-thumb: var(--w-color-primary-50);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.slider {
|
|
10
|
-
@include border-radius(xl);
|
|
11
|
-
@include size('w100%');
|
|
12
|
-
@include visibility(hidden);
|
|
13
|
-
@include size(h10px);
|
|
14
|
-
@include spacing(m0);
|
|
15
|
-
|
|
16
|
-
-webkit-appearance: none;
|
|
17
|
-
appearance: none;
|
|
18
|
-
cursor: pointer;
|
|
19
|
-
|
|
20
|
-
&[disabled]::-webkit-slider-runnable-track {
|
|
21
|
-
@include background(primary-50);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
&[disabled]::-moz-range-track {
|
|
25
|
-
@include background(primary-50);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
&[disabled]::-webkit-slider-thumb {
|
|
29
|
-
@include background(primary-50);
|
|
30
|
-
@include border(primary-30);
|
|
31
|
-
box-shadow: -995px 0 0 990px var(--w-color-primary-30);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
&[disabled]::-moz-range-thumb {
|
|
35
|
-
@include background(primary-50);
|
|
36
|
-
@include border(primary-30);
|
|
37
|
-
box-shadow: -995px 0 0 990px var(--w-color-primary-30);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.slider::-webkit-slider-runnable-track {
|
|
42
|
-
@include background(var(--w-slider-background));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.slider::-moz-range-track {
|
|
46
|
-
@include background(var(--w-slider-background));
|
|
47
|
-
@include size(h10px);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.slider::-webkit-slider-thumb {
|
|
51
|
-
@include background(var(--w-slider-thumb));
|
|
52
|
-
@include size(10px);
|
|
53
|
-
@include border-radius(max);
|
|
54
|
-
@include border(var(--w-slider-color));
|
|
55
|
-
|
|
56
|
-
-webkit-appearance: none;
|
|
57
|
-
appearance: none;
|
|
58
|
-
box-shadow: -995px 0 0 990px var(--w-slider-color);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.slider::-moz-range-thumb {
|
|
62
|
-
@include background(var(--w-slider-thumb));
|
|
63
|
-
@include size(9px);
|
|
64
|
-
@include border-radius(max);
|
|
65
|
-
@include border(var(--w-slider-color));
|
|
66
|
-
|
|
67
|
-
box-shadow: -995px 0 0 990px var(--w-slider-color);
|
|
68
|
-
}
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
body {
|
|
4
|
+
--w-slider-background: var(--w-color-primary-50);
|
|
5
|
+
--w-slider-color: var(--w-color-primary);
|
|
6
|
+
--w-slider-thumb: var(--w-color-primary-50);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.slider {
|
|
10
|
+
@include border-radius(xl);
|
|
11
|
+
@include size('w100%');
|
|
12
|
+
@include visibility(hidden);
|
|
13
|
+
@include size(h10px);
|
|
14
|
+
@include spacing(m0);
|
|
15
|
+
|
|
16
|
+
-webkit-appearance: none;
|
|
17
|
+
appearance: none;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
|
|
20
|
+
&[disabled]::-webkit-slider-runnable-track {
|
|
21
|
+
@include background(primary-50);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&[disabled]::-moz-range-track {
|
|
25
|
+
@include background(primary-50);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&[disabled]::-webkit-slider-thumb {
|
|
29
|
+
@include background(primary-50);
|
|
30
|
+
@include border(primary-30);
|
|
31
|
+
box-shadow: -995px 0 0 990px var(--w-color-primary-30);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&[disabled]::-moz-range-thumb {
|
|
35
|
+
@include background(primary-50);
|
|
36
|
+
@include border(primary-30);
|
|
37
|
+
box-shadow: -995px 0 0 990px var(--w-color-primary-30);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.slider::-webkit-slider-runnable-track {
|
|
42
|
+
@include background(var(--w-slider-background));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.slider::-moz-range-track {
|
|
46
|
+
@include background(var(--w-slider-background));
|
|
47
|
+
@include size(h10px);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.slider::-webkit-slider-thumb {
|
|
51
|
+
@include background(var(--w-slider-thumb));
|
|
52
|
+
@include size(10px);
|
|
53
|
+
@include border-radius(max);
|
|
54
|
+
@include border(var(--w-slider-color));
|
|
55
|
+
|
|
56
|
+
-webkit-appearance: none;
|
|
57
|
+
appearance: none;
|
|
58
|
+
box-shadow: -995px 0 0 990px var(--w-slider-color);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.slider::-moz-range-thumb {
|
|
62
|
+
@include background(var(--w-slider-thumb));
|
|
63
|
+
@include size(9px);
|
|
64
|
+
@include border-radius(max);
|
|
65
|
+
@include border(var(--w-slider-color));
|
|
66
|
+
|
|
67
|
+
box-shadow: -995px 0 0 990px var(--w-slider-color);
|
|
68
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { SpoilerProps } from './spoiler'
|
|
3
|
+
|
|
4
|
+
import styles from './spoiler.module.scss'
|
|
5
|
+
|
|
6
|
+
interface Props extends SpoilerProps {}
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
color,
|
|
10
|
+
animated = true,
|
|
11
|
+
block,
|
|
12
|
+
tooltip,
|
|
13
|
+
tooltipPosition
|
|
14
|
+
} = Astro.props
|
|
15
|
+
|
|
16
|
+
const classes = [
|
|
17
|
+
styles.spoiler,
|
|
18
|
+
animated && styles.anim,
|
|
19
|
+
block && styles.block
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const style = color
|
|
23
|
+
? `--w-spoiler-color: ${color};`
|
|
24
|
+
: null
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<span
|
|
28
|
+
class:list={classes}
|
|
29
|
+
style={style}
|
|
30
|
+
data-tooltip={tooltip}
|
|
31
|
+
data-position={tooltipPosition}
|
|
32
|
+
data-id="w-spoiler"
|
|
33
|
+
role="button"
|
|
34
|
+
tabindex="0"
|
|
35
|
+
>
|
|
36
|
+
<slot />
|
|
37
|
+
</span>
|
|
38
|
+
|
|
39
|
+
<script>
|
|
40
|
+
import { on } from '../../utils/DOMUtils'
|
|
41
|
+
|
|
42
|
+
on('[data-id="w-spoiler"]', 'click', (event: Event) => {
|
|
43
|
+
const target = event.currentTarget as HTMLDivElement
|
|
44
|
+
|
|
45
|
+
target.dataset.visible = 'true'
|
|
46
|
+
target.removeAttribute('data-tooltip')
|
|
47
|
+
target.removeAttribute('role')
|
|
48
|
+
target.removeAttribute('tabindex')
|
|
49
|
+
}, true)
|
|
50
|
+
</script>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SpoilerProps } from './spoiler'
|
|
3
|
+
|
|
4
|
+
import { classNames } from '../../utils/classNames'
|
|
5
|
+
|
|
6
|
+
import styles from './spoiler.module.scss'
|
|
7
|
+
|
|
8
|
+
export let color: SpoilerProps['color'] = ''
|
|
9
|
+
export let animated: SpoilerProps['animated'] = true
|
|
10
|
+
export let block: SpoilerProps['block'] = false
|
|
11
|
+
export let tooltip: SpoilerProps['tooltip'] = ''
|
|
12
|
+
export let tooltipPosition: SpoilerProps['tooltipPosition'] = null
|
|
13
|
+
|
|
14
|
+
const classes = classNames([
|
|
15
|
+
styles.spoiler,
|
|
16
|
+
animated && styles.anim,
|
|
17
|
+
block && styles.block
|
|
18
|
+
])
|
|
19
|
+
|
|
20
|
+
const style = color
|
|
21
|
+
? `--w-spoiler-color: ${color};`
|
|
22
|
+
: null
|
|
23
|
+
|
|
24
|
+
const toggle = (event: MouseEvent | KeyboardEvent) => {
|
|
25
|
+
const target = event.currentTarget as HTMLSpanElement
|
|
26
|
+
|
|
27
|
+
target.dataset.visible = 'true'
|
|
28
|
+
target.removeAttribute('data-tooltip')
|
|
29
|
+
target.removeAttribute('role')
|
|
30
|
+
target.removeAttribute('tabindex')
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<span
|
|
35
|
+
class={classes}
|
|
36
|
+
style={style}
|
|
37
|
+
data-tooltip={tooltip || null}
|
|
38
|
+
data-position={tooltipPosition}
|
|
39
|
+
role="button"
|
|
40
|
+
tabindex="0"
|
|
41
|
+
on:click={toggle}
|
|
42
|
+
on:keyup={toggle}
|
|
43
|
+
>
|
|
44
|
+
<slot />
|
|
45
|
+
</span>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { ReactSpoilerProps } from './spoiler'
|
|
3
|
+
|
|
4
|
+
import { classNames } from '../../utils/classNames'
|
|
5
|
+
|
|
6
|
+
import styles from './spoiler.module.scss'
|
|
7
|
+
|
|
8
|
+
const Spoiler = ({
|
|
9
|
+
color,
|
|
10
|
+
animated = true,
|
|
11
|
+
block,
|
|
12
|
+
tooltip,
|
|
13
|
+
tooltipPosition,
|
|
14
|
+
children
|
|
15
|
+
}: ReactSpoilerProps) => {
|
|
16
|
+
const classes = classNames([
|
|
17
|
+
styles.spoiler,
|
|
18
|
+
animated && styles.anim,
|
|
19
|
+
block && styles.block
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
const style = color
|
|
23
|
+
? { '--w-spoiler-color': color } as React.CSSProperties
|
|
24
|
+
: undefined
|
|
25
|
+
|
|
26
|
+
const toggle = (event: React.MouseEvent<HTMLSpanElement>) => {
|
|
27
|
+
const target = event.currentTarget
|
|
28
|
+
|
|
29
|
+
target.dataset.visible = 'true'
|
|
30
|
+
target.removeAttribute('data-tooltip')
|
|
31
|
+
target.removeAttribute('role')
|
|
32
|
+
target.removeAttribute('tabindex')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<span
|
|
37
|
+
className={classes}
|
|
38
|
+
style={style}
|
|
39
|
+
data-tooltip={tooltip}
|
|
40
|
+
data-position={tooltipPosition}
|
|
41
|
+
role="button"
|
|
42
|
+
tabIndex={0}
|
|
43
|
+
onClick={toggle}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</span>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default Spoiler
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
body {
|
|
4
|
+
--w-spoiler-color: var(--w-color-primary);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
span.spoiler {
|
|
8
|
+
@include border-radius();
|
|
9
|
+
@include background(var(--w-spoiler-color));
|
|
10
|
+
@include typography(hmd);
|
|
11
|
+
@include visibility(inline);
|
|
12
|
+
|
|
13
|
+
color: transparent;
|
|
14
|
+
user-select: none;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
|
|
17
|
+
&.anim {
|
|
18
|
+
@include transition();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&.block {
|
|
22
|
+
@include visibility(block);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
code {
|
|
26
|
+
@include border(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&[data-visible] {
|
|
30
|
+
@include background(transparent);
|
|
31
|
+
|
|
32
|
+
color: inherit;
|
|
33
|
+
user-select: auto;
|
|
34
|
+
cursor: auto;
|
|
35
|
+
|
|
36
|
+
code {
|
|
37
|
+
@include border(primary-50);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { StepperProps } from './stepper'
|
|
3
|
+
|
|
4
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.astro'
|
|
5
|
+
import Icon from '../Icon/Icon.astro'
|
|
6
|
+
|
|
7
|
+
import styles from './stepper.module.scss'
|
|
8
|
+
|
|
9
|
+
import type { IconProps } from '../Icon/icon'
|
|
10
|
+
|
|
11
|
+
interface Props extends StepperProps {}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
items,
|
|
15
|
+
color,
|
|
16
|
+
completedColor,
|
|
17
|
+
activeColor,
|
|
18
|
+
borderless,
|
|
19
|
+
vertical,
|
|
20
|
+
className
|
|
21
|
+
} = Astro.props
|
|
22
|
+
|
|
23
|
+
const classes = [
|
|
24
|
+
styles.stepper,
|
|
25
|
+
borderless && styles.borderless,
|
|
26
|
+
vertical && styles.vertical,
|
|
27
|
+
className
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
const styleVariables = [
|
|
31
|
+
color && `--w-stepper-color-border: ${color}`,
|
|
32
|
+
completedColor && `--w-stepper-color-complete: ${completedColor}`,
|
|
33
|
+
activeColor && `--w-stepper-color-active: ${activeColor}`
|
|
34
|
+
].filter(Boolean).join(';')
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
<ol class:list={classes} style={styleVariables}>
|
|
38
|
+
{items?.map((item, index) => (
|
|
39
|
+
<li class:list={[
|
|
40
|
+
index !== 0 && styles.connect,
|
|
41
|
+
item.active && styles.active,
|
|
42
|
+
item.completed && styles.completed
|
|
43
|
+
]}>
|
|
44
|
+
<span class={styles.number}>
|
|
45
|
+
{item.icon ? (
|
|
46
|
+
<Fragment>
|
|
47
|
+
{item.icon.startsWith('<svg')
|
|
48
|
+
? <Fragment set:html={item.icon} />
|
|
49
|
+
: <Icon type={item.icon as IconProps['type']} />
|
|
50
|
+
}
|
|
51
|
+
</Fragment>
|
|
52
|
+
) : index + 1}
|
|
53
|
+
</span>
|
|
54
|
+
<ConditionalWrapper condition={!!(item.title && item.subTitle)}>
|
|
55
|
+
<div slot="wrapper" class={styles.container}>children</div>
|
|
56
|
+
{item.title && <span>{item.title}</span>}
|
|
57
|
+
{item.subTitle && <span class={styles.muted}>{item.subTitle}</span>}
|
|
58
|
+
</ConditionalWrapper>
|
|
59
|
+
</li>
|
|
60
|
+
))}
|
|
61
|
+
</ol>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { StepperProps } from './stepper'
|
|
3
|
+
|
|
4
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.svelte'
|
|
5
|
+
|
|
6
|
+
import { classNames } from '../../utils/classNames'
|
|
7
|
+
|
|
8
|
+
import styles from './stepper.module.scss'
|
|
9
|
+
|
|
10
|
+
export let items: StepperProps['items'] = []
|
|
11
|
+
export let color: StepperProps['color'] = ''
|
|
12
|
+
export let completedColor: StepperProps['completedColor'] = ''
|
|
13
|
+
export let activeColor: StepperProps['activeColor'] = ''
|
|
14
|
+
export let borderless: StepperProps['vertical'] = false
|
|
15
|
+
export let vertical: StepperProps['vertical'] = false
|
|
16
|
+
export let className: StepperProps['className'] = ''
|
|
17
|
+
|
|
18
|
+
const classes = classNames([
|
|
19
|
+
styles.stepper,
|
|
20
|
+
borderless && styles.borderless,
|
|
21
|
+
vertical && styles.vertical,
|
|
22
|
+
className
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
const styleVariables = [
|
|
26
|
+
color && `--w-stepper-color-border: ${color}`,
|
|
27
|
+
completedColor && `--w-stepper-color-complete: ${completedColor}`,
|
|
28
|
+
activeColor && `--w-stepper-color-active: ${activeColor}`
|
|
29
|
+
].filter(Boolean).join(';')
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<ol class={classes} style={styleVariables || null}>
|
|
33
|
+
{#each items as item, index}
|
|
34
|
+
<li class={classNames([
|
|
35
|
+
index !== 0 && styles.connect,
|
|
36
|
+
item.active && styles.active,
|
|
37
|
+
item.completed && styles.completed
|
|
38
|
+
])}>
|
|
39
|
+
<span class={styles.number}>
|
|
40
|
+
{#if item.icon}
|
|
41
|
+
{@html item.icon}
|
|
42
|
+
{:else}
|
|
43
|
+
{index + 1}
|
|
44
|
+
{/if}
|
|
45
|
+
</span>
|
|
46
|
+
<ConditionalWrapper
|
|
47
|
+
condition={!!(item.title && item.subTitle)}
|
|
48
|
+
class={styles.container}
|
|
49
|
+
>
|
|
50
|
+
{#if item.title}
|
|
51
|
+
<span>{item.title}</span>
|
|
52
|
+
{/if}
|
|
53
|
+
{#if item.subTitle}
|
|
54
|
+
<span class={styles.muted}>{item.subTitle}</span>
|
|
55
|
+
{/if}
|
|
56
|
+
</ConditionalWrapper>
|
|
57
|
+
</li>
|
|
58
|
+
{/each}
|
|
59
|
+
</ol>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { StepperProps } from './stepper'
|
|
3
|
+
|
|
4
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx'
|
|
5
|
+
|
|
6
|
+
import { classNames } from '../../utils/classNames'
|
|
7
|
+
|
|
8
|
+
import styles from './stepper.module.scss'
|
|
9
|
+
|
|
10
|
+
const Stepper = ({
|
|
11
|
+
items,
|
|
12
|
+
color,
|
|
13
|
+
completedColor,
|
|
14
|
+
activeColor,
|
|
15
|
+
borderless,
|
|
16
|
+
vertical,
|
|
17
|
+
className
|
|
18
|
+
}: StepperProps) => {
|
|
19
|
+
const classes = classNames([
|
|
20
|
+
styles.stepper,
|
|
21
|
+
borderless && styles.borderless,
|
|
22
|
+
vertical && styles.vertical,
|
|
23
|
+
className
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
const styleVariables = {
|
|
27
|
+
...(color && { '--w-stepper-color-border': color }),
|
|
28
|
+
...(completedColor && { '--w-stepper-color-complete': completedColor }),
|
|
29
|
+
...(activeColor && { '--w-stepper-color-active': activeColor })
|
|
30
|
+
} as React.CSSProperties
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<ol className={classes} style={styleVariables}>
|
|
34
|
+
{items?.map((item, index) => (
|
|
35
|
+
<li className={classNames([
|
|
36
|
+
index !== 0 && styles.connect,
|
|
37
|
+
item.active && styles.active,
|
|
38
|
+
item.completed && styles.completed
|
|
39
|
+
])} key={index}>
|
|
40
|
+
<span
|
|
41
|
+
className={styles.number}
|
|
42
|
+
dangerouslySetInnerHTML={{ __html: item.icon
|
|
43
|
+
? item.icon
|
|
44
|
+
: index + 1
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
<ConditionalWrapper
|
|
48
|
+
condition={!!(item.title && item.subTitle)}
|
|
49
|
+
wrapper={children => <div className={styles.container}>{children}</div>}
|
|
50
|
+
>
|
|
51
|
+
{item.title && <span>{item.title}</span>}
|
|
52
|
+
{item.subTitle && <span className={styles.muted}>{item.subTitle}</span>}
|
|
53
|
+
</ConditionalWrapper>
|
|
54
|
+
</li>
|
|
55
|
+
))}
|
|
56
|
+
</ol>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default Stepper
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
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
|
+
$size: 20px;
|
|
10
|
+
|
|
11
|
+
.stepper {
|
|
12
|
+
@include layout(flex, default, column);
|
|
13
|
+
@include spacing(0);
|
|
14
|
+
@include size('w100%');
|
|
15
|
+
|
|
16
|
+
list-style-type: none;
|
|
17
|
+
|
|
18
|
+
&:not(.borderless) .number {
|
|
19
|
+
border: 2px solid var(--w-stepper-color-border);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
li {
|
|
23
|
+
@include layout(flex, sm, v-center);
|
|
24
|
+
@include typography(normal);
|
|
25
|
+
@include spacing(m0);
|
|
26
|
+
|
|
27
|
+
flex: 1;
|
|
28
|
+
|
|
29
|
+
&.connect {
|
|
30
|
+
@include position(relative);
|
|
31
|
+
|
|
32
|
+
&::before {
|
|
33
|
+
@include position(absolute, l16px);
|
|
34
|
+
@include background(var(--w-stepper-color-border));
|
|
35
|
+
@include size(w2px);
|
|
36
|
+
|
|
37
|
+
top: -50%;
|
|
38
|
+
bottom: calc(50% + $size);
|
|
39
|
+
|
|
40
|
+
content: '';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.completed::before,
|
|
44
|
+
&.active::before {
|
|
45
|
+
@include background(var(--w-stepper-color-complete));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.active .number {
|
|
50
|
+
border-color: var(--w-stepper-color-active);
|
|
51
|
+
color: var(--w-stepper-color-active);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.completed .number {
|
|
55
|
+
border-color: var(--w-stepper-color-complete);
|
|
56
|
+
color: var(--w-stepper-color-complete);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.number {
|
|
60
|
+
@include size($size);
|
|
61
|
+
@include border-radius(max);
|
|
62
|
+
@include layout(flex, center);
|
|
63
|
+
@include spacing(p-md);
|
|
64
|
+
@include typography(bold, md);
|
|
65
|
+
|
|
66
|
+
svg {
|
|
67
|
+
@include position(absolute);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.container {
|
|
72
|
+
@include layout(flex, column);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.muted {
|
|
76
|
+
@include typography(primary-20, md);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@include media(xs) {
|
|
82
|
+
.stepper:not(.vertical) {
|
|
83
|
+
@include layout(row);
|
|
84
|
+
|
|
85
|
+
li {
|
|
86
|
+
@include layout(column, xs, v-center);
|
|
87
|
+
|
|
88
|
+
&.connect::before {
|
|
89
|
+
@include size(h2px);
|
|
90
|
+
|
|
91
|
+
width: auto;
|
|
92
|
+
top: 16px;
|
|
93
|
+
left: calc(-50%);
|
|
94
|
+
right: calc(50% + $size);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.container {
|
|
98
|
+
@include layout(v-center);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|