@valerius_petrini/corekit-ui 0.1.84 → 0.1.86
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/display/Accordion/AccordionItem.svelte +64 -0
- package/dist/components/display/Accordion/AccordionItem.svelte.d.ts +4 -0
- package/dist/components/display/Accordion/index.stories.svelte +26 -0
- package/dist/components/display/Accordion/index.stories.svelte.d.ts +18 -0
- package/dist/components/display/Accordion/index.svelte +43 -0
- package/dist/components/display/Accordion/index.svelte.d.ts +4 -0
- package/dist/components/display/Accordion/types.d.ts +16 -0
- package/dist/components/display/Accordion/types.js +1 -0
- package/dist/components/display/Tree/TreeNode.svelte +77 -0
- package/dist/components/display/Tree/TreeNode.svelte.d.ts +4 -0
- package/dist/components/display/Tree/index.stories.svelte +35 -0
- package/dist/components/display/Tree/index.stories.svelte.d.ts +18 -0
- package/dist/components/display/Tree/index.svelte +24 -0
- package/dist/components/display/Tree/index.svelte.d.ts +4 -0
- package/dist/components/display/Tree/types.d.ts +15 -0
- package/dist/components/display/Tree/types.js +1 -0
- package/dist/components/display/index.d.ts +6 -0
- package/dist/components/display/index.js +4 -0
- package/dist/components/inputs/Combobox/index.svelte +3 -0
- package/dist/components/inputs/Combobox/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
let counter = 0;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { getContext } from "svelte";
|
|
7
|
+
import type { AccordionItemProps, AccordionContext } from "./types.js";
|
|
8
|
+
import { Button } from "../../inputs/index.js";
|
|
9
|
+
import { slide } from "svelte/transition";
|
|
10
|
+
import ChevronRight from "@lucide/svelte/icons/chevron-right";
|
|
11
|
+
import { twMerge } from "tailwind-merge";
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
children = undefined,
|
|
15
|
+
class: className = "",
|
|
16
|
+
title = "",
|
|
17
|
+
open = $bindable(false),
|
|
18
|
+
static: isStatic = false,
|
|
19
|
+
disabled = false,
|
|
20
|
+
ontoggle = undefined,
|
|
21
|
+
id = "accordion-item-" + counter++,
|
|
22
|
+
...restProps
|
|
23
|
+
}: AccordionItemProps = $props();
|
|
24
|
+
|
|
25
|
+
const ctx = getContext<AccordionContext | undefined>('accordion');
|
|
26
|
+
|
|
27
|
+
const isOpen = $derived(ctx ? ctx.activeIds.has(id) : open);
|
|
28
|
+
|
|
29
|
+
function toggle() {
|
|
30
|
+
if (disabled || isStatic) return;
|
|
31
|
+
if (ctx)
|
|
32
|
+
ctx.setActive(id);
|
|
33
|
+
else
|
|
34
|
+
open = !open;
|
|
35
|
+
ontoggle?.(!isOpen);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const combinedClass = $derived(twMerge(
|
|
39
|
+
"w-full bg-sub-background rounded-none",
|
|
40
|
+
className
|
|
41
|
+
));
|
|
42
|
+
|
|
43
|
+
const buttonClass = $derived(twMerge(
|
|
44
|
+
"justify-start p-2 w-full gap-1 rounded-none",
|
|
45
|
+
disabled ? "cursor-not-allowed opacity-50" : "",
|
|
46
|
+
isStatic ? "cursor-default" : "",
|
|
47
|
+
isOpen ? "border-b border-b-sub-background-border" : "",
|
|
48
|
+
));
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<div class={combinedClass} {...restProps}>
|
|
52
|
+
{#if !isStatic}
|
|
53
|
+
<Button aria-controls="content-{id}" id="trigger-{id}" class={buttonClass} size="full" color="sub" onclick={toggle} aria-expanded={isOpen}>
|
|
54
|
+
<ChevronRight size={18} class="transition-transform duration-200 {isOpen ? 'rotate-90' : ''}"/>
|
|
55
|
+
{title}
|
|
56
|
+
</Button>
|
|
57
|
+
{/if}
|
|
58
|
+
|
|
59
|
+
{#if isOpen || isStatic}
|
|
60
|
+
<div id="content-{id}" role="region" class="content p-2" transition:slide={{ duration: 200 }}>
|
|
61
|
+
{@render children?.()}
|
|
62
|
+
</div>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Text from "../../typography/Text/index.svelte";
|
|
4
|
+
import Accordion from "./index.svelte";
|
|
5
|
+
import AccordionItem from "./AccordionItem.svelte";
|
|
6
|
+
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
title: "Components/Display/Accordion",
|
|
9
|
+
component: Accordion,
|
|
10
|
+
argTypes: {
|
|
11
|
+
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<Story name="Default" args={{ }}>
|
|
17
|
+
<AccordionItem title="Accordion Item 1">
|
|
18
|
+
<Text>This is the content of the first accordion item.</Text>
|
|
19
|
+
</AccordionItem>
|
|
20
|
+
<AccordionItem title="Accordion Item 2" static>
|
|
21
|
+
<Text>This is the content of the second accordion item.</Text>
|
|
22
|
+
</AccordionItem>
|
|
23
|
+
<AccordionItem title="Accordion Item 3">
|
|
24
|
+
<Text>This is the content of the third accordion item.</Text>
|
|
25
|
+
</AccordionItem>
|
|
26
|
+
</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,43 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext } from "svelte";
|
|
3
|
+
import type { AccordionProps, AccordionContext } from "./types.js";
|
|
4
|
+
import { twMerge } from "tailwind-merge";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
class: className = "",
|
|
9
|
+
exclusive = false,
|
|
10
|
+
...restProps
|
|
11
|
+
}: AccordionProps = $props();
|
|
12
|
+
|
|
13
|
+
let activeIds = $state<Set<string>>(new Set());
|
|
14
|
+
|
|
15
|
+
function setActive(id: string | null) {
|
|
16
|
+
if (!id) {
|
|
17
|
+
activeIds = new Set();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (exclusive) {
|
|
21
|
+
activeIds = activeIds.has(id) ? new Set() : new Set([id]);
|
|
22
|
+
} else {
|
|
23
|
+
const next = new Set(activeIds);
|
|
24
|
+
next.has(id) ? next.delete(id) : next.add(id);
|
|
25
|
+
activeIds = next;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setContext<AccordionContext>('accordion', {
|
|
30
|
+
get exclusive() { return exclusive; },
|
|
31
|
+
get activeIds() { return activeIds; },
|
|
32
|
+
setActive
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const combinedClass = $derived(twMerge(
|
|
36
|
+
"w-full rounded overflow-hidden divide-y divide-sub-background-border",
|
|
37
|
+
className
|
|
38
|
+
));
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<div class={combinedClass} {...restProps}>
|
|
42
|
+
{@render children?.()}
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BaseComponentProps } from "../../../types/BaseComponent";
|
|
2
|
+
export interface AccordionItemProps extends BaseComponentProps {
|
|
3
|
+
title: string;
|
|
4
|
+
open?: boolean;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
static?: boolean;
|
|
7
|
+
ontoggle?: (open: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
export interface AccordionProps extends BaseComponentProps {
|
|
10
|
+
exclusive?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface AccordionContext {
|
|
13
|
+
exclusive: boolean;
|
|
14
|
+
activeIds: Set<string>;
|
|
15
|
+
setActive: (id: string) => void;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Text from "../../typography/Text/index.svelte";
|
|
3
|
+
import { getContext, setContext } from "svelte";
|
|
4
|
+
import type { TreeNodeProps, TreeContext } from "./types.js";
|
|
5
|
+
import { slide } from "svelte/transition";
|
|
6
|
+
import ChevronRight from "@lucide/svelte/icons/chevron-right";
|
|
7
|
+
import { twMerge } from "tailwind-merge";
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
children = undefined,
|
|
11
|
+
class: className = "",
|
|
12
|
+
label = "",
|
|
13
|
+
open = $bindable(false),
|
|
14
|
+
disabled = false,
|
|
15
|
+
...restProps
|
|
16
|
+
}: TreeNodeProps = $props();
|
|
17
|
+
|
|
18
|
+
const ctx = getContext<TreeContext>('tree');
|
|
19
|
+
|
|
20
|
+
const depth = ctx.depth;
|
|
21
|
+
|
|
22
|
+
setContext<TreeContext>('tree', {
|
|
23
|
+
depth: depth + 1
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
function toggle() {
|
|
27
|
+
if (disabled || !children) return;
|
|
28
|
+
open = !open;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const combinedClass = $derived(twMerge(
|
|
32
|
+
"w-full",
|
|
33
|
+
className
|
|
34
|
+
));
|
|
35
|
+
|
|
36
|
+
const rowClass = $derived(twMerge(
|
|
37
|
+
"flex items-center gap-1 py-1 w-full text-sm",
|
|
38
|
+
disabled ? "opacity-50 cursor-not-allowed" : children ? "cursor-pointer hover:bg-sub-background" : "cursor-default",
|
|
39
|
+
));
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<li class={combinedClass} role="treeitem" aria-expanded={children ? open : undefined} {...restProps}>
|
|
43
|
+
<Text
|
|
44
|
+
class={rowClass}
|
|
45
|
+
style="padding-left: {depth * 1.25 / 2}rem"
|
|
46
|
+
onclick={toggle}
|
|
47
|
+
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && toggle()}
|
|
48
|
+
tabindex={disabled ? -1 : 0}
|
|
49
|
+
role="button">
|
|
50
|
+
<Text label="span" class="shrink-0 transition-transform duration-200 {open ? 'rotate-90' : ''} {children ? 'visible' : 'invisible'}">
|
|
51
|
+
<ChevronRight size={14} />
|
|
52
|
+
</Text>
|
|
53
|
+
{label}
|
|
54
|
+
</Text>
|
|
55
|
+
|
|
56
|
+
{#if open && children}
|
|
57
|
+
<ul class="vpcui-tree-list relative" style="--vpcui-tree-depth: {depth * 1.25}rem" role="group" transition:slide={{ duration: 200 }}>
|
|
58
|
+
{@render children()}
|
|
59
|
+
</ul>
|
|
60
|
+
{/if}
|
|
61
|
+
</li>
|
|
62
|
+
|
|
63
|
+
<style>
|
|
64
|
+
.vpcui-tree-list::before {
|
|
65
|
+
content: '';
|
|
66
|
+
position: absolute;
|
|
67
|
+
left: calc(var(--vpcui-tree-depth) / 2 + 0.375rem);
|
|
68
|
+
top: 0;
|
|
69
|
+
bottom: 0;
|
|
70
|
+
width: 1px;
|
|
71
|
+
background-color: var(--color-sub-background-border);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
:global(.vpcui-tree-list > :not(li[role="treeitem"])) {
|
|
75
|
+
padding-left: calc(var(--vpcui-tree-depth) / 2 + 1rem);
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Text from "../../typography/Text/index.svelte";
|
|
4
|
+
import Tree from "./index.svelte";
|
|
5
|
+
import TreeNode from "./TreeNode.svelte";
|
|
6
|
+
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
title: "Components/Display/Tree",
|
|
9
|
+
component: Tree,
|
|
10
|
+
argTypes: {
|
|
11
|
+
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<Story name="Default" args={{ }}>
|
|
17
|
+
<TreeNode label="Node 1">
|
|
18
|
+
<Text>This is the content of the first tree node.</Text>
|
|
19
|
+
<TreeNode label="Child Node 1">
|
|
20
|
+
<Text>This is the content of the first child node.</Text>
|
|
21
|
+
</TreeNode>
|
|
22
|
+
</TreeNode>
|
|
23
|
+
<TreeNode label="Node 2">
|
|
24
|
+
<Text>This is the content of the second tree node.</Text>
|
|
25
|
+
<TreeNode label="Child Node 2">
|
|
26
|
+
<Text>This is the content of the second child node.</Text>
|
|
27
|
+
<TreeNode label="Grandchild Node 1">
|
|
28
|
+
<Text>This is the content of the first grandchild node.</Text>
|
|
29
|
+
</TreeNode>
|
|
30
|
+
</TreeNode>
|
|
31
|
+
</TreeNode>
|
|
32
|
+
<TreeNode label="Node 3">
|
|
33
|
+
<Text>This is the content of the third tree node.</Text>
|
|
34
|
+
</TreeNode>
|
|
35
|
+
</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,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext } from "svelte";
|
|
3
|
+
import type { TreeProps, TreeContext } from "./types.js";
|
|
4
|
+
import { twMerge } from "tailwind-merge";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
class: className = "",
|
|
9
|
+
...restProps
|
|
10
|
+
}: TreeProps = $props();
|
|
11
|
+
|
|
12
|
+
setContext<TreeContext>('tree', {
|
|
13
|
+
depth: 0
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const combinedClass = $derived(twMerge(
|
|
17
|
+
"w-full",
|
|
18
|
+
className
|
|
19
|
+
));
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<ul class={combinedClass} role="tree" {...restProps}>
|
|
23
|
+
{@render children?.()}
|
|
24
|
+
</ul>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BaseComponentProps } from "../../../types/BaseComponent";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
export interface TreeProps extends BaseComponentProps {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
}
|
|
6
|
+
export interface TreeNodeProps extends BaseComponentProps {
|
|
7
|
+
label: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
open?: boolean;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
depth?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface TreeContext {
|
|
14
|
+
depth: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,6 +2,12 @@ export { default as Card } from "./Card/index.svelte";
|
|
|
2
2
|
export { default as Table } from "./Table/index.svelte";
|
|
3
3
|
export { default as KBD } from "./KBD/index.svelte";
|
|
4
4
|
export { default as Skeleton } from "./Skeleton/index.svelte";
|
|
5
|
+
export { default as Accordion } from "./Accordion/index.svelte";
|
|
6
|
+
export { default as AccordionItem } from "./Accordion/AccordionItem.svelte";
|
|
7
|
+
export { default as Tree } from "./Tree/index.svelte";
|
|
8
|
+
export { default as TreeNode } from "./Tree/TreeNode.svelte";
|
|
5
9
|
export type { CardProps } from "./Card/types.ts";
|
|
6
10
|
export type { TableProps } from "./Table/types.ts";
|
|
7
11
|
export type { SkeletonProps } from "./Skeleton/types.ts";
|
|
12
|
+
export type { AccordionProps, AccordionItemProps, AccordionContext } from "./Accordion/types.ts";
|
|
13
|
+
export type { TreeProps, TreeNodeProps, TreeContext } from "./Tree/types.ts";
|
|
@@ -2,3 +2,7 @@ export { default as Card } from "./Card/index.svelte";
|
|
|
2
2
|
export { default as Table } from "./Table/index.svelte";
|
|
3
3
|
export { default as KBD } from "./KBD/index.svelte";
|
|
4
4
|
export { default as Skeleton } from "./Skeleton/index.svelte";
|
|
5
|
+
export { default as Accordion } from "./Accordion/index.svelte";
|
|
6
|
+
export { default as AccordionItem } from "./Accordion/AccordionItem.svelte";
|
|
7
|
+
export { default as Tree } from "./Tree/index.svelte";
|
|
8
|
+
export { default as TreeNode } from "./Tree/TreeNode.svelte";
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
value = $bindable(),
|
|
28
28
|
onfocus = undefined,
|
|
29
29
|
onblur = undefined,
|
|
30
|
+
onselectitem = undefined,
|
|
30
31
|
required = false,
|
|
31
32
|
disabled = false,
|
|
32
33
|
size = "md",
|
|
@@ -79,6 +80,7 @@
|
|
|
79
80
|
value = option;
|
|
80
81
|
isFocused = false;
|
|
81
82
|
inputElement?.blur();
|
|
83
|
+
onselectitem?.(value);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
function initFloating(node: HTMLDivElement) {
|
|
@@ -152,6 +154,7 @@
|
|
|
152
154
|
if (option) {
|
|
153
155
|
value = option;
|
|
154
156
|
isFocused = false;
|
|
157
|
+
onselectitem?.(value);
|
|
155
158
|
inputElement?.blur();
|
|
156
159
|
}
|
|
157
160
|
activeIndex = 0;
|