@coyalabs/bts-style 1.3.10 → 1.3.12
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 +193 -5
- package/dist/Base/BaseContainer.svelte +10 -2
- package/dist/Base/BasePage.svelte +1 -6
- package/dist/Base/BasePage.svelte.d.ts +0 -3
- package/dist/Base/BaseText.svelte +20 -7
- package/dist/Base/BaseText.svelte.d.ts +4 -2
- package/dist/Base/variantTypes.d.ts +3 -2
- package/dist/Base/variantTypes.js +3 -1
- package/dist/Components/Button.svelte +78 -17
- package/dist/Components/Button.svelte.d.ts +8 -0
- package/dist/Components/CodeBlock.svelte +167 -0
- package/dist/Components/CodeBlock.svelte.d.ts +40 -0
- package/dist/Components/ContextMenu.svelte +120 -31
- package/dist/Components/ContextMenu.svelte.d.ts +2 -0
- package/dist/Components/Dropdown.svelte +2 -2
- package/dist/Components/InputBox.svelte +3 -3
- package/dist/Components/LinearList.svelte +7 -2
- package/dist/Components/LoadingSpinner.svelte +58 -0
- package/dist/Components/LoadingSpinner.svelte.d.ts +30 -0
- package/dist/Components/Popup/Popup.svelte +1 -1
- package/dist/Components/ScrollContainer.svelte +95 -0
- package/dist/Components/ScrollContainer.svelte.d.ts +59 -0
- package/dist/Components/Special/SpecialAction.svelte +11 -13
- package/dist/Components/Special/SpecialAction.svelte.d.ts +2 -0
- package/dist/Components/TabBar.svelte +4 -3
- package/dist/Components/TabBar.svelte.d.ts +10 -2
- package/dist/Components/Toast/Toast.svelte +36 -11
- package/dist/Components/Toast/Toast.svelte.d.ts +6 -0
- package/dist/Components/Toggle.svelte +3 -3
- package/dist/Components/TreeDirectory.svelte +28 -10
- package/dist/Components/TreeDirectory.svelte.d.ts +36 -4
- package/dist/Structure/TextHeader.svelte +33 -4
- package/dist/Structure/TextHeader.svelte.d.ts +6 -0
- package/dist/icons.d.ts +8 -0
- package/dist/icons.js +11 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +2 -2
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import BaseContainer from '../Base/BaseContainer.svelte';
|
|
3
|
+
import BaseIcon from '../Base/BaseIcon.svelte';
|
|
4
|
+
import BaseText from '../Base/BaseText.svelte';
|
|
5
|
+
import ScrollContainer from './ScrollContainer.svelte';
|
|
6
|
+
import IconButton from './IconButton.svelte';
|
|
7
|
+
import { icons } from '../icons.js';
|
|
8
|
+
import { VARIANT_SECONDARY } from '../Base/variantTypes.js';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import('../Base/variantTypes.js').BaseContainerVariant} BaseContainerVariant
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {BaseContainerVariant}
|
|
18
|
+
*/
|
|
19
|
+
export let theme = VARIANT_SECONDARY;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {string}
|
|
23
|
+
*/
|
|
24
|
+
export let code = '';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @type {string}
|
|
28
|
+
*/
|
|
29
|
+
export let language = '';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @type {boolean}
|
|
33
|
+
*/
|
|
34
|
+
export let showCopy = true;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @type {string}
|
|
38
|
+
*/
|
|
39
|
+
export let borderRadiusTopLeft = '25px';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @type {string}
|
|
43
|
+
*/
|
|
44
|
+
export let borderRadiusTopRight = '25px';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @type {string}
|
|
48
|
+
*/
|
|
49
|
+
export let borderRadiusBottomLeft = '25px';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @type {string}
|
|
53
|
+
*/
|
|
54
|
+
export let borderRadiusBottomRight = '25px';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @type {boolean}
|
|
58
|
+
*/
|
|
59
|
+
let copied = false;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @type {number | null}
|
|
63
|
+
*/
|
|
64
|
+
let copyTimeout = null;
|
|
65
|
+
|
|
66
|
+
function copyToClipboard() {
|
|
67
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
68
|
+
navigator.clipboard.writeText(code).then(() => {
|
|
69
|
+
copied = true;
|
|
70
|
+
if (copyTimeout) clearTimeout(copyTimeout);
|
|
71
|
+
copyTimeout = setTimeout(() => {
|
|
72
|
+
copied = false;
|
|
73
|
+
}, 2000);
|
|
74
|
+
}).catch((err) => {
|
|
75
|
+
console.error('Failed to copy:', err);
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
// Fallback for older browsers
|
|
79
|
+
const textarea = document.createElement('textarea');
|
|
80
|
+
textarea.value = code;
|
|
81
|
+
textarea.style.position = 'fixed';
|
|
82
|
+
textarea.style.opacity = '0';
|
|
83
|
+
document.body.appendChild(textarea);
|
|
84
|
+
textarea.select();
|
|
85
|
+
try {
|
|
86
|
+
document.execCommand('copy');
|
|
87
|
+
copied = true;
|
|
88
|
+
if (copyTimeout) clearTimeout(copyTimeout);
|
|
89
|
+
copyTimeout = setTimeout(() => {
|
|
90
|
+
copied = false;
|
|
91
|
+
}, 2000);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
console.error('Failed to copy:', err);
|
|
94
|
+
}
|
|
95
|
+
document.body.removeChild(textarea);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</script>
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
<div class="codeblock-wrapper">
|
|
102
|
+
<BaseContainer {theme} {borderRadiusTopLeft} {borderRadiusTopRight} {borderRadiusBottomLeft} {borderRadiusBottomRight}>
|
|
103
|
+
<div class="codeblock-content">
|
|
104
|
+
{#if language || showCopy}
|
|
105
|
+
<div class="codeblock-header">
|
|
106
|
+
{#if language}
|
|
107
|
+
<div class="language-label">
|
|
108
|
+
<BaseText textModifier="-3px" variant="button">{language}</BaseText>
|
|
109
|
+
</div>
|
|
110
|
+
{/if}
|
|
111
|
+
{#if showCopy}
|
|
112
|
+
<div class="copy-button">
|
|
113
|
+
<IconButton
|
|
114
|
+
svg={copied ? icons.check : icons.copy}
|
|
115
|
+
variant="toned"
|
|
116
|
+
size="18px"
|
|
117
|
+
on:click={copyToClipboard}
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
{/if}
|
|
121
|
+
</div>
|
|
122
|
+
{/if}
|
|
123
|
+
<ScrollContainer overflowX="auto" overflowY="hidden">
|
|
124
|
+
<pre><code>{code}</code></pre>
|
|
125
|
+
</ScrollContainer>
|
|
126
|
+
</div>
|
|
127
|
+
</BaseContainer>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<style>
|
|
131
|
+
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
|
132
|
+
.codeblock-wrapper {
|
|
133
|
+
width: 100%;
|
|
134
|
+
}
|
|
135
|
+
.codeblock-content {
|
|
136
|
+
display: flex;
|
|
137
|
+
flex-direction: column;
|
|
138
|
+
gap: 0.75rem;
|
|
139
|
+
}
|
|
140
|
+
.codeblock-header {
|
|
141
|
+
display: flex;
|
|
142
|
+
justify-content: space-between;
|
|
143
|
+
align-items: center;
|
|
144
|
+
gap: 0.5rem;
|
|
145
|
+
}
|
|
146
|
+
.language-label {
|
|
147
|
+
user-select: none;
|
|
148
|
+
opacity: 0.6;
|
|
149
|
+
}
|
|
150
|
+
.copy-button {
|
|
151
|
+
margin-left: auto;
|
|
152
|
+
}
|
|
153
|
+
pre {
|
|
154
|
+
margin: 0;
|
|
155
|
+
padding: 0;
|
|
156
|
+
font-family: 'JetBrains Mono', monospace;
|
|
157
|
+
font-size: 14px;
|
|
158
|
+
line-height: 1.6;
|
|
159
|
+
color: #E3D8D8;
|
|
160
|
+
white-space: pre;
|
|
161
|
+
}
|
|
162
|
+
code {
|
|
163
|
+
display: block;
|
|
164
|
+
font-family: inherit;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
</style>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export default CodeBlock;
|
|
2
|
+
type CodeBlock = SvelteComponent<{
|
|
3
|
+
theme?: BaseContainerVariant | undefined;
|
|
4
|
+
borderRadiusTopLeft?: string | undefined;
|
|
5
|
+
borderRadiusTopRight?: string | undefined;
|
|
6
|
+
borderRadiusBottomLeft?: string | undefined;
|
|
7
|
+
borderRadiusBottomRight?: string | undefined;
|
|
8
|
+
code?: string | undefined;
|
|
9
|
+
language?: string | undefined;
|
|
10
|
+
showCopy?: boolean | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}> & {
|
|
14
|
+
$$bindings?: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
declare const CodeBlock: $$__sveltets_2_IsomorphicComponent<{
|
|
17
|
+
theme?: import("../Base/variantTypes.js").BaseContainerVariant | undefined;
|
|
18
|
+
borderRadiusTopLeft?: string | undefined;
|
|
19
|
+
borderRadiusTopRight?: string | undefined;
|
|
20
|
+
borderRadiusBottomLeft?: string | undefined;
|
|
21
|
+
borderRadiusBottomRight?: string | undefined;
|
|
22
|
+
code?: string | undefined;
|
|
23
|
+
language?: string | undefined;
|
|
24
|
+
showCopy?: boolean | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
[evt: string]: CustomEvent<any>;
|
|
27
|
+
}, {}, {}, string>;
|
|
28
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
29
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
30
|
+
$$bindings?: Bindings;
|
|
31
|
+
} & Exports;
|
|
32
|
+
(internal: unknown, props: Props & {
|
|
33
|
+
$$events?: Events;
|
|
34
|
+
$$slots?: Slots;
|
|
35
|
+
}): Exports & {
|
|
36
|
+
$set?: any;
|
|
37
|
+
$on?: any;
|
|
38
|
+
};
|
|
39
|
+
z_$$bindings?: Bindings;
|
|
40
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { expoOut } from 'svelte/easing';
|
|
2
3
|
import BaseContainer from '../Base/BaseContainer.svelte';
|
|
3
4
|
import BaseText from '../Base/BaseText.svelte';
|
|
4
5
|
|
|
@@ -17,6 +18,56 @@
|
|
|
17
18
|
*/
|
|
18
19
|
export let onSelect = () => {};
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @type {'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'}
|
|
23
|
+
*/
|
|
24
|
+
export let origin = 'top-left';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Map origin to transform-origin CSS value
|
|
28
|
+
*/
|
|
29
|
+
const originMap = {
|
|
30
|
+
'top-left': 'top left',
|
|
31
|
+
'top-right': 'top right',
|
|
32
|
+
'bottom-left': 'bottom left',
|
|
33
|
+
'bottom-right': 'bottom right'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Custom scale transition with independent x and y animations
|
|
38
|
+
* @param {HTMLElement} node
|
|
39
|
+
* @param {{duration?: number, easing?: (t: number) => number}} params
|
|
40
|
+
*/
|
|
41
|
+
function scaleIn(node, { duration = 250, easing = expoOut } = {}) {
|
|
42
|
+
return {
|
|
43
|
+
duration,
|
|
44
|
+
easing,
|
|
45
|
+
css: (/** @type {number} */ t) => {
|
|
46
|
+
// X animates faster (completes at ~65% of animation)
|
|
47
|
+
const scaleX = Math.min(t * 1.6, 1);
|
|
48
|
+
// Y animates at normal speed
|
|
49
|
+
const scaleY = t;
|
|
50
|
+
return `
|
|
51
|
+
transform: scaleX(${scaleX}) scaleY(${scaleY});
|
|
52
|
+
opacity: ${t};
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {HTMLElement} node
|
|
60
|
+
* @param {{duration?: number}} params
|
|
61
|
+
*/
|
|
62
|
+
function scaleOut(node, { duration = 100 } = {}) {
|
|
63
|
+
return {
|
|
64
|
+
duration,
|
|
65
|
+
css: (/** @type {number} */ t) => `
|
|
66
|
+
opacity: ${t};
|
|
67
|
+
`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
20
71
|
/**
|
|
21
72
|
* Group items into categories based on separators
|
|
22
73
|
* @typedef {{label: string | null, items: Array<{item: {label: string, value: any, disabled?: boolean, type?: 'item' | 'separator'}, originalIndex: number}>}} Category
|
|
@@ -42,52 +93,73 @@
|
|
|
42
93
|
}
|
|
43
94
|
</script>
|
|
44
95
|
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
96
|
+
<div
|
|
97
|
+
class="context-menu-wrapper"
|
|
98
|
+
style:transform-origin={originMap[origin]}
|
|
99
|
+
in:scaleIn
|
|
100
|
+
out:scaleOut
|
|
101
|
+
>
|
|
102
|
+
<BaseContainer theme="filled" padding="0.5rem" borderRadiusTopLeft="28px" borderRadiusTopRight="28px" borderRadiusBottomLeft="28px" borderRadiusBottomRight="28px">
|
|
103
|
+
<div style="height: 0.3rem;"></div>
|
|
104
|
+
{#each categories as category, catIndex}
|
|
105
|
+
{#if category.label}
|
|
106
|
+
<div class="separator" class:not-first={catIndex > 0}>
|
|
107
|
+
<BaseText textModifier="-4px" variant="button">{category.label}</BaseText>
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
<div class="category-items">
|
|
111
|
+
{#each category.items as {item}}
|
|
112
|
+
<button
|
|
113
|
+
class="context-item"
|
|
114
|
+
class:selected={item.value === selectedValue}
|
|
115
|
+
class:disabled={item.disabled}
|
|
116
|
+
disabled={item.disabled}
|
|
117
|
+
on:click={() => handleSelect(item.value)}
|
|
118
|
+
>
|
|
119
|
+
{item.label}
|
|
120
|
+
</button>
|
|
121
|
+
{/each}
|
|
50
122
|
</div>
|
|
51
|
-
{/
|
|
52
|
-
<div
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class="context-item"
|
|
56
|
-
class:selected={item.value === selectedValue}
|
|
57
|
-
class:disabled={item.disabled}
|
|
58
|
-
disabled={item.disabled}
|
|
59
|
-
on:click={() => handleSelect(item.value)}
|
|
60
|
-
>
|
|
61
|
-
{item.label}
|
|
62
|
-
</button>
|
|
63
|
-
{/each}
|
|
64
|
-
</div>
|
|
65
|
-
{/each}
|
|
66
|
-
</BaseContainer>
|
|
123
|
+
{/each}
|
|
124
|
+
<div style="height: 0.3rem;"></div>
|
|
125
|
+
</BaseContainer>
|
|
126
|
+
</div>
|
|
67
127
|
|
|
68
128
|
<style>
|
|
129
|
+
.context-menu-wrapper {
|
|
130
|
+
display: inline-block;
|
|
131
|
+
}
|
|
132
|
+
|
|
69
133
|
.category-items {
|
|
70
134
|
display: flex;
|
|
71
135
|
flex-direction: column;
|
|
136
|
+
min-width: 160px;
|
|
72
137
|
}
|
|
73
138
|
|
|
74
139
|
.separator {
|
|
75
|
-
opacity: 0.
|
|
76
|
-
padding: 0
|
|
140
|
+
opacity: 0.7;
|
|
141
|
+
padding-top: 0.5rem;
|
|
142
|
+
padding-left: 1rem;
|
|
143
|
+
padding-right: 1rem;
|
|
144
|
+
padding-bottom: 0.5rem;
|
|
77
145
|
font-size: 0.85rem;
|
|
78
|
-
margin-top: 0.5rem;
|
|
79
|
-
|
|
80
146
|
}
|
|
81
147
|
|
|
82
148
|
.separator.not-first {
|
|
83
|
-
padding-top:
|
|
84
|
-
border-top: 1px solid rgba(227, 216, 216, 0.1);
|
|
149
|
+
padding-top: 1rem;
|
|
85
150
|
margin-top: 0.5rem;
|
|
151
|
+
border-top: 1px solid rgba(227, 216, 216, 0.3);
|
|
152
|
+
margin-top: 1rem;
|
|
153
|
+
margin-bottom: 0.1rem;
|
|
154
|
+
padding-left: 0;
|
|
155
|
+
padding-right: 0;
|
|
156
|
+
margin-left: 1rem;
|
|
157
|
+
margin-right: 1rem;
|
|
86
158
|
}
|
|
87
159
|
|
|
88
160
|
.context-item {
|
|
89
161
|
width: 100%;
|
|
90
|
-
padding: 0.
|
|
162
|
+
padding: 0.3rem 1rem;
|
|
91
163
|
background: none;
|
|
92
164
|
border: none;
|
|
93
165
|
color: #E3D8D8;
|
|
@@ -96,20 +168,37 @@
|
|
|
96
168
|
font-weight: 500;
|
|
97
169
|
text-align: left;
|
|
98
170
|
cursor: pointer;
|
|
99
|
-
transition: background-color 0.15s ease;
|
|
100
171
|
border-radius: 10px;
|
|
101
172
|
white-space: nowrap;
|
|
102
173
|
overflow: hidden;
|
|
103
174
|
text-overflow: ellipsis;
|
|
175
|
+
transition: all 0.2s cubic-bezier(0.075, 0.82, 0.165, 1);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.context-item:first-child {
|
|
179
|
+
border-radius: 15px 15px 10px 10px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.context-item:last-child {
|
|
183
|
+
border-radius: 10px 10px 15px 15px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.context-item:first-child:last-child {
|
|
187
|
+
border-radius: 15px;
|
|
104
188
|
}
|
|
105
189
|
|
|
106
190
|
.context-item:hover:not(.disabled) {
|
|
107
|
-
background-color:
|
|
191
|
+
background-color: #9c7aaa;
|
|
192
|
+
color: black;
|
|
193
|
+
box-shadow: inset 0 2px 4px 1px rgba(255, 255, 255, 0.35);
|
|
108
194
|
}
|
|
109
195
|
|
|
110
196
|
.context-item.selected {
|
|
111
|
-
background-color:
|
|
197
|
+
background-color: #402e43;
|
|
112
198
|
font-weight: 700;
|
|
199
|
+
box-shadow:
|
|
200
|
+
0px 0px 13px 0px rgba(255, 255, 255, 0.07),
|
|
201
|
+
inset 0px 0px 9px 2px rgba(102, 88, 128, 0.5);
|
|
113
202
|
}
|
|
114
203
|
|
|
115
204
|
.context-item.disabled {
|
|
@@ -8,6 +8,7 @@ type ContextMenu = SvelteComponent<{
|
|
|
8
8
|
}[] | undefined;
|
|
9
9
|
selectedValue?: any;
|
|
10
10
|
onSelect?: ((value: any) => void) | undefined;
|
|
11
|
+
origin?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | undefined;
|
|
11
12
|
}, {
|
|
12
13
|
[evt: string]: CustomEvent<any>;
|
|
13
14
|
}, {}> & {
|
|
@@ -22,6 +23,7 @@ declare const ContextMenu: $$__sveltets_2_IsomorphicComponent<{
|
|
|
22
23
|
}[] | undefined;
|
|
23
24
|
selectedValue?: any;
|
|
24
25
|
onSelect?: ((value: any) => void) | undefined;
|
|
26
|
+
origin?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | undefined;
|
|
25
27
|
}, {
|
|
26
28
|
[evt: string]: CustomEvent<any>;
|
|
27
29
|
}, {}, {}, string>;
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
{theme}
|
|
164
164
|
{icon}
|
|
165
165
|
actionIcon={icons.icon_expand}
|
|
166
|
-
actionIconSize="
|
|
166
|
+
actionIconSize="15px"
|
|
167
167
|
actionIconRotation={isOpen ? 180 : 0}
|
|
168
168
|
{borderRadiusTopLeft}
|
|
169
169
|
{borderRadiusTopRight}
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
top: {menuPosition.top}px;
|
|
185
185
|
left: {menuPosition.left}px;
|
|
186
186
|
width: {menuPosition.width}px;
|
|
187
|
-
z-index:
|
|
187
|
+
z-index: 100001;
|
|
188
188
|
"
|
|
189
189
|
>
|
|
190
190
|
<ContextMenu items={options} selectedValue={value} onSelect={selectOption} />
|
|
@@ -102,9 +102,9 @@
|
|
|
102
102
|
input {
|
|
103
103
|
all: unset;
|
|
104
104
|
flex: 1;
|
|
105
|
-
font-family: '
|
|
106
|
-
font-weight:
|
|
107
|
-
font-size:
|
|
105
|
+
font-family: 'Noto Serif KR', serif;
|
|
106
|
+
font-weight: 900;
|
|
107
|
+
font-size: 17px;
|
|
108
108
|
color: #E3D8D8;
|
|
109
109
|
width: 100%;
|
|
110
110
|
}
|
|
@@ -82,8 +82,12 @@
|
|
|
82
82
|
display: flex;
|
|
83
83
|
justify-content: space-between;
|
|
84
84
|
align-items: center;
|
|
85
|
-
padding:
|
|
86
|
-
|
|
85
|
+
padding: 15px 0;
|
|
86
|
+
background-image: linear-gradient(to right, #4a3b5561 50%, transparent 50%);
|
|
87
|
+
background-size: 8px 2px;
|
|
88
|
+
background-position: 0 100%;
|
|
89
|
+
background-repeat: repeat-x;
|
|
90
|
+
padding-bottom: 15px;
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
.list-item:last-child {
|
|
@@ -98,6 +102,7 @@
|
|
|
98
102
|
|
|
99
103
|
.actions {
|
|
100
104
|
display: flex;
|
|
105
|
+
margin-left: 1rem;
|
|
101
106
|
gap: 0.5rem;
|
|
102
107
|
align-items: center;
|
|
103
108
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { gearSVGLight } from '../Structure/BG/assetGear.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Size of the spinner (e.g., '20px', '2rem', '50px')
|
|
6
|
+
* @type {string}
|
|
7
|
+
*/
|
|
8
|
+
export let size = '20px';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Animation speed in seconds (default 2s for one full rotation)
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
14
|
+
export let speed = 2;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Custom color for the spinner (optional, uses default if not provided)
|
|
18
|
+
* @type {string | null}
|
|
19
|
+
*/
|
|
20
|
+
export let color = '#E3D8D8';
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
class="loading-spinner"
|
|
25
|
+
style:width={size}
|
|
26
|
+
style:height={size}
|
|
27
|
+
style:--spin-speed="{speed}s"
|
|
28
|
+
style:--spinner-color={color}
|
|
29
|
+
>
|
|
30
|
+
{@html gearSVGLight}
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<style>
|
|
34
|
+
.loading-spinner {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
animation: spin var(--spin-speed) linear infinite;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.loading-spinner :global(svg) {
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.loading-spinner :global(path) {
|
|
47
|
+
fill: var(--spinner-color, currentColor);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@keyframes spin {
|
|
51
|
+
from {
|
|
52
|
+
transform: rotate(0deg);
|
|
53
|
+
}
|
|
54
|
+
to {
|
|
55
|
+
transform: rotate(360deg);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default LoadingSpinner;
|
|
2
|
+
type LoadingSpinner = SvelteComponent<{
|
|
3
|
+
speed?: number | undefined;
|
|
4
|
+
size?: string | undefined;
|
|
5
|
+
color?: string | null | undefined;
|
|
6
|
+
}, {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
}, {}> & {
|
|
9
|
+
$$bindings?: string | undefined;
|
|
10
|
+
};
|
|
11
|
+
declare const LoadingSpinner: $$__sveltets_2_IsomorphicComponent<{
|
|
12
|
+
speed?: number | undefined;
|
|
13
|
+
size?: string | undefined;
|
|
14
|
+
color?: string | null | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
19
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
20
|
+
$$bindings?: Bindings;
|
|
21
|
+
} & Exports;
|
|
22
|
+
(internal: unknown, props: Props & {
|
|
23
|
+
$$events?: Events;
|
|
24
|
+
$$slots?: Slots;
|
|
25
|
+
}): Exports & {
|
|
26
|
+
$set?: any;
|
|
27
|
+
$on?: any;
|
|
28
|
+
};
|
|
29
|
+
z_$$bindings?: Bindings;
|
|
30
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
/**
|
|
3
|
+
* @type {'auto' | 'scroll' | 'hidden' | 'visible'}
|
|
4
|
+
*/
|
|
5
|
+
export let overflowX = 'auto';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @type {'auto' | 'scroll' | 'hidden' | 'visible'}
|
|
9
|
+
*/
|
|
10
|
+
export let overflowY = 'auto';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {string}
|
|
14
|
+
*/
|
|
15
|
+
export let width = '100%';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @type {string}
|
|
19
|
+
*/
|
|
20
|
+
export let height = 'auto';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @type {string}
|
|
24
|
+
*/
|
|
25
|
+
export let maxWidth = '100%';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @type {string}
|
|
29
|
+
*/
|
|
30
|
+
export let maxHeight = 'none';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @type {string}
|
|
34
|
+
*/
|
|
35
|
+
export let scrollbarSize = '8px';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @type {string}
|
|
39
|
+
*/
|
|
40
|
+
export let trackColor = 'rgba(161, 143, 143, 0.1)';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @type {string}
|
|
44
|
+
*/
|
|
45
|
+
export let thumbColor = 'rgba(161, 143, 143, 0.3)';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @type {string}
|
|
49
|
+
*/
|
|
50
|
+
export let thumbHoverColor = 'rgba(161, 143, 143, 0.5)';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @type {string}
|
|
54
|
+
*/
|
|
55
|
+
export let borderRadius = '4px';
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<div
|
|
59
|
+
class="scroll-container"
|
|
60
|
+
style="--overflow-x: {overflowX}; --overflow-y: {overflowY}; --width: {width}; --height: {height}; --max-width: {maxWidth}; --max-height: {maxHeight}; --scrollbar-size: {scrollbarSize}; --scroll-track-color: {trackColor}; --scroll-thumb-color: {thumbColor}; --scroll-thumb-hover-color: {thumbHoverColor}; --scroll-radius: {borderRadius};"
|
|
61
|
+
>
|
|
62
|
+
<slot />
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<style>
|
|
66
|
+
.scroll-container {
|
|
67
|
+
width: var(--width);
|
|
68
|
+
height: var(--height);
|
|
69
|
+
max-width: var(--max-width);
|
|
70
|
+
max-height: var(--max-height);
|
|
71
|
+
overflow-x: var(--overflow-x);
|
|
72
|
+
overflow-y: var(--overflow-y);
|
|
73
|
+
scrollbar-color: var(--scroll-thumb-color) var(--scroll-track-color);
|
|
74
|
+
scrollbar-width: thin;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.scroll-container::-webkit-scrollbar {
|
|
78
|
+
width: var(--scrollbar-size);
|
|
79
|
+
height: var(--scrollbar-size);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.scroll-container::-webkit-scrollbar-track {
|
|
83
|
+
background: var(--scroll-track-color);
|
|
84
|
+
border-radius: var(--scroll-radius);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.scroll-container::-webkit-scrollbar-thumb {
|
|
88
|
+
background: var(--scroll-thumb-color);
|
|
89
|
+
border-radius: var(--scroll-radius);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.scroll-container::-webkit-scrollbar-thumb:hover {
|
|
93
|
+
background: var(--scroll-thumb-hover-color);
|
|
94
|
+
}
|
|
95
|
+
</style>
|