nuance-ui 0.1.8 → 0.1.9
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/module.json +1 -1
- package/dist/runtime/components/action-icon/action-icon.d.vue.ts +1 -0
- package/dist/runtime/components/action-icon/action-icon.vue.d.ts +1 -0
- package/dist/runtime/components/alert.d.vue.ts +48 -0
- package/dist/runtime/components/alert.vue +178 -0
- package/dist/runtime/components/alert.vue.d.ts +48 -0
- package/dist/runtime/components/app-shell/app-shell-main.vue +1 -0
- package/dist/runtime/components/button/button.d.vue.ts +1 -0
- package/dist/runtime/components/button/button.vue.d.ts +1 -0
- package/dist/runtime/components/index.d.ts +1 -0
- package/dist/runtime/components/index.js +1 -0
- package/dist/runtime/components/input/number-input.vue +12 -16
- package/dist/runtime/components/input/ui/input-base.d.vue.ts +3 -3
- package/dist/runtime/components/input/ui/input-base.vue +2 -2
- package/dist/runtime/components/input/ui/input-base.vue.d.ts +3 -3
- package/dist/runtime/components/nav-link/nav-link.vue +10 -10
- package/dist/runtime/components/progress/index.d.ts +3 -0
- package/dist/runtime/components/progress/index.js +0 -0
- package/dist/runtime/components/progress/progress-label.d.vue.ts +14 -0
- package/dist/runtime/components/progress/progress-label.vue +14 -0
- package/dist/runtime/components/progress/progress-label.vue.d.ts +14 -0
- package/dist/runtime/components/progress/progress-root.d.vue.ts +25 -0
- package/dist/runtime/components/progress/progress-root.vue +31 -0
- package/dist/runtime/components/progress/progress-root.vue.d.ts +25 -0
- package/dist/runtime/components/progress/progress-section.d.vue.ts +25 -0
- package/dist/runtime/components/progress/progress-section.vue +42 -0
- package/dist/runtime/components/progress/progress-section.vue.d.ts +25 -0
- package/dist/runtime/components/progress/progress.d.vue.ts +16 -0
- package/dist/runtime/components/progress/progress.module.css +1 -0
- package/dist/runtime/components/progress/progress.vue +39 -0
- package/dist/runtime/components/progress/progress.vue.d.ts +16 -0
- package/dist/runtime/components/tree/_ui/tree-item.vue +8 -7
- package/dist/runtime/components/tree/_ui/tree-root.d.vue.ts +11 -5
- package/dist/runtime/components/tree/_ui/tree-root.vue +15 -5
- package/dist/runtime/components/tree/_ui/tree-root.vue.d.ts +11 -5
- package/dist/runtime/components/tree/lib/context.d.ts +9 -1
- package/dist/runtime/components/tree/lib/context.js +16 -15
- package/dist/runtime/components/tree/tree.vue +15 -5
- package/dist/runtime/styles/colors.css +1 -1
- package/dist/runtime/styles/light-theme.css +1 -1
- package/dist/runtime/utils/tree.d.ts +19 -0
- package/dist/runtime/utils/tree.js +16 -16
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BoxProps } from '@nui/components';
|
|
2
|
+
import type { NuanceColor } from '@nui/types';
|
|
3
|
+
export interface ProgressSectionProps extends BoxProps {
|
|
4
|
+
/** Determines whether `aria-*` props should be added to the root element @default `true` */
|
|
5
|
+
withAria?: boolean;
|
|
6
|
+
/** Key of `theme.colors` or any valid CSS value @default `theme.primaryColor` */
|
|
7
|
+
color?: NuanceColor;
|
|
8
|
+
/** If set, the section has stripes @default `false` */
|
|
9
|
+
striped?: boolean;
|
|
10
|
+
/** If set, the sections stripes are animated, `striped` prop is ignored @default `false` */
|
|
11
|
+
animated?: boolean;
|
|
12
|
+
}
|
|
13
|
+
type __VLS_Props = ProgressSectionProps;
|
|
14
|
+
type __VLS_ModelProps = {
|
|
15
|
+
/** Value of the section in 0–100 range */
|
|
16
|
+
modelValue: number;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
19
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
20
|
+
"update:modelValue": (value: number) => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
22
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
23
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useStyleResolver } from "@nui/composals";
|
|
3
|
+
import { getThemeColor } from "@nui/utils";
|
|
4
|
+
import { computed } from "vue";
|
|
5
|
+
import Box from "../box.vue";
|
|
6
|
+
import css from "./progress.module.css";
|
|
7
|
+
const {
|
|
8
|
+
withAria,
|
|
9
|
+
animated,
|
|
10
|
+
striped,
|
|
11
|
+
color,
|
|
12
|
+
mod
|
|
13
|
+
} = defineProps({
|
|
14
|
+
withAria: { type: Boolean, required: false },
|
|
15
|
+
color: { type: null, required: false },
|
|
16
|
+
striped: { type: Boolean, required: false },
|
|
17
|
+
animated: { type: Boolean, required: false },
|
|
18
|
+
is: { type: null, required: false },
|
|
19
|
+
mod: { type: [Object, Array, null], required: false }
|
|
20
|
+
});
|
|
21
|
+
const value = defineModel({ type: Number, ...{ required: true } });
|
|
22
|
+
const ariaAttributes = computed(() => withAria ? {
|
|
23
|
+
"role": "progressbar",
|
|
24
|
+
"aria-valuemax": 100,
|
|
25
|
+
"aria-valuemin": 0,
|
|
26
|
+
"aria-valuenow": value.value,
|
|
27
|
+
"aria-valuetext": `${value.value}%`
|
|
28
|
+
} : {});
|
|
29
|
+
const style = computed(() => useStyleResolver((theme) => ({
|
|
30
|
+
"--progress-section-size": `${value.value}%`,
|
|
31
|
+
"--progress-section-color": getThemeColor(color, theme)
|
|
32
|
+
})));
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<Box
|
|
37
|
+
:style
|
|
38
|
+
v-bind='ariaAttributes'
|
|
39
|
+
:class='css.section'
|
|
40
|
+
:mod='[{ striped: striped || animated, animated }, mod]'
|
|
41
|
+
/>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BoxProps } from '@nui/components';
|
|
2
|
+
import type { NuanceColor } from '@nui/types';
|
|
3
|
+
export interface ProgressSectionProps extends BoxProps {
|
|
4
|
+
/** Determines whether `aria-*` props should be added to the root element @default `true` */
|
|
5
|
+
withAria?: boolean;
|
|
6
|
+
/** Key of `theme.colors` or any valid CSS value @default `theme.primaryColor` */
|
|
7
|
+
color?: NuanceColor;
|
|
8
|
+
/** If set, the section has stripes @default `false` */
|
|
9
|
+
striped?: boolean;
|
|
10
|
+
/** If set, the sections stripes are animated, `striped` prop is ignored @default `false` */
|
|
11
|
+
animated?: boolean;
|
|
12
|
+
}
|
|
13
|
+
type __VLS_Props = ProgressSectionProps;
|
|
14
|
+
type __VLS_ModelProps = {
|
|
15
|
+
/** Value of the section in 0–100 range */
|
|
16
|
+
modelValue: number;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
19
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
20
|
+
"update:modelValue": (value: number) => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
22
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
23
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ProgressRootProps } from './progress-root.vue.js';
|
|
2
|
+
import type { ProgressSectionProps } from './progress-section.vue.js';
|
|
3
|
+
export interface ProgressProps extends ProgressRootProps, ProgressSectionProps {
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = ProgressProps;
|
|
6
|
+
type __VLS_ModelProps = {
|
|
7
|
+
modelValue: number;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
"update:modelValue": (value: number) => any;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
13
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
14
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.root{--progress-radius:var(--radius-default);--progress-size:var(--progress-size-md);--progress-size-xs:rem(8px);--progress-size-sm:rem(12px);--progress-size-md:rem(16px);--progress-size-lg:rem(20px);--progress-size-xl:rem(24px);border-radius:var(--progress-radius);display:flex;height:var(--progress-size);overflow:hidden;position:relative;@mixin where-light{background-color:var(--color-gray-2)}@mixin where-dark{background-color:var(--color-dark-4)}}.root:where([data-orientation=vertical]){flex-direction:column-reverse;height:auto;width:var(--progress-size)}.section{--progress-section-size:var(--progress-size-sm);--progress-section-color:var(--color-primary-4);--progress-transition-duration:100ms;align-items:center;background-color:var(--progress-section-color);background-size:20px 20px;display:flex;height:100%;justify-content:center;overflow:hidden;transition:width var(--progress-transition-duration) ease;width:var(--progress-section-size)}.section:where([data-striped]){background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent)}.section:where([data-animated]){animation:stripes-animation 1s linear infinite}.section:where(:last-of-type){border-radius:0;border-end-end-radius:var(--progress-radius);border-start-end-radius:var(--progress-radius)}.section:where(:first-of-type){border-radius:0;border-end-start-radius:var(--progress-radius);border-start-start-radius:var(--progress-radius)}.root:where([data-orientation=vertical]) .section{height:var(--progress-section-size);transition:height var(--progress-transition-duration,.1s) ease;width:100%}.root:where([data-orientation=vertical]) .section:where([data-striped]){background-image:linear-gradient(135deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent)}.root:where([data-orientation=vertical]) .section:where([data-animated]){animation:stripes-animation-vertical 1s linear infinite}.root:where([data-orientation=vertical]) .section:where(:last-of-type){border-radius:0;border-start-end-radius:var(--progress-radius);border-start-start-radius:var(--progress-radius)}.root:where([data-orientation=vertical]) .section:where(:first-of-type){border-radius:0;border-end-end-radius:var(--progress-radius);border-end-start-radius:var(--progress-radius)}.label{--progress-label-color:var(--color-white);color:var(--progress-label-color);font-size:min(calc(var(--progress-size)*.65));font-weight:700;line-height:1;overflow:hidden;padding-inline:4px;text-overflow:ellipsis;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.root:where([data-orientation=vertical]) .label{writing-mode:vertical-rl}@keyframes stripes-animation{0%{background-position:0 0}to{background-position:40px 0}}@keyframes stripes-animation-vertical{0%{background-position:0 0}to{background-position:0 40px}}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import ProgressRoot from "./progress-root.vue";
|
|
3
|
+
import ProgressSection from "./progress-section.vue";
|
|
4
|
+
const {
|
|
5
|
+
mod,
|
|
6
|
+
size,
|
|
7
|
+
color,
|
|
8
|
+
radius,
|
|
9
|
+
striped,
|
|
10
|
+
animated,
|
|
11
|
+
withAria,
|
|
12
|
+
orientation,
|
|
13
|
+
transitionDuration
|
|
14
|
+
} = defineProps({
|
|
15
|
+
size: { type: String, required: false },
|
|
16
|
+
radius: { type: [String, Number], required: false },
|
|
17
|
+
transitionDuration: { type: Number, required: false },
|
|
18
|
+
orientation: { type: String, required: false },
|
|
19
|
+
is: { type: null, required: false },
|
|
20
|
+
mod: { type: [Object, Array, null], required: false },
|
|
21
|
+
withAria: { type: Boolean, required: false },
|
|
22
|
+
color: { type: null, required: false },
|
|
23
|
+
striped: { type: Boolean, required: false },
|
|
24
|
+
animated: { type: Boolean, required: false }
|
|
25
|
+
});
|
|
26
|
+
const value = defineModel({ type: Number, ...{ required: true } });
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<ProgressRoot :size :radius :orientation :transition-duration :mod>
|
|
31
|
+
<ProgressSection
|
|
32
|
+
v-model='value'
|
|
33
|
+
:striped
|
|
34
|
+
:animated
|
|
35
|
+
:color
|
|
36
|
+
:with-aria
|
|
37
|
+
/>
|
|
38
|
+
</ProgressRoot>
|
|
39
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ProgressRootProps } from './progress-root.vue.js';
|
|
2
|
+
import type { ProgressSectionProps } from './progress-section.vue.js';
|
|
3
|
+
export interface ProgressProps extends ProgressRootProps, ProgressSectionProps {
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = ProgressProps;
|
|
6
|
+
type __VLS_ModelProps = {
|
|
7
|
+
modelValue: number;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
"update:modelValue": (value: number) => any;
|
|
12
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
13
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
14
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -56,9 +56,10 @@ function handleKeyDown(event) {
|
|
|
56
56
|
break;
|
|
57
57
|
}
|
|
58
58
|
// Enter/Space - выбор элемента
|
|
59
|
-
case "Enter":
|
|
59
|
+
case "Enter": {
|
|
60
60
|
ctx.on("select", value);
|
|
61
61
|
return ctx.setActive(value);
|
|
62
|
+
}
|
|
62
63
|
case " ": {
|
|
63
64
|
event.preventDefault();
|
|
64
65
|
if (event.shiftKey)
|
|
@@ -75,8 +76,10 @@ function handleKeyDown(event) {
|
|
|
75
76
|
<li :class='$style.root' role='presentation'>
|
|
76
77
|
<RovingFocusItem>
|
|
77
78
|
<Button
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
:size='ctx.size'
|
|
80
|
+
:color='ctx.color'
|
|
81
|
+
:variant='ctx.variant'
|
|
82
|
+
:disabled
|
|
80
83
|
role='treeitem'
|
|
81
84
|
:classes='{
|
|
82
85
|
root: $style.button,
|
|
@@ -84,10 +87,9 @@ function handleKeyDown(event) {
|
|
|
84
87
|
inner: $style.inner,
|
|
85
88
|
section: $style.section
|
|
86
89
|
}'
|
|
87
|
-
:mod='{ active, selected, level }'
|
|
88
|
-
:aria-selected='selected'
|
|
89
90
|
:aria-level='level'
|
|
90
|
-
:
|
|
91
|
+
:aria-selected='selected'
|
|
92
|
+
:mod='{ active, selected, level }'
|
|
91
93
|
@click.prevent='handleClick'
|
|
92
94
|
@keydown.prevent='handleKeyDown'
|
|
93
95
|
>
|
|
@@ -135,7 +137,6 @@ function handleKeyDown(event) {
|
|
|
135
137
|
color: var(--color-text);
|
|
136
138
|
|
|
137
139
|
.label {
|
|
138
|
-
font-size: var(--font-size-sm);
|
|
139
140
|
font-weight: 500;
|
|
140
141
|
}
|
|
141
142
|
}
|
|
@@ -1,28 +1,34 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ButtonProps } from '@nui/components';
|
|
2
2
|
import type { RovingFocusProps } from '../../roving-focus/roving-focus.vue.js';
|
|
3
3
|
import type { TreeIconResolver, TreeModels } from '../model.js';
|
|
4
4
|
export type TreeRootProps<T extends string = string> = RovingFocusProps & {
|
|
5
|
-
size?: NuanceSize | string;
|
|
6
5
|
iconResolver?: TreeIconResolver<T>;
|
|
7
6
|
removable?: boolean;
|
|
7
|
+
selectable?: boolean;
|
|
8
|
+
variant?: ButtonProps['variant'];
|
|
9
|
+
color?: ButtonProps['color'];
|
|
10
|
+
size?: ButtonProps['size'];
|
|
8
11
|
};
|
|
9
12
|
declare const __VLS_export: <T extends string = string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
10
13
|
props: __VLS_PrettifyLocal<(RovingFocusProps & {
|
|
11
|
-
size?: NuanceSize | string;
|
|
12
14
|
iconResolver?: TreeIconResolver<T> | undefined;
|
|
13
15
|
removable?: boolean;
|
|
16
|
+
selectable?: boolean;
|
|
17
|
+
variant?: ButtonProps["variant"];
|
|
18
|
+
color?: ButtonProps["color"];
|
|
19
|
+
size?: ButtonProps["size"];
|
|
14
20
|
} & {
|
|
15
21
|
tree: TreeModels<T>["tree"];
|
|
16
22
|
active?: TreeModels<T>["active"];
|
|
17
23
|
selected?: TreeModels<T>["selected"];
|
|
18
24
|
expanded?: TreeModels<T>["expanded"];
|
|
19
|
-
}) & __VLS_EmitsToProps<__VLS_NormalizeEmits<((evt: "update:tree", value: import("
|
|
25
|
+
}) & __VLS_EmitsToProps<__VLS_NormalizeEmits<((evt: "update:tree", value: import("@nui/components").TreeItem<T>[]) => void) & ((evt: "update:active", value: T | null) => void) & ((evt: "update:selected", value: T[]) => void) & ((evt: "update:expanded", value: T[]) => void)>>> & import("vue").PublicProps;
|
|
20
26
|
expose: (exposed: {}) => void;
|
|
21
27
|
attrs: any;
|
|
22
28
|
slots: {
|
|
23
29
|
default?: (props: {}) => any;
|
|
24
30
|
};
|
|
25
|
-
emit: ((evt: "update:tree", value: import("
|
|
31
|
+
emit: ((evt: "update:tree", value: import("@nui/components").TreeItem<T>[]) => void) & ((evt: "update:active", value: T | null) => void) & ((evt: "update:selected", value: T[]) => void) & ((evt: "update:expanded", value: T[]) => void);
|
|
26
32
|
}>) => import("vue").VNode & {
|
|
27
33
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
28
34
|
};
|
|
@@ -7,19 +7,25 @@ import Box from "../../box.vue";
|
|
|
7
7
|
import RovingFocus from "../../roving-focus/roving-focus.vue";
|
|
8
8
|
import { useProvideTreeState } from "../lib/context";
|
|
9
9
|
const {
|
|
10
|
-
|
|
10
|
+
color,
|
|
11
11
|
attr,
|
|
12
12
|
loop,
|
|
13
13
|
orientation,
|
|
14
|
+
variant = "subtle",
|
|
15
|
+
size = "compact-sm",
|
|
14
16
|
iconResolver = () => ({ icon: "gravity-ui:file" }),
|
|
15
|
-
removable = false
|
|
17
|
+
removable = false,
|
|
18
|
+
selectable = false
|
|
16
19
|
} = defineProps({
|
|
17
20
|
loop: { type: Boolean, required: false },
|
|
18
21
|
orientation: { type: String, required: false },
|
|
19
22
|
attr: { type: String, required: false },
|
|
20
|
-
size: { type: String, required: false },
|
|
21
23
|
iconResolver: { type: Function, required: false },
|
|
22
|
-
removable: { type: Boolean, required: false }
|
|
24
|
+
removable: { type: Boolean, required: false },
|
|
25
|
+
selectable: { type: Boolean, required: false },
|
|
26
|
+
variant: { type: String, required: false },
|
|
27
|
+
color: { type: null, required: false },
|
|
28
|
+
size: { type: null, required: false }
|
|
23
29
|
});
|
|
24
30
|
const tree = defineModel("tree", { type: Array, ...{ required: true } });
|
|
25
31
|
const active = defineModel("active", { type: null, ...{ default: null } });
|
|
@@ -35,7 +41,11 @@ useProvideTreeState({
|
|
|
35
41
|
active,
|
|
36
42
|
selected,
|
|
37
43
|
expanded,
|
|
38
|
-
iconResolver
|
|
44
|
+
iconResolver,
|
|
45
|
+
size,
|
|
46
|
+
color,
|
|
47
|
+
variant,
|
|
48
|
+
selectable
|
|
39
49
|
});
|
|
40
50
|
if (removable) {
|
|
41
51
|
useEventListener(root, "keydown", (event) => {
|
|
@@ -1,28 +1,34 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ButtonProps } from '@nui/components';
|
|
2
2
|
import type { RovingFocusProps } from '../../roving-focus/roving-focus.vue.js';
|
|
3
3
|
import type { TreeIconResolver, TreeModels } from '../model.js';
|
|
4
4
|
export type TreeRootProps<T extends string = string> = RovingFocusProps & {
|
|
5
|
-
size?: NuanceSize | string;
|
|
6
5
|
iconResolver?: TreeIconResolver<T>;
|
|
7
6
|
removable?: boolean;
|
|
7
|
+
selectable?: boolean;
|
|
8
|
+
variant?: ButtonProps['variant'];
|
|
9
|
+
color?: ButtonProps['color'];
|
|
10
|
+
size?: ButtonProps['size'];
|
|
8
11
|
};
|
|
9
12
|
declare const __VLS_export: <T extends string = string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
10
13
|
props: __VLS_PrettifyLocal<(RovingFocusProps & {
|
|
11
|
-
size?: NuanceSize | string;
|
|
12
14
|
iconResolver?: TreeIconResolver<T> | undefined;
|
|
13
15
|
removable?: boolean;
|
|
16
|
+
selectable?: boolean;
|
|
17
|
+
variant?: ButtonProps["variant"];
|
|
18
|
+
color?: ButtonProps["color"];
|
|
19
|
+
size?: ButtonProps["size"];
|
|
14
20
|
} & {
|
|
15
21
|
tree: TreeModels<T>["tree"];
|
|
16
22
|
active?: TreeModels<T>["active"];
|
|
17
23
|
selected?: TreeModels<T>["selected"];
|
|
18
24
|
expanded?: TreeModels<T>["expanded"];
|
|
19
|
-
}) & __VLS_EmitsToProps<__VLS_NormalizeEmits<((evt: "update:tree", value: import("
|
|
25
|
+
}) & __VLS_EmitsToProps<__VLS_NormalizeEmits<((evt: "update:tree", value: import("@nui/components").TreeItem<T>[]) => void) & ((evt: "update:active", value: T | null) => void) & ((evt: "update:selected", value: T[]) => void) & ((evt: "update:expanded", value: T[]) => void)>>> & import("vue").PublicProps;
|
|
20
26
|
expose: (exposed: {}) => void;
|
|
21
27
|
attrs: any;
|
|
22
28
|
slots: {
|
|
23
29
|
default?: (props: {}) => any;
|
|
24
30
|
};
|
|
25
|
-
emit: ((evt: "update:tree", value: import("
|
|
31
|
+
emit: ((evt: "update:tree", value: import("@nui/components").TreeItem<T>[]) => void) & ((evt: "update:active", value: T | null) => void) & ((evt: "update:selected", value: T[]) => void) & ((evt: "update:expanded", value: T[]) => void);
|
|
26
32
|
}>) => import("vue").VNode & {
|
|
27
33
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
28
34
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TreeIconResolver, TreeItem } from '@nui/components';
|
|
1
|
+
import type { ButtonProps, TreeIconResolver, TreeItem } from '@nui/components';
|
|
2
2
|
import type { ModelRef } from 'vue';
|
|
3
3
|
type EventType = 'select' | 'expand';
|
|
4
4
|
type SelectMode = 'single' | 'multiple' | 'range';
|
|
@@ -8,6 +8,10 @@ export interface TreeContext<T extends string = string> {
|
|
|
8
8
|
selected: ModelRef<T[]>;
|
|
9
9
|
expanded: ModelRef<T[]>;
|
|
10
10
|
iconResolver: TreeIconResolver<T>;
|
|
11
|
+
selectable: boolean;
|
|
12
|
+
variant: ButtonProps['variant'];
|
|
13
|
+
color: ButtonProps['color'];
|
|
14
|
+
size: ButtonProps['size'];
|
|
11
15
|
}
|
|
12
16
|
export interface TreeState<T extends string = string> {
|
|
13
17
|
active: ModelRef<T | null>;
|
|
@@ -18,6 +22,10 @@ export interface TreeState<T extends string = string> {
|
|
|
18
22
|
on: ((type: 'expand', value: T) => void) & ((type: 'select', value: T, mode?: SelectMode) => void);
|
|
19
23
|
off: (type: EventType, value: T) => void;
|
|
20
24
|
setActive: (value: T | null) => void;
|
|
25
|
+
selectable: boolean;
|
|
26
|
+
variant: ButtonProps['variant'];
|
|
27
|
+
color: ButtonProps['color'];
|
|
28
|
+
size: ButtonProps['size'];
|
|
21
29
|
}
|
|
22
30
|
export declare function useProvideTreeState<T extends string = string>(ctx: TreeContext<T>): TreeState<T>;
|
|
23
31
|
export declare function useTreeState<T extends string = string>(): TreeState<T>;
|
|
@@ -6,12 +6,16 @@ const [useProvide, useState] = createStrictInjection(({
|
|
|
6
6
|
active,
|
|
7
7
|
selected,
|
|
8
8
|
expanded,
|
|
9
|
-
iconResolver
|
|
9
|
+
iconResolver,
|
|
10
|
+
selectable,
|
|
11
|
+
...rest
|
|
10
12
|
}) => {
|
|
11
13
|
const setActive = (value) => active.value = value;
|
|
12
14
|
function on(type, value, mode) {
|
|
13
15
|
if (type === "select") {
|
|
14
16
|
setActive(value);
|
|
17
|
+
if (!selectable)
|
|
18
|
+
return;
|
|
15
19
|
switch (mode) {
|
|
16
20
|
case "single":
|
|
17
21
|
return selected.value = [value];
|
|
@@ -48,8 +52,8 @@ const [useProvide, useState] = createStrictInjection(({
|
|
|
48
52
|
return;
|
|
49
53
|
}
|
|
50
54
|
case "expand": {
|
|
51
|
-
const children = getBranchChildren(tree.value, value);
|
|
52
|
-
return expanded.value = expanded.value.filter((v) => !children.
|
|
55
|
+
const children = new Set(getBranchChildren(tree.value, value));
|
|
56
|
+
return expanded.value = expanded.value.filter((v) => v !== value && !children.has(v));
|
|
53
57
|
}
|
|
54
58
|
default:
|
|
55
59
|
return console.warn(`Unknown target type in NuiTree: ${type}`);
|
|
@@ -61,34 +65,31 @@ const [useProvide, useState] = createStrictInjection(({
|
|
|
61
65
|
const isSelected = selected.value.includes(value);
|
|
62
66
|
if (mode === "single")
|
|
63
67
|
return on(type, value, mode);
|
|
64
|
-
if (mode === "multiple")
|
|
65
|
-
|
|
66
|
-
return off(type, value);
|
|
67
|
-
return on(type, value, mode);
|
|
68
|
-
}
|
|
68
|
+
if (mode === "multiple")
|
|
69
|
+
return isSelected ? off(type, value) : on(type, value, mode);
|
|
69
70
|
if (mode === "range")
|
|
70
71
|
return on(type, value, mode);
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
case "expand": {
|
|
74
75
|
const isExpanded = expanded.value.includes(value);
|
|
75
|
-
|
|
76
|
-
return off(type, value);
|
|
77
|
-
return on(type, value);
|
|
76
|
+
return isExpanded ? off(type, value) : on(type, value);
|
|
78
77
|
}
|
|
79
78
|
default:
|
|
80
79
|
console.warn(`Unknown target type in NuiTree: ${type}`);
|
|
81
80
|
}
|
|
82
81
|
};
|
|
83
82
|
return {
|
|
83
|
+
on,
|
|
84
|
+
off,
|
|
85
|
+
toggle,
|
|
86
|
+
setActive,
|
|
84
87
|
active,
|
|
85
88
|
selected,
|
|
86
89
|
expanded,
|
|
87
90
|
iconResolver,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
off,
|
|
91
|
-
setActive
|
|
91
|
+
selectable,
|
|
92
|
+
...rest
|
|
92
93
|
};
|
|
93
94
|
}, {
|
|
94
95
|
injectionKey,
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { unref } from "vue";
|
|
3
2
|
import UTreeItem from "./_ui/tree-item.vue";
|
|
4
3
|
import TreeRoot from "./_ui/tree-root.vue";
|
|
5
4
|
import { getExpandedItems } from "./lib/get-default";
|
|
6
|
-
const
|
|
5
|
+
const {
|
|
6
|
+
color,
|
|
7
|
+
variant = "subtle",
|
|
8
|
+
size = "compact-sm",
|
|
9
|
+
...props
|
|
10
|
+
} = defineProps({
|
|
7
11
|
loop: { type: Boolean, required: false },
|
|
8
12
|
orientation: { type: String, required: false },
|
|
9
13
|
attr: { type: String, required: false },
|
|
10
|
-
size: { type: String, required: false },
|
|
11
14
|
iconResolver: { type: Function, required: false },
|
|
12
|
-
removable: { type: Boolean, required: false }
|
|
15
|
+
removable: { type: Boolean, required: false },
|
|
16
|
+
selectable: { type: Boolean, required: false },
|
|
17
|
+
variant: { type: String, required: false },
|
|
18
|
+
color: { type: null, required: false },
|
|
19
|
+
size: { type: null, required: false }
|
|
13
20
|
});
|
|
14
21
|
const tree = defineModel("tree", { type: Array, ...{ required: true } });
|
|
15
22
|
const active = defineModel("active", { type: null, ...{ default: null } });
|
|
@@ -25,9 +32,12 @@ expanded.value = getExpandedItems(tree.value);
|
|
|
25
32
|
v-model:active='active'
|
|
26
33
|
v-model:selected='selected'
|
|
27
34
|
v-model:expanded='expanded'
|
|
35
|
+
:size
|
|
36
|
+
:color
|
|
37
|
+
:variant
|
|
28
38
|
>
|
|
29
39
|
<UTreeItem
|
|
30
|
-
v-for='item in
|
|
40
|
+
v-for='item in tree'
|
|
31
41
|
:key='item.value'
|
|
32
42
|
:item
|
|
33
43
|
:level='1'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--color-white:#fff;--color-black:#000;--color-primary-0:var(--color-blue-0);--color-primary-1:var(--color-blue-1);--color-primary-2:var(--color-blue-2);--color-primary-3:var(--color-blue-3);--color-primary-4:var(--color-blue-4);--color-primary-5:var(--color-blue-5);--color-primary-6:var(--color-blue-6);--color-primary-7:var(--color-blue-7);--color-primary-8:var(--color-blue-8);--color-primary-9:var(--color-blue-9);--color-primary-filled:var(--color-blue-filled);--color-primary-filled-hover:var(--color-blue-filled-hover);--color-primary-light:alpha(var(--color-blue-light),.15);--color-primary-light-hover:var(--color-blue-light-hover);--color-primary-light-color:var(--color-blue-light-color);--color-primary-outline:var(--color-blue-outline);--color-primary-outline-hover:alpha(var(--color-blue-outline),.1);--color-dark-0:#c9c9c9;--color-dark-1:#b8b8b8;--color-dark-2:#828282;--color-dark-3:#696969;--color-dark-4:#424242;--color-dark-5:#3b3b3b;--color-dark-6:#2e2e2e;--color-dark-7:#242424;--color-dark-8:#1f1f1f;--color-dark-9:#141414;--color-slate-0:#f8f9fb;--color-slate-1:#f1f3f6;--color-slate-2:#e4e7ed;--color-slate-3:#dadce5;--color-slate-4:#c1c6d4;--color-slate-5:#9096b2;--color-slate-6:#4a5568;--color-slate-7:#313446;--color-slate-8:#252938;--color-slate-9:#1d1f29;--color-gray-0:#f8f9fa;--color-gray-1:#f1f3f5;--color-gray-2:#e9ecef;--color-gray-3:#dee2e6;--color-gray-4:#ced4da;--color-gray-5:#adb5bd;--color-gray-6:#868e96;--color-gray-7:#495057;--color-gray-8:#343a40;--color-gray-9:#212529;--color-red-0:#
|
|
1
|
+
:root{--color-white:#fff;--color-black:#000;--color-primary-0:var(--color-blue-0);--color-primary-1:var(--color-blue-1);--color-primary-2:var(--color-blue-2);--color-primary-3:var(--color-blue-3);--color-primary-4:var(--color-blue-4);--color-primary-5:var(--color-blue-5);--color-primary-6:var(--color-blue-6);--color-primary-7:var(--color-blue-7);--color-primary-8:var(--color-blue-8);--color-primary-9:var(--color-blue-9);--color-primary-filled:var(--color-blue-filled);--color-primary-filled-hover:var(--color-blue-filled-hover);--color-primary-light:alpha(var(--color-blue-light),.15);--color-primary-light-hover:var(--color-blue-light-hover);--color-primary-light-color:var(--color-blue-light-color);--color-primary-outline:var(--color-blue-outline);--color-primary-outline-hover:alpha(var(--color-blue-outline),.1);--color-dark-0:#c9c9c9;--color-dark-1:#b8b8b8;--color-dark-2:#828282;--color-dark-3:#696969;--color-dark-4:#424242;--color-dark-5:#3b3b3b;--color-dark-6:#2e2e2e;--color-dark-7:#242424;--color-dark-8:#1f1f1f;--color-dark-9:#141414;--color-slate-0:#f8f9fb;--color-slate-1:#f1f3f6;--color-slate-2:#e4e7ed;--color-slate-3:#dadce5;--color-slate-4:#c1c6d4;--color-slate-5:#9096b2;--color-slate-6:#4a5568;--color-slate-7:#313446;--color-slate-8:#252938;--color-slate-9:#1d1f29;--color-gray-0:#f8f9fa;--color-gray-1:#f1f3f5;--color-gray-2:#e9ecef;--color-gray-3:#dee2e6;--color-gray-4:#ced4da;--color-gray-5:#adb5bd;--color-gray-6:#868e96;--color-gray-7:#495057;--color-gray-8:#343a40;--color-gray-9:#212529;--color-red-0:#fff5f5;--color-red-1:#ffe3e3;--color-red-2:#ffc9c9;--color-red-3:#ffa8a8;--color-red-4:#ff8787;--color-red-5:#ff6b6b;--color-red-6:#fa5252;--color-red-7:#f03e3e;--color-red-8:#e03131;--color-red-9:#c92a2a;--color-pink-0:#fdf6f8;--color-pink-1:#f7e4e9;--color-pink-2:#edc2d0;--color-pink-3:#dd9bb0;--color-pink-4:#c97a93;--color-pink-5:#b26179;--color-pink-6:#954d65;--color-pink-7:#7a3e52;--color-pink-8:#603140;--color-pink-9:#4d2733;--color-grape-0:#f8f0fc;--color-grape-1:#f3d9fa;--color-grape-2:#eebefa;--color-grape-3:#e599f7;--color-grape-4:#da77f2;--color-grape-5:#cc5de8;--color-grape-6:#be4bdb;--color-grape-7:#ae3ec9;--color-grape-8:#9c36b5;--color-grape-9:#862e9c;--color-violet-0:#f3f0ff;--color-violet-1:#e5dbff;--color-violet-2:#d0bfff;--color-violet-3:#b197fc;--color-violet-4:#9775fa;--color-violet-5:#845ef7;--color-violet-6:#7950f2;--color-violet-7:#7048e8;--color-violet-8:#6741d9;--color-violet-9:#5f3dc4;--color-indigo-0:#edf2ff;--color-indigo-1:#dbe4ff;--color-indigo-2:#bac8ff;--color-indigo-3:#91a7ff;--color-indigo-4:#748ffc;--color-indigo-5:#5c7cfa;--color-indigo-6:#4c6ef5;--color-indigo-7:#4263eb;--color-indigo-8:#3b5bdb;--color-indigo-9:#364fc7;--color-blue-0:#e7f5ff;--color-blue-1:#d0ebff;--color-blue-2:#a5d8ff;--color-blue-3:#74c0fc;--color-blue-4:#4dabf7;--color-blue-5:#339af0;--color-blue-6:#228be6;--color-blue-7:#1c7ed6;--color-blue-8:#1971c2;--color-blue-9:#1864ab;--color-cyan-0:#e3fafc;--color-cyan-1:#c5f6fa;--color-cyan-2:#99e9f2;--color-cyan-3:#66d9e8;--color-cyan-4:#3bc9db;--color-cyan-5:#22b8cf;--color-cyan-6:#15aabf;--color-cyan-7:#1098ad;--color-cyan-8:#0c8599;--color-cyan-9:#0b7285;--color-teal-0:#e6fcf5;--color-teal-1:#c3fae8;--color-teal-2:#96f2d7;--color-teal-3:#63e6be;--color-teal-4:#38d9a9;--color-teal-5:#20c997;--color-teal-6:#12b886;--color-teal-7:#0ca678;--color-teal-8:#099268;--color-teal-9:#087f5b;--color-green-0:#ebfbee;--color-green-1:#d3f9d8;--color-green-2:#b2f2bb;--color-green-3:#8ce99a;--color-green-4:#69db7c;--color-green-5:#51cf66;--color-green-6:#40c057;--color-green-7:#37b24d;--color-green-8:#2f9e44;--color-green-9:#2b8a3e;--color-lime-0:#f4fce3;--color-lime-1:#e9fac8;--color-lime-2:#d8f5a2;--color-lime-3:#c0eb75;--color-lime-4:#a9e34b;--color-lime-5:#94d82d;--color-lime-6:#82c91e;--color-lime-7:#74b816;--color-lime-8:#66a80f;--color-lime-9:#5c940d;--color-yellow-0:#fff9db;--color-yellow-1:#fff3bf;--color-yellow-2:#ffec99;--color-yellow-3:#ffe066;--color-yellow-4:#ffd43b;--color-yellow-5:#fcc419;--color-yellow-6:#fab005;--color-yellow-7:#f59f00;--color-yellow-8:#f08c00;--color-yellow-9:#e67700;--color-orange-0:#fff4e6;--color-orange-1:#ffe8cc;--color-orange-2:#ffd8a8;--color-orange-3:#ffc078;--color-orange-4:#ffa94d;--color-orange-5:#ff922b;--color-orange-6:#fd7e14;--color-orange-7:#f76707;--color-orange-8:#e8590c;--color-orange-9:#d9480f}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{@mixin light-root{--primary-color-contrast:var(--color-white);--color-bright:var(--color-black);--color-text:#000;--color-body:#fff;--color-error:var(--color-red-6);--color-placeholder:var(--color-gray-5);--color-anchor:var(--color-blue-6);--color-default:var(--color-white);--color-default-hover:var(--color-gray-0);--color-default-color:var(--color-black);--color-default-border:var(--color-gray-4);--color-dimmed:var(--color-gray-6);--color-disabled:var(--color-gray-2);--color-disabled-text:var(--color-gray-5);--color-disabled-border:var(--color-gray-3);--color-dark-color:var(--color-dark-filled);--color-dark-filled:var(--color-dark-6);--color-dark-filled-hover:var(--color-dark-7);--color-dark-light:
|
|
1
|
+
:root{@mixin light-root{--primary-color-contrast:var(--color-white);--color-bright:var(--color-black);--color-text:#000;--color-body:#fff;--color-error:var(--color-red-6);--color-placeholder:var(--color-gray-5);--color-anchor:var(--color-blue-6);--color-default:var(--color-white);--color-default-hover:var(--color-gray-0);--color-default-color:var(--color-black);--color-default-border:var(--color-gray-4);--color-dimmed:var(--color-gray-6);--color-disabled:var(--color-gray-2);--color-disabled-text:var(--color-gray-5);--color-disabled-border:var(--color-gray-3);--color-dark-color:var(--color-dark-filled);--color-dark-filled:var(--color-dark-6);--color-dark-filled-hover:var(--color-dark-7);--color-dark-light:alpha(var(--color-dark-6),0.1);--color-dark-light-hover:alpha(var(--color-dark-6),0.12);--color-dark-light-color:var(--color-dark-6);--color-dark-outline:var(--color-dark-6);--color-dark-outline-hover:alpha(var(--color-dark-6),0.05);--color-gray-color:var(--color-gray-filled);--color-gray-filled:var(--color-gray-6);--color-gray-filled-hover:var(--color-gray-7);--color-gray-light:alpha(var(--color-gray-6),0.1);--color-gray-light-hover:alpha(var(--color-gray-6),0.12);--color-gray-light-color:var(--color-gray-6);--color-gray-outline:var(--color-gray-6);--color-gray-outline-hover:alpha(var(--color-gray-6),0.05);--color-red-color:var(--color-red-filled);--color-red-filled:var(--color-red-6);--color-red-filled-hover:var(--color-red-7);--color-red-light:alpha(var(--color-red-8),.1);--color-red-light-hover:alpha(var(--color-red-8),.12);--color-red-light-color:var(--color-red-6);--color-red-outline:var(--color-red-6);--color-red-outline-hover:alpha(var(--color-red-8),.01);--color-pink-color:var(--color-pink-filled);--color-pink-filled:var(--color-pink-6);--color-pink-filled-hover:var(--color-pink-7);--color-pink-light:alpha(var(--color-pink-6),0.1);--color-pink-light-hover:alpha(var(--color-pink-6),0.12);--color-pink-light-color:var(--color-pink-6);--color-pink-outline:var(--color-pink-6);--color-pink-outline-hover:alpha(var(--color-pink-6),0.05);--color-grape-color:var(--color-grape-filled);--color-grape-filled:var(--color-grape-6);--color-grape-filled-hover:var(--color-grape-7);--color-grape-light:alpha(var(--color-grape-6),0.1);--color-grape-light-hover:alpha(var(--color-grape-6),0.12);--color-grape-light-color:var(--color-grape-6);--color-grape-outline:var(--color-grape-6);--color-grape-outline-hover:alpha(var(--color-grape-6),0.05);--color-violet-color:var(--color-violet-filled);--color-violet-filled:var(--color-violet-6);--color-violet-filled-hover:var(--color-violet-7);--color-violet-light:alpha(var(--color-violet-6),0.1);--color-violet-light-hover:alpha(var(--color-violet-6),0.12);--color-violet-light-color:var(--color-violet-6);--color-violet-outline:var(--color-violet-6);--color-violet-outline-hover:alpha(var(--color-violet-6),0.05);--color-indigo-color:var(--color-indigo-filled);--color-indigo-filled:var(--color-indigo-6);--color-indigo-filled-hover:var(--color-indigo-7);--color-indigo-light:alpha(var(--color-indigo-6),0.1);--color-indigo-light-hover:alpha(var(--color-indigo-6),0.12);--color-indigo-light-color:var(--color-indigo-6);--color-indigo-outline:var(--color-indigo-6);--color-indigo-outline-hover:alpha(var(--color-indigo-6),0.05);--color-blue-color:var(--color-blue-filled);--color-blue-filled:var(--color-blue-6);--color-blue-filled-hover:var(--color-blue-7);--color-blue-light:alpha(var(--color-blue-6),0.1);--color-blue-light-hover:alpha(var(--color-blue-6),0.12);--color-blue-light-color:var(--color-blue-6);--color-blue-outline:var(--color-blue-6);--color-blue-outline-hover:alpha(var(--color-blue-6),0.05);--color-cyan-color:var(--color-cyan-filled);--color-cyan-filled:var(--color-cyan-6);--color-cyan-filled-hover:var(--color-cyan-7);--color-cyan-light:alpha(var(--color-cyan-6),0.1);--color-cyan-light-hover:alpha(var(--color-cyan-6),0.12);--color-cyan-light-color:var(--color-cyan-6);--color-cyan-outline:var(--color-cyan-6);--color-cyan-outline-hover:alpha(var(--color-cyan-6),0.05);--color-teal-color:var(--color-teal-filled);--color-teal-filled:var(--color-teal-6);--color-teal-filled-hover:var(--color-teal-7);--color-teal-light:alpha(var(--color-teal-6),0.1);--color-teal-light-hover:alpha(var(--color-teal-6),0.12);--color-teal-light-color:var(--color-teal-6);--color-teal-outline:var(--color-teal-6);--color-teal-outline-hover:alpha(var(--color-teal-6),0.05);--color-green-color:var(--color-green-filled);--color-green-filled:var(--color-green-6);--color-green-filled-hover:var(--color-green-7);--color-green-light:alpha(var(--color-green-6),0.1);--color-green-light-hover:alpha(var(--color-green-6),0.12);--color-green-light-color:var(--color-green-6);--color-green-outline:var(--color-green-6);--color-green-outline-hover:alpha(var(--color-green-6),0.05);--color-lime-color:var(--color-lime-filled);--color-lime-filled:var(--color-lime-6);--color-lime-filled-hover:var(--color-lime-7);--color-lime-light:alpha(var(--color-lime-6),0.1);--color-lime-light-hover:alpha(var(--color-lime-6),0.12);--color-lime-light-color:var(--color-lime-6);--color-lime-outline:var(--color-lime-6);--color-lime-outline-hover:alpha(var(--color-lime-6),0.05);--color-yellow-color:var(--color-yellow-filled);--color-yellow-filled:var(--color-yellow-6);--color-yellow-filled-hover:var(--color-yellow-7);--color-yellow-light:alpha(var(--color-yellow-6),0.1);--color-yellow-light-hover:alpha(var(--color-yellow-6),0.12);--color-yellow-light-color:var(--color-yellow-6);--color-yellow-outline:var(--color-yellow-6);--color-yellow-outline-hover:alpha(var(--color-yellow-6),0.05);--color-orange-color:var(--color-orange-filled);--color-orange-filled:var(--color-orange-6);--color-orange-filled-hover:var(--color-orange-7);--color-orange-light:alpha(var(--color-orange-6),0.1);--color-orange-light-hover:alpha(var(--color-orange-6),0.12);--color-orange-light-color:var(--color-orange-6);--color-orange-outline:var(--color-orange-6);--color-orange-outline-hover:alpha(var(--color-orange-6),0.05)}}
|
|
@@ -5,6 +5,25 @@ export interface TreeNode<T extends string = string> {
|
|
|
5
5
|
/** Optional array of child nodes */
|
|
6
6
|
children?: TreeNode<T>[];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Filters tree nodes based on a predicate function.
|
|
10
|
+
* Returns a new tree containing only nodes that match the predicate.
|
|
11
|
+
* Parent nodes are kept if they have matching children.
|
|
12
|
+
*
|
|
13
|
+
* @template Node - The type of tree nodes
|
|
14
|
+
* @param {Node[]} tree - The tree to filter
|
|
15
|
+
* @param {(node: Node) => boolean} predicate - Function to test each node
|
|
16
|
+
* @returns {Node[]} New filtered tree
|
|
17
|
+
* @example
|
|
18
|
+
* const tree = [
|
|
19
|
+
* { value: 'folder', children: [{ value: 'file1' }, { value: 'file2' }] },
|
|
20
|
+
* { value: 'file3' }
|
|
21
|
+
* ]
|
|
22
|
+
* // Keep only folders (nodes with children)
|
|
23
|
+
* filterTree(tree, node => node.children && node.children.length > 0)
|
|
24
|
+
* // Result: [{ value: 'folder', children: [{ value: 'file1' }, { value: 'file2' }] }]
|
|
25
|
+
*/
|
|
26
|
+
export declare function filterTree<Node extends TreeNode = TreeNode>(tree: Node[], predicate: (node: Node) => boolean): Node[];
|
|
8
27
|
/**
|
|
9
28
|
* Searches for a tree item by its value using depth-first search.
|
|
10
29
|
* @template T - The type of node values
|
|
@@ -7,6 +7,21 @@ function traverse(nodes) {
|
|
|
7
7
|
}
|
|
8
8
|
return result;
|
|
9
9
|
}
|
|
10
|
+
export function filterTree(tree, predicate) {
|
|
11
|
+
const result = [];
|
|
12
|
+
for (const node of tree) {
|
|
13
|
+
const filteredChildren = node.children?.length ? filterTree(node.children, predicate) : void 0;
|
|
14
|
+
if (predicate(node) || filteredChildren && filteredChildren.length > 0) {
|
|
15
|
+
const newNode = { ...node };
|
|
16
|
+
if (filteredChildren && filteredChildren.length > 0)
|
|
17
|
+
newNode.children = filteredChildren;
|
|
18
|
+
else
|
|
19
|
+
delete newNode.children;
|
|
20
|
+
result.push(newNode);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
10
25
|
export function findTreeItem(items, value) {
|
|
11
26
|
for (const item of items) {
|
|
12
27
|
if (item.value === value)
|
|
@@ -66,20 +81,5 @@ export function getTreeItemsBetween(tree, start, end) {
|
|
|
66
81
|
}
|
|
67
82
|
export function removeTreeNodes(tree, valuesToRemove) {
|
|
68
83
|
const removeSet = new Set(valuesToRemove);
|
|
69
|
-
|
|
70
|
-
const result = [];
|
|
71
|
-
for (const node of nodes) {
|
|
72
|
-
if (removeSet.has(node.value))
|
|
73
|
-
continue;
|
|
74
|
-
const newNode = { ...node };
|
|
75
|
-
if (node.children?.length) {
|
|
76
|
-
const filteredChildren = recurse(node.children);
|
|
77
|
-
if (filteredChildren.length > 0)
|
|
78
|
-
newNode.children = filteredChildren;
|
|
79
|
-
}
|
|
80
|
-
result.push(newNode);
|
|
81
|
-
}
|
|
82
|
-
return result;
|
|
83
|
-
}
|
|
84
|
-
return recurse(tree);
|
|
84
|
+
return filterTree(tree, (n) => !removeSet.has(n.value));
|
|
85
85
|
}
|