@tuspe/components 1.6.26
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 +203 -0
- package/dist/Breadcrumbs.svelte +81 -0
- package/dist/Breadcrumbs.svelte.d.ts +9 -0
- package/dist/Button.svelte +266 -0
- package/dist/Button.svelte.d.ts +36 -0
- package/dist/ButtonArrow.svelte +21 -0
- package/dist/ButtonArrow.svelte.d.ts +9 -0
- package/dist/ButtonClose.svelte +25 -0
- package/dist/ButtonClose.svelte.d.ts +6 -0
- package/dist/ButtonMenu.svelte +51 -0
- package/dist/ButtonMenu.svelte.d.ts +12 -0
- package/dist/Checkbox.svelte +55 -0
- package/dist/Checkbox.svelte.d.ts +13 -0
- package/dist/Image.svelte +89 -0
- package/dist/Image.svelte.d.ts +15 -0
- package/dist/Input.svelte +170 -0
- package/dist/Input.svelte.d.ts +21 -0
- package/dist/Modal.svelte +78 -0
- package/dist/Modal.svelte.d.ts +11 -0
- package/dist/Select.svelte +60 -0
- package/dist/Select.svelte.d.ts +15 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +105 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Tuspe SvelteKit Components
|
|
2
|
+
|
|
3
|
+
[Tuspe Design](https://tuspe.com/en) builds websites and online stores for small and large businesses. This component library includes essential elements for forms, modals, breadcrumbs, and images. It also offers utility functions for price display, VAT calculations, and validations for tables and strings.
|
|
4
|
+
|
|
5
|
+
## Breadcrumbs
|
|
6
|
+
|
|
7
|
+
A breadcrumb navigation provide links back to previous pages, and shows the user's current location in a website. The component complies with [Google standards](https://developers.google.com/search/docs/appearance/structured-data/breadcrumb).
|
|
8
|
+
|
|
9
|
+
```TypeScript
|
|
10
|
+
interface Breadcrumb {
|
|
11
|
+
'@type'?: string
|
|
12
|
+
item: string
|
|
13
|
+
name: string
|
|
14
|
+
position?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
homeName?: string
|
|
19
|
+
homeSlug?: string
|
|
20
|
+
values: Breadcrumb[]
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Button
|
|
25
|
+
|
|
26
|
+
Easily replace most buttons in your project with this versatile button component. The `control` value makes it ideal for icons and as a toggler for the mobile menu.
|
|
27
|
+
|
|
28
|
+
```TypeScript
|
|
29
|
+
interface Props {
|
|
30
|
+
ariaControls?: string | undefined
|
|
31
|
+
ariaExpanded?: boolean | undefined
|
|
32
|
+
ariaLabel?: string
|
|
33
|
+
ariaPopup?: 'dialog' | 'menu' | 'listbox' | undefined
|
|
34
|
+
ball?: boolean
|
|
35
|
+
borderColor?: 'content' | 'default' | 'primary'
|
|
36
|
+
borderSize?: 0 | 1 | 2
|
|
37
|
+
children: Snippet
|
|
38
|
+
color?: string
|
|
39
|
+
colorBg?: string
|
|
40
|
+
control?: boolean
|
|
41
|
+
disabled?: boolean
|
|
42
|
+
extraClass?: string
|
|
43
|
+
fill?: boolean
|
|
44
|
+
fontWeight?: 'normal' | 'bold'
|
|
45
|
+
fullWidth?: boolean
|
|
46
|
+
hover?: 'black' | 'primary' | 'secondary' | 'success' | 'transparent'
|
|
47
|
+
hoverText?: 'black' | 'primary' | 'secondary' | 'white'
|
|
48
|
+
href?: string | undefined
|
|
49
|
+
id?: string
|
|
50
|
+
isActive?: boolean
|
|
51
|
+
noHeight?: boolean
|
|
52
|
+
noPadding?: boolean
|
|
53
|
+
onclick?: any
|
|
54
|
+
preload?: 'hover' | 'tap'
|
|
55
|
+
role?: string
|
|
56
|
+
target?: '_blank' | '_top' | undefined
|
|
57
|
+
type?: 'submit'
|
|
58
|
+
uppercase?: boolean
|
|
59
|
+
value?: string | number
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## ButtonArrow
|
|
64
|
+
|
|
65
|
+
Arrow icons for navigation, such as image sliders or content transitions.
|
|
66
|
+
|
|
67
|
+
```TypeScript
|
|
68
|
+
interface Props {
|
|
69
|
+
onclick?: () => any
|
|
70
|
+
ariaLabel: string
|
|
71
|
+
color?: string
|
|
72
|
+
direction: 'left' | 'right'
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## ButtonClose
|
|
77
|
+
|
|
78
|
+
Close button for modals and other dismissible elements.
|
|
79
|
+
|
|
80
|
+
```TypeScript
|
|
81
|
+
interface Props {
|
|
82
|
+
onclick: () => any
|
|
83
|
+
color?: string
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## ButtonMenu
|
|
88
|
+
|
|
89
|
+
A button for toggling the mobile menu, dynamically changing its icon based on the menu's open or closed state.
|
|
90
|
+
|
|
91
|
+
```TypeScript
|
|
92
|
+
interface Props {
|
|
93
|
+
onclick?: () => any
|
|
94
|
+
ariaControls: string
|
|
95
|
+
ariaLabel: string
|
|
96
|
+
color?: 'black' | 'white'
|
|
97
|
+
extraClass?: string
|
|
98
|
+
hidden?: boolean
|
|
99
|
+
open: boolean
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Image
|
|
104
|
+
|
|
105
|
+
A versatile image component supporting various aspect ratios and object fit options. Features include optional borders, centering, full-width display, custom classes, and configurable loading behavior.
|
|
106
|
+
|
|
107
|
+
```TypeScript
|
|
108
|
+
interface ImageData {
|
|
109
|
+
alt: string
|
|
110
|
+
height?: number
|
|
111
|
+
src: string
|
|
112
|
+
width?: number
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
interface Props {
|
|
116
|
+
aspect?: '3:4' | '4:3' | 'square' | 'video'
|
|
117
|
+
ball?: boolean
|
|
118
|
+
border?: boolean
|
|
119
|
+
center?: boolean
|
|
120
|
+
extraClasses?: string
|
|
121
|
+
fullWidth?: boolean
|
|
122
|
+
image: ImageData
|
|
123
|
+
loading?: 'eager' | 'lazy'
|
|
124
|
+
objectFit?: 'contain' | 'cover'
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Input
|
|
129
|
+
|
|
130
|
+
A flexible `Input` component supporting common input types with basic styling for form fields. It includes optional attributes for labels, placeholders, min/max values, steps, and event handlers but does not perform content validation.
|
|
131
|
+
|
|
132
|
+
```TypeScript
|
|
133
|
+
interface Props {
|
|
134
|
+
onchange?: () => void
|
|
135
|
+
onclick?: () => void
|
|
136
|
+
borderColor?: string
|
|
137
|
+
disabled?: boolean
|
|
138
|
+
id?: string
|
|
139
|
+
label: string
|
|
140
|
+
max?: number | string
|
|
141
|
+
min?: number | string
|
|
142
|
+
outerClass?: string
|
|
143
|
+
placeholder?: string
|
|
144
|
+
required?: boolean
|
|
145
|
+
step?: number
|
|
146
|
+
type?: 'email' | 'date' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'textarea' | 'time' | 'url'
|
|
147
|
+
value: string | number
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Select
|
|
152
|
+
|
|
153
|
+
A customizable `Select` component for choosing from a list of options. Supports labels, placeholders, required fields, and disabled states. Accepts an array of selectable items and triggers an optional onchange event when the value changes.
|
|
154
|
+
|
|
155
|
+
```TypeScript
|
|
156
|
+
interface SelectItem {
|
|
157
|
+
name: string
|
|
158
|
+
value: number | string
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
interface Props {
|
|
162
|
+
onchange?: () => void
|
|
163
|
+
disabled?: boolean
|
|
164
|
+
outerClass?: string
|
|
165
|
+
id?: string
|
|
166
|
+
label: string
|
|
167
|
+
placeholder?: string
|
|
168
|
+
required?: boolean
|
|
169
|
+
value: string | number
|
|
170
|
+
values: SelectItem[]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Checkbox
|
|
175
|
+
|
|
176
|
+
Allows users to toggle between checked and unchecked states.
|
|
177
|
+
|
|
178
|
+
```TypeScript
|
|
179
|
+
interface Props {
|
|
180
|
+
children: Snippet
|
|
181
|
+
onchange?: () => void
|
|
182
|
+
checked: boolean
|
|
183
|
+
disabled?: boolean
|
|
184
|
+
group?: boolean
|
|
185
|
+
id?: string
|
|
186
|
+
outerClass?: string
|
|
187
|
+
value?: string
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Modal
|
|
192
|
+
|
|
193
|
+
A simple `Modal` component that displays a popup with customizable content.
|
|
194
|
+
|
|
195
|
+
```TypeScript
|
|
196
|
+
interface Props {
|
|
197
|
+
children: Snippet
|
|
198
|
+
innerClass?: string
|
|
199
|
+
open?: boolean
|
|
200
|
+
outerClass?: string
|
|
201
|
+
title?: string
|
|
202
|
+
}
|
|
203
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {page} from '$app/state'
|
|
3
|
+
import type {Breadcrumb} from './'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
homeName?: string
|
|
7
|
+
homeSlug?: string
|
|
8
|
+
values: Breadcrumb[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let {homeName = 'Etusivu', homeSlug = '', values}: Props = $props()
|
|
12
|
+
const origin = page.url.origin + '/'
|
|
13
|
+
|
|
14
|
+
let originWithSlug = $state(origin + homeSlug),
|
|
15
|
+
listItems = $derived<Breadcrumb[]>(
|
|
16
|
+
Array.isArray(values) && values.length > 0
|
|
17
|
+
? [
|
|
18
|
+
{
|
|
19
|
+
'@type': 'ListItem',
|
|
20
|
+
item: originWithSlug,
|
|
21
|
+
name: homeName,
|
|
22
|
+
position: '1'
|
|
23
|
+
},
|
|
24
|
+
...values.map((page: Breadcrumb, index: number) => ({
|
|
25
|
+
'@type': 'ListItem',
|
|
26
|
+
item: homeSlug ? originWithSlug + '/' + page.item : origin + page.item,
|
|
27
|
+
name: page.name,
|
|
28
|
+
position: String(index + 2)
|
|
29
|
+
}))
|
|
30
|
+
]
|
|
31
|
+
: []
|
|
32
|
+
),
|
|
33
|
+
ldjson = $derived(
|
|
34
|
+
listItems.length > 0
|
|
35
|
+
? `<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":${JSON.stringify(listItems)}}${'<'}/script>`
|
|
36
|
+
: ''
|
|
37
|
+
)
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<svelte:head>
|
|
41
|
+
{#if ldjson}
|
|
42
|
+
{@html ldjson}
|
|
43
|
+
{/if}
|
|
44
|
+
</svelte:head>
|
|
45
|
+
|
|
46
|
+
{#if Array.isArray(listItems) && listItems.length > 0}
|
|
47
|
+
<div class="border-bottom truncate">
|
|
48
|
+
<ol id="breadcrumb" class="max-w-screen-xl mx-auto my-0 px-4 py-2" vocab="https://schema.org/" typeof="BreadcrumbList">
|
|
49
|
+
{#each listItems as page}
|
|
50
|
+
<li property="itemListElement" typeof="ListItem">
|
|
51
|
+
<a href={page.item} class="bc-link" property="item" typeof="WebPage">
|
|
52
|
+
<span property="name">{page.name}</span>
|
|
53
|
+
</a>
|
|
54
|
+
<meta property="position" content={page.position} />
|
|
55
|
+
</li>
|
|
56
|
+
{/each}
|
|
57
|
+
</ol>
|
|
58
|
+
</div>
|
|
59
|
+
{/if}
|
|
60
|
+
|
|
61
|
+
<style scoped>
|
|
62
|
+
#breadcrumb {
|
|
63
|
+
white-space: nowrap;
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#breadcrumb li {
|
|
68
|
+
display: inline-block;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#breadcrumb li:not(:last-child):after {
|
|
72
|
+
content: '»';
|
|
73
|
+
display: inline;
|
|
74
|
+
font-size: 0.95em;
|
|
75
|
+
padding: 0 5px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#breadcrumb a:not(:hover) {
|
|
79
|
+
text-decoration: none;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Breadcrumb } from './';
|
|
2
|
+
interface Props {
|
|
3
|
+
homeName?: string;
|
|
4
|
+
homeSlug?: string;
|
|
5
|
+
values: Breadcrumb[];
|
|
6
|
+
}
|
|
7
|
+
declare const Breadcrumbs: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Breadcrumbs = ReturnType<typeof Breadcrumbs>;
|
|
9
|
+
export default Breadcrumbs;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {loading} from './'
|
|
3
|
+
import type {Snippet} from 'svelte'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
ariaControls?: string | undefined
|
|
7
|
+
ariaExpanded?: boolean | undefined
|
|
8
|
+
ariaLabel?: string
|
|
9
|
+
ariaPopup?: 'dialog' | 'menu' | 'listbox' | undefined
|
|
10
|
+
ball?: boolean
|
|
11
|
+
borderColor?: 'content' | 'default' | 'primary'
|
|
12
|
+
borderSize?: 0 | 1 | 2
|
|
13
|
+
children: Snippet
|
|
14
|
+
color?: string
|
|
15
|
+
colorBg?: string
|
|
16
|
+
control?: boolean
|
|
17
|
+
disabled?: boolean
|
|
18
|
+
extraClass?: string
|
|
19
|
+
fill?: boolean
|
|
20
|
+
fontWeight?: 'normal' | 'bold'
|
|
21
|
+
fullWidth?: boolean
|
|
22
|
+
hover?: 'black' | 'primary' | 'secondary' | 'success' | 'transparent'
|
|
23
|
+
hoverText?: 'black' | 'primary' | 'secondary' | 'white'
|
|
24
|
+
href?: string | undefined
|
|
25
|
+
id?: string
|
|
26
|
+
isActive?: boolean
|
|
27
|
+
noHeight?: boolean
|
|
28
|
+
noPadding?: boolean
|
|
29
|
+
onclick?: any
|
|
30
|
+
preload?: 'hover' | 'tap'
|
|
31
|
+
role?: string
|
|
32
|
+
target?: '_blank' | '_top' | undefined
|
|
33
|
+
type?: 'submit'
|
|
34
|
+
uppercase?: boolean
|
|
35
|
+
value?: string | number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let {
|
|
39
|
+
ariaControls,
|
|
40
|
+
ariaExpanded,
|
|
41
|
+
ariaLabel,
|
|
42
|
+
ariaPopup,
|
|
43
|
+
ball,
|
|
44
|
+
borderColor = 'content',
|
|
45
|
+
borderSize = 0,
|
|
46
|
+
children,
|
|
47
|
+
color = 'white',
|
|
48
|
+
colorBg = 'primary',
|
|
49
|
+
control,
|
|
50
|
+
disabled,
|
|
51
|
+
extraClass,
|
|
52
|
+
fill,
|
|
53
|
+
fontWeight = 'bold',
|
|
54
|
+
fullWidth,
|
|
55
|
+
hover = 'secondary',
|
|
56
|
+
hoverText = 'white',
|
|
57
|
+
href,
|
|
58
|
+
id,
|
|
59
|
+
isActive = false,
|
|
60
|
+
noHeight,
|
|
61
|
+
noPadding,
|
|
62
|
+
onclick = undefined,
|
|
63
|
+
preload,
|
|
64
|
+
role,
|
|
65
|
+
target,
|
|
66
|
+
type,
|
|
67
|
+
uppercase = true,
|
|
68
|
+
value
|
|
69
|
+
}: Props = $props()
|
|
70
|
+
|
|
71
|
+
let classes = $state('btn text-' + color)
|
|
72
|
+
|
|
73
|
+
if (control) {
|
|
74
|
+
classes += ' control'
|
|
75
|
+
} else {
|
|
76
|
+
classes += ' bg-' + colorBg
|
|
77
|
+
}
|
|
78
|
+
if (ball) {
|
|
79
|
+
classes += ' radius-full'
|
|
80
|
+
}
|
|
81
|
+
if (borderSize) {
|
|
82
|
+
classes += ' border-solid border-' + borderSize + ' border-' + borderColor
|
|
83
|
+
}
|
|
84
|
+
if (extraClass) {
|
|
85
|
+
classes += ' ' + extraClass
|
|
86
|
+
}
|
|
87
|
+
if (fill) {
|
|
88
|
+
classes += ' fill'
|
|
89
|
+
}
|
|
90
|
+
if (fontWeight) {
|
|
91
|
+
classes += ' font-' + fontWeight
|
|
92
|
+
}
|
|
93
|
+
if (fullWidth) {
|
|
94
|
+
classes += ' w-full'
|
|
95
|
+
}
|
|
96
|
+
if (hover) {
|
|
97
|
+
classes += ' hover-' + hover
|
|
98
|
+
}
|
|
99
|
+
if (hoverText) {
|
|
100
|
+
classes += ' hover-text-' + hoverText
|
|
101
|
+
}
|
|
102
|
+
if (isActive) {
|
|
103
|
+
classes += ' active'
|
|
104
|
+
}
|
|
105
|
+
if (noHeight) {
|
|
106
|
+
classes += ' no-height'
|
|
107
|
+
}
|
|
108
|
+
if (noPadding) {
|
|
109
|
+
classes += ' no-padding'
|
|
110
|
+
}
|
|
111
|
+
if (uppercase) {
|
|
112
|
+
classes += ' uppercase'
|
|
113
|
+
}
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
{#if href}
|
|
117
|
+
<a {href} class={classes} {target} data-sveltekit-preload-data={preload} rel="nofollow noopener">
|
|
118
|
+
{@render children?.()}
|
|
119
|
+
</a>
|
|
120
|
+
{:else if control}
|
|
121
|
+
<button
|
|
122
|
+
{id}
|
|
123
|
+
{onclick}
|
|
124
|
+
{role}
|
|
125
|
+
{value}
|
|
126
|
+
aria-controls={ariaControls}
|
|
127
|
+
aria-expanded={ariaExpanded}
|
|
128
|
+
aria-haspopup={ariaPopup}
|
|
129
|
+
aria-label={ariaLabel}
|
|
130
|
+
class={classes}
|
|
131
|
+
disabled={disabled || $loading}
|
|
132
|
+
>
|
|
133
|
+
{@render children?.()}
|
|
134
|
+
</button>
|
|
135
|
+
{:else}
|
|
136
|
+
<button {onclick} class={classes} {disabled} {type}>
|
|
137
|
+
{@render children?.()}
|
|
138
|
+
</button>
|
|
139
|
+
{/if}
|
|
140
|
+
|
|
141
|
+
<style scoped>
|
|
142
|
+
a {
|
|
143
|
+
text-decoration: none;
|
|
144
|
+
}
|
|
145
|
+
.bg-primary:not(:hover),
|
|
146
|
+
.hover-primary:hover {
|
|
147
|
+
background-color: var(--color-primary);
|
|
148
|
+
}
|
|
149
|
+
.bg-secondary:not(:hover),
|
|
150
|
+
.hover-secondary:hover {
|
|
151
|
+
background-color: var(--color-secondary);
|
|
152
|
+
}
|
|
153
|
+
.bg-success:not(:hover),
|
|
154
|
+
.hover-success:hover {
|
|
155
|
+
background-color: green;
|
|
156
|
+
}
|
|
157
|
+
.bg-danger:not(:hover),
|
|
158
|
+
.hover-danger:hover {
|
|
159
|
+
background-color: darkred;
|
|
160
|
+
}
|
|
161
|
+
.bg-black:not(:hover),
|
|
162
|
+
.hover-black:hover {
|
|
163
|
+
background-color: #000;
|
|
164
|
+
}
|
|
165
|
+
.border-solid {
|
|
166
|
+
border-style: solid;
|
|
167
|
+
}
|
|
168
|
+
.border-1 {
|
|
169
|
+
border-width: 1px;
|
|
170
|
+
}
|
|
171
|
+
.border-2 {
|
|
172
|
+
border-width: 2px;
|
|
173
|
+
}
|
|
174
|
+
.border-content {
|
|
175
|
+
border-color: var(--color-content);
|
|
176
|
+
}
|
|
177
|
+
.border-default {
|
|
178
|
+
border-color: var(--color-border);
|
|
179
|
+
}
|
|
180
|
+
.border-primary {
|
|
181
|
+
border-color: var(--color-primary);
|
|
182
|
+
}
|
|
183
|
+
.btn {
|
|
184
|
+
align-items: center;
|
|
185
|
+
display: inline-flex;
|
|
186
|
+
justify-content: center;
|
|
187
|
+
}
|
|
188
|
+
.btn:not(.border-solid) {
|
|
189
|
+
border: 0;
|
|
190
|
+
}
|
|
191
|
+
.btn:not(.fill):not(.no-height) {
|
|
192
|
+
height: 48px;
|
|
193
|
+
}
|
|
194
|
+
.btn:not(:disabled) {
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
}
|
|
197
|
+
.btn:not(.control) {
|
|
198
|
+
font-size: 1rem;
|
|
199
|
+
}
|
|
200
|
+
.btn:not(.control):not(.flll):not(.no-padding):not(.radius-full) {
|
|
201
|
+
padding-left: 2rem;
|
|
202
|
+
padding-right: 2rem;
|
|
203
|
+
}
|
|
204
|
+
.btn:not(.radius-full) {
|
|
205
|
+
border-radius: 0.375rem;
|
|
206
|
+
}
|
|
207
|
+
.btn:disabled {
|
|
208
|
+
cursor: not-allowed;
|
|
209
|
+
opacity: 0.6;
|
|
210
|
+
}
|
|
211
|
+
.control {
|
|
212
|
+
border: 0;
|
|
213
|
+
}
|
|
214
|
+
.control,
|
|
215
|
+
.hover-transparent:hover {
|
|
216
|
+
background-color: transparent;
|
|
217
|
+
}
|
|
218
|
+
.control,
|
|
219
|
+
.fill,
|
|
220
|
+
.radius-full {
|
|
221
|
+
padding: 0;
|
|
222
|
+
}
|
|
223
|
+
.control:not(.fill) {
|
|
224
|
+
width: 48px;
|
|
225
|
+
}
|
|
226
|
+
.fill {
|
|
227
|
+
height: 100%;
|
|
228
|
+
width: 100%;
|
|
229
|
+
}
|
|
230
|
+
.font-400 {
|
|
231
|
+
font-weight: 400;
|
|
232
|
+
}
|
|
233
|
+
.font-700 {
|
|
234
|
+
font-weight: 700;
|
|
235
|
+
}
|
|
236
|
+
.hover-text-black:hover,
|
|
237
|
+
.text-black {
|
|
238
|
+
color: #000;
|
|
239
|
+
}
|
|
240
|
+
.hover-text-primary:hover,
|
|
241
|
+
.text-primary {
|
|
242
|
+
color: var(--color-primary);
|
|
243
|
+
}
|
|
244
|
+
.hover-text-content:hover,
|
|
245
|
+
.text-content {
|
|
246
|
+
color: var(--color-content);
|
|
247
|
+
}
|
|
248
|
+
.hover-black:hover,
|
|
249
|
+
.hover-primary:hover,
|
|
250
|
+
.hover-success:hover,
|
|
251
|
+
.hover-text-white:hover,
|
|
252
|
+
.text-white {
|
|
253
|
+
color: #fff;
|
|
254
|
+
}
|
|
255
|
+
.hover-text-secondary:hover,
|
|
256
|
+
.text-secondary {
|
|
257
|
+
color: var(--color-secondary);
|
|
258
|
+
}
|
|
259
|
+
.radius-full {
|
|
260
|
+
border-radius: 50%;
|
|
261
|
+
overflow: hidden;
|
|
262
|
+
}
|
|
263
|
+
.w-full {
|
|
264
|
+
width: 100%;
|
|
265
|
+
}
|
|
266
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
ariaControls?: string | undefined;
|
|
4
|
+
ariaExpanded?: boolean | undefined;
|
|
5
|
+
ariaLabel?: string;
|
|
6
|
+
ariaPopup?: 'dialog' | 'menu' | 'listbox' | undefined;
|
|
7
|
+
ball?: boolean;
|
|
8
|
+
borderColor?: 'content' | 'default' | 'primary';
|
|
9
|
+
borderSize?: 0 | 1 | 2;
|
|
10
|
+
children: Snippet;
|
|
11
|
+
color?: string;
|
|
12
|
+
colorBg?: string;
|
|
13
|
+
control?: boolean;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
extraClass?: string;
|
|
16
|
+
fill?: boolean;
|
|
17
|
+
fontWeight?: 'normal' | 'bold';
|
|
18
|
+
fullWidth?: boolean;
|
|
19
|
+
hover?: 'black' | 'primary' | 'secondary' | 'success' | 'transparent';
|
|
20
|
+
hoverText?: 'black' | 'primary' | 'secondary' | 'white';
|
|
21
|
+
href?: string | undefined;
|
|
22
|
+
id?: string;
|
|
23
|
+
isActive?: boolean;
|
|
24
|
+
noHeight?: boolean;
|
|
25
|
+
noPadding?: boolean;
|
|
26
|
+
onclick?: any;
|
|
27
|
+
preload?: 'hover' | 'tap';
|
|
28
|
+
role?: string;
|
|
29
|
+
target?: '_blank' | '_top' | undefined;
|
|
30
|
+
type?: 'submit';
|
|
31
|
+
uppercase?: boolean;
|
|
32
|
+
value?: string | number;
|
|
33
|
+
}
|
|
34
|
+
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
35
|
+
type Button = ReturnType<typeof Button>;
|
|
36
|
+
export default Button;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Button from './Button.svelte'
|
|
3
|
+
interface Props {
|
|
4
|
+
onclick?: () => any
|
|
5
|
+
ariaLabel: string
|
|
6
|
+
color?: string
|
|
7
|
+
direction: 'left' | 'right'
|
|
8
|
+
}
|
|
9
|
+
let {onclick, ariaLabel, color = 'black', direction}: Props = $props()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Button {color} {onclick} {ariaLabel} control>
|
|
13
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
14
|
+
<title>Arrow {direction}</title>
|
|
15
|
+
{#if direction === 'left'}
|
|
16
|
+
<path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z" />
|
|
17
|
+
{:else}
|
|
18
|
+
<path d="M7.33 24l-2.83-2.829 9.339-9.175-9.339-9.167 2.83-2.829 12.17 11.996z" />
|
|
19
|
+
{/if}
|
|
20
|
+
</svg>
|
|
21
|
+
</Button>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
onclick?: () => any;
|
|
3
|
+
ariaLabel: string;
|
|
4
|
+
color?: string;
|
|
5
|
+
direction: 'left' | 'right';
|
|
6
|
+
}
|
|
7
|
+
declare const ButtonArrow: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ButtonArrow = ReturnType<typeof ButtonArrow>;
|
|
9
|
+
export default ButtonArrow;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Button from './Button.svelte'
|
|
3
|
+
let {color = 'black', onclick} = $props()
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<div class="close-button">
|
|
7
|
+
<Button {color} {onclick} control fill>
|
|
8
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
9
|
+
<title>Sulje ikkuna</title>
|
|
10
|
+
<path
|
|
11
|
+
d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5 15.538l-3.592-3.548 3.546-3.587-1.416-1.403-3.545 3.589-3.588-3.543-1.405 1.405 3.593 3.552-3.547 3.592 1.405 1.405 3.555-3.596 3.591 3.55 1.403-1.416z"
|
|
12
|
+
/>
|
|
13
|
+
</svg>
|
|
14
|
+
</Button>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<style scoped>
|
|
18
|
+
.close-button {
|
|
19
|
+
height: 48px;
|
|
20
|
+
position: absolute;
|
|
21
|
+
right: 0;
|
|
22
|
+
top: 0;
|
|
23
|
+
width: 48px;
|
|
24
|
+
}
|
|
25
|
+
</style>
|