{"version":3,"file":"TreeItem.cjs","sources":["../../src/Tree/TreeItem.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface TreeItemProps<T> extends PrimitiveProps {\n  /** Value given to this item */\n  value: T\n  /** Level of depth */\n  level: number\n}\n\nexport type SelectEvent<T> = CustomEvent<{ originalEvent: PointerEvent | KeyboardEvent, value?: T, isExpanded: boolean, isSelected: boolean }>\nexport type ToggleEvent<T> = CustomEvent<{ originalEvent: PointerEvent | KeyboardEvent, value?: T, isExpanded: boolean, isSelected: boolean }>\n\nexport type TreeItemEmits<T> = {\n  /** Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. */\n  select: [event: SelectEvent<T>]\n  /** Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. */\n  toggle: [event: ToggleEvent<T>]\n}\n\nconst TREE_SELECT = 'tree.select'\nconst TREE_TOGGLE = 'tree.toggle'\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { Primitive, type PrimitiveProps } from '@/Primitive'\nimport { RovingFocusItem } from '@/RovingFocus'\nimport { injectTreeRootContext } from './TreeRoot.vue'\nimport { computed } from 'vue'\nimport { useCollection } from '@/Collection'\nimport { getActiveElement, handleAndDispatchCustomEvent } from '@/shared'\nimport { flatten } from './utils'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<TreeItemProps<T>>(), {\n  as: 'li',\n})\n\nconst emits = defineEmits<TreeItemEmits<T>>()\n\ndefineSlots<{\n  default: (props: {\n    isExpanded: boolean\n    isSelected: boolean\n    isIndeterminate: boolean | undefined\n    handleToggle: () => void\n    handleSelect: () => void\n  }) => any\n}>()\nconst rootContext = injectTreeRootContext()\nconst { getItems } = useCollection()\n\nconst hasChildren = computed(() => !!rootContext.getChildren(props.value))\n\nconst isExpanded = computed(() => {\n  const key = rootContext.getKey(props.value)\n  return rootContext.expanded.value.includes(key)\n})\n\nconst isSelected = computed(() => {\n  const key = rootContext.getKey(props.value)\n  return rootContext.selectedKeys.value.includes(key)\n})\n\nconst isIndeterminate = computed(() => {\n  if (rootContext.propagateSelect.value && isSelected.value && hasChildren.value && Array.isArray(rootContext.modelValue.value)) {\n    const children = flatten<T, any>(rootContext.getChildren(props.value) || [])\n\n    return !children.every(child => rootContext.modelValue.value.find((v: any) => rootContext.getKey(v) === rootContext.getKey(child)))\n  }\n  else {\n    return undefined\n  }\n})\n\nfunction handleKeydownRight(ev: KeyboardEvent) {\n  if (!hasChildren.value)\n    return\n\n  if (isExpanded.value) {\n    // go to first child\n    const collection = getItems().map(i => i.ref)\n    const currentElement = getActiveElement() as HTMLElement\n    const currentIndex = collection.indexOf(currentElement)\n    const list = [...collection].slice(currentIndex)\n    const nextElement = list.find(el => Number(el.getAttribute('data-indent')) === (props.level + 1))\n\n    if (nextElement)\n      nextElement.focus()\n  }\n  else {\n    //  open expanded\n    handleToggleCustomEvent(ev)\n  }\n}\n\nfunction handleKeydownLeft(ev: KeyboardEvent) {\n  if (isExpanded.value) {\n    //  close expanded\n    handleToggleCustomEvent(ev)\n  }\n  else {\n    // go back to parent\n    const collection = getItems().map(i => i.ref)\n    const currentElement = getActiveElement() as HTMLElement\n    const currentIndex = collection.indexOf(currentElement)\n    const list = [...collection].slice(0, currentIndex).reverse()\n    const parentElement = list.find(el => Number(el.getAttribute('data-indent')) === (props.level - 1))\n\n    if (parentElement)\n      parentElement.focus()\n  }\n}\n\nasync function handleSelect(ev: SelectEvent<T>) {\n  emits('select', ev)\n  if (ev?.defaultPrevented)\n    return\n\n  rootContext.onSelect(props.value)\n}\nasync function handleToggle(ev: ToggleEvent<T>) {\n  emits('toggle', ev)\n  if (ev?.defaultPrevented)\n    return\n\n  rootContext.onToggle(props.value)\n}\n\nasync function handleSelectCustomEvent(ev?: PointerEvent | KeyboardEvent) {\n  if (!ev)\n    return\n\n  const eventDetail = { originalEvent: ev, value: props.value, isExpanded: isExpanded.value, isSelected: isSelected.value }\n  handleAndDispatchCustomEvent(TREE_SELECT, handleSelect, eventDetail)\n}\n\nasync function handleToggleCustomEvent(ev?: PointerEvent | KeyboardEvent) {\n  if (!ev)\n    return\n\n  const eventDetail = { originalEvent: ev, value: props.value, isExpanded: isExpanded.value, isSelected: isSelected.value }\n  handleAndDispatchCustomEvent(TREE_TOGGLE, handleToggle, eventDetail)\n}\n\ndefineExpose({\n  isExpanded,\n  isSelected,\n  isIndeterminate,\n  handleToggle: () => rootContext.onToggle(props.value),\n  handleSelect: () => rootContext.onSelect(props.value),\n})\n</script>\n\n<template>\n  <RovingFocusItem\n    as-child\n    :value=\"value\"\n    allow-shift-key\n  >\n    <Primitive\n      v-bind=\"$attrs\"\n      role=\"treeitem\"\n      :as=\"as\"\n      :as-child=\"asChild\"\n      :aria-selected=\"isSelected\"\n      :aria-expanded=\"hasChildren ? isExpanded : undefined\"\n      :aria-level=\"level\"\n      :data-indent=\"level\"\n      :data-selected=\"isSelected ? '' : undefined\"\n      :data-expanded=\"isExpanded ? '' : undefined\"\n      @keydown.enter.space.self.prevent=\"handleSelectCustomEvent\"\n      @keydown.right.prevent=\"(ev) => rootContext.dir.value === 'ltr' ? handleKeydownRight(ev) : handleKeydownLeft(ev)\"\n      @keydown.left.prevent=\"(ev) => rootContext.dir.value === 'ltr' ? handleKeydownLeft(ev) : handleKeydownRight(ev)\"\n      @click.stop=\"(ev) => {\n        handleSelectCustomEvent(ev)\n        handleToggleCustomEvent(ev)\n      }\"\n    >\n      <slot\n        :is-expanded=\"isExpanded\"\n        :is-selected=\"isSelected\"\n        :is-indeterminate=\"isIndeterminate\"\n        :handle-select=\"() => rootContext.onSelect(value)\"\n        :handle-toggle=\"() => rootContext.onToggle(value)\"\n      />\n    </Primitive>\n  </RovingFocusItem>\n</template>\n"],"names":["injectTreeRootContext","useCollection","computed","flatten","getActiveElement","handleAndDispatchCustomEvent"],"mappings":"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"}