nuance-ui 0.1.29 → 0.1.31

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.0.0"
6
6
  },
7
- "version": "0.1.29",
7
+ "version": "0.1.31",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -4,6 +4,7 @@ import type { BoxProps } from './box.vue.js';
4
4
  import type { LinkProps } from './link/index.js';
5
5
  import type { TextProps } from './text.vue.js';
6
6
  export interface BreadcrumbsItem extends Omit<LinkProps, 'mod'> {
7
+ active?: boolean;
7
8
  label: string;
8
9
  icon?: string;
9
10
  class?: string;
@@ -16,15 +17,13 @@ export interface BreadcrumbsProps extends BoxProps {
16
17
  separator?: string;
17
18
  /** Controls spacing between separator and breadcrumb @default `'xs'` */
18
19
  spacing?: NuanceSpacing;
19
- /** Function to determine if an item is active */
20
- activeItem?: (item: BreadcrumbsItem) => boolean;
21
20
  color?: NuanceColor;
22
21
  size?: TextProps['fz'];
23
22
  }
24
23
  declare var __VLS_16: string, __VLS_17: {
25
24
  item: BreadcrumbsItem;
26
25
  ix: number;
27
- active: any;
26
+ active: boolean;
28
27
  }, __VLS_32: {};
29
28
  type __VLS_Slots = {} & {
30
29
  [K in NonNullable<typeof __VLS_16>]?: (props: typeof __VLS_17) => any;
@@ -17,7 +17,6 @@ const {
17
17
  items: { type: null, required: false },
18
18
  separator: { type: String, required: false },
19
19
  spacing: { type: [String, Number], required: false },
20
- activeItem: { type: Function, required: false },
21
20
  color: { type: null, required: false },
22
21
  size: { type: null, required: false },
23
22
  is: { type: null, required: false },
@@ -26,11 +25,12 @@ const {
26
25
  const style = computed(() => ({
27
26
  "--bc-spacing": getSpacing(spacing)
28
27
  }));
28
+ const breadcrumbs = computed(() => unref(items) ?? []);
29
29
  </script>
30
30
 
31
31
  <template>
32
32
  <Box :is :mod :style :class='$style.root' aria-label='breadcrumb'>
33
- <template v-for='(item, ix) in unref(items)' :key='ix'>
33
+ <template v-for='(item, ix) in breadcrumbs' :key='ix'>
34
34
  <Text
35
35
  is='li'
36
36
  :c='color'
@@ -39,18 +39,18 @@ const style = computed(() => ({
39
39
  role='presentation'
40
40
  aria-hidden='true'
41
41
  >
42
- <NuxtLink v-slot='{ isActive }' v-bind='pickLinkProps(item).link' custom>
42
+ <NuxtLink v-bind='pickLinkProps(item).link' custom>
43
43
  <slot
44
44
  :name='item.slot ?? "item"'
45
45
  :item='item'
46
46
  :ix='ix'
47
- :active='activeItem ? activeItem(item) : isActive'
47
+ :active='item.active ?? ix === breadcrumbs.length - 1'
48
48
  >
49
49
  <Link
50
50
  v-bind='pickLinkProps(item).link'
51
51
  inherit
52
52
  :class='$style.item'
53
- :mod='{ active: activeItem ? activeItem(item) : isActive }'
53
+ :mod='{ active: item.active ?? ix === breadcrumbs.length - 1 }'
54
54
  >
55
55
  <Icon v-if='item?.icon' :name='item.icon' :class='$style.icon' />
56
56
  <Text is='span' inherit truncate>
@@ -60,7 +60,7 @@ const style = computed(() => ({
60
60
  </slot>
61
61
  </NuxtLink>
62
62
  </Text>
63
- <li v-if='ix < unref(items).length - 1' role='presentation' aria-hidden='true' :class='$style.separator'>
63
+ <li v-if='ix < breadcrumbs.length - 1' role='presentation' aria-hidden='true' :class='$style.separator'>
64
64
  <slot name='separator'>
65
65
  <Icon :name='separator' />
66
66
  </slot>
@@ -4,6 +4,7 @@ import type { BoxProps } from './box.vue.js';
4
4
  import type { LinkProps } from './link/index.js';
5
5
  import type { TextProps } from './text.vue.js';
6
6
  export interface BreadcrumbsItem extends Omit<LinkProps, 'mod'> {
7
+ active?: boolean;
7
8
  label: string;
8
9
  icon?: string;
9
10
  class?: string;
@@ -16,15 +17,13 @@ export interface BreadcrumbsProps extends BoxProps {
16
17
  separator?: string;
17
18
  /** Controls spacing between separator and breadcrumb @default `'xs'` */
18
19
  spacing?: NuanceSpacing;
19
- /** Function to determine if an item is active */
20
- activeItem?: (item: BreadcrumbsItem) => boolean;
21
20
  color?: NuanceColor;
22
21
  size?: TextProps['fz'];
23
22
  }
24
23
  declare var __VLS_16: string, __VLS_17: {
25
24
  item: BreadcrumbsItem;
26
25
  ix: number;
27
- active: any;
26
+ active: boolean;
28
27
  }, __VLS_32: {};
29
28
  type __VLS_Slots = {} & {
30
29
  [K in NonNullable<typeof __VLS_16>]?: (props: typeof __VLS_17) => any;
@@ -38,7 +38,7 @@ const mod = computed(() => [
38
38
  <slot />
39
39
 
40
40
  <div :class='$style.wrapper'>
41
- <Box is='label' :class='$style.label' :for='id' :mod='{ disabled }'>
41
+ <Box is='label' v-if='label || $slots.label' :class='$style.label' :for='id' :mod='{ disabled }'>
42
42
  <slot name='label'>
43
43
  {{ label }}
44
44
  </slot>
@@ -104,6 +104,10 @@ const mod = computed(() => [
104
104
  &[data-disabled] {
105
105
  --label-cursor: not-allowed;
106
106
  }
107
+
108
+ &:empty {
109
+ display: none;
110
+ }
107
111
  }
108
112
 
109
113
  .label {
@@ -8,6 +8,7 @@ import Loader from "../../loader/loader.vue";
8
8
  import RovingFocusItem from "../../roving-focus/roving-focus-item.vue";
9
9
  import UTransition from "../../transition/transition.vue";
10
10
  import { useTreeState } from "../lib/context";
11
+ import { filterTreeItems } from "../lib/filter-tree-items";
11
12
  import { useTreeItemHandlers } from "../lib/item-handlers";
12
13
  const {
13
14
  type = "file",
@@ -33,7 +34,8 @@ const ctx = useTreeState();
33
34
  const selected = computed(() => ctx.selected.value.includes(path));
34
35
  const expanded = computed(() => ctx.expanded.value.includes(path));
35
36
  const active = computed(() => ctx.active.value === path);
36
- const { data, pending, execute } = ctx.loadBranch(path);
37
+ const { data: state, pending, execute } = ctx.loadBranch(path);
38
+ const data = computed(() => filterTreeItems(state.value, ctx.filter));
37
39
  watch(expanded, (expanded2) => {
38
40
  if (expanded2) {
39
41
  try {
@@ -1,11 +1,12 @@
1
1
  import type { ButtonProps } from '@nui/components';
2
2
  import type { RovingFocusProps } from '../../roving-focus/roving-focus.vue.js';
3
- import type { TreeIconResolver, TreeLoader, TreeModels } from '../model.js';
3
+ import type { TreeFilter, TreeIconResolver, TreeLoader, TreeModels } from '../model.js';
4
4
  export type TreeRootProps = RovingFocusProps & {
5
5
  iconResolver?: TreeIconResolver;
6
6
  removable?: boolean;
7
7
  selectable?: boolean;
8
8
  loadBranch: TreeLoader;
9
+ filter?: TreeFilter;
9
10
  variant?: ButtonProps['variant'];
10
11
  color?: ButtonProps['color'];
11
12
  size?: ButtonProps['size'];
@@ -16,7 +16,8 @@ const {
16
16
  iconResolver = () => ({ icon: "gravity-ui:file" }),
17
17
  removable = false,
18
18
  selectable = false,
19
- loadBranch
19
+ loadBranch,
20
+ filter
20
21
  } = defineProps({
21
22
  loop: { type: Boolean, required: false },
22
23
  orientation: { type: String, required: false },
@@ -25,6 +26,7 @@ const {
25
26
  removable: { type: Boolean, required: false },
26
27
  selectable: { type: Boolean, required: false },
27
28
  loadBranch: { type: Function, required: true },
29
+ filter: { type: [String, null, Function], required: false },
28
30
  variant: { type: String, required: false },
29
31
  color: { type: null, required: false },
30
32
  size: { type: null, required: false }
@@ -48,7 +50,8 @@ useProvideTreeState({
48
50
  color,
49
51
  variant,
50
52
  selectable,
51
- loadBranch
53
+ loadBranch,
54
+ filter
52
55
  });
53
56
  if (removable) {
54
57
  useEventListener(root, "keydown", (event) => {
@@ -1,11 +1,12 @@
1
1
  import type { ButtonProps } from '@nui/components';
2
2
  import type { RovingFocusProps } from '../../roving-focus/roving-focus.vue.js';
3
- import type { TreeIconResolver, TreeLoader, TreeModels } from '../model.js';
3
+ import type { TreeFilter, TreeIconResolver, TreeLoader, TreeModels } from '../model.js';
4
4
  export type TreeRootProps = RovingFocusProps & {
5
5
  iconResolver?: TreeIconResolver;
6
6
  removable?: boolean;
7
7
  selectable?: boolean;
8
8
  loadBranch: TreeLoader;
9
+ filter?: TreeFilter;
9
10
  variant?: ButtonProps['variant'];
10
11
  color?: ButtonProps['color'];
11
12
  size?: ButtonProps['size'];
@@ -1,6 +1,6 @@
1
1
  import type { ButtonProps } from '@nui/components';
2
2
  import type { ModelRef, ShallowRef } from 'vue';
3
- import type { TreeIconResolver, TreeLoader } from '../model.js';
3
+ import type { TreeFilter, TreeIconResolver, TreeLoader } from '../model.js';
4
4
  type EventType = 'select' | 'expand';
5
5
  type SelectMode = 'single' | 'multiple' | 'range';
6
6
  export interface TreeContext {
@@ -10,6 +10,7 @@ export interface TreeContext {
10
10
  expanded: ModelRef<string[]>;
11
11
  iconResolver: TreeIconResolver;
12
12
  loadBranch: TreeLoader;
13
+ filter?: TreeFilter;
13
14
  selectable: boolean;
14
15
  variant: ButtonProps['variant'];
15
16
  color: ButtonProps['color'];
@@ -0,0 +1,2 @@
1
+ import type { TreeFilter, TreeItem } from '../model.js';
2
+ export declare function filterTreeItems(items: TreeItem[] | undefined, filter?: TreeFilter): TreeItem[] | undefined;
@@ -0,0 +1,7 @@
1
+ export function filterTreeItems(items, filter) {
2
+ if (!filter || !items)
3
+ return items;
4
+ if (typeof filter === "string")
5
+ return items.filter((i) => i.type === filter);
6
+ return items.filter(filter);
7
+ }
@@ -10,8 +10,6 @@ export function useTreeItemHandlers(path, isFolder, expanded) {
10
10
  ctx.toggle("select", path, "multiple");
11
11
  else
12
12
  ctx.toggle("select", path, "single");
13
- if (isFolder.value && !event.ctrlKey && !event.metaKey && !event.shiftKey)
14
- ctx.toggle("expand", path);
15
13
  }
16
14
  function handleKeyDown(event) {
17
15
  switch (event.key) {
@@ -38,3 +38,4 @@ export type TreeIconResolver = (type: TreeItemType, name?: string, path?: string
38
38
  icon: string;
39
39
  color?: NuanceColor;
40
40
  };
41
+ export type TreeFilter = 'directory' | null | ((item: TreeItem) => boolean);
@@ -1,12 +1,14 @@
1
1
  <script setup>
2
- import { onMounted } from "vue";
2
+ import { computed, onMounted } from "vue";
3
3
  import UTreeItem from "./_ui/tree-item.vue";
4
4
  import TreeRoot from "./_ui/tree-root.vue";
5
+ import { filterTreeItems } from "./lib/filter-tree-items";
5
6
  const {
6
7
  color,
7
8
  variant = "subtle",
8
9
  size = "compact-sm",
9
10
  loadBranch,
11
+ filter = "directory",
10
12
  ...props
11
13
  } = defineProps({
12
14
  loop: { type: Boolean, required: false },
@@ -16,6 +18,7 @@ const {
16
18
  removable: { type: Boolean, required: false },
17
19
  selectable: { type: Boolean, required: false },
18
20
  loadBranch: { type: Function, required: true },
21
+ filter: { type: [String, null, Function], required: false },
19
22
  variant: { type: String, required: false },
20
23
  color: { type: null, required: false },
21
24
  size: { type: null, required: false }
@@ -24,7 +27,8 @@ defineEmits(["delete"]);
24
27
  const active = defineModel("active", { type: [String, null], ...{ default: null } });
25
28
  const selected = defineModel("selected", { type: Array, ...{ default: [] } });
26
29
  const expanded = defineModel("expanded", { type: Array, ...{ default: [] } });
27
- const { data: root, execute } = loadBranch("/");
30
+ const { data: state, execute } = loadBranch("/");
31
+ const root = computed(() => filterTreeItems(state.value, filter));
28
32
  onMounted(execute);
29
33
  </script>
30
34
 
@@ -38,6 +42,7 @@ onMounted(execute);
38
42
  :size
39
43
  :color
40
44
  :variant
45
+ :filter
41
46
  @delete='(path) => $emit("delete", path)'
42
47
  >
43
48
  <UTreeItem
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuance-ui",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "A UI Library for Modern Web Apps, powered by Vue.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,7 +0,0 @@
1
- import type { TreeItem } from '../model.js';
2
- /**
3
- * Получает все элементы дерева с expanded: true
4
- * @param items - массив элементов дерева
5
- * @returns массив value элементов с expanded: true
6
- */
7
- export declare function getExpandedItems<T extends string = string>(items: TreeItem<T>[]): T[];
@@ -1,10 +0,0 @@
1
- export function getExpandedItems(items) {
2
- const result = [];
3
- for (const item of items) {
4
- if (item.expanded === true)
5
- result.push(item.value);
6
- if (item.children && item.children.length > 0)
7
- result.push(...getExpandedItems(item.children));
8
- }
9
- return result;
10
- }