sveltacular 0.0.34 → 0.0.35
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/dist/forms/check-box/check-box.svelte +4 -4
- package/dist/forms/file-area/file-area.svelte +54 -14
- package/dist/forms/file-area/file-area.svelte.d.ts +6 -1
- package/dist/forms/form-field.svelte +0 -1
- package/dist/forms/number-box/number-box.svelte +2 -2
- package/dist/forms/radio-group/radio-box.svelte +4 -4
- package/dist/forms/switch-box/switch-box.svelte +3 -8
- package/dist/forms/switch-box/switch-box.svelte.d.ts +0 -2
- package/dist/generic/card/card.svelte +0 -1
- package/dist/generic/date/date-time.svelte +0 -6
- package/dist/generic/header/header.svelte +1 -1
- package/dist/generic/link/link.svelte +0 -11
- package/dist/generic/menu/menu.svelte +6 -6
- package/dist/generic/panel/panel.svelte +3 -1
- package/dist/generic/scorecard/scorecard.svelte +1 -0
- package/dist/images/image.svelte +8 -8
- package/dist/modals/dialog-window.svelte +9 -1
- package/dist/navigation/app-bar/app-bar.svelte +9 -0
- package/dist/navigation/app-bar/app-logo.svelte +2 -2
- package/dist/navigation/app-bar/app-nav-item.svelte +6 -5
- package/dist/navigation/breadcrumbs/breadcrumbs.svelte +3 -5
- package/dist/navigation/tabs/tab-context.d.ts +3 -0
- package/dist/navigation/tabs/tab-group.svelte +5 -1
- package/dist/navigation/tabs/tab-group.svelte.d.ts +5 -1
- package/dist/navigation/tabs/tab.svelte +71 -29
- package/dist/types/generic.d.ts +1 -0
- package/package.json +1 -1
|
@@ -64,10 +64,10 @@ label .checkbox .checkmark {
|
|
|
64
64
|
left: 0;
|
|
65
65
|
width: 0;
|
|
66
66
|
height: 0;
|
|
67
|
-
background-color: var(--form-input-
|
|
68
|
-
color: var(--form-input-
|
|
69
|
-
fill: var(--form-input-
|
|
70
|
-
stroke: var(--form-input-
|
|
67
|
+
background-color: var(--form-input-selected-bg, #3182ce);
|
|
68
|
+
color: var(--form-input-selected-fg, white);
|
|
69
|
+
fill: var(--form-input-selected-bg, #3182ce);
|
|
70
|
+
stroke: var(--form-input-selected-fg, white);
|
|
71
71
|
transition: width 0.2s ease-in-out, height 0.2s ease-in-out;
|
|
72
72
|
}
|
|
73
73
|
label input {
|
|
@@ -1,25 +1,42 @@
|
|
|
1
1
|
<script>import UploadIcon from "../../icons/upload-icon.svelte";
|
|
2
2
|
import { createEventDispatcher } from "svelte";
|
|
3
|
-
let
|
|
3
|
+
export let selectedFiles = [];
|
|
4
|
+
export let disabled = false;
|
|
5
|
+
export let fileLimit = 1;
|
|
6
|
+
export let fileMimePattern = void 0;
|
|
4
7
|
let isDragging = false;
|
|
5
8
|
const dispatch = createEventDispatcher();
|
|
9
|
+
const filterFiles = (files) => {
|
|
10
|
+
if (!fileMimePattern)
|
|
11
|
+
return files;
|
|
12
|
+
return [...files].filter((file) => {
|
|
13
|
+
if (!file.type)
|
|
14
|
+
return false;
|
|
15
|
+
if (!fileMimePattern)
|
|
16
|
+
return true;
|
|
17
|
+
if (typeof fileMimePattern === "string")
|
|
18
|
+
return file.type.startsWith(fileMimePattern);
|
|
19
|
+
return file.type.match(fileMimePattern);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
const addFiles = async (files) => {
|
|
23
|
+
if (!files.length)
|
|
24
|
+
return;
|
|
25
|
+
selectedFiles = [...files, selectedFiles].flat().slice(0, fileLimit);
|
|
26
|
+
dispatch("filesSelected", selectedFiles);
|
|
27
|
+
};
|
|
6
28
|
const selectFiles = async (e) => {
|
|
7
29
|
const target = e.target;
|
|
8
30
|
if (!target?.files || !target.files.length)
|
|
9
31
|
return;
|
|
10
|
-
|
|
11
|
-
if (!files.length)
|
|
12
|
-
return;
|
|
13
|
-
dispatch("filesSelected", files);
|
|
32
|
+
addFiles(filterFiles([...target.files]));
|
|
14
33
|
};
|
|
15
34
|
const dropFiles = async (e) => {
|
|
16
35
|
dragStop(e);
|
|
17
36
|
if (!e.dataTransfer)
|
|
18
37
|
return;
|
|
19
|
-
const files = e.dataTransfer.items ? [...e.dataTransfer.items].filter((item) => item.kind === "file").map((item) => item.getAsFile())
|
|
20
|
-
|
|
21
|
-
return;
|
|
22
|
-
dispatch("filesSelected", files);
|
|
38
|
+
const files = e.dataTransfer.items ? [...e.dataTransfer.items].filter((item) => item.kind === "file").map((item) => item.getAsFile()) : e.dataTransfer.files;
|
|
39
|
+
addFiles(filterFiles(files));
|
|
23
40
|
};
|
|
24
41
|
const dragStart = (e) => {
|
|
25
42
|
e.preventDefault();
|
|
@@ -31,9 +48,20 @@ const dragStop = (e) => {
|
|
|
31
48
|
e.stopPropagation();
|
|
32
49
|
isDragging = false;
|
|
33
50
|
};
|
|
51
|
+
$:
|
|
52
|
+
filesClass = selectedFiles.length ? "has-files" : "no-files";
|
|
53
|
+
$:
|
|
54
|
+
enabledClass = disabled ? "disabled" : "";
|
|
55
|
+
$:
|
|
56
|
+
draggingClass = isDragging ? "isDragging" : "";
|
|
57
|
+
$:
|
|
58
|
+
filesSelectedText = selectedFiles.length ? `${selectedFiles.length} file${selectedFiles.length > 1 ? "s" : ""} selected` : "";
|
|
34
59
|
</script>
|
|
35
60
|
|
|
36
|
-
<div
|
|
61
|
+
<div
|
|
62
|
+
class="dropzone {filesClass} {enabledClass} {draggingClass}"
|
|
63
|
+
data-file-count={selectedFiles.length}
|
|
64
|
+
>
|
|
37
65
|
<label
|
|
38
66
|
on:drop={dropFiles}
|
|
39
67
|
on:dragenter={dragStart}
|
|
@@ -51,6 +79,9 @@ const dragStop = (e) => {
|
|
|
51
79
|
{:else}
|
|
52
80
|
<span>Drop file or click to select</span>
|
|
53
81
|
{/if}
|
|
82
|
+
{#if filesSelectedText}
|
|
83
|
+
<span class="file-count">{filesSelectedText}</span>
|
|
84
|
+
{/if}
|
|
54
85
|
</div>
|
|
55
86
|
</label>
|
|
56
87
|
</div>
|
|
@@ -65,9 +96,10 @@ const dragStop = (e) => {
|
|
|
65
96
|
align-items: center;
|
|
66
97
|
width: 100%;
|
|
67
98
|
height: 100%;
|
|
68
|
-
border: 2px dashed
|
|
99
|
+
border: 2px dashed var(--form-input-border, black);
|
|
100
|
+
background-color: var(--form-input-bg, white);
|
|
101
|
+
color: var(--form-input-fg, black);
|
|
69
102
|
border-radius: 0.25rem;
|
|
70
|
-
color: #ccc;
|
|
71
103
|
cursor: pointer;
|
|
72
104
|
}
|
|
73
105
|
.dropzone.disabled {
|
|
@@ -75,8 +107,8 @@ const dragStop = (e) => {
|
|
|
75
107
|
cursor: not-allowed;
|
|
76
108
|
}
|
|
77
109
|
.dropzone.isDragging {
|
|
78
|
-
background-color: #
|
|
79
|
-
color:
|
|
110
|
+
background-color: var(--form-input-selected-bg, #3182ce);
|
|
111
|
+
color: var(--form-input-selected-fg, white);
|
|
80
112
|
}
|
|
81
113
|
.dropzone label {
|
|
82
114
|
display: flex;
|
|
@@ -90,9 +122,17 @@ const dragStop = (e) => {
|
|
|
90
122
|
}
|
|
91
123
|
.dropzone label .icon {
|
|
92
124
|
width: 50%;
|
|
125
|
+
opacity: 0.5;
|
|
93
126
|
}
|
|
94
127
|
.dropzone label .text {
|
|
95
128
|
font-size: 1rem;
|
|
96
129
|
letter-spacing: 0.075rem;
|
|
97
130
|
margin-top: 1rem;
|
|
131
|
+
opacity: 0.5;
|
|
132
|
+
text-align: center;
|
|
133
|
+
}
|
|
134
|
+
.dropzone label .file-count {
|
|
135
|
+
display: block;
|
|
136
|
+
font-size: 0.75rem;
|
|
137
|
+
margin-top: 0.5rem;
|
|
98
138
|
}</style>
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
|
-
props:
|
|
3
|
+
props: {
|
|
4
|
+
selectedFiles?: (FileList | File[]) | undefined;
|
|
5
|
+
disabled?: boolean | undefined;
|
|
6
|
+
fileLimit?: number | undefined;
|
|
7
|
+
fileMimePattern?: string | RegExp | undefined;
|
|
8
|
+
};
|
|
4
9
|
events: {
|
|
5
10
|
filesSelected: CustomEvent<FileList | File[]>;
|
|
6
11
|
} & {
|
|
@@ -80,8 +80,8 @@ const valueChanged = () => {
|
|
|
80
80
|
line-height: 2rem;
|
|
81
81
|
padding-left: 1rem;
|
|
82
82
|
padding-right: 1rem;
|
|
83
|
-
background-color: var(--
|
|
84
|
-
color: var(--
|
|
83
|
+
background-color: var(--form-input-accent-bg, #ccc);
|
|
84
|
+
color: var(--form-input-accent-fg, black);
|
|
85
85
|
}
|
|
86
86
|
.input .prefix {
|
|
87
87
|
border-right: 1px solid var(--form-input-border, black);
|
|
@@ -48,9 +48,9 @@ label .checkbox .checkmark {
|
|
|
48
48
|
display: block;
|
|
49
49
|
width: 0;
|
|
50
50
|
height: 0;
|
|
51
|
-
color: var(--form-input-
|
|
52
|
-
fill: var(--form-input-
|
|
53
|
-
stroke: var(--form-input-
|
|
51
|
+
color: var(--form-input-selected-fg, white);
|
|
52
|
+
fill: var(--form-input-selected-bg, #3182ce);
|
|
53
|
+
stroke: var(--form-input-selected-fg, white);
|
|
54
54
|
transition: width 0.2s ease-in-out, height 0.2s ease-in-out;
|
|
55
55
|
}
|
|
56
56
|
label input {
|
|
@@ -58,7 +58,7 @@ label input {
|
|
|
58
58
|
height: 0;
|
|
59
59
|
}
|
|
60
60
|
label input:checked + .checkbox {
|
|
61
|
-
background-color: var(--form-input-
|
|
61
|
+
background-color: var(--form-input-selected-bg, #3182ce);
|
|
62
62
|
}
|
|
63
63
|
label input:checked + .checkbox .checkmark {
|
|
64
64
|
width: 100%;
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
<script>import { uniqueId } from "../../helpers/unique-id.js";
|
|
2
2
|
import { createEventDispatcher } from "svelte";
|
|
3
3
|
export let checked = false;
|
|
4
|
-
export let unCheckedColor = "#ccc";
|
|
5
|
-
export let checkedColor = "#007bff";
|
|
6
4
|
export let size = "full";
|
|
7
5
|
const id = uniqueId();
|
|
8
6
|
const dispatch = createEventDispatcher();
|
|
9
7
|
</script>
|
|
10
8
|
|
|
11
|
-
<label
|
|
12
|
-
class="switch-box {checked ? 'checked' : ''} {size}"
|
|
13
|
-
style={`--checked-color: ${checkedColor}; --unchecked-color: ${unCheckedColor};`}
|
|
14
|
-
>
|
|
9
|
+
<label class="switch-box {checked ? 'checked' : ''} {size}">
|
|
15
10
|
<input type="checkbox" bind:checked on:change={() => dispatch('change', checked)} {id} />
|
|
16
11
|
<!-- svelte-ignore a11y-interactive-supports-focus -->
|
|
17
12
|
<span class="switch">
|
|
@@ -48,10 +43,10 @@ label .slider {
|
|
|
48
43
|
background-color: var(--form-input-fg, black);
|
|
49
44
|
}
|
|
50
45
|
label.checked .switch {
|
|
51
|
-
background-color: var(--form-input-
|
|
46
|
+
background-color: var(--form-input-selected-bg, #3182ce);
|
|
52
47
|
}
|
|
53
48
|
label.checked .slider {
|
|
54
|
-
background-color: var(--form-input-
|
|
49
|
+
background-color: var(--form-input-selected-fg, white);
|
|
55
50
|
}
|
|
56
51
|
label.xl .switch {
|
|
57
52
|
width: 4rem;
|
|
@@ -3,8 +3,6 @@ import type { FormFieldSizeOptions } from '../../index.js';
|
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
checked?: boolean | undefined;
|
|
6
|
-
unCheckedColor?: string | undefined;
|
|
7
|
-
checkedColor?: string | undefined;
|
|
8
6
|
size?: FormFieldSizeOptions | undefined;
|
|
9
7
|
};
|
|
10
8
|
events: {
|
|
@@ -33,15 +33,4 @@ export let display = "inline";
|
|
|
33
33
|
}
|
|
34
34
|
.link[href].underline-hover:hover {
|
|
35
35
|
text-decoration: underline;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
a {
|
|
39
|
-
color: var(--link-fg, #77b9ff);
|
|
40
|
-
cursor: pointer;
|
|
41
|
-
}
|
|
42
|
-
a:visited {
|
|
43
|
-
color: var(--link-visited-fg, #459fff);
|
|
44
|
-
}
|
|
45
|
-
a:hover {
|
|
46
|
-
color: var(--link-hover-fg, #d00);
|
|
47
36
|
}</style>
|
|
@@ -64,9 +64,6 @@ $:
|
|
|
64
64
|
<style>.menu {
|
|
65
65
|
position: relative;
|
|
66
66
|
width: 8rem;
|
|
67
|
-
background: white;
|
|
68
|
-
color: #000;
|
|
69
|
-
border: 1px solid black;
|
|
70
67
|
list-style: none;
|
|
71
68
|
z-index: 999;
|
|
72
69
|
margin: 0;
|
|
@@ -75,6 +72,9 @@ $:
|
|
|
75
72
|
max-height: 15rem;
|
|
76
73
|
overflow-y: auto;
|
|
77
74
|
font-family: var(--base-font-family, sans-serif);
|
|
75
|
+
border: 1px solid var(--form-input-border, black);
|
|
76
|
+
background-color: var(--form-input-bg, white);
|
|
77
|
+
color: var(--form-input-fg, black);
|
|
78
78
|
}
|
|
79
79
|
.menu.closed {
|
|
80
80
|
display: none;
|
|
@@ -101,13 +101,13 @@ $:
|
|
|
101
101
|
.menu li.instructions {
|
|
102
102
|
padding: 0.5rem 1rem;
|
|
103
103
|
font-style: italic;
|
|
104
|
-
color: #
|
|
104
|
+
color: var(--form-input-placeholder, #aaa);
|
|
105
105
|
cursor: pointer;
|
|
106
106
|
}
|
|
107
107
|
.menu li div:hover,
|
|
108
108
|
.menu li div.selected {
|
|
109
|
-
background: #
|
|
110
|
-
color:
|
|
109
|
+
background: var(--form-input-selected-bg, #003c75);
|
|
110
|
+
color: var(--form-input-selected-fg, white);
|
|
111
111
|
}
|
|
112
112
|
.menu li .check {
|
|
113
113
|
display: inline-block;
|
|
@@ -13,8 +13,9 @@ export let border = true;
|
|
|
13
13
|
position: relative;
|
|
14
14
|
margin-bottom: 1rem;
|
|
15
15
|
padding: 1rem;
|
|
16
|
-
border: soild 1px
|
|
16
|
+
border: soild 1px;
|
|
17
17
|
border-radius: 0.5rem;
|
|
18
|
+
border-color: var(--base-fg, #ccc);
|
|
18
19
|
font-family: var(--base-font-family, sans-serif);
|
|
19
20
|
}
|
|
20
21
|
fieldset.no-border {
|
|
@@ -25,5 +26,6 @@ fieldset legend {
|
|
|
25
26
|
font-weight: 500;
|
|
26
27
|
text-transform: uppercase;
|
|
27
28
|
letter-spacing: 0.1rem;
|
|
29
|
+
color: var(--base-fg, #ccc);
|
|
28
30
|
font-family: var(--base-headline-font-family, sans-serif);
|
|
29
31
|
}</style>
|
package/dist/images/image.svelte
CHANGED
|
@@ -33,13 +33,13 @@ $:
|
|
|
33
33
|
{/if}
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
|
-
<style
|
|
36
|
+
<style>.image {
|
|
37
37
|
position: relative;
|
|
38
38
|
width: 100%;
|
|
39
39
|
height: 100%;
|
|
40
40
|
flex-grow: 1;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
.image .caption {
|
|
43
43
|
position: absolute;
|
|
44
44
|
bottom: 0;
|
|
45
45
|
left: 0;
|
|
@@ -48,7 +48,7 @@ div .caption {
|
|
|
48
48
|
background: rgba(0, 0, 0, 0.5);
|
|
49
49
|
color: white;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
.image picture {
|
|
52
52
|
display: block;
|
|
53
53
|
width: 100%;
|
|
54
54
|
height: 100%;
|
|
@@ -57,7 +57,7 @@ div picture {
|
|
|
57
57
|
object-fit: contain;
|
|
58
58
|
object-position: center;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
.image img {
|
|
61
61
|
display: block;
|
|
62
62
|
width: 100%;
|
|
63
63
|
height: 100%;
|
|
@@ -66,11 +66,11 @@ div img {
|
|
|
66
66
|
object-fit: contain;
|
|
67
67
|
object-position: center;
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
.image.left picture,
|
|
70
|
+
.image.left img {
|
|
71
71
|
object-position: left;
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
.image.right picture,
|
|
74
|
+
.image.right img {
|
|
75
75
|
object-position: right;
|
|
76
76
|
}</style>
|
|
@@ -4,6 +4,8 @@ const captureClick = (e) => {
|
|
|
4
4
|
};
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
8
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
7
9
|
<div class={size} on:click={captureClick}>
|
|
8
10
|
<slot />
|
|
9
11
|
</div>
|
|
@@ -34,5 +36,11 @@ div.xl {
|
|
|
34
36
|
}
|
|
35
37
|
div.full {
|
|
36
38
|
width: 100%;
|
|
37
|
-
max-width:
|
|
39
|
+
max-width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@media (max-width: 640px) {
|
|
43
|
+
div {
|
|
44
|
+
max-width: 100%;
|
|
45
|
+
}
|
|
38
46
|
}</style>
|
|
@@ -28,6 +28,15 @@ setContext("app-bar", {
|
|
|
28
28
|
right: 0;
|
|
29
29
|
z-index: 999;
|
|
30
30
|
height: 3rem;
|
|
31
|
+
font-family: var(--base-font-family, sans-serif);
|
|
32
|
+
}
|
|
33
|
+
header a {
|
|
34
|
+
color: var(--nav-link, rgb(33, 150, 243));
|
|
35
|
+
text-decoration: none;
|
|
36
|
+
}
|
|
37
|
+
header a:hover {
|
|
38
|
+
color: var(--nav-link-hover, rgb(66, 165, 245));
|
|
39
|
+
text-decoration: underline;
|
|
31
40
|
}
|
|
32
41
|
header.fixed {
|
|
33
42
|
position: fixed;
|
|
@@ -29,7 +29,7 @@ const click = () => {
|
|
|
29
29
|
align-items: center;
|
|
30
30
|
height: 100%;
|
|
31
31
|
font-family: var(--nav-font-family, sans-serif);
|
|
32
|
-
color: var(--nav-link
|
|
32
|
+
color: var(--nav-link, black);
|
|
33
33
|
text-decoration: none;
|
|
34
34
|
appearance: none;
|
|
35
35
|
border: none;
|
|
@@ -37,14 +37,14 @@ const click = () => {
|
|
|
37
37
|
cursor: pointer;
|
|
38
38
|
}
|
|
39
39
|
button:hover {
|
|
40
|
-
color: var(--nav-link-hover
|
|
40
|
+
color: var(--nav-link-hover, black);
|
|
41
41
|
text-decoration: underline;
|
|
42
42
|
}
|
|
43
43
|
button .icon {
|
|
44
44
|
width: 100%;
|
|
45
45
|
height: 1.5rem;
|
|
46
|
-
fill: var(--nav-link
|
|
47
|
-
stroke: var(--nav-link
|
|
46
|
+
fill: var(--nav-link, black);
|
|
47
|
+
stroke: var(--nav-link, black);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
@media (max-width: 640px) {
|
|
@@ -57,7 +57,8 @@ button .icon {
|
|
|
57
57
|
}
|
|
58
58
|
button.open:hover {
|
|
59
59
|
text-decoration: none;
|
|
60
|
-
background-color: #
|
|
60
|
+
background-color: var(--nav-menu-hover-bg, #ddd);
|
|
61
|
+
color: var(--nav-menu-hover-fg, black);
|
|
61
62
|
}
|
|
62
63
|
button.open .title {
|
|
63
64
|
flex-grow: 1;
|
|
@@ -40,21 +40,19 @@ const getCrumLabel = (crumb) => {
|
|
|
40
40
|
padding: 0;
|
|
41
41
|
margin: 0;
|
|
42
42
|
line-height: 1.5rem;
|
|
43
|
-
font-family: var(--breadcrumbs-font-family, sans-serif);
|
|
44
|
-
text-shadow: 0 0 0.125rem rgba(0, 0, 0, 0.5);
|
|
45
43
|
}
|
|
46
44
|
nav li {
|
|
47
|
-
color: var(--breadcrumbs-fg, #
|
|
45
|
+
color: var(--breadcrumbs-fg, #555);
|
|
48
46
|
padding: 0;
|
|
49
47
|
margin: 0;
|
|
50
48
|
}
|
|
51
49
|
nav li a {
|
|
52
|
-
color: var(--breadcrumbs-
|
|
50
|
+
color: var(--breadcrumbs-fg, #555);
|
|
53
51
|
text-decoration: none;
|
|
54
52
|
width: 100%;
|
|
55
53
|
}
|
|
56
54
|
nav li a:hover {
|
|
57
|
-
color: var(--breadcrumbs-
|
|
55
|
+
color: var(--breadcrumbs-hover, #955);
|
|
58
56
|
text-decoration: underline;
|
|
59
57
|
}
|
|
60
58
|
nav.sm li {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/// <reference types="svelte" />
|
|
2
|
+
import type { TabStyle } from '../../types/generic.js';
|
|
2
3
|
import type { Writable } from 'svelte/store';
|
|
3
4
|
export interface TabContext {
|
|
4
5
|
active: Writable<string | null>;
|
|
6
|
+
style: TabStyle;
|
|
7
|
+
squared: boolean;
|
|
5
8
|
}
|
|
6
9
|
export declare const tabContext = "tabContext";
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<script>import { writable } from "svelte/store";
|
|
2
2
|
import { setContext } from "svelte";
|
|
3
3
|
import { tabContext } from "./tab-context.js";
|
|
4
|
+
export let style = "traditional";
|
|
5
|
+
export let squared = false;
|
|
4
6
|
const ctx = {
|
|
5
|
-
active: writable(null)
|
|
7
|
+
active: writable(null),
|
|
8
|
+
style,
|
|
9
|
+
squared
|
|
6
10
|
};
|
|
7
11
|
setContext(tabContext, ctx);
|
|
8
12
|
</script>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { TabStyle } from '../../types/generic.js';
|
|
2
3
|
declare const __propDef: {
|
|
3
|
-
props:
|
|
4
|
+
props: {
|
|
5
|
+
style?: TabStyle | undefined;
|
|
6
|
+
squared?: boolean | undefined;
|
|
7
|
+
};
|
|
4
8
|
events: {
|
|
5
9
|
[evt: string]: CustomEvent<any>;
|
|
6
10
|
};
|
|
@@ -1,27 +1,33 @@
|
|
|
1
|
-
<script>import { createEventDispatcher, getContext } from "svelte";
|
|
1
|
+
<script>import { createEventDispatcher, getContext, onDestroy } from "svelte";
|
|
2
2
|
import { tabContext } from "./tab-context.js";
|
|
3
3
|
export let title;
|
|
4
4
|
export let active = false;
|
|
5
5
|
const dispatch = createEventDispatcher();
|
|
6
6
|
const ctx = getContext(tabContext);
|
|
7
|
+
const tabStyle = ctx.style || "traditional";
|
|
7
8
|
const selectThisTab = () => {
|
|
8
9
|
dispatch("selectTab", title);
|
|
9
10
|
ctx.active.set(title);
|
|
10
11
|
};
|
|
11
12
|
if (active)
|
|
12
13
|
selectThisTab();
|
|
13
|
-
ctx.active.subscribe((value) => {
|
|
14
|
+
const unsubscribe = ctx.active.subscribe((value) => {
|
|
14
15
|
active = value === title;
|
|
15
16
|
});
|
|
17
|
+
onDestroy(() => {
|
|
18
|
+
unsubscribe();
|
|
19
|
+
});
|
|
20
|
+
$:
|
|
21
|
+
classes = `${active ? "active" : "inactive"} ${tabStyle} ${ctx.squared ? "squared" : "rounded"}`;
|
|
16
22
|
</script>
|
|
17
23
|
|
|
18
|
-
<section class
|
|
19
|
-
<header>
|
|
24
|
+
<section class={classes}>
|
|
25
|
+
<header class="tabTitle">
|
|
20
26
|
<button type="button" on:click={selectThisTab}>
|
|
21
27
|
{title}
|
|
22
28
|
</button>
|
|
23
29
|
</header>
|
|
24
|
-
<div>
|
|
30
|
+
<div class="tabContent">
|
|
25
31
|
{#if active}
|
|
26
32
|
<slot />
|
|
27
33
|
{/if}
|
|
@@ -31,59 +37,95 @@ ctx.active.subscribe((value) => {
|
|
|
31
37
|
<style>section {
|
|
32
38
|
display: inline;
|
|
33
39
|
}
|
|
34
|
-
|
|
40
|
+
|
|
41
|
+
.tabTitle {
|
|
35
42
|
display: inline-block;
|
|
36
43
|
cursor: pointer;
|
|
37
|
-
height: 2rem;
|
|
44
|
+
height: 2.2rem;
|
|
38
45
|
overflow: hidden;
|
|
39
|
-
border-width: 0.1rem 0.1rem 0 0.1rem;
|
|
40
|
-
border-style: solid;
|
|
41
|
-
border-radius: 0.5rem 0.5rem 0 0;
|
|
42
|
-
margin-right: 0.5rem;
|
|
43
|
-
border-color: transparent;
|
|
44
46
|
position: relative;
|
|
45
47
|
z-index: 2;
|
|
46
|
-
background: var(--tab-bg, transparent);
|
|
47
|
-
color: var(--tab-fg, #fff);
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
.tabTitle button {
|
|
50
50
|
appearance: none;
|
|
51
51
|
background: transparent;
|
|
52
|
-
border:
|
|
52
|
+
border-style: solid;
|
|
53
|
+
border-width: 0 0 0.2rem 0;
|
|
54
|
+
border-color: transparent;
|
|
55
|
+
border-radius: 0.5rem 0.5rem 0 0;
|
|
53
56
|
color: inherit;
|
|
54
|
-
padding: 0;
|
|
55
57
|
cursor: pointer;
|
|
56
58
|
width: 100%;
|
|
57
59
|
height: 100%;
|
|
58
60
|
font-size: 1rem;
|
|
59
|
-
line-height:
|
|
61
|
+
line-height: 1.8rem;
|
|
62
|
+
height: 2.2rem;
|
|
60
63
|
font-weight: 300;
|
|
61
64
|
padding: 0 1rem;
|
|
62
65
|
}
|
|
63
|
-
|
|
66
|
+
.tabTitle button:focus {
|
|
64
67
|
outline: none;
|
|
65
68
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
color: var(--tab-hover-fg, #fbb);
|
|
69
|
-
}
|
|
70
|
-
section div {
|
|
69
|
+
|
|
70
|
+
.tabContent {
|
|
71
71
|
display: none;
|
|
72
72
|
width: 100%;
|
|
73
73
|
position: absolute;
|
|
74
74
|
top: 2rem;
|
|
75
75
|
left: 0;
|
|
76
|
-
border-top: solid 0.2rem var(--tab-
|
|
76
|
+
border-top: solid 0.2rem var(--tab-content-border, rgb(220, 220, 230));
|
|
77
77
|
padding-top: 1rem;
|
|
78
78
|
z-index: 1;
|
|
79
79
|
font-size: 1rem;
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
|
|
82
|
+
.active button {
|
|
82
83
|
font-weight: 700;
|
|
83
|
-
background: var(--tab-active-bg, #eee);
|
|
84
|
-
color: var(--tab-active-fg, #000);
|
|
85
84
|
cursor: default;
|
|
86
85
|
}
|
|
87
|
-
|
|
86
|
+
|
|
87
|
+
.inactive button {
|
|
88
|
+
color: var(--tab-inactive-fg, #999);
|
|
89
|
+
}
|
|
90
|
+
.inactive button:hover {
|
|
91
|
+
color: var(--tab-hover-fg, #ccc);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.active .tabContent {
|
|
88
95
|
display: block;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.squared button {
|
|
99
|
+
border-radius: 0.2rem 0.2rem 0 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.traditional.inactive button {
|
|
103
|
+
background: var(--tab-traditional-inactive-bg, transparent);
|
|
104
|
+
color: var(--tab-traditional-inactive-fg, rgb(100, 100, 100));
|
|
105
|
+
}
|
|
106
|
+
.traditional.inactive button:hover {
|
|
107
|
+
background: var(--tab-traditional-hover-bg, transparent);
|
|
108
|
+
color: var(--tab-traditional-hover-fg, rgb(160, 160, 160));
|
|
109
|
+
}
|
|
110
|
+
.traditional.active button {
|
|
111
|
+
background: var(--tab-traditional-active-bg, rgb(220, 220, 230));
|
|
112
|
+
color: var(--tab-traditional-active-fg, rgb(51, 51, 51));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.underline.inactive button {
|
|
116
|
+
background: var(--tab-underline-inactive-bg, transparent);
|
|
117
|
+
color: var(--tab-underline-inactive-fg, rgb(100, 100, 100));
|
|
118
|
+
}
|
|
119
|
+
.underline.inactive button:hover {
|
|
120
|
+
background: var(--tab-underline-hover-bg, transparent);
|
|
121
|
+
color: var(--tab-underline-hover-fg, rgb(150, 150, 150));
|
|
122
|
+
}
|
|
123
|
+
.underline.active button {
|
|
124
|
+
color: var(--tab-underline-active-fg, rgb(255, 134, 78));
|
|
125
|
+
border-color: var(--tab-underline-active-fg, rgb(255, 134, 78));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.outline.active button {
|
|
129
|
+
border-width: 0.1rem 0.1rem 0 0.1rem;
|
|
130
|
+
border-color: var(--tab-content-border, rgb(220, 220, 230));
|
|
89
131
|
}</style>
|
package/dist/types/generic.d.ts
CHANGED