UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

1 lines 13 kB
{"version":3,"file":"TreeRoot.cjs","sources":["../../src/Tree/TreeRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { createContext, getActiveElement, useDirection, useSelectionBehavior, useTypeahead } from '@/shared'\nimport type { Direction } from '@/shared/types'\nimport { flatten } from './utils'\n\nexport interface TreeRootProps<T = Record<string, any>, U extends Record<string, any> = Record<string, any>> extends PrimitiveProps {\n /** The controlled value of the tree. Can be binded with with `v-model`. */\n modelValue?: U | U[]\n /** The value of the tree when initially rendered. Use when you do not need to control the state of the tree */\n defaultValue?: U | U[]\n /** List of items */\n items?: T[]\n /** The controlled value of the expanded item. Can be binded with with `v-model`. */\n expanded?: string[]\n /** The value of the expanded tree when initially rendered. Use when you do not need to control the state of the expanded tree */\n defaultExpanded?: string[]\n /** This function is passed the index of each item and should return a unique key for that item */\n getKey: (val: T) => string\n /** This function is passed the index of each item and should return a list of children for that item */\n getChildren?: (val: T) => T[] | undefined\n /** How multiple selection should behave in the collection. */\n selectionBehavior?: 'toggle' | 'replace'\n /** Whether multiple options can be selected or not. */\n multiple?: boolean\n /** The reading direction of the listbox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. */\n dir?: Direction\n /** When `true`, prevents the user from interacting with tree */\n disabled?: boolean\n /** When `true`, selecting parent will select the descendants. */\n propagateSelect?: boolean\n}\n\nexport type TreeRootEmits<T = Record<string, any>> = {\n 'update:modelValue': [val: T]\n 'update:expanded': [val: string[]]\n}\n\ninterface TreeRootContext<T = Record<string, any>> {\n modelValue: Ref<T | T[]>\n selectedKeys: Ref<string[]>\n onSelect: (val: T) => void\n expanded: Ref<string[]>\n onToggle: (val: T) => void\n items: Ref<T[]>\n expandedItems: Ref<T[]>\n getKey: (val: T) => string\n getChildren: (val: T) => T[] | undefined\n multiple: Ref<boolean>\n disabled: Ref<boolean>\n dir: Ref<Direction>\n propagateSelect: Ref<boolean>\n isVirtual: Ref<boolean>\n virtualKeydownHook: EventHook<KeyboardEvent>\n\n handleMultipleReplace: ReturnType<typeof useSelectionBehavior>['handleMultipleReplace']\n}\n\nexport type FlattenedItem<T> = {\n _id: string\n index: number\n value: T\n level: number\n hasChildren: boolean\n parentItem?: T\n bind: {\n value: T\n level: number\n [key: string]: any\n }\n}\n\nexport const [injectTreeRootContext, provideTreeRootContext] = createContext<TreeRootContext<any>>('TreeRoot')\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>, U extends Record<string, any>\">\nimport { Primitive, type PrimitiveProps } from '@/Primitive'\nimport { type EventHook, createEventHook, useVModel } from '@vueuse/core'\nimport { RovingFocusGroup } from '@/RovingFocus'\nimport { type Ref, computed, nextTick, ref, toRefs } from 'vue'\nimport { MAP_KEY_TO_FOCUS_INTENT } from '@/RovingFocus/utils'\n\nconst props = withDefaults(defineProps<TreeRootProps<T, U>>(), {\n as: 'ul',\n selectionBehavior: 'toggle',\n getChildren: (val: T) => val.children,\n})\nconst emits = defineEmits<TreeRootEmits<U>>()\n\ndefineSlots<{\n default: (props: {\n flattenItems: FlattenedItem<T>[]\n modelValue: typeof modelValue.value\n expanded: typeof expanded.value\n }) => any\n}>()\n\nconst { items, multiple, disabled, propagateSelect, dir: propDir } = toRefs(props)\nconst { handleTypeaheadSearch } = useTypeahead()\nconst dir = useDirection(propDir)\nconst rovingFocusGroupRef = ref<InstanceType<typeof RovingFocusGroup>>()\n\n// Virtualizer\nconst isVirtual = ref(false)\nconst virtualKeydownHook = createEventHook<KeyboardEvent>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n // @ts-expect-error idk\n defaultValue: props.defaultValue ?? (multiple.value ? [] : undefined),\n passive: (props.modelValue === undefined) as false,\n deep: true,\n}) as Ref<U | U[]>\n\nconst expanded = useVModel(props, 'expanded', emits, {\n // @ts-expect-error idk\n defaultValue: props.defaultExpanded ?? [],\n passive: (props.expanded === undefined) as false,\n deep: true,\n}) as Ref<string[]>\n\nconst { onSelectItem, handleMultipleReplace } = useSelectionBehavior(modelValue, props)\n\nconst selectedKeys = computed(() => {\n if (multiple.value && Array.isArray(modelValue.value))\n return modelValue.value.map(i => props.getKey(i as any))\n else\n return [props.getKey(modelValue.value as any ?? {})]\n})\n\nfunction flattenItems(items: T[], level: number = 1, parentItem?: T): FlattenedItem<T>[] {\n return items.reduce((acc: FlattenedItem<T>[], item: T, index: number) => {\n const key = props.getKey(item)\n const children = props.getChildren(item)\n const isExpanded = expanded.value.includes(key)\n\n const flattenedItem: FlattenedItem<T> = {\n _id: key,\n value: item,\n index,\n level,\n parentItem,\n hasChildren: !!children,\n bind: {\n 'value': item,\n level,\n 'aria-setsize': items.length,\n 'aria-posinset': index + 1,\n },\n }\n acc.push(flattenedItem)\n\n if (children && isExpanded)\n acc.push(...flattenItems(children, level + 1, item))\n\n return acc\n }, [])\n}\n\nconst expandedItems = computed(() => {\n const items = props.items\n const expandedKeys = expanded.value.map(i => i)\n return flattenItems(items ?? [])\n})\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (isVirtual.value) {\n virtualKeydownHook.trigger(event)\n }\n else {\n const collections = rovingFocusGroupRef.value?.getItems() ?? []\n handleTypeaheadSearch(event.key, collections)\n }\n}\n\nfunction handleKeydownNavigation(event: KeyboardEvent) {\n if (isVirtual.value)\n return\n\n const intent = MAP_KEY_TO_FOCUS_INTENT[event.key]\n nextTick(() => {\n handleMultipleReplace(\n intent,\n getActiveElement(),\n rovingFocusGroupRef.value?.getItems!,\n expandedItems.value.map(i => i.value),\n )\n })\n}\n\nprovideTreeRootContext({\n modelValue,\n selectedKeys,\n onSelect: (val) => {\n const condition = (baseValue: U) => props.getKey(baseValue as any ?? {}) === props.getKey(val)\n const exist = props.multiple && Array.isArray(modelValue.value) ? modelValue.value?.findIndex(condition) !== -1 : undefined\n onSelectItem(val, condition)\n\n if (props.propagateSelect && props.multiple && Array.isArray(modelValue.value)) {\n const children = flatten<U, any>(props.getChildren(val) ?? [])\n if (exist) {\n // remove all child\n modelValue.value = [...modelValue.value]\n .filter(i => !children.some(child => props.getKey(i as any ?? {}) === props.getKey(child as any)))\n }\n else {\n // select all child\n modelValue.value = [...modelValue.value, ...children]\n }\n }\n },\n expanded,\n onToggle(val) {\n const children = val ? props.getChildren(val) : undefined\n if (!children)\n return\n\n const key = props.getKey(val) ?? val\n if (expanded.value.includes(key))\n expanded.value = expanded.value.filter(val => val !== key)\n else\n expanded.value.push(key)\n },\n getKey: props.getKey,\n getChildren: props.getChildren,\n items,\n expandedItems,\n disabled,\n multiple,\n dir,\n propagateSelect,\n\n isVirtual,\n virtualKeydownHook,\n handleMultipleReplace,\n})\n</script>\n\n<template>\n <RovingFocusGroup\n ref=\"rovingFocusGroupRef\"\n as-child\n orientation=\"vertical\"\n :dir=\"dir\"\n >\n <Primitive\n role=\"tree\"\n :as=\"as\"\n :as-child=\"asChild\"\n :aria-multiselectable=\"multiple ? true : undefined\"\n @keydown=\"handleKeydown\"\n @keydown.up.down.shift=\"handleKeydownNavigation\"\n >\n <slot\n :flatten-items=\"expandedItems\"\n :model-value=\"modelValue\"\n :expanded=\"expanded\"\n />\n </Primitive>\n </RovingFocusGroup>\n</template>\n"],"names":["createContext","toRefs","useTypeahead","useDirection","ref","createEventHook","useVModel","useSelectionBehavior","computed","items","MAP_KEY_TO_FOCUS_INTENT","nextTick","getActiveElement","flatten","val"],"mappings":"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"}