webcoreui 0.0.11 → 0.1.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 +42 -11
- package/astro.d.ts +4 -0
- package/astro.js +4 -0
- package/components/Accordion/Accordion.astro +10 -8
- package/components/Accordion/Accordion.svelte +8 -8
- package/components/Accordion/Accordion.tsx +7 -6
- package/components/Accordion/accordion.module.scss +65 -0
- package/components/Alert/Alert.astro +11 -7
- package/components/Alert/Alert.svelte +9 -7
- package/components/Alert/Alert.tsx +11 -7
- package/components/Alert/alert.module.scss +51 -0
- package/components/Alert/alert.ts +3 -1
- package/components/Avatar/Avatar.astro +4 -4
- package/components/Avatar/Avatar.svelte +13 -7
- package/components/Avatar/Avatar.tsx +11 -9
- package/components/Avatar/{avatar.scss → avatar.module.scss} +11 -8
- package/components/Badge/Badge.astro +8 -8
- package/components/Badge/Badge.svelte +25 -13
- package/components/Badge/Badge.tsx +26 -8
- package/components/Badge/badge.module.scss +86 -0
- package/components/Badge/badge.ts +8 -1
- package/components/Button/Button.astro +9 -7
- package/components/Button/Button.svelte +13 -11
- package/components/Button/Button.tsx +10 -8
- package/components/Button/button.module.scss +87 -0
- package/components/Button/button.ts +6 -2
- package/components/Card/Card.astro +7 -15
- package/components/Card/Card.svelte +16 -13
- package/components/Card/Card.tsx +15 -11
- package/components/Card/card.module.scss +38 -0
- package/components/Checkbox/Checkbox.astro +10 -10
- package/components/Checkbox/Checkbox.svelte +19 -18
- package/components/Checkbox/Checkbox.tsx +12 -11
- package/components/Checkbox/checkbox.module.scss +70 -0
- package/components/Checkbox/checkbox.ts +5 -1
- package/components/ConditionalWrapper/ConditionalWrapper.svelte +1 -1
- package/components/Icon/Icon.astro +2 -2
- package/components/Icon/Icon.svelte +1 -8
- package/components/Icon/Icon.tsx +1 -8
- package/components/Icon/map.ts +23 -0
- package/components/Input/Input.astro +50 -52
- package/components/Input/Input.svelte +52 -52
- package/components/Input/Input.tsx +59 -59
- package/components/Input/input.module.scss +79 -0
- package/components/Input/input.ts +8 -2
- package/components/Menu/Menu.astro +107 -0
- package/components/Menu/Menu.svelte +88 -0
- package/components/Menu/Menu.tsx +107 -0
- package/components/Menu/menu.module.scss +141 -0
- package/components/Menu/menu.ts +21 -0
- package/components/Progress/Progress.astro +42 -40
- package/components/Progress/Progress.svelte +40 -38
- package/components/Progress/Progress.tsx +48 -47
- package/components/Progress/progress.module.scss +70 -0
- package/components/Radio/Radio.astro +57 -57
- package/components/Radio/Radio.svelte +58 -56
- package/components/Radio/Radio.tsx +69 -68
- package/components/Radio/radio.module.scss +84 -0
- package/components/Radio/radio.ts +4 -0
- package/components/Rating/Rating.astro +13 -10
- package/components/Rating/Rating.svelte +15 -15
- package/components/Rating/Rating.tsx +22 -11
- package/components/Rating/rating.module.scss +45 -0
- package/components/Rating/rating.ts +1 -1
- package/components/Spinner/Spinner.astro +44 -42
- package/components/Spinner/Spinner.svelte +40 -38
- package/components/Spinner/Spinner.tsx +45 -44
- package/components/Spinner/{spinner.scss → spinner.module.scss} +50 -41
- package/components/Switch/Switch.astro +13 -11
- package/components/Switch/Switch.svelte +26 -24
- package/components/Switch/Switch.tsx +14 -12
- package/components/Switch/switch.module.scss +82 -0
- package/components/Switch/switch.ts +8 -4
- package/components/Table/Table.astro +60 -60
- package/components/Table/Table.svelte +56 -54
- package/components/Table/Table.tsx +64 -63
- package/components/Table/{table.scss → table.module.scss} +60 -65
- package/components/Tabs/Tabs.astro +76 -76
- package/components/Tabs/Tabs.svelte +56 -54
- package/components/Tabs/Tabs.tsx +70 -69
- package/components/Tabs/tabs.module.scss +125 -0
- package/components/ThemeSwitcher/ThemeSwitcher.astro +106 -0
- package/components/ThemeSwitcher/ThemeSwitcher.svelte +76 -0
- package/components/ThemeSwitcher/ThemeSwitcher.tsx +89 -0
- package/components/ThemeSwitcher/themeswitcher.module.scss +76 -0
- package/components/ThemeSwitcher/themeswitcher.ts +13 -0
- package/components/Timeline/Timeline.astro +36 -34
- package/components/Timeline/Timeline.svelte +32 -30
- package/components/Timeline/Timeline.tsx +38 -37
- package/components/Timeline/{timeline.scss → timeline.module.scss} +76 -71
- package/components/TimelineItem/TimelineItem.astro +27 -26
- package/components/TimelineItem/TimelineItem.svelte +24 -22
- package/components/TimelineItem/TimelineItem.tsx +33 -32
- package/components/TimelineItem/timelineitem.module.scss +29 -0
- package/components/Toast/Toast.astro +41 -30
- package/components/Toast/Toast.svelte +32 -21
- package/components/Toast/Toast.tsx +38 -28
- package/components/Toast/toast.module.scss +40 -0
- package/components/Toast/toast.ts +8 -6
- package/icons/moon.svg +3 -0
- package/icons/sun.svg +3 -0
- package/icons.d.ts +11 -0
- package/icons.js +9 -0
- package/index.js +3 -0
- package/package.json +5 -1
- package/react.d.ts +4 -0
- package/react.js +4 -0
- package/scss/config/color-palette.scss +23 -0
- package/scss/config/css-values.scss +44 -0
- package/scss/config/layout.scss +41 -0
- package/scss/config/mixins.scss +395 -9
- package/scss/config/typography.scss +66 -0
- package/scss/config.scss +6 -1
- package/scss/global/elements.scss +22 -2
- package/scss/global/scrollbar.scss +24 -0
- package/scss/global/theme.scss +140 -0
- package/scss/global/tooltip.scss +47 -39
- package/scss/global/utility.scss +33 -4
- package/scss/global.scss +2 -1
- package/scss/resets.scss +64 -11
- package/scss/setup.scss +25 -31
- package/svelte.d.ts +16 -12
- package/svelte.js +4 -0
- package/utils/classNames.ts +4 -0
- package/utils/cookies.ts +28 -0
- package/utils/event.ts +17 -0
- package/utils/toast.ts +15 -11
- package/components/Accordion/accordion.scss +0 -63
- package/components/Alert/alert.scss +0 -53
- package/components/Badge/badge.scss +0 -85
- package/components/Button/button.scss +0 -91
- package/components/Card/card.scss +0 -37
- package/components/Checkbox/checkbox.scss +0 -85
- package/components/Input/input.scss +0 -83
- package/components/Progress/progress.scss +0 -66
- package/components/Radio/radio.scss +0 -92
- package/components/Rating/rating.scss +0 -37
- package/components/Switch/switch.scss +0 -84
- package/components/Tabs/tabs.scss +0 -134
- package/components/TimelineItem/timelineitem.scss +0 -31
- package/components/Toast/toast.scss +0 -43
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import type { ReactInputProps } from './input'
|
|
3
|
-
import ConditionalWrapper from '
|
|
4
|
-
|
|
5
|
-
import './input.scss'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
icon,
|
|
14
|
-
value,
|
|
15
|
-
className,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
className
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
const useLabel = !!(label || subText ||
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<ConditionalWrapper condition={useLabel} wrapper={children => (
|
|
29
|
-
<label className=
|
|
30
|
-
{children}
|
|
31
|
-
</label>
|
|
32
|
-
)}>
|
|
33
|
-
{label && (
|
|
34
|
-
<div className=
|
|
35
|
-
)}
|
|
36
|
-
<ConditionalWrapper condition={!!
|
|
37
|
-
<div className=
|
|
38
|
-
{children}
|
|
39
|
-
</div>
|
|
40
|
-
)}>
|
|
41
|
-
{
|
|
42
|
-
<input
|
|
43
|
-
type={type}
|
|
44
|
-
className={classes}
|
|
45
|
-
defaultValue={value}
|
|
46
|
-
{...rest}
|
|
47
|
-
/>
|
|
48
|
-
</ConditionalWrapper>
|
|
49
|
-
{subText && (
|
|
50
|
-
<div
|
|
51
|
-
className=
|
|
52
|
-
dangerouslySetInnerHTML={{ __html: subText }}
|
|
53
|
-
/>
|
|
54
|
-
)}
|
|
55
|
-
</ConditionalWrapper>
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export default Input
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { ReactInputProps } from './input'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx'
|
|
4
|
+
|
|
5
|
+
import styles from './input.module.scss'
|
|
6
|
+
import { classNames } from '../../utils/classNames'
|
|
7
|
+
|
|
8
|
+
const Input = ({
|
|
9
|
+
type = 'text',
|
|
10
|
+
theme,
|
|
11
|
+
label,
|
|
12
|
+
subText,
|
|
13
|
+
icon,
|
|
14
|
+
value,
|
|
15
|
+
className,
|
|
16
|
+
children,
|
|
17
|
+
...rest
|
|
18
|
+
}: ReactInputProps) => {
|
|
19
|
+
const classes = classNames([
|
|
20
|
+
styles.input,
|
|
21
|
+
theme && styles[theme],
|
|
22
|
+
className
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
const useLabel = !!(label || subText || children)
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<ConditionalWrapper condition={useLabel} wrapper={children => (
|
|
29
|
+
<label className={styles['input-label']}>
|
|
30
|
+
{children}
|
|
31
|
+
</label>
|
|
32
|
+
)}>
|
|
33
|
+
{label && (
|
|
34
|
+
<div className={styles.label}>{label}</div>
|
|
35
|
+
)}
|
|
36
|
+
<ConditionalWrapper condition={!!children} wrapper={children => (
|
|
37
|
+
<div className={styles.wrapper}>
|
|
38
|
+
{children}
|
|
39
|
+
</div>
|
|
40
|
+
)}>
|
|
41
|
+
{children}
|
|
42
|
+
<input
|
|
43
|
+
type={type}
|
|
44
|
+
className={classes}
|
|
45
|
+
defaultValue={value}
|
|
46
|
+
{...rest}
|
|
47
|
+
/>
|
|
48
|
+
</ConditionalWrapper>
|
|
49
|
+
{subText && (
|
|
50
|
+
<div
|
|
51
|
+
className={styles.subtext}
|
|
52
|
+
dangerouslySetInnerHTML={{ __html: subText }}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
</ConditionalWrapper>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default Input
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
.input {
|
|
4
|
+
@include border-radius(sm);
|
|
5
|
+
@include spacing(py-xs, px-sm);
|
|
6
|
+
@include border(primary-50);
|
|
7
|
+
@include background(transparent);
|
|
8
|
+
@include typography(regular, primary, hlg);
|
|
9
|
+
@include size('w100%');
|
|
10
|
+
|
|
11
|
+
color-scheme: var(--w-color-scheme);
|
|
12
|
+
|
|
13
|
+
&[disabled] {
|
|
14
|
+
@include typography(primary-30);
|
|
15
|
+
cursor: no-drop;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&::file-selector-button {
|
|
19
|
+
@include background(transparent);
|
|
20
|
+
@include border(0);
|
|
21
|
+
@include typography(primary);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&::placeholder {
|
|
25
|
+
@include typography(primary-30);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&[type="color"] {
|
|
29
|
+
@include spacing(p0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.info {
|
|
33
|
+
@include border(info);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&.success {
|
|
37
|
+
@include border(success);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&.warning {
|
|
41
|
+
@include border(warning);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&.alert {
|
|
45
|
+
@include border(alert);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&.fill {
|
|
49
|
+
@include background(primary-50);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.input-label {
|
|
54
|
+
@include layout(flex, column);
|
|
55
|
+
|
|
56
|
+
.label {
|
|
57
|
+
@include typography(md, primary-20);
|
|
58
|
+
@include spacing(mb-xs);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.wrapper {
|
|
62
|
+
@include layout(flex, v-center, sm);
|
|
63
|
+
@include position(relative);
|
|
64
|
+
|
|
65
|
+
input {
|
|
66
|
+
padding-left: 40px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
svg {
|
|
70
|
+
@include position(absolute, l10px);
|
|
71
|
+
@include size(20px);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.subtext {
|
|
76
|
+
@include typography(sm, primary-30);
|
|
77
|
+
@include spacing(mt-xs);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -17,6 +17,7 @@ export type InputProps = {
|
|
|
17
17
|
| 'success'
|
|
18
18
|
| 'warning'
|
|
19
19
|
| 'alert'
|
|
20
|
+
| 'fill'
|
|
20
21
|
| null
|
|
21
22
|
value?: string | number
|
|
22
23
|
name?: string
|
|
@@ -24,7 +25,6 @@ export type InputProps = {
|
|
|
24
25
|
label?: string
|
|
25
26
|
disabled?: boolean
|
|
26
27
|
subText?: string
|
|
27
|
-
fill?: boolean
|
|
28
28
|
maxLength?: number
|
|
29
29
|
min?: number
|
|
30
30
|
max?: number
|
|
@@ -38,7 +38,13 @@ export type InputProps = {
|
|
|
38
38
|
[key: string]: any
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export type SvelteInputProps = {
|
|
42
|
+
onChange?: (e: any) => any
|
|
43
|
+
onKeyUp?: (e: any) => any
|
|
44
|
+
} & InputProps
|
|
45
|
+
|
|
41
46
|
export type ReactInputProps = {
|
|
42
|
-
|
|
47
|
+
onChange?: (e: any) => any
|
|
48
|
+
onKeyUp?: (e: any) => any
|
|
43
49
|
children?: React.ReactNode
|
|
44
50
|
} & InputProps
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { MenuProps } from './menu'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.astro'
|
|
4
|
+
|
|
5
|
+
import styles from './menu.module.scss'
|
|
6
|
+
|
|
7
|
+
interface Props extends MenuProps {}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
items,
|
|
11
|
+
logo,
|
|
12
|
+
centerLogo,
|
|
13
|
+
className,
|
|
14
|
+
wrapperClassName
|
|
15
|
+
} = Astro.props
|
|
16
|
+
|
|
17
|
+
const classes = [
|
|
18
|
+
styles.menu,
|
|
19
|
+
className
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const containerClasses = [
|
|
23
|
+
styles.container,
|
|
24
|
+
wrapperClassName
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const wrapMenu = (logo?.url || logo?.html) && items?.length && Astro.slots.has('default')
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<header class:list={classes}>
|
|
31
|
+
<div class:list={containerClasses}>
|
|
32
|
+
<ConditionalWrapper condition={!!wrapMenu}>
|
|
33
|
+
<div slot="wrapper" class={styles.wrapper}>
|
|
34
|
+
children
|
|
35
|
+
</div>
|
|
36
|
+
{logo?.url && !centerLogo && (
|
|
37
|
+
<a href="/">
|
|
38
|
+
<img
|
|
39
|
+
src={logo.url}
|
|
40
|
+
alt={logo.alt || 'Logo'}
|
|
41
|
+
width={logo.width}
|
|
42
|
+
height={logo.height}
|
|
43
|
+
/>
|
|
44
|
+
</a>
|
|
45
|
+
)}
|
|
46
|
+
|
|
47
|
+
{!centerLogo && logo?.html && (
|
|
48
|
+
<a href="/">
|
|
49
|
+
<Fragment set:html={logo.html} />
|
|
50
|
+
</a>
|
|
51
|
+
)}
|
|
52
|
+
|
|
53
|
+
{items?.length && (
|
|
54
|
+
<ul>
|
|
55
|
+
{items.map(item => (
|
|
56
|
+
<li>
|
|
57
|
+
<a href={item.url} target={item.target}>
|
|
58
|
+
{item.name}
|
|
59
|
+
</a>
|
|
60
|
+
</li>
|
|
61
|
+
))}
|
|
62
|
+
</ul>
|
|
63
|
+
)}
|
|
64
|
+
</ConditionalWrapper>
|
|
65
|
+
|
|
66
|
+
{items?.length && (
|
|
67
|
+
<button class={styles.hamburger} data-id="hamburger">
|
|
68
|
+
<span class={styles.meat}></span>
|
|
69
|
+
<span class={styles.meat}></span>
|
|
70
|
+
<span class={styles.meat}></span>
|
|
71
|
+
<span class={styles.meat}></span>
|
|
72
|
+
</button>
|
|
73
|
+
)}
|
|
74
|
+
|
|
75
|
+
{centerLogo && logo?.html && (
|
|
76
|
+
<a href="/">
|
|
77
|
+
<Fragment set:html={logo.html} />
|
|
78
|
+
</a>
|
|
79
|
+
)}
|
|
80
|
+
|
|
81
|
+
{logo?.url && centerLogo && (
|
|
82
|
+
<a href="/">
|
|
83
|
+
<img
|
|
84
|
+
src={logo.url}
|
|
85
|
+
alt={logo.alt || 'Logo'}
|
|
86
|
+
width={logo.width}
|
|
87
|
+
height={logo.height}
|
|
88
|
+
/>
|
|
89
|
+
</a>
|
|
90
|
+
)}
|
|
91
|
+
|
|
92
|
+
<slot />
|
|
93
|
+
</div>
|
|
94
|
+
</header>
|
|
95
|
+
|
|
96
|
+
<script>
|
|
97
|
+
document
|
|
98
|
+
.querySelector('[data-id="hamburger"]')
|
|
99
|
+
?.addEventListener('click', event => {
|
|
100
|
+
const hamburger = event.currentTarget as HTMLDivElement
|
|
101
|
+
const header = hamburger.parentElement?.parentElement as HTMLHeadElement
|
|
102
|
+
|
|
103
|
+
header.dataset.active = header.dataset.active === 'true'
|
|
104
|
+
? 'false'
|
|
105
|
+
: 'true'
|
|
106
|
+
})
|
|
107
|
+
</script>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { MenuProps } from './menu'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.svelte'
|
|
4
|
+
|
|
5
|
+
import styles from './menu.module.scss'
|
|
6
|
+
import { classNames } from '../../utils/classNames'
|
|
7
|
+
|
|
8
|
+
export let items: MenuProps['items'] = []
|
|
9
|
+
export let logo: MenuProps['logo'] = null
|
|
10
|
+
export let centerLogo: MenuProps['centerLogo'] = false
|
|
11
|
+
export let className: MenuProps['className'] = ''
|
|
12
|
+
export let wrapperClassName: MenuProps['wrapperClassName'] = ''
|
|
13
|
+
|
|
14
|
+
const classes = classNames([
|
|
15
|
+
styles.menu,
|
|
16
|
+
className
|
|
17
|
+
])
|
|
18
|
+
|
|
19
|
+
const containerClasses = classNames([
|
|
20
|
+
styles.container,
|
|
21
|
+
wrapperClassName
|
|
22
|
+
])
|
|
23
|
+
|
|
24
|
+
const wrapMenu = (logo?.url || logo?.html) && items?.length && $$slots.default
|
|
25
|
+
|
|
26
|
+
let active = false
|
|
27
|
+
|
|
28
|
+
const toggleMenu = () => active = !active
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<header class={classes} data-active={active || null}>
|
|
32
|
+
<div class={containerClasses}>
|
|
33
|
+
<ConditionalWrapper condition={!!wrapMenu} class={styles.wrapper}>
|
|
34
|
+
{#if logo?.url && !centerLogo}
|
|
35
|
+
<a href="/">
|
|
36
|
+
<img
|
|
37
|
+
src={logo.url}
|
|
38
|
+
alt={logo.alt || 'Logo'}
|
|
39
|
+
width={logo.width}
|
|
40
|
+
height={logo.height}
|
|
41
|
+
/>
|
|
42
|
+
</a>
|
|
43
|
+
{/if}
|
|
44
|
+
|
|
45
|
+
{#if !centerLogo && logo?.html}
|
|
46
|
+
<a href="/">{@html logo.html}</a>
|
|
47
|
+
{/if}
|
|
48
|
+
|
|
49
|
+
{#if items?.length}
|
|
50
|
+
<ul>
|
|
51
|
+
{#each items as item}
|
|
52
|
+
<li>
|
|
53
|
+
<a href={item.url} target={item.target}>
|
|
54
|
+
{item.name}
|
|
55
|
+
</a>
|
|
56
|
+
</li>
|
|
57
|
+
{/each}
|
|
58
|
+
</ul>
|
|
59
|
+
{/if}
|
|
60
|
+
</ConditionalWrapper>
|
|
61
|
+
|
|
62
|
+
{#if items?.length}
|
|
63
|
+
<button class={styles.hamburger} on:click={toggleMenu}>
|
|
64
|
+
<span class={styles.meat}></span>
|
|
65
|
+
<span class={styles.meat}></span>
|
|
66
|
+
<span class={styles.meat}></span>
|
|
67
|
+
<span class={styles.meat}></span>
|
|
68
|
+
</button>
|
|
69
|
+
{/if}
|
|
70
|
+
|
|
71
|
+
{#if centerLogo && logo?.html}
|
|
72
|
+
<a href="/">{@html logo.html}</a>
|
|
73
|
+
{/if}
|
|
74
|
+
|
|
75
|
+
{#if logo?.url && centerLogo}
|
|
76
|
+
<a href="/">
|
|
77
|
+
<img
|
|
78
|
+
src={logo.url}
|
|
79
|
+
alt={logo.alt || 'Logo'}
|
|
80
|
+
width={logo.width}
|
|
81
|
+
height={logo.height}
|
|
82
|
+
/>
|
|
83
|
+
</a>
|
|
84
|
+
{/if}
|
|
85
|
+
|
|
86
|
+
<slot />
|
|
87
|
+
</div>
|
|
88
|
+
</header>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import type { ReactMenuProps } from './menu'
|
|
3
|
+
import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx'
|
|
4
|
+
|
|
5
|
+
import styles from './menu.module.scss'
|
|
6
|
+
import { classNames } from '../../utils/classNames'
|
|
7
|
+
|
|
8
|
+
const Menu = ({
|
|
9
|
+
items,
|
|
10
|
+
logo,
|
|
11
|
+
centerLogo,
|
|
12
|
+
className,
|
|
13
|
+
wrapperClassName,
|
|
14
|
+
children
|
|
15
|
+
}: ReactMenuProps) => {
|
|
16
|
+
const [active, setActive] = useState(false)
|
|
17
|
+
|
|
18
|
+
const classes = classNames([
|
|
19
|
+
styles.menu,
|
|
20
|
+
className
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
const containerClasses = classNames([
|
|
24
|
+
styles.container,
|
|
25
|
+
wrapperClassName
|
|
26
|
+
])
|
|
27
|
+
|
|
28
|
+
const wrapMenu = (logo?.url || logo?.html) && items?.length && children
|
|
29
|
+
|
|
30
|
+
const toggleMenu = () => setActive(!active)
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<header className={classes} data-active={active || null}>
|
|
34
|
+
<div className={containerClasses}>
|
|
35
|
+
<ConditionalWrapper
|
|
36
|
+
condition={!!wrapMenu}
|
|
37
|
+
wrapper={children => (
|
|
38
|
+
<div className={styles.wrapper}>
|
|
39
|
+
{children}
|
|
40
|
+
</div>
|
|
41
|
+
)}
|
|
42
|
+
>
|
|
43
|
+
{logo?.url && !centerLogo && (
|
|
44
|
+
<a href="/">
|
|
45
|
+
<img
|
|
46
|
+
src={logo.url}
|
|
47
|
+
alt={logo.alt || 'Logo'}
|
|
48
|
+
width={logo.width}
|
|
49
|
+
height={logo.height}
|
|
50
|
+
/>
|
|
51
|
+
</a>
|
|
52
|
+
)}
|
|
53
|
+
|
|
54
|
+
{!centerLogo && logo?.html && (
|
|
55
|
+
<a
|
|
56
|
+
href="/"
|
|
57
|
+
dangerouslySetInnerHTML={{ __html: logo.html }}
|
|
58
|
+
/>
|
|
59
|
+
)}
|
|
60
|
+
|
|
61
|
+
{!!items?.length && (
|
|
62
|
+
<ul>
|
|
63
|
+
{items.map((item, index) => (
|
|
64
|
+
<li key={index}>
|
|
65
|
+
<a href={item.url} target={item.target}>
|
|
66
|
+
{item.name}
|
|
67
|
+
</a>
|
|
68
|
+
</li>
|
|
69
|
+
))}
|
|
70
|
+
</ul>
|
|
71
|
+
)}
|
|
72
|
+
</ConditionalWrapper>
|
|
73
|
+
|
|
74
|
+
{!!items?.length && (
|
|
75
|
+
<button className={styles.hamburger} onClick={toggleMenu}>
|
|
76
|
+
<span className={styles.meat}></span>
|
|
77
|
+
<span className={styles.meat}></span>
|
|
78
|
+
<span className={styles.meat}></span>
|
|
79
|
+
<span className={styles.meat}></span>
|
|
80
|
+
</button>
|
|
81
|
+
)}
|
|
82
|
+
|
|
83
|
+
{centerLogo && logo?.html && (
|
|
84
|
+
<a
|
|
85
|
+
href="/"
|
|
86
|
+
dangerouslySetInnerHTML={{ __html: logo.html }}
|
|
87
|
+
/>
|
|
88
|
+
)}
|
|
89
|
+
|
|
90
|
+
{logo?.url && centerLogo && (
|
|
91
|
+
<a href="/">
|
|
92
|
+
<img
|
|
93
|
+
src={logo.url}
|
|
94
|
+
alt={logo.alt || 'Logo'}
|
|
95
|
+
width={logo.width}
|
|
96
|
+
height={logo.height}
|
|
97
|
+
/>
|
|
98
|
+
</a>
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
{children}
|
|
102
|
+
</div>
|
|
103
|
+
</header>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default Menu
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
@use '../../scss/config.scss' as *;
|
|
2
|
+
|
|
3
|
+
.menu {
|
|
4
|
+
@include background(primary-70);
|
|
5
|
+
@include spacing(p-md);
|
|
6
|
+
@include typography(md);
|
|
7
|
+
@include border(bottom, primary-50);
|
|
8
|
+
@include position(sticky, t0);
|
|
9
|
+
@include layer(header);
|
|
10
|
+
|
|
11
|
+
&[data-active="true"] {
|
|
12
|
+
.hamburger {
|
|
13
|
+
box-shadow: 0 0 0 1000px var(--w-color-primary-70);
|
|
14
|
+
|
|
15
|
+
.meat:first-child,
|
|
16
|
+
.meat:last-child {
|
|
17
|
+
@include visibility(0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.meat:first-child {
|
|
21
|
+
transform: translateY(20px) scale(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.meat:last-child {
|
|
25
|
+
transform: translateY(-20px) scale(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.meat:nth-child(2) {
|
|
29
|
+
transform: rotate(45deg);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.meat:nth-child(3) {
|
|
33
|
+
transform: rotate(-45deg);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ul {
|
|
38
|
+
@include transition(opacity);
|
|
39
|
+
@include visibility(1);
|
|
40
|
+
@include layer(header);
|
|
41
|
+
pointer-events: all;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.wrapper {
|
|
46
|
+
@include layout(flex, v-center, default);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
a {
|
|
50
|
+
@include typography(none);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
img,
|
|
54
|
+
svg {
|
|
55
|
+
display: block;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ul {
|
|
59
|
+
@include spacing(0);
|
|
60
|
+
@include layout(flex, default, column);
|
|
61
|
+
@include position(fixed, t20px, l20px);
|
|
62
|
+
@include visibility(0);
|
|
63
|
+
@include typography(normal);
|
|
64
|
+
|
|
65
|
+
list-style-type: none;
|
|
66
|
+
pointer-events: none;
|
|
67
|
+
|
|
68
|
+
li {
|
|
69
|
+
@include spacing(m0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
a {
|
|
73
|
+
@include typography(primary-20);
|
|
74
|
+
|
|
75
|
+
&:hover {
|
|
76
|
+
@include typography(primary);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.hamburger {
|
|
82
|
+
@include transition(box-shadow);
|
|
83
|
+
@include position(relative);
|
|
84
|
+
@include size(w30px, h20px);
|
|
85
|
+
@include border-radius(max);
|
|
86
|
+
@include spacing(p0);
|
|
87
|
+
@include border(0);
|
|
88
|
+
@include background(transparent);
|
|
89
|
+
@include layer(top);
|
|
90
|
+
|
|
91
|
+
box-shadow: 0 0 0 0 var(--w-color-primary-70);
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
|
|
94
|
+
.meat {
|
|
95
|
+
@include transition();
|
|
96
|
+
@include size('w100%', h2px);
|
|
97
|
+
@include position(absolute);
|
|
98
|
+
@include background(primary);
|
|
99
|
+
@include border-radius(md);
|
|
100
|
+
|
|
101
|
+
display: block;
|
|
102
|
+
|
|
103
|
+
&:first-child {
|
|
104
|
+
@include position(t0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&:nth-child(2),
|
|
108
|
+
&:nth-child(3) {
|
|
109
|
+
@include position(v-center);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&:last-child {
|
|
113
|
+
@include position(b0);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.container {
|
|
120
|
+
@include layout(flex, v-center, default, h-between, wrap);
|
|
121
|
+
@include spacing(auto-none, px-default);
|
|
122
|
+
|
|
123
|
+
max-width: 1200px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@include media('sm') {
|
|
127
|
+
.menu {
|
|
128
|
+
.hamburger {
|
|
129
|
+
@include visibility(none);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
ul {
|
|
133
|
+
@include position(static);
|
|
134
|
+
@include visibility(1);
|
|
135
|
+
@include layout(row);
|
|
136
|
+
|
|
137
|
+
pointer-events: all;
|
|
138
|
+
transform: none;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type MenuProps = {
|
|
2
|
+
items?: {
|
|
3
|
+
url: string
|
|
4
|
+
name: string
|
|
5
|
+
target?: string
|
|
6
|
+
}[]
|
|
7
|
+
logo?: {
|
|
8
|
+
url?: string
|
|
9
|
+
alt?: string
|
|
10
|
+
width?: number
|
|
11
|
+
height?: number
|
|
12
|
+
html?: string
|
|
13
|
+
} | null
|
|
14
|
+
centerLogo?: boolean
|
|
15
|
+
className?: string
|
|
16
|
+
wrapperClassName?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ReactMenuProps = {
|
|
20
|
+
children?: React.ReactNode
|
|
21
|
+
} & MenuProps
|