123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- // Composables
- import { useProxiedModel } from "../proxiedModel.mjs"; // Utilities
- import { computed, inject, onBeforeUnmount, provide, ref, shallowRef, toRaw } from 'vue';
- import { listOpenStrategy, multipleOpenStrategy, singleOpenStrategy } from "./openStrategies.mjs";
- import { classicSelectStrategy, independentSelectStrategy, independentSingleSelectStrategy, leafSelectStrategy, leafSingleSelectStrategy } from "./selectStrategies.mjs";
- import { getCurrentInstance, getUid, propsFactory } from "../../util/index.mjs"; // Types
- export const VNestedSymbol = Symbol.for('vuetify:nested');
- export const emptyNested = {
- id: shallowRef(),
- root: {
- register: () => null,
- unregister: () => null,
- parents: ref(new Map()),
- children: ref(new Map()),
- open: () => null,
- openOnSelect: () => null,
- select: () => null,
- opened: ref(new Set()),
- selected: ref(new Map()),
- selectedValues: ref([])
- }
- };
- export const makeNestedProps = propsFactory({
- selectStrategy: [String, Function],
- openStrategy: [String, Object],
- opened: Array,
- selected: Array,
- mandatory: Boolean
- }, 'nested');
- export const useNested = props => {
- let isUnmounted = false;
- const children = ref(new Map());
- const parents = ref(new Map());
- const opened = useProxiedModel(props, 'opened', props.opened, v => new Set(v), v => [...v.values()]);
- const selectStrategy = computed(() => {
- if (typeof props.selectStrategy === 'object') return props.selectStrategy;
- switch (props.selectStrategy) {
- case 'single-leaf':
- return leafSingleSelectStrategy(props.mandatory);
- case 'leaf':
- return leafSelectStrategy(props.mandatory);
- case 'independent':
- return independentSelectStrategy(props.mandatory);
- case 'single-independent':
- return independentSingleSelectStrategy(props.mandatory);
- case 'classic':
- default:
- return classicSelectStrategy(props.mandatory);
- }
- });
- const openStrategy = computed(() => {
- if (typeof props.openStrategy === 'object') return props.openStrategy;
- switch (props.openStrategy) {
- case 'list':
- return listOpenStrategy;
- case 'single':
- return singleOpenStrategy;
- case 'multiple':
- default:
- return multipleOpenStrategy;
- }
- });
- const selected = useProxiedModel(props, 'selected', props.selected, v => selectStrategy.value.in(v, children.value, parents.value), v => selectStrategy.value.out(v, children.value, parents.value));
- onBeforeUnmount(() => {
- isUnmounted = true;
- });
- function getPath(id) {
- const path = [];
- let parent = id;
- while (parent != null) {
- path.unshift(parent);
- parent = parents.value.get(parent);
- }
- return path;
- }
- const vm = getCurrentInstance('nested');
- const nested = {
- id: shallowRef(),
- root: {
- opened,
- selected,
- selectedValues: computed(() => {
- const arr = [];
- for (const [key, value] of selected.value.entries()) {
- if (value === 'on') arr.push(key);
- }
- return arr;
- }),
- register: (id, parentId, isGroup) => {
- parentId && id !== parentId && parents.value.set(id, parentId);
- isGroup && children.value.set(id, []);
- if (parentId != null) {
- children.value.set(parentId, [...(children.value.get(parentId) || []), id]);
- }
- },
- unregister: id => {
- if (isUnmounted) return;
- children.value.delete(id);
- const parent = parents.value.get(id);
- if (parent) {
- const list = children.value.get(parent) ?? [];
- children.value.set(parent, list.filter(child => child !== id));
- }
- parents.value.delete(id);
- opened.value.delete(id);
- },
- open: (id, value, event) => {
- vm.emit('click:open', {
- id,
- value,
- path: getPath(id),
- event
- });
- const newOpened = openStrategy.value.open({
- id,
- value,
- opened: new Set(opened.value),
- children: children.value,
- parents: parents.value,
- event
- });
- newOpened && (opened.value = newOpened);
- },
- openOnSelect: (id, value, event) => {
- const newOpened = openStrategy.value.select({
- id,
- value,
- selected: new Map(selected.value),
- opened: new Set(opened.value),
- children: children.value,
- parents: parents.value,
- event
- });
- newOpened && (opened.value = newOpened);
- },
- select: (id, value, event) => {
- vm.emit('click:select', {
- id,
- value,
- path: getPath(id),
- event
- });
- const newSelected = selectStrategy.value.select({
- id,
- value,
- selected: new Map(selected.value),
- children: children.value,
- parents: parents.value,
- event
- });
- newSelected && (selected.value = newSelected);
- nested.root.openOnSelect(id, value, event);
- },
- children,
- parents
- }
- };
- provide(VNestedSymbol, nested);
- return nested.root;
- };
- export const useNestedItem = (id, isGroup) => {
- const parent = inject(VNestedSymbol, emptyNested);
- const uidSymbol = Symbol(getUid());
- const computedId = computed(() => id.value !== undefined ? id.value : uidSymbol);
- const item = {
- ...parent,
- id: computedId,
- open: (open, e) => parent.root.open(computedId.value, open, e),
- openOnSelect: (open, e) => parent.root.openOnSelect(computedId.value, open, e),
- isOpen: computed(() => parent.root.opened.value.has(computedId.value)),
- parent: computed(() => parent.root.parents.value.get(computedId.value)),
- select: (selected, e) => parent.root.select(computedId.value, selected, e),
- isSelected: computed(() => parent.root.selected.value.get(toRaw(computedId.value)) === 'on'),
- isIndeterminate: computed(() => parent.root.selected.value.get(computedId.value) === 'indeterminate'),
- isLeaf: computed(() => !parent.root.children.value.get(computedId.value)),
- isGroupActivator: parent.isGroupActivator
- };
- !parent.isGroupActivator && parent.root.register(computedId.value, parent.id.value, isGroup);
- onBeforeUnmount(() => {
- !parent.isGroupActivator && parent.root.unregister(computedId.value);
- });
- isGroup && provide(VNestedSymbol, item);
- return item;
- };
- export const useNestedGroupActivator = () => {
- const parent = inject(VNestedSymbol, emptyNested);
- provide(VNestedSymbol, {
- ...parent,
- isGroupActivator: true
- });
- };
- //# sourceMappingURL=nested.mjs.map
|