webcoreui 0.0.7 → 0.0.9
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 +18 -1
- package/astro.d.ts +10 -0
- package/astro.js +11 -1
- package/components/Accordion/Accordion.astro +1 -4
- package/components/Accordion/Accordion.svelte +1 -4
- package/components/Alert/Alert.astro +3 -5
- package/components/Alert/Alert.svelte +3 -5
- package/components/Alert/Alert.tsx +9 -2
- package/components/Alert/alert.ts +0 -1
- package/components/Avatar/Avatar.astro +51 -0
- package/components/Avatar/Avatar.svelte +48 -0
- package/components/Avatar/Avatar.tsx +63 -0
- package/components/Avatar/avatar.scss +35 -0
- package/components/Avatar/avatar.ts +10 -0
- package/components/Badge/Badge.astro +1 -5
- package/components/Badge/Badge.svelte +1 -4
- package/components/Badge/Badge.tsx +5 -1
- package/components/Badge/badge.ts +0 -1
- package/components/Button/Button.astro +1 -4
- package/components/Button/Button.svelte +1 -4
- package/components/Button/Button.tsx +5 -1
- package/components/Button/button.ts +1 -1
- package/components/Card/Card.astro +2 -5
- package/components/Card/Card.svelte +1 -4
- package/components/Card/Card.tsx +7 -1
- package/components/Card/card.ts +1 -0
- package/components/Checkbox/Checkbox.astro +51 -0
- package/components/Checkbox/Checkbox.svelte +52 -0
- package/components/Checkbox/Checkbox.tsx +69 -0
- package/components/Checkbox/checkbox.scss +85 -0
- package/components/Checkbox/checkbox.ts +8 -0
- package/components/Radio/Radio.astro +57 -0
- package/components/Radio/Radio.svelte +56 -0
- package/components/Radio/Radio.tsx +72 -0
- package/components/Radio/radio.scss +92 -0
- package/components/Radio/radio.ts +13 -0
- package/components/Rating/Rating.astro +66 -0
- package/components/Rating/Rating.svelte +70 -0
- package/components/Rating/Rating.tsx +67 -0
- package/components/Rating/rating.scss +37 -0
- package/components/Rating/rating.ts +16 -0
- package/components/Switch/Switch.astro +38 -0
- package/components/Switch/Switch.svelte +42 -0
- package/components/Switch/Switch.tsx +50 -0
- package/components/Switch/switch.scss +84 -0
- package/components/Switch/switch.ts +11 -0
- package/icons/check.svg +1 -2
- package/icons/circle-check.svg +4 -0
- package/package.json +3 -2
- package/react.d.ts +10 -0
- package/react.js +11 -1
- package/scss/setup.scss +11 -0
- package/svelte.d.ts +10 -0
- package/svelte.js +11 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CheckboxProps } from './checkbox'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.svelte'
|
|
4
|
+
|
|
5
|
+
import check from '../../icons/check.svg?raw'
|
|
6
|
+
|
|
7
|
+
import './checkbox.scss'
|
|
8
|
+
|
|
9
|
+
export let checked: CheckboxProps['checked'] = false
|
|
10
|
+
export let label: CheckboxProps['label'] = ''
|
|
11
|
+
export let subText: CheckboxProps['subText'] = ''
|
|
12
|
+
export let disabled: CheckboxProps['disabled'] = false
|
|
13
|
+
export let boxed: CheckboxProps['boxed'] = false
|
|
14
|
+
export let color: CheckboxProps['color'] = ''
|
|
15
|
+
export let onClick: () => any = () => {}
|
|
16
|
+
|
|
17
|
+
const classes = [
|
|
18
|
+
'w-checkbox',
|
|
19
|
+
boxed && 'boxed',
|
|
20
|
+
label && subText && 'col'
|
|
21
|
+
].filter(Boolean).join(' ')
|
|
22
|
+
|
|
23
|
+
const style = color
|
|
24
|
+
? `--w-checkbox-color: ${color};`
|
|
25
|
+
: null
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<label class={classes} style={style}>
|
|
29
|
+
<ConditionalWrapper
|
|
30
|
+
condition={!!(label && subText)}
|
|
31
|
+
element="div"
|
|
32
|
+
class="checkbox-wrapper"
|
|
33
|
+
>
|
|
34
|
+
<input
|
|
35
|
+
type="checkbox"
|
|
36
|
+
checked={checked}
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
on:click={onClick}
|
|
39
|
+
/>
|
|
40
|
+
<span class="check">
|
|
41
|
+
{@html check}
|
|
42
|
+
</span>
|
|
43
|
+
{#if label}
|
|
44
|
+
<span class="label">
|
|
45
|
+
{@html label}
|
|
46
|
+
</span>
|
|
47
|
+
{/if}
|
|
48
|
+
</ConditionalWrapper>
|
|
49
|
+
{#if label && subText}
|
|
50
|
+
<span class="sub-text">{@html subText}</span>
|
|
51
|
+
{/if}
|
|
52
|
+
</label>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { CheckboxProps } from './checkbox'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx'
|
|
4
|
+
|
|
5
|
+
import check from '../../icons/check.svg?raw'
|
|
6
|
+
|
|
7
|
+
import './checkbox.scss'
|
|
8
|
+
|
|
9
|
+
type ReactCheckboxProps = {
|
|
10
|
+
onClick?: () => any
|
|
11
|
+
} & CheckboxProps
|
|
12
|
+
|
|
13
|
+
const Checkbox = ({
|
|
14
|
+
checked,
|
|
15
|
+
label,
|
|
16
|
+
subText,
|
|
17
|
+
disabled,
|
|
18
|
+
boxed,
|
|
19
|
+
color,
|
|
20
|
+
onClick
|
|
21
|
+
}: ReactCheckboxProps) => {
|
|
22
|
+
const classes = [
|
|
23
|
+
'w-checkbox',
|
|
24
|
+
boxed && 'boxed',
|
|
25
|
+
label && subText && 'col'
|
|
26
|
+
].filter(Boolean).join(' ')
|
|
27
|
+
|
|
28
|
+
const style = color
|
|
29
|
+
? { '--w-checkbox-color': color } as React.CSSProperties
|
|
30
|
+
: undefined
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<label className={classes} style={style}>
|
|
34
|
+
<ConditionalWrapper
|
|
35
|
+
condition={!!(label && subText)}
|
|
36
|
+
wrapper={children => (
|
|
37
|
+
<div className="checkbox-wrapper">
|
|
38
|
+
{children}
|
|
39
|
+
</div>
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<input
|
|
43
|
+
type="checkbox"
|
|
44
|
+
checked={checked}
|
|
45
|
+
disabled={disabled}
|
|
46
|
+
onClick={onClick}
|
|
47
|
+
/>
|
|
48
|
+
<span
|
|
49
|
+
className="check"
|
|
50
|
+
dangerouslySetInnerHTML={{ __html: check }}
|
|
51
|
+
/>
|
|
52
|
+
{label && (
|
|
53
|
+
<span
|
|
54
|
+
className="label"
|
|
55
|
+
dangerouslySetInnerHTML={{ __html: label }}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
</ConditionalWrapper>
|
|
59
|
+
{label && subText && (
|
|
60
|
+
<span
|
|
61
|
+
className="sub-text"
|
|
62
|
+
dangerouslySetInnerHTML={{ __html: subText }}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
</label>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default Checkbox
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
@import '../../scss/config.scss';
|
|
2
|
+
|
|
3
|
+
.w-checkbox {
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
gap: 10px;
|
|
8
|
+
font-size: 16px;
|
|
9
|
+
|
|
10
|
+
&.col {
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
align-items: flex-start;
|
|
13
|
+
justify-content: flex-start;
|
|
14
|
+
gap: 5px;
|
|
15
|
+
|
|
16
|
+
.checkbox-wrapper {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 10px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.boxed {
|
|
24
|
+
border: 1px solid #252525;
|
|
25
|
+
border-radius: 5px;
|
|
26
|
+
padding: 20px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
input {
|
|
30
|
+
display: none;
|
|
31
|
+
|
|
32
|
+
&:checked + span {
|
|
33
|
+
background-color: var(--w-checkbox-color);
|
|
34
|
+
|
|
35
|
+
svg {
|
|
36
|
+
position: absolute;
|
|
37
|
+
top: 50%;
|
|
38
|
+
left: 50%;
|
|
39
|
+
transform: translate(-50%, -50%);
|
|
40
|
+
display: block;
|
|
41
|
+
color: #252525;
|
|
42
|
+
width: 10px;
|
|
43
|
+
height: 10px;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&:disabled + span {
|
|
48
|
+
background-color: #333;
|
|
49
|
+
border-color: #333;
|
|
50
|
+
cursor: no-drop;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
a {
|
|
55
|
+
text-decoration: underline;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.check {
|
|
59
|
+
display: inline-block;
|
|
60
|
+
width: 15px;
|
|
61
|
+
height: 15px;
|
|
62
|
+
border: 1px solid var(--w-checkbox-color);
|
|
63
|
+
border-radius: 2px;
|
|
64
|
+
position: relative;
|
|
65
|
+
|
|
66
|
+
svg {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.sub-text {
|
|
72
|
+
margin-left: 25px;
|
|
73
|
+
font-size: 14px;
|
|
74
|
+
color: #BBB;
|
|
75
|
+
|
|
76
|
+
a {
|
|
77
|
+
@include Transition(color);
|
|
78
|
+
color: #BBB;
|
|
79
|
+
|
|
80
|
+
&:hover {
|
|
81
|
+
color: #FFF;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { RadioProps } from './radio'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.astro'
|
|
4
|
+
|
|
5
|
+
import './radio.scss'
|
|
6
|
+
|
|
7
|
+
interface Props extends RadioProps {}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
name,
|
|
11
|
+
items,
|
|
12
|
+
color,
|
|
13
|
+
inline,
|
|
14
|
+
className
|
|
15
|
+
} = Astro.props
|
|
16
|
+
|
|
17
|
+
const classes = [
|
|
18
|
+
'w-radio',
|
|
19
|
+
inline && 'inline',
|
|
20
|
+
className
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
const style = color
|
|
24
|
+
? `--w-radio-color: ${color};`
|
|
25
|
+
: null
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<div class:list={classes} style={style}>
|
|
29
|
+
{items.map(item => (
|
|
30
|
+
<label class:list={[
|
|
31
|
+
item.subText && 'col',
|
|
32
|
+
item.disabled && 'disabled'
|
|
33
|
+
]}>
|
|
34
|
+
<ConditionalWrapper condition={!!(item.subText)}>
|
|
35
|
+
<div class="radio-wrapper" slot="wrapper">
|
|
36
|
+
children
|
|
37
|
+
</div>
|
|
38
|
+
<input
|
|
39
|
+
type="radio"
|
|
40
|
+
name={name}
|
|
41
|
+
value={item.value}
|
|
42
|
+
checked={item.selected}
|
|
43
|
+
disabled={item.disabled}
|
|
44
|
+
/>
|
|
45
|
+
<span class="radio" />
|
|
46
|
+
<span class="label">
|
|
47
|
+
<Fragment set:html={item.label} />
|
|
48
|
+
</span>
|
|
49
|
+
</ConditionalWrapper>
|
|
50
|
+
{item.subText && (
|
|
51
|
+
<span class="sub-text">
|
|
52
|
+
<Fragment set:html={item.subText} />
|
|
53
|
+
</span>
|
|
54
|
+
)}
|
|
55
|
+
</label>
|
|
56
|
+
))}
|
|
57
|
+
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { RadioProps } from './radio'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.svelte'
|
|
4
|
+
|
|
5
|
+
import './radio.scss'
|
|
6
|
+
|
|
7
|
+
export let name: RadioProps['name'] = ''
|
|
8
|
+
export let items: RadioProps['items'] = []
|
|
9
|
+
export let color: RadioProps['color'] = ''
|
|
10
|
+
export let inline: RadioProps['inline'] = false
|
|
11
|
+
export let className: RadioProps['className'] = ''
|
|
12
|
+
export let onChange: () => any = () => {}
|
|
13
|
+
|
|
14
|
+
const classes = [
|
|
15
|
+
'w-radio',
|
|
16
|
+
inline && 'inline',
|
|
17
|
+
className
|
|
18
|
+
].filter(Boolean).join(' ')
|
|
19
|
+
|
|
20
|
+
const style = color
|
|
21
|
+
? `--w-radio-color: ${color};`
|
|
22
|
+
: null
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div class={classes} style={style}>
|
|
26
|
+
{#each items as item}
|
|
27
|
+
<label
|
|
28
|
+
class:col={item.subText}
|
|
29
|
+
class:disabled={item.disabled}
|
|
30
|
+
>
|
|
31
|
+
<ConditionalWrapper
|
|
32
|
+
condition={!!(item.subText)}
|
|
33
|
+
element="div"
|
|
34
|
+
class="radio-wrapper"
|
|
35
|
+
>
|
|
36
|
+
<input
|
|
37
|
+
type="radio"
|
|
38
|
+
name={name}
|
|
39
|
+
value={item.value}
|
|
40
|
+
checked={item.selected}
|
|
41
|
+
disabled={item.disabled}
|
|
42
|
+
on:change={onChange}
|
|
43
|
+
/>
|
|
44
|
+
<span class="radio" />
|
|
45
|
+
<span class="label">
|
|
46
|
+
{@html item.label}
|
|
47
|
+
</span>
|
|
48
|
+
</ConditionalWrapper>
|
|
49
|
+
{#if item.subText}
|
|
50
|
+
<span class="sub-text">
|
|
51
|
+
{@html item.subText}
|
|
52
|
+
</span>
|
|
53
|
+
{/if}
|
|
54
|
+
</label>
|
|
55
|
+
{/each}
|
|
56
|
+
</div>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { RadioProps } from './radio'
|
|
3
|
+
|
|
4
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx'
|
|
5
|
+
|
|
6
|
+
import './radio.scss'
|
|
7
|
+
|
|
8
|
+
type ReactRadioProps = {
|
|
9
|
+
onChange?: () => any
|
|
10
|
+
} & RadioProps
|
|
11
|
+
|
|
12
|
+
const Radio = ({
|
|
13
|
+
name,
|
|
14
|
+
items,
|
|
15
|
+
color,
|
|
16
|
+
inline,
|
|
17
|
+
className,
|
|
18
|
+
onChange
|
|
19
|
+
}: ReactRadioProps) => {
|
|
20
|
+
const classes = [
|
|
21
|
+
'w-radio',
|
|
22
|
+
inline && 'inline',
|
|
23
|
+
className
|
|
24
|
+
].filter(Boolean).join(' ')
|
|
25
|
+
|
|
26
|
+
const style = color
|
|
27
|
+
? { '--w-radio-color': color } as React.CSSProperties
|
|
28
|
+
: undefined
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className={classes} style={style}>
|
|
32
|
+
{items.map((item, index) => (
|
|
33
|
+
<label className={[
|
|
34
|
+
item.subText && 'col',
|
|
35
|
+
item.disabled && 'disabled'
|
|
36
|
+
].filter(Boolean).join(' ')} key={index}>
|
|
37
|
+
<ConditionalWrapper
|
|
38
|
+
condition={!!(item.subText)}
|
|
39
|
+
wrapper={children => (
|
|
40
|
+
<div className="radio-wrapper">
|
|
41
|
+
{children}
|
|
42
|
+
</div>
|
|
43
|
+
)}
|
|
44
|
+
>
|
|
45
|
+
<input
|
|
46
|
+
type="radio"
|
|
47
|
+
name={name}
|
|
48
|
+
value={item.value}
|
|
49
|
+
checked={item.selected}
|
|
50
|
+
disabled={item.disabled}
|
|
51
|
+
onChange={onChange}
|
|
52
|
+
/>
|
|
53
|
+
<span className="radio" />
|
|
54
|
+
<span
|
|
55
|
+
className="label"
|
|
56
|
+
dangerouslySetInnerHTML={{ __html: item.label }}
|
|
57
|
+
/>
|
|
58
|
+
</ConditionalWrapper>
|
|
59
|
+
{item.subText && (
|
|
60
|
+
<span
|
|
61
|
+
className="sub-text"
|
|
62
|
+
dangerouslySetInnerHTML={{ __html: item.subText }}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
</label>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default Radio
|
|
72
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
@import '../../scss/config.scss';
|
|
2
|
+
|
|
3
|
+
.w-radio {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 10px;
|
|
7
|
+
|
|
8
|
+
&.inline {
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
label {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
gap: 5px;
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
font-size: 16px;
|
|
18
|
+
|
|
19
|
+
&.disabled {
|
|
20
|
+
cursor: no-drop;
|
|
21
|
+
|
|
22
|
+
input + span::after {
|
|
23
|
+
background: #BBB;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&.col {
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
input {
|
|
34
|
+
display: none;
|
|
35
|
+
|
|
36
|
+
+ span::after {
|
|
37
|
+
@include Transition(transform);
|
|
38
|
+
content: '';
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 50%;
|
|
41
|
+
left: 50%;
|
|
42
|
+
transform: translate(-50%, -50%) scale(0);
|
|
43
|
+
width: 8px;
|
|
44
|
+
height: 8px;
|
|
45
|
+
border-radius: 100%;
|
|
46
|
+
background: var(--w-radio-color);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:checked + span::after {
|
|
50
|
+
transform: translate(-50%, -50%) scale(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&:disabled + span {
|
|
54
|
+
background-color: #333;
|
|
55
|
+
border-color: #333;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
a {
|
|
60
|
+
text-decoration: underline;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.radio-wrapper {
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: 10px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.radio {
|
|
70
|
+
display: inline-block;
|
|
71
|
+
width: 16px;
|
|
72
|
+
height: 16px;
|
|
73
|
+
border-radius: 100%;
|
|
74
|
+
border: 1px solid var(--w-radio-color);
|
|
75
|
+
position: relative;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.sub-text {
|
|
79
|
+
margin-left: 25px;
|
|
80
|
+
font-size: 14px;
|
|
81
|
+
color: #BBB;
|
|
82
|
+
|
|
83
|
+
a {
|
|
84
|
+
@include Transition(color);
|
|
85
|
+
color: #BBB;
|
|
86
|
+
|
|
87
|
+
&:hover {
|
|
88
|
+
color: #FFF;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { RatingProps } from './rating'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.astro'
|
|
4
|
+
|
|
5
|
+
import './rating.scss'
|
|
6
|
+
|
|
7
|
+
interface Props extends RatingProps {}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
score,
|
|
11
|
+
total = 5,
|
|
12
|
+
showText,
|
|
13
|
+
text = '{0} out of {1}',
|
|
14
|
+
showEmpty = true,
|
|
15
|
+
outline = true,
|
|
16
|
+
reviewCount,
|
|
17
|
+
reviewText = '{0} reviews',
|
|
18
|
+
reviewLink,
|
|
19
|
+
reviewTarget,
|
|
20
|
+
color,
|
|
21
|
+
emptyColor,
|
|
22
|
+
size,
|
|
23
|
+
className
|
|
24
|
+
} = Astro.props
|
|
25
|
+
|
|
26
|
+
const classes = [
|
|
27
|
+
'w-rating',
|
|
28
|
+
outline && 'outline',
|
|
29
|
+
className
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
const styles = [
|
|
33
|
+
color && `--w-rating-color: ${color};`,
|
|
34
|
+
size && `--w-rating-size: ${size}px;`,
|
|
35
|
+
emptyColor && `--w-rating-empty-color: ${emptyColor};`
|
|
36
|
+
].filter(Boolean).join(' ')
|
|
37
|
+
|
|
38
|
+
const translatedText = text
|
|
39
|
+
.replace('{0}', `${score}`)
|
|
40
|
+
.replace('{1}', `${total}`)
|
|
41
|
+
|
|
42
|
+
const translatedReviewText = reviewText.replace('{0}', `${reviewCount}`)
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<span class:list={classes} style={styles || null}>
|
|
46
|
+
<span class="score">{Array(score).fill('★').join('')}</span>
|
|
47
|
+
{showEmpty && (
|
|
48
|
+
<span class:list={['empty', total === 10 && 'ten-star']}>
|
|
49
|
+
{Array(total - score).fill('★').join('')}
|
|
50
|
+
</span>
|
|
51
|
+
)}
|
|
52
|
+
{showText && (
|
|
53
|
+
<span class:list={['text', reviewCount && 'm']}>
|
|
54
|
+
{translatedText}
|
|
55
|
+
</span>
|
|
56
|
+
)}
|
|
57
|
+
{reviewCount && '•'}
|
|
58
|
+
{reviewCount && (
|
|
59
|
+
<ConditionalWrapper condition={!!reviewLink}>
|
|
60
|
+
<a href={reviewLink} target={reviewTarget} slot="wrapper">
|
|
61
|
+
children
|
|
62
|
+
</a>
|
|
63
|
+
<span class="text">{translatedReviewText}</span>
|
|
64
|
+
</ConditionalWrapper>
|
|
65
|
+
)}
|
|
66
|
+
</span>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { RatingProps } from './rating'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.svelte'
|
|
4
|
+
|
|
5
|
+
import './rating.scss'
|
|
6
|
+
|
|
7
|
+
export let score: RatingProps['score']
|
|
8
|
+
export let total: RatingProps['total'] = 5
|
|
9
|
+
export let showText: RatingProps['showText'] = false
|
|
10
|
+
export let text: RatingProps['text'] = '{0} out of {1}'
|
|
11
|
+
export let showEmpty: RatingProps['showEmpty'] = true
|
|
12
|
+
export let outline: RatingProps['outline'] = true
|
|
13
|
+
export let reviewCount: RatingProps['reviewCount'] = 0
|
|
14
|
+
export let reviewText: RatingProps['reviewText'] = '{0} reviews'
|
|
15
|
+
export let reviewLink: RatingProps['reviewLink'] = ''
|
|
16
|
+
export let reviewTarget: RatingProps['reviewTarget'] = ''
|
|
17
|
+
export let color: RatingProps['color'] = ''
|
|
18
|
+
export let emptyColor: RatingProps['emptyColor'] = ''
|
|
19
|
+
export let size: RatingProps['size'] = 0
|
|
20
|
+
export let className: RatingProps['className'] = ''
|
|
21
|
+
|
|
22
|
+
const classes = [
|
|
23
|
+
'w-rating',
|
|
24
|
+
outline && 'outline',
|
|
25
|
+
className
|
|
26
|
+
].filter(Boolean).join(' ')
|
|
27
|
+
|
|
28
|
+
const styles = [
|
|
29
|
+
color && `--w-rating-color: ${color};`,
|
|
30
|
+
size && `--w-rating-size: ${size}px;`,
|
|
31
|
+
emptyColor && `--w-rating-empty-color: ${emptyColor};`
|
|
32
|
+
].filter(Boolean).join(' ')
|
|
33
|
+
|
|
34
|
+
const translatedText = text!
|
|
35
|
+
.replace('{0}', `${score}`)
|
|
36
|
+
.replace('{1}', `${total}`)
|
|
37
|
+
|
|
38
|
+
const translatedReviewText = reviewText?.replace('{0}', `${reviewCount}`)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
<span class={classes} style={styles || null}>
|
|
43
|
+
<span class="score">{Array(score).fill('★').join('')}</span>
|
|
44
|
+
{#if showEmpty}
|
|
45
|
+
<span
|
|
46
|
+
class="empty"
|
|
47
|
+
class:ten-star={total === 10}
|
|
48
|
+
>
|
|
49
|
+
{Array((total || 5) - score).fill('★').join('')}
|
|
50
|
+
</span>
|
|
51
|
+
{/if}
|
|
52
|
+
|
|
53
|
+
{#if showText}
|
|
54
|
+
<span class="text" class:m={reviewCount}>
|
|
55
|
+
{translatedText}
|
|
56
|
+
</span>
|
|
57
|
+
{/if}
|
|
58
|
+
|
|
59
|
+
{#if reviewCount}
|
|
60
|
+
{'•'}
|
|
61
|
+
<ConditionalWrapper
|
|
62
|
+
condition={!!reviewLink}
|
|
63
|
+
element="a"
|
|
64
|
+
href={reviewLink}
|
|
65
|
+
target={reviewTarget}
|
|
66
|
+
>
|
|
67
|
+
<span class="text">{translatedReviewText}</span>
|
|
68
|
+
</ConditionalWrapper>
|
|
69
|
+
{/if}
|
|
70
|
+
</span>
|