@valerius_petrini/corekit-ui 0.1.72 → 0.1.74
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/components/feedback/Modal/index.stories.svelte +34 -0
- package/dist/components/feedback/Modal/index.stories.svelte.d.ts +18 -0
- package/dist/components/feedback/Modal/index.svelte +21 -12
- package/dist/components/inputs/Checkbox/index.svelte +5 -1
- package/dist/components/inputs/ColorInput/index.svelte +18 -13
- package/dist/components/inputs/ColorInput/types.d.ts +1 -1
- package/dist/components/inputs/Combobox/index.svelte +50 -63
- package/dist/components/inputs/FileInput/index.svelte +13 -7
- package/dist/components/inputs/FileInput/types.d.ts +1 -1
- package/dist/components/inputs/Input/index.svelte +11 -10
- package/dist/components/inputs/Select/index.svelte +5 -1
- package/dist/components/inputs/Textarea/index.stories.svelte +22 -0
- package/dist/components/inputs/Textarea/index.stories.svelte.d.ts +18 -0
- package/dist/components/inputs/Textarea/index.svelte +82 -0
- package/dist/components/inputs/Textarea/index.svelte.d.ts +4 -0
- package/dist/components/inputs/Textarea/types.d.ts +3 -0
- package/dist/components/inputs/Textarea/types.js +1 -0
- package/dist/components/inputs/helper/BaseInput.svelte +18 -19
- package/dist/components/navigation/Navbar/NavbarDropdown.svelte +72 -41
- package/dist/components/navigation/Navbar/NavbarElement.svelte +3 -4
- package/dist/components/navigation/Navbar/index.stories.svelte +29 -0
- package/dist/components/navigation/Navbar/index.stories.svelte.d.ts +18 -0
- package/dist/components/navigation/Navbar/types.d.ts +1 -0
- package/dist/components/navigation/Navbar/types.js +1 -1
- package/dist/components/navigation/SideNavbar/index.svelte +1 -1
- package/dist/styles/posititon.d.ts +1 -0
- package/dist/styles/posititon.js +11 -0
- package/dist/types/BaseComponent.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Button from "../../inputs/Button/index.svelte";
|
|
4
|
+
import Text from "../../typography/Text/index.svelte";
|
|
5
|
+
import Modal from "./index.svelte";
|
|
6
|
+
import { sizeStyles } from "../../../styles/size.js";
|
|
7
|
+
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
title: "Components/Feedback/Modal",
|
|
10
|
+
component: Modal,
|
|
11
|
+
argTypes: {
|
|
12
|
+
variant: {
|
|
13
|
+
control: "select",
|
|
14
|
+
options: ["bordered", "elevated"],
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
control: "select",
|
|
18
|
+
options: sizeStyles,
|
|
19
|
+
},
|
|
20
|
+
radius: {
|
|
21
|
+
control: "select",
|
|
22
|
+
options: sizeStyles,
|
|
23
|
+
},
|
|
24
|
+
href: { control: "text" },
|
|
25
|
+
external: { control: "boolean" },
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<Story name="Default" args={{ variant: "bordered", size: "md" }}>
|
|
31
|
+
<Text tag="h2" class="text-2xl font-bold mb-4">Customizable Modal</Text>
|
|
32
|
+
<Text class="mb-4">This is a customizable modal component. You can add any content here and style it as needed.</Text>
|
|
33
|
+
<Button href="https://example.com" target="_blank">Learn More</Button>
|
|
34
|
+
</Story>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
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> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const Index: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type Index = InstanceType<typeof Index>;
|
|
18
|
+
export default Index;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import type { ModalProps } from "./types";
|
|
3
3
|
import { fade, fly } from "svelte/transition";
|
|
4
4
|
import Card from "../../display/Card/index.svelte";
|
|
5
|
-
import {
|
|
5
|
+
import { modalPositionParts } from "../../../styles/posititon.js";
|
|
6
|
+
import { getSizeStyleClass } from "../../../styles/size.js";
|
|
6
7
|
import { twMerge } from "tailwind-merge";
|
|
7
8
|
|
|
8
9
|
let {
|
|
@@ -11,26 +12,34 @@
|
|
|
11
12
|
element = $bindable(),
|
|
12
13
|
open = $bindable(),
|
|
13
14
|
position = "center",
|
|
15
|
+
size = "md",
|
|
14
16
|
...restProps
|
|
15
17
|
}: ModalProps = $props();
|
|
16
18
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
+
const outerClass = $derived(twMerge(
|
|
20
|
+
"fixed inset-0 z-300 flex flex-col bg-black/50 p-4",
|
|
21
|
+
modalPositionParts[position]
|
|
22
|
+
));
|
|
19
23
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const combinedCardClass = $derived(twMerge(defaultCardClass, className));
|
|
24
|
+
const cardClass = $derived(twMerge(
|
|
25
|
+
"w-full max-h-[95vh] overflow-y-auto",
|
|
26
|
+
getSizeStyleClass(size, "card"),
|
|
27
|
+
className
|
|
28
|
+
));
|
|
26
29
|
</script>
|
|
27
30
|
|
|
28
31
|
{#if open}
|
|
29
32
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
30
33
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
31
|
-
<div
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
<div
|
|
35
|
+
class={outerClass}
|
|
36
|
+
transition:fade={{ duration: 200 }}
|
|
37
|
+
onclick={() => open = false}
|
|
38
|
+
bind:this={element}>
|
|
39
|
+
<div
|
|
40
|
+
transition:fly={{ y: -20, duration: 200 }}
|
|
41
|
+
onclick={(e) => e.stopPropagation()}>
|
|
42
|
+
<Card class={cardClass} {...restProps}>
|
|
34
43
|
{@render children()}
|
|
35
44
|
</Card>
|
|
36
45
|
</div>
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import { twMerge } from "tailwind-merge";
|
|
3
7
|
import Text from "../../typography/Text/index.svelte";
|
|
@@ -11,7 +15,7 @@
|
|
|
11
15
|
labelClass = "",
|
|
12
16
|
divClass = "",
|
|
13
17
|
checked = $bindable(),
|
|
14
|
-
id =
|
|
18
|
+
id = `checkbox-${count++}`,
|
|
15
19
|
...restProps
|
|
16
20
|
}: CheckboxProps = $props();
|
|
17
21
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import { getSizeStyle, getSizeStyleClass } from "../../../styles/size.js";
|
|
3
7
|
import type { ColorInputProps } from "./types";
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
size = "md",
|
|
31
35
|
radius = "md",
|
|
32
36
|
variant = "full",
|
|
33
|
-
id =
|
|
37
|
+
id = `color-input-${count++}`,
|
|
34
38
|
...restProps
|
|
35
39
|
}: ColorInputProps = $props();
|
|
36
40
|
|
|
@@ -263,12 +267,14 @@
|
|
|
263
267
|
<svelte:window onmousedown={handleMouseDown}/>
|
|
264
268
|
|
|
265
269
|
<div class={combinedOuterDivClass} bind:this={element}>
|
|
266
|
-
|
|
267
|
-
{
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
{#if label}
|
|
271
|
+
<Text tag="label" for={id} class={combinedLabelClass} style={getSizeStyle(size, "formLabel")}>
|
|
272
|
+
{label}
|
|
273
|
+
{#if required}
|
|
274
|
+
<span class="text-[#E05555]">*</span>
|
|
275
|
+
{/if}
|
|
276
|
+
</Text>
|
|
277
|
+
{/if}
|
|
272
278
|
<Button color="none" class={combinedDivClass} onclick={handleClick} {disabled}>
|
|
273
279
|
<input
|
|
274
280
|
{id}
|
|
@@ -288,7 +294,6 @@
|
|
|
288
294
|
{value ? value : "Select color"}
|
|
289
295
|
</Text>
|
|
290
296
|
</Button>
|
|
291
|
-
|
|
292
297
|
{#if isOpen}
|
|
293
298
|
{@const rgb = hexToRgb(value || "#000000")}
|
|
294
299
|
{@const hsl = hexToHsl(value || "#000000")}
|
|
@@ -305,11 +310,11 @@
|
|
|
305
310
|
style="background-color: {value || 'transparent'}; left: {thumbX}px; top: {thumbY}px;"
|
|
306
311
|
></div>
|
|
307
312
|
</div>
|
|
308
|
-
|
|
313
|
+
|
|
309
314
|
<div class="h-36 w-4 hue-slider relative" bind:this={hueEl}>
|
|
310
315
|
<div class="slider absolute w-5 h-1 border border-white shadow" style="top: {(hue / 360) * 100}%"></div>
|
|
311
316
|
</div>
|
|
312
|
-
|
|
317
|
+
|
|
313
318
|
<div class="grow flex flex-col gap-2 min-w-40">
|
|
314
319
|
<Input
|
|
315
320
|
type="text"
|
|
@@ -321,7 +326,7 @@
|
|
|
321
326
|
onkeydown={handleEnter}
|
|
322
327
|
placeholder="#ffffff"
|
|
323
328
|
/>
|
|
324
|
-
|
|
329
|
+
|
|
325
330
|
<Input
|
|
326
331
|
type="text"
|
|
327
332
|
variant="floating"
|
|
@@ -332,7 +337,7 @@
|
|
|
332
337
|
onkeydown={handleEnter}
|
|
333
338
|
placeholder="0, 0, 0"
|
|
334
339
|
/>
|
|
335
|
-
|
|
340
|
+
|
|
336
341
|
<Input
|
|
337
342
|
type="text"
|
|
338
343
|
variant="floating"
|
|
@@ -343,7 +348,7 @@
|
|
|
343
348
|
onkeydown={handleEnter}
|
|
344
349
|
placeholder="0, 0, 0"
|
|
345
350
|
/>
|
|
346
|
-
|
|
351
|
+
|
|
347
352
|
<Input
|
|
348
353
|
type="text"
|
|
349
354
|
variant="floating"
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import type { ComboboxProps } from "./types";
|
|
3
7
|
import { twMerge } from "tailwind-merge";
|
|
@@ -7,8 +11,6 @@
|
|
|
7
11
|
import BaseInput from "../helper/BaseInput.svelte";
|
|
8
12
|
import Text from "../../typography/Text/index.svelte";
|
|
9
13
|
import { fly } from "svelte/transition";
|
|
10
|
-
import { debounce } from "../../../utils/debounce.js";
|
|
11
|
-
import { tick } from "svelte";
|
|
12
14
|
|
|
13
15
|
let {
|
|
14
16
|
children = undefined,
|
|
@@ -30,43 +32,28 @@
|
|
|
30
32
|
radius = "md",
|
|
31
33
|
options = [],
|
|
32
34
|
limit = 10,
|
|
33
|
-
id =
|
|
35
|
+
id = `combobox-${count++}`,
|
|
34
36
|
...restProps
|
|
35
37
|
}: ComboboxProps = $props();
|
|
36
38
|
|
|
37
39
|
let isFocused = $state(false);
|
|
38
40
|
let activeIndex = $state(0);
|
|
39
41
|
|
|
42
|
+
let floatingEl = $state<HTMLDivElement>();
|
|
40
43
|
let dropdownX = $state(0);
|
|
41
44
|
let dropdownY = $state(0);
|
|
42
|
-
let
|
|
43
|
-
|
|
44
|
-
let debouncedSearch = $state("");
|
|
45
|
-
|
|
46
|
-
const updateSearch = debounce((v: string) => {
|
|
47
|
-
debouncedSearch = v;
|
|
48
|
-
}, 150);
|
|
49
|
-
|
|
50
|
-
$effect(() => {
|
|
51
|
-
updateSearch(value ?? "");
|
|
52
|
-
});
|
|
45
|
+
let referenceWidth = $state(0);
|
|
46
|
+
let ready = $state(false);
|
|
53
47
|
|
|
54
48
|
const sizeClasses = $derived(getSizeStyleClass(size, "form"));
|
|
55
49
|
const labelSizeClass = $derived(getSizeStyleClass(size, "formLabel"));
|
|
56
50
|
|
|
57
51
|
let inputElement = $state<HTMLInputElement>();
|
|
58
52
|
|
|
59
|
-
const customStyle = $derived
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
styles.push(`width: ${size}px`);
|
|
64
|
-
|
|
65
|
-
if (typeof radius === "number")
|
|
66
|
-
styles.push(`border-radius: ${radius}px`);
|
|
67
|
-
|
|
68
|
-
return styles.join("; ");
|
|
69
|
-
});
|
|
53
|
+
const customStyle = $derived([
|
|
54
|
+
typeof size === "number" ? `width: ${size}px` : "",
|
|
55
|
+
typeof radius === "number" ? `border-radius: ${radius}px` : "",
|
|
56
|
+
].filter(Boolean).join("; "));
|
|
70
57
|
|
|
71
58
|
function handleFocus(e: FocusEvent) {
|
|
72
59
|
isFocused = true;
|
|
@@ -80,32 +67,12 @@
|
|
|
80
67
|
onblur?.(e);
|
|
81
68
|
}
|
|
82
69
|
|
|
83
|
-
async function updateDropdownPosition() {
|
|
84
|
-
if (!element || !floatingEl) return;
|
|
85
|
-
|
|
86
|
-
referenceWidth = element.offsetWidth;
|
|
87
|
-
|
|
88
|
-
const { x, y } = await computePosition(element, floatingEl, {
|
|
89
|
-
placement: "bottom-start",
|
|
90
|
-
middleware: [
|
|
91
|
-
offset(8),
|
|
92
|
-
flip(),
|
|
93
|
-
shift({ padding: 8 })
|
|
94
|
-
]
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
dropdownX = x;
|
|
98
|
-
dropdownY = y;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
70
|
let defaultClass = "text-main-text w-full outline-none px-1.5 w-full bg-inherit border-0 focus:ring-0 focus-visible:ring-0 rounded-none";
|
|
102
71
|
|
|
103
72
|
let defaultInputClassCheck = $derived(variant !== "floating" ? "py-0" : "");
|
|
104
73
|
let combinedClass = $derived(twMerge(defaultClass, sizeClasses, defaultInputClassCheck, labelSizeClass, className));
|
|
105
74
|
let combinedDivClass = $derived(twMerge(divClass));
|
|
106
75
|
|
|
107
|
-
let referenceWidth = $state(0);
|
|
108
|
-
|
|
109
76
|
function onClickItem(event: MouseEvent, option: string) {
|
|
110
77
|
event.preventDefault();
|
|
111
78
|
value = option;
|
|
@@ -113,6 +80,36 @@
|
|
|
113
80
|
inputElement?.blur();
|
|
114
81
|
}
|
|
115
82
|
|
|
83
|
+
function initFloating(node: HTMLDivElement) {
|
|
84
|
+
if (!element) return {};
|
|
85
|
+
|
|
86
|
+
let cleanup: (() => void) | null = null;
|
|
87
|
+
|
|
88
|
+
async function updatePosition() {
|
|
89
|
+
referenceWidth = element!.offsetWidth;
|
|
90
|
+
|
|
91
|
+
const { x, y } = await computePosition(element!, node, {
|
|
92
|
+
placement: "bottom-start",
|
|
93
|
+
middleware: [offset(8), flip(), shift({ padding: 8 })]
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
dropdownX = x;
|
|
97
|
+
dropdownY = y;
|
|
98
|
+
ready = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
updatePosition().then(() => {
|
|
102
|
+
cleanup = autoUpdate(element!, node, updatePosition);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
destroy() {
|
|
107
|
+
cleanup?.();
|
|
108
|
+
ready = false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
116
113
|
function highlight(label: string, search: string) {
|
|
117
114
|
const index = label.toLowerCase().indexOf(search.toLowerCase());
|
|
118
115
|
if (index === -1) return escapeHtml(label);
|
|
@@ -130,7 +127,7 @@
|
|
|
130
127
|
|
|
131
128
|
let filteredOptions = $derived(
|
|
132
129
|
options.filter(option =>
|
|
133
|
-
option.toLowerCase().includes(
|
|
130
|
+
option.toLowerCase().includes(value?.toLowerCase() ?? ""))
|
|
134
131
|
);
|
|
135
132
|
|
|
136
133
|
let validOptions = $derived(filteredOptions.slice(0, limit));
|
|
@@ -172,17 +169,6 @@
|
|
|
172
169
|
|
|
173
170
|
let optionsContainerElement = $state<HTMLDivElement>();
|
|
174
171
|
|
|
175
|
-
$effect(() => {
|
|
176
|
-
if (isFocused && element && floatingEl) {
|
|
177
|
-
const cleanup = autoUpdate(
|
|
178
|
-
element,
|
|
179
|
-
floatingEl,
|
|
180
|
-
updateDropdownPosition
|
|
181
|
-
);
|
|
182
|
-
return () => cleanup();
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
|
|
186
172
|
function handleMouseDown(e: MouseEvent) {
|
|
187
173
|
if (
|
|
188
174
|
isFocused &&
|
|
@@ -236,24 +222,25 @@
|
|
|
236
222
|
{#snippet outerDivElementAfter()}
|
|
237
223
|
{#if isFocused}
|
|
238
224
|
<div
|
|
239
|
-
|
|
240
|
-
transition:fly={{ y: -10, duration: 200 }}
|
|
225
|
+
use:initFloating
|
|
241
226
|
style="position: fixed; top: {dropdownY}px; left: {dropdownX}px; width: {referenceWidth}px;"
|
|
242
|
-
|
|
227
|
+
style:visibility={ready ? "visible" : "hidden"}
|
|
228
|
+
transition:fly={{ y: -10, duration: 200 }}
|
|
229
|
+
class="z-999999 overflow-hidden border border-white/10 bg-sub-background shadow-xl shadow-black/40 {getSizeStyleClass(radius, 'radius')}"
|
|
243
230
|
>
|
|
244
231
|
{#if totalMatches > 0 && options.length > limit}
|
|
245
|
-
<Text class="text-xs py-
|
|
232
|
+
<Text class="text-xs py-1.5 px-2.5 text-sub-text italic sticky top-0 bg-sub-background w-full">
|
|
246
233
|
Showing {limit} of {totalMatches} results for "{value}"
|
|
247
234
|
</Text>
|
|
248
235
|
{/if}
|
|
249
236
|
{#if totalMatches === 0}
|
|
250
|
-
<Text class="text-xs py-
|
|
237
|
+
<Text class="text-xs py-1.5 px-2.5 text-sub-text italic sticky top-0 bg-sub-background w-full">
|
|
251
238
|
No results found for "{value}"
|
|
252
239
|
</Text>
|
|
253
240
|
{/if}
|
|
254
241
|
<div bind:this={optionsContainerElement} class="overflow-auto max-h-40">
|
|
255
242
|
{#each validOptions as option, index}
|
|
256
|
-
<Text class="text-sm py-
|
|
243
|
+
<Text class="text-sm py-1.5 px-2.5 cursor-pointer hover:bg-white/5 transition-colors {activeIndex === index ? 'bg-white/5' : ''}" onmousedown={(e: MouseEvent) => onClickItem(e, option)}>
|
|
257
244
|
{@html highlight(option, value ?? "")}
|
|
258
245
|
</Text>
|
|
259
246
|
{/each}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import { getSizeStyle, getSizeStyleClass } from "../../../styles/size.js";
|
|
3
7
|
import type { FileInputProps } from "./types";
|
|
@@ -22,7 +26,7 @@
|
|
|
22
26
|
disabled = false,
|
|
23
27
|
size = "md",
|
|
24
28
|
radius = "md",
|
|
25
|
-
id =
|
|
29
|
+
id = `file-input-${count++}`,
|
|
26
30
|
...restProps
|
|
27
31
|
}: FileInputProps = $props();
|
|
28
32
|
|
|
@@ -77,12 +81,14 @@
|
|
|
77
81
|
</script>
|
|
78
82
|
|
|
79
83
|
<div class={combinedOuterDivClass} bind:this={element}>
|
|
80
|
-
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
{#if label}
|
|
85
|
+
<Text tag="label" for={id} class={combinedLabelClass} style={getSizeStyle(size, "formLabel")}>
|
|
86
|
+
{label}
|
|
87
|
+
{#if required}
|
|
88
|
+
<span class="text-[#E05555]">*</span>
|
|
89
|
+
{/if}
|
|
90
|
+
</Text>
|
|
91
|
+
{/if}
|
|
86
92
|
<Button color="none" class={combinedDivClass} onclick={handleClick} {disabled}>
|
|
87
93
|
<div class={iconContainerClass}>
|
|
88
94
|
<Icon class={iconClass}></Icon>
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import type { InputProps } from "./types";
|
|
3
7
|
import { twMerge } from "tailwind-merge";
|
|
@@ -37,7 +41,7 @@
|
|
|
37
41
|
valid = $bindable(true),
|
|
38
42
|
size = "md",
|
|
39
43
|
radius = "md",
|
|
40
|
-
id =
|
|
44
|
+
id = `input-${count++}`,
|
|
41
45
|
min = undefined,
|
|
42
46
|
max = undefined,
|
|
43
47
|
step = undefined,
|
|
@@ -85,11 +89,15 @@
|
|
|
85
89
|
onblur?.(e);
|
|
86
90
|
}
|
|
87
91
|
|
|
92
|
+
const isValid = $derived(
|
|
93
|
+
(requirements ?? []).every(req => testRequirement(req.requirements))
|
|
94
|
+
);
|
|
95
|
+
|
|
88
96
|
let inputClassIcon = $derived(Icon !== null ? "pl-0 pr-1" : "");
|
|
89
97
|
|
|
90
98
|
let defaultInputClassCheck = $derived(variant !== "floating" ? "py-0" : "");
|
|
91
99
|
let combinedClass = $derived(twMerge(defaultClass, sizeClasses, defaultInputClassCheck, labelSizeClass, inputClassIcon, className));
|
|
92
|
-
let combinedDivClass = $derived(twMerge(divClass, (!
|
|
100
|
+
let combinedDivClass = $derived(twMerge(divClass, (!isValid && touched) && invalidClass));
|
|
93
101
|
|
|
94
102
|
let EyeComponent = $derived(canSeePassword ? Eye : EyeOff);
|
|
95
103
|
|
|
@@ -101,15 +109,8 @@
|
|
|
101
109
|
return true;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
function isValidInput() {
|
|
105
|
-
for (const requirement of requirements || [])
|
|
106
|
-
if (!testRequirement(requirement.requirements))
|
|
107
|
-
return false;
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
112
|
$effect(() => {
|
|
112
|
-
valid =
|
|
113
|
+
valid = isValid;
|
|
113
114
|
});
|
|
114
115
|
</script>
|
|
115
116
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import { twMerge } from "tailwind-merge";
|
|
3
7
|
import { getSizeStyleClass } from "../../../styles/size";
|
|
@@ -20,7 +24,7 @@
|
|
|
20
24
|
disabled = false,
|
|
21
25
|
size = "md",
|
|
22
26
|
radius = "md",
|
|
23
|
-
id =
|
|
27
|
+
id = `select-${count++}`,
|
|
24
28
|
...restProps
|
|
25
29
|
}: SelectProps = $props();
|
|
26
30
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Textarea from "./index.svelte";
|
|
4
|
+
import { sizeStyles } from "../../../styles/size.js";
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: "Components/Inputs/Textarea",
|
|
8
|
+
component: Textarea,
|
|
9
|
+
argTypes: {
|
|
10
|
+
size: {
|
|
11
|
+
control: "select",
|
|
12
|
+
options: sizeStyles,
|
|
13
|
+
},
|
|
14
|
+
radius: {
|
|
15
|
+
control: "select",
|
|
16
|
+
options: sizeStyles,
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<Story name="Default" args={{ label: "Input Label", placeholder: "Enter text here..." }}></Story>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
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> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const Index: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type Index = InstanceType<typeof Index>;
|
|
18
|
+
export default Index;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import type { TextareaProps } from "./types";
|
|
7
|
+
import { twMerge } from "tailwind-merge";
|
|
8
|
+
import { getSizeStyleClass } from "../../../styles/size.js";
|
|
9
|
+
|
|
10
|
+
import BaseInput from "../helper/BaseInput.svelte";
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
children = undefined,
|
|
14
|
+
class: className = "",
|
|
15
|
+
element = $bindable(),
|
|
16
|
+
label = "",
|
|
17
|
+
labelClass = "",
|
|
18
|
+
divClass = "",
|
|
19
|
+
outerDivClass = "",
|
|
20
|
+
icon = undefined,
|
|
21
|
+
placeholder = "",
|
|
22
|
+
value = $bindable(),
|
|
23
|
+
required = false,
|
|
24
|
+
disabled = false,
|
|
25
|
+
size = "md",
|
|
26
|
+
radius = "md",
|
|
27
|
+
id = `textarea-${count++}`,
|
|
28
|
+
...restProps
|
|
29
|
+
}: TextareaProps = $props();
|
|
30
|
+
|
|
31
|
+
const sizeClasses = $derived(getSizeStyleClass(size, "form"));
|
|
32
|
+
const labelSizeClass = $derived(getSizeStyleClass(size, "formLabel"));
|
|
33
|
+
|
|
34
|
+
const customStyle = $derived.by(() => {
|
|
35
|
+
const styles: string[] = [];
|
|
36
|
+
|
|
37
|
+
if (typeof size === "number")
|
|
38
|
+
styles.push(`width: ${size}px`);
|
|
39
|
+
|
|
40
|
+
if (typeof radius === "number")
|
|
41
|
+
styles.push(`border-radius: ${radius}px`);
|
|
42
|
+
|
|
43
|
+
return styles.join("; ");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
let defaultClass = "text-main-text w-full outline-none px-1.5 w-full bg-inherit border-0 focus:ring-0 focus-visible:ring-0 rounded-none py-2.5!";
|
|
47
|
+
|
|
48
|
+
let combinedClass = $derived(twMerge(defaultClass, sizeClasses, labelSizeClass, className));
|
|
49
|
+
let combinedDivClass = $derived(twMerge(divClass));
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<BaseInput
|
|
53
|
+
{children}
|
|
54
|
+
{className}
|
|
55
|
+
{label}
|
|
56
|
+
{labelClass}
|
|
57
|
+
divClass={combinedDivClass}
|
|
58
|
+
{outerDivClass}
|
|
59
|
+
{value}
|
|
60
|
+
{required}
|
|
61
|
+
{disabled}
|
|
62
|
+
{size}
|
|
63
|
+
{radius}
|
|
64
|
+
{id}
|
|
65
|
+
bind:wrapper={element}
|
|
66
|
+
{...restProps}>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
{#snippet innerDivElement()}
|
|
70
|
+
<textarea
|
|
71
|
+
{id}
|
|
72
|
+
bind:value={value}
|
|
73
|
+
class={combinedClass}
|
|
74
|
+
{required}
|
|
75
|
+
{disabled}
|
|
76
|
+
placeholder={placeholder}
|
|
77
|
+
aria-disabled={disabled}
|
|
78
|
+
style={customStyle}
|
|
79
|
+
{...restProps}></textarea>
|
|
80
|
+
{/snippet}
|
|
81
|
+
</BaseInput>
|
|
82
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let count = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script lang="ts">
|
|
2
6
|
import { twMerge } from "tailwind-merge";
|
|
3
7
|
import type { BaseInputProps } from "../../../types/BaseComponent";
|
|
@@ -20,7 +24,7 @@
|
|
|
20
24
|
isFocused = false,
|
|
21
25
|
icon = undefined,
|
|
22
26
|
wrapper = $bindable(),
|
|
23
|
-
id =
|
|
27
|
+
id = `base-input-${count++}`,
|
|
24
28
|
|
|
25
29
|
innerDivElement = undefined,
|
|
26
30
|
outerDivElementAfter = undefined,
|
|
@@ -30,14 +34,9 @@
|
|
|
30
34
|
|
|
31
35
|
const hasContent = $derived(value !== undefined && value !== null && value.toString().length > 0);
|
|
32
36
|
|
|
33
|
-
const customLabelStyle = $derived
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (typeof size === "number")
|
|
37
|
-
styles.push(`font-size: ${size / 4}px`);
|
|
38
|
-
|
|
39
|
-
return styles.join("; ");
|
|
40
|
-
});
|
|
37
|
+
const customLabelStyle = $derived(
|
|
38
|
+
typeof size === "number" ? `font-size: ${size / 4}px` : ""
|
|
39
|
+
);
|
|
41
40
|
|
|
42
41
|
let labelClassIcon = $derived(icon != null && variant === "floating" ? "pl-[32px] pr-2" : "");
|
|
43
42
|
|
|
@@ -62,21 +61,21 @@
|
|
|
62
61
|
));
|
|
63
62
|
|
|
64
63
|
const combinedDivClass = $derived(twMerge(
|
|
65
|
-
"vpcui-base-input-div-class relative *:transition-all transition-colors flex-center bg-form-background border
|
|
64
|
+
"vpcui-base-input-div-class relative *:transition-all transition-colors flex-center bg-form-background border border-form-border focus-within:border-blue-400/40 overflow-hidden",
|
|
66
65
|
getSizeStyleClass(radius, "radius"),
|
|
67
|
-
|
|
68
|
-
divClass,
|
|
69
|
-
disabled ? "opacity-50 pointer-events-none" : ""
|
|
66
|
+
divClass
|
|
70
67
|
));
|
|
71
68
|
</script>
|
|
72
69
|
|
|
73
70
|
{#snippet labelElement()}
|
|
74
|
-
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
{#if label}
|
|
72
|
+
<Text tag="label" for={id} class={combinedLabelClass} style={customLabelStyle}>
|
|
73
|
+
{label}
|
|
74
|
+
{#if required}
|
|
75
|
+
<span class="text-[#E05555]">*</span>
|
|
76
|
+
{/if}
|
|
77
|
+
</Text>
|
|
78
|
+
{/if}
|
|
80
79
|
{/snippet}
|
|
81
80
|
|
|
82
81
|
{#snippet innerDivElementWrapper()}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { fly } from "svelte/transition";
|
|
3
3
|
import NavbarElement from "./NavbarElement.svelte";
|
|
4
|
-
import { tick } from "svelte";
|
|
5
4
|
import type { NavbarDropdownProps } from "./types.js";
|
|
5
|
+
import {
|
|
6
|
+
computePosition,
|
|
7
|
+
flip,
|
|
8
|
+
shift,
|
|
9
|
+
offset,
|
|
10
|
+
autoUpdate,
|
|
11
|
+
type Placement,
|
|
12
|
+
} from "@floating-ui/dom";
|
|
13
|
+
import { tick } from "svelte";
|
|
6
14
|
|
|
7
15
|
let {
|
|
8
|
-
children = undefined,
|
|
9
|
-
class: className = "",
|
|
16
|
+
children = undefined,
|
|
17
|
+
class: className = "",
|
|
10
18
|
element = $bindable(),
|
|
11
19
|
wrapperClass = "",
|
|
12
20
|
label = "",
|
|
@@ -15,69 +23,92 @@
|
|
|
15
23
|
}: NavbarDropdownProps = $props();
|
|
16
24
|
|
|
17
25
|
let open = $state(false);
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
let
|
|
21
|
-
let
|
|
26
|
+
let x = $state(0);
|
|
27
|
+
let y = $state(0);
|
|
28
|
+
let resolvedPlacement: Placement = $state("bottom-start");
|
|
29
|
+
let ready = $state(false);
|
|
30
|
+
|
|
31
|
+
const flyParams = $derived(
|
|
32
|
+
resolvedPlacement.startsWith("top")
|
|
33
|
+
? { y: 5, duration: 150 }
|
|
34
|
+
: { y: -5, duration: 150 }
|
|
35
|
+
);
|
|
22
36
|
|
|
23
|
-
function
|
|
24
|
-
if (!
|
|
37
|
+
function initDropdown(node: HTMLElement) {
|
|
38
|
+
if (!element) return {};
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
let cleanup: (() => void) | null = null;
|
|
27
41
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
async function updatePosition() {
|
|
43
|
+
const { x: fx, y: fy, placement } = await computePosition(element!, node, {
|
|
44
|
+
placement: "bottom-start",
|
|
45
|
+
middleware: [offset(4), flip(), shift({ padding: 12 })],
|
|
46
|
+
});
|
|
47
|
+
x = fx;
|
|
48
|
+
y = fy;
|
|
49
|
+
resolvedPlacement = placement;
|
|
50
|
+
ready = true;
|
|
51
|
+
}
|
|
31
52
|
|
|
32
|
-
|
|
53
|
+
updatePosition().then(() => {
|
|
54
|
+
cleanup = autoUpdate(element!, node, updatePosition);
|
|
55
|
+
});
|
|
33
56
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
return {
|
|
58
|
+
destroy() {
|
|
59
|
+
cleanup?.();
|
|
60
|
+
ready = false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
async function toggle() {
|
|
43
|
-
open = !open;
|
|
44
66
|
if (open) {
|
|
45
|
-
|
|
46
|
-
calculateOverflow();
|
|
67
|
+
open = false;
|
|
47
68
|
} else {
|
|
48
|
-
|
|
69
|
+
ready = false;
|
|
70
|
+
open = true;
|
|
49
71
|
}
|
|
50
72
|
}
|
|
51
73
|
|
|
52
74
|
function handleClickOutside(event: MouseEvent) {
|
|
53
|
-
|
|
75
|
+
const target = event.target as Node;
|
|
76
|
+
if (element && !element.contains(target))
|
|
54
77
|
open = false;
|
|
55
|
-
offsetX = 0;
|
|
56
|
-
}
|
|
57
78
|
}
|
|
58
79
|
</script>
|
|
59
80
|
|
|
60
|
-
<svelte:window onclick={handleClickOutside}/>
|
|
81
|
+
<svelte:window onclick={handleClickOutside} />
|
|
61
82
|
|
|
62
|
-
<div class="relative
|
|
63
|
-
<NavbarElement
|
|
83
|
+
<div class="relative h-full {wrapperClass}" bind:this={element}>
|
|
84
|
+
<NavbarElement
|
|
85
|
+
onclick={toggle}
|
|
86
|
+
class={className}
|
|
87
|
+
{...restProps}
|
|
88
|
+
aria-haspopup="true"
|
|
89
|
+
aria-expanded={open}
|
|
90
|
+
>
|
|
64
91
|
{label}
|
|
65
92
|
{#if navelement}
|
|
66
93
|
{@render navelement()}
|
|
67
94
|
{/if}
|
|
68
95
|
</NavbarElement>
|
|
96
|
+
</div>
|
|
69
97
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
98
|
+
{#if open}
|
|
99
|
+
<div
|
|
100
|
+
use:initDropdown
|
|
101
|
+
style="position: fixed; top: {y}px; left: {x}px;"
|
|
102
|
+
class="z-100 shadow-lg"
|
|
103
|
+
style:visibility={ready ? "visible" : "hidden"}
|
|
104
|
+
>
|
|
105
|
+
<div
|
|
106
|
+
transition:fly={flyParams}
|
|
107
|
+
class="bg-sub-background p-2 min-w-max flex flex-col *:px-0 rounded border-sub-background-hover border"
|
|
108
|
+
>
|
|
109
|
+
<button onclick={() => (open = false)} class="contents">
|
|
79
110
|
{@render children?.()}
|
|
80
111
|
</button>
|
|
81
112
|
</div>
|
|
82
|
-
|
|
83
|
-
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { twMerge } from "tailwind-merge";
|
|
3
3
|
import Button from "../../inputs/Button/index.svelte";
|
|
4
4
|
import type { NavbarElementProps } from "./types";
|
|
5
|
-
import { page } from "$app/state";
|
|
6
5
|
|
|
7
6
|
let {
|
|
8
7
|
children = undefined,
|
|
@@ -10,6 +9,7 @@
|
|
|
10
9
|
element = $bindable(),
|
|
11
10
|
classTop = "",
|
|
12
11
|
activeClass = "",
|
|
12
|
+
active = false,
|
|
13
13
|
href = undefined,
|
|
14
14
|
threshold = 10,
|
|
15
15
|
...restProps
|
|
@@ -19,18 +19,17 @@
|
|
|
19
19
|
|
|
20
20
|
let scrollY = $state(0);
|
|
21
21
|
let isAtTop = $derived(scrollY <= threshold);
|
|
22
|
-
let isActive = $derived(page.url.pathname === href);
|
|
23
22
|
|
|
24
23
|
const combinedClass = $derived(twMerge(
|
|
25
24
|
defaultClass,
|
|
26
25
|
className,
|
|
27
|
-
|
|
26
|
+
active ? activeClass : "",
|
|
28
27
|
isAtTop ? classTop : "",
|
|
29
28
|
));
|
|
30
29
|
</script>
|
|
31
30
|
|
|
32
31
|
<svelte:window bind:scrollY={scrollY}/>
|
|
33
32
|
|
|
34
|
-
<Button bind:element radius="none" {href} color="
|
|
33
|
+
<Button bind:element radius="none" {href} color="sub" class={combinedClass} {...restProps} aria-current={active ? 'page' : undefined}>
|
|
35
34
|
{@render children?.()}
|
|
36
35
|
</Button>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Navbar from "./index.svelte";
|
|
4
|
+
import NavbarElement from "./NavbarElement.svelte";
|
|
5
|
+
import NavbarSeparator from "./NavbarSeparator.svelte";
|
|
6
|
+
import NavbarDropdown from "./NavbarDropdown.svelte";
|
|
7
|
+
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
title: "Components/Navigation/Navbar",
|
|
10
|
+
component: Navbar,
|
|
11
|
+
argTypes: {
|
|
12
|
+
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<Story name="Default" args={{ color: "primary", size: "md" }}>
|
|
18
|
+
<NavbarElement href="/">Home</NavbarElement>
|
|
19
|
+
<NavbarElement href="/library">Library</NavbarElement>
|
|
20
|
+
<NavbarElement>Data</NavbarElement>
|
|
21
|
+
|
|
22
|
+
<NavbarSeparator/>
|
|
23
|
+
|
|
24
|
+
<NavbarDropdown label="More">
|
|
25
|
+
<NavbarElement href="/about">About</NavbarElement>
|
|
26
|
+
<NavbarSeparator variant="horizontal"/>
|
|
27
|
+
<NavbarElement href="/contact">Contact</NavbarElement>
|
|
28
|
+
</NavbarDropdown>
|
|
29
|
+
</Story>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
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> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const Index: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type Index = InstanceType<typeof Index>;
|
|
18
|
+
export default Index;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
;
|
|
2
2
|
export const NavbarSeparatorClasses = {
|
|
3
3
|
"vertical": "w-0.5 h-full py-3 bg-sub-background-hover bg-clip-content",
|
|
4
|
-
"horizontal": "h-0.5 w-full
|
|
4
|
+
"horizontal": "h-0.5 w-full my-1 bg-sub-background-hover bg-clip-content",
|
|
5
5
|
"dynamic": "ml-auto"
|
|
6
6
|
};
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<nav class={combinedClass} {...restProps} onmouseenter={() => expanded = true} onmouseleave={() => expanded = false} bind:this={element}>
|
|
29
29
|
{#each items as item}
|
|
30
30
|
{@const isActive = page.url.pathname === item.href}
|
|
31
|
-
<Button size="xs" class="{isActive ? 'bg-form-background text-main-text' : 'text-sub-text'} hover:text-main-text py-1 text-nowrap flex justify-start gap-2 overflow-hidden mx-1 w-[calc(100%-16px)] hover:bg-form-background px-1.5" href={item.href}>
|
|
31
|
+
<Button size="xs" color="none" class="{isActive ? 'bg-form-background text-main-text' : 'text-sub-text'} hover:text-main-text py-1 text-nowrap flex justify-start gap-2 overflow-hidden mx-1 w-[calc(100%-16px)] hover:bg-form-background px-1.5" href={item.href}>
|
|
32
32
|
<item.icon class="w-5 h-5 shrink-0"/>
|
|
33
33
|
<Text tag="span" class="transition-opacity duration-200 text-sm text-inherit {expanded ? 'w-auto opacity-100 pr-3' : 'w-0 opacity-0'}">
|
|
34
34
|
{item.label}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type PositionStyle = "top" | "right" | "bottom" | "left" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "center";
|
|
2
2
|
export type TooltipPosition = "top" | "right" | "bottom" | "left";
|
|
3
3
|
export declare const positionParts: Record<PositionStyle, string>;
|
|
4
|
+
export declare const modalPositionParts: Record<PositionStyle, string>;
|
package/dist/styles/posititon.js
CHANGED
|
@@ -9,3 +9,14 @@ export const positionParts = {
|
|
|
9
9
|
"bottom-right": "bottom-4 right-4",
|
|
10
10
|
"center": "top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
|
11
11
|
};
|
|
12
|
+
export const modalPositionParts = {
|
|
13
|
+
"center": "items-center justify-center",
|
|
14
|
+
"top": "items-center justify-start pt-4",
|
|
15
|
+
"bottom": "items-center justify-end pb-4",
|
|
16
|
+
"left": "items-start justify-center pl-4",
|
|
17
|
+
"right": "items-end justify-center pr-4",
|
|
18
|
+
"top-left": "items-start justify-start p-4",
|
|
19
|
+
"top-right": "items-end justify-start p-4",
|
|
20
|
+
"bottom-left": "items-start justify-end p-4",
|
|
21
|
+
"bottom-right": "items-end justify-end p-4",
|
|
22
|
+
};
|