@fluentui/react-tree 9.15.15 → 9.16.0
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/CHANGELOG.md +37 -2
- package/dist/index.d.ts +9 -8
- package/lib/components/FlatTree/useFlatControllableCheckedItems.js.map +1 -1
- package/lib/components/FlatTree/useFlatTree.js.map +1 -1
- package/lib/components/FlatTree/useFlatTreeContextValues.js +16 -5
- package/lib/components/FlatTree/useFlatTreeContextValues.js.map +1 -1
- package/lib/components/FlatTree/useFlatTreeStyles.styles.raw.js.map +1 -1
- package/lib/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
- package/lib/components/FlatTreeItem/FlatTreeItem.js.map +1 -1
- package/lib/components/Tree/Tree.types.js.map +1 -1
- package/lib/components/Tree/useNestedControllableCheckedItems.js.map +1 -1
- package/lib/components/Tree/useTreeContextValues.js +16 -5
- package/lib/components/Tree/useTreeContextValues.js.map +1 -1
- package/lib/components/TreeItem/TreeItem.types.js +3 -1
- package/lib/components/TreeItem/TreeItem.types.js.map +1 -1
- package/lib/components/TreeItem/useTreeItemContextValues.js +17 -5
- package/lib/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib/components/TreeItem/useTreeItemStyles.styles.raw.js.map +1 -1
- package/lib/components/TreeItemLayout/TreeItemLayout.types.js.map +1 -1
- package/lib/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib/components/TreeItemPersonaLayout/TreeItemPersonaLayout.types.js.map +1 -1
- package/lib/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.js +0 -1
- package/lib/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.js.map +1 -1
- package/lib/components/TreeProvider.js.map +1 -1
- package/lib/contexts/treeContext.js.map +1 -1
- package/lib/contexts/treeItemContext.js.map +1 -1
- package/lib/hooks/useControllableOpenItems.js.map +1 -1
- package/lib/hooks/useFlatTreeNavigation.js.map +1 -1
- package/lib/hooks/useHTMLElementWalkerRef.js.map +1 -1
- package/lib/hooks/useRootTree.js.map +1 -1
- package/lib/hooks/useRovingTabIndexes.js.map +1 -1
- package/lib/hooks/useSubtree.js +0 -1
- package/lib/hooks/useSubtree.js.map +1 -1
- package/lib/hooks/useTreeNavigation.js.map +1 -1
- package/lib/utils/assert.js +0 -1
- package/lib/utils/assert.js.map +1 -1
- package/lib/utils/createHeadlessTree.js.map +1 -1
- package/lib/utils/flattenTree.js.map +1 -1
- package/lib/utils/nextTypeAheadElement.js.map +1 -1
- package/lib/utils/tokens.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatControllableCheckedItems.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTree.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTreeContextValues.js +17 -5
- package/lib-commonjs/components/FlatTree/useFlatTreeContextValues.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTreeStyles.styles.raw.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
- package/lib-commonjs/components/FlatTreeItem/FlatTreeItem.js.map +1 -1
- package/lib-commonjs/components/Tree/Tree.types.js.map +1 -1
- package/lib-commonjs/components/Tree/useNestedControllableCheckedItems.js.map +1 -1
- package/lib-commonjs/components/Tree/useTreeContextValues.js +16 -5
- package/lib-commonjs/components/Tree/useTreeContextValues.js.map +1 -1
- package/lib-commonjs/components/TreeItem/TreeItem.types.js +3 -3
- package/lib-commonjs/components/TreeItem/TreeItem.types.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js +18 -5
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItemStyles.styles.raw.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/TreeItemLayout.types.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib-commonjs/components/TreeItemPersonaLayout/TreeItemPersonaLayout.types.js.map +1 -1
- package/lib-commonjs/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.js +0 -2
- package/lib-commonjs/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.js.map +1 -1
- package/lib-commonjs/components/TreeProvider.js.map +1 -1
- package/lib-commonjs/contexts/treeContext.js.map +1 -1
- package/lib-commonjs/contexts/treeItemContext.js.map +1 -1
- package/lib-commonjs/hooks/useControllableOpenItems.js.map +1 -1
- package/lib-commonjs/hooks/useFlatTreeNavigation.js.map +1 -1
- package/lib-commonjs/hooks/useHTMLElementWalkerRef.js.map +1 -1
- package/lib-commonjs/hooks/useRootTree.js.map +1 -1
- package/lib-commonjs/hooks/useRovingTabIndexes.js.map +1 -1
- package/lib-commonjs/hooks/useSubtree.js +0 -2
- package/lib-commonjs/hooks/useSubtree.js.map +1 -1
- package/lib-commonjs/hooks/useTreeNavigation.js.map +1 -1
- package/lib-commonjs/utils/assert.js +0 -2
- package/lib-commonjs/utils/assert.js.map +1 -1
- package/lib-commonjs/utils/createHeadlessTree.js.map +1 -1
- package/lib-commonjs/utils/flattenTree.js.map +1 -1
- package/lib-commonjs/utils/nextTypeAheadElement.js.map +1 -1
- package/lib-commonjs/utils/tokens.js.map +1 -1
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/TreeItemLayout/useTreeItemLayout.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n getIntrinsicElementProps,\n isResolvedShorthand,\n useMergedRefs,\n slot,\n useEventCallback,\n elementContains,\n useControllableState,\n} from '@fluentui/react-utilities';\nimport { useTreeItemContext_unstable, useTreeContext_unstable } from '../../contexts';\nimport type {\n TreeItemLayoutActionSlotProps,\n TreeItemLayoutActionVisibilityChangeData,\n TreeItemLayoutProps,\n TreeItemLayoutState,\n} from './TreeItemLayout.types';\nimport { Checkbox, CheckboxProps } from '@fluentui/react-checkbox';\nimport { Radio, RadioProps } from '@fluentui/react-radio';\nimport { TreeItemChevron } from '../TreeItemChevron';\nimport { useArrowNavigationGroup, useIsNavigatingWithKeyboard } from '@fluentui/react-tabster';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\n\n/**\n * Create the state required to render TreeItemLayout.\n *\n * The returned state can be modified with hooks such as useTreeItemLayoutStyles_unstable,\n * before being passed to renderTreeItemLayout_unstable.\n *\n * @param props - props from this instance of TreeItemLayout\n * @param ref - reference to root HTMLElement of TreeItemLayout\n */\nexport const useTreeItemLayout_unstable = (\n props: TreeItemLayoutProps,\n ref: React.Ref<HTMLElement>,\n): TreeItemLayoutState => {\n 'use no memo';\n\n const { main, iconAfter, iconBefore } = props;\n\n const layoutRef = useTreeItemContext_unstable(ctx => ctx.layoutRef);\n const selectionMode = useTreeContext_unstable(ctx => ctx.selectionMode);\n const navigationMode = useTreeContext_unstable(ctx => ctx.navigationMode ?? 'tree');\n\n const [isActionsVisibleFromProps, onActionVisibilityChange]: [\n TreeItemLayoutActionSlotProps['visible'],\n TreeItemLayoutActionSlotProps['onVisibilityChange'],\n ] = isResolvedShorthand(props.actions)\n ? // .visible .onVisibilityChange prop should not be propagated to the DOM\n [props.actions.visible, props.actions.onVisibilityChange]\n : [undefined, undefined];\n\n const [isActionsVisible, setIsActionsVisible] = useControllableState({\n state: isActionsVisibleFromProps,\n initialState: false,\n });\n\n const selectionRef = useTreeItemContext_unstable(ctx => ctx.selectionRef);\n const expandIconRef = useTreeItemContext_unstable(ctx => ctx.expandIconRef);\n const actionsRef = useTreeItemContext_unstable(ctx => ctx.actionsRef);\n const actionsRefInternal = React.useRef<HTMLDivElement>(null);\n const treeItemRef = useTreeItemContext_unstable(ctx => ctx.treeItemRef);\n const subtreeRef = useTreeItemContext_unstable(ctx => ctx.subtreeRef);\n const checked = useTreeItemContext_unstable(ctx => ctx.checked);\n const isBranch = useTreeItemContext_unstable(ctx => ctx.itemType === 'branch');\n\n // FIXME: Asserting is required here, as converting this to RefObject on context type would be a breaking change\n assertIsRefObject(treeItemRef);\n // FIXME: Asserting is required here, as converting this to RefObject on context type would be a breaking change\n assertIsRefObject(subtreeRef);\n\n const setActionsVisibleIfNotFromSubtree = React.useCallback(\n (event: MouseEvent | FocusEvent) => {\n const isTargetFromSubtree = Boolean(\n subtreeRef.current && elementContains(subtreeRef.current, event.target as Node),\n );\n if (!isTargetFromSubtree) {\n onActionVisibilityChange?.(event, {\n visible: true,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(true);\n }\n },\n [subtreeRef, setIsActionsVisible, onActionVisibilityChange],\n );\n\n const { targetDocument } = useFluent();\n const isNavigatingWithKeyboard = useIsNavigatingWithKeyboard();\n\n const setActionsInvisibleIfNotFromSubtree = React.useCallback(\n (event: FocusEvent | MouseEvent) => {\n const isRelatedTargetFromActions = () =>\n Boolean(actionsRefInternal.current && elementContains(actionsRefInternal.current, event.relatedTarget as Node));\n const isRelatedTargetFromTreeItem = () =>\n Boolean(treeItemRef.current && elementContains(treeItemRef.current, event.relatedTarget as Node));\n const isTargetFromActions = () => Boolean(actionsRefInternal.current?.contains(event.target as Node));\n if (isRelatedTargetFromActions()) {\n onActionVisibilityChange?.(event, {\n visible: true,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(true);\n return;\n }\n if (isTargetFromActions() && isRelatedTargetFromTreeItem()) {\n return;\n }\n // when a mouseout event happens during keyboard interaction\n // we should not hide the actions if the activeElement is the treeitem or an action\n // as the focus on the treeitem takes precedence over the mouseout event\n if (\n event.type === 'mouseout' &&\n isNavigatingWithKeyboard() &&\n (targetDocument?.activeElement === treeItemRef.current ||\n elementContains(actionsRefInternal.current, targetDocument?.activeElement as Node))\n ) {\n return;\n }\n onActionVisibilityChange?.(event, {\n visible: false,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(false);\n },\n [setIsActionsVisible, onActionVisibilityChange, treeItemRef, isNavigatingWithKeyboard, targetDocument],\n );\n\n const expandIcon = slot.optional(props.expandIcon, {\n renderByDefault: isBranch,\n defaultProps: {\n children: <TreeItemChevron />,\n 'aria-hidden': true,\n },\n elementType: 'div',\n });\n const expandIconRefs = useMergedRefs(expandIcon?.ref, expandIconRef);\n if (expandIcon) {\n expandIcon.ref = expandIconRefs;\n }\n const arrowNavigationProps = useArrowNavigationGroup({ circular: navigationMode === 'tree', axis: 'horizontal' });\n const actions = isActionsVisible\n ? slot.optional(props.actions, {\n defaultProps: { ...arrowNavigationProps, role: 'toolbar' },\n elementType: 'div',\n })\n : undefined;\n delete actions?.visible;\n delete actions?.onVisibilityChange;\n\n const actionsRefs = useMergedRefs(actions?.ref, actionsRef, actionsRefInternal);\n const handleActionsBlur = useEventCallback((event: React.FocusEvent<HTMLDivElement>) => {\n if (isResolvedShorthand(props.actions)) {\n props.actions.onBlur?.(event);\n }\n const isRelatedTargetFromActions = Boolean(elementContains(event.currentTarget, event.relatedTarget as Node));\n onActionVisibilityChange?.(event, {\n visible: isRelatedTargetFromActions,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n setIsActionsVisible(isRelatedTargetFromActions);\n });\n if (actions) {\n actions.ref = actionsRefs;\n actions.onBlur = handleActionsBlur;\n }\n\n const hasActions = Boolean(props.actions);\n\n React.useEffect(() => {\n if (treeItemRef.current && hasActions) {\n const treeItemElement = treeItemRef.current;\n\n const handleMouseOver = setActionsVisibleIfNotFromSubtree;\n const handleMouseOut = setActionsInvisibleIfNotFromSubtree;\n const handleFocus = setActionsVisibleIfNotFromSubtree;\n const handleBlur = setActionsInvisibleIfNotFromSubtree;\n\n treeItemElement.addEventListener('mouseover', handleMouseOver);\n treeItemElement.addEventListener('mouseout', handleMouseOut);\n treeItemElement.addEventListener('focus', handleFocus);\n treeItemElement.addEventListener('blur', handleBlur);\n\n return () => {\n treeItemElement.removeEventListener('mouseover', handleMouseOver);\n treeItemElement.removeEventListener('mouseout', handleMouseOut);\n treeItemElement.removeEventListener('focus', handleFocus);\n treeItemElement.removeEventListener('blur', handleBlur);\n };\n }\n }, [hasActions, treeItemRef, setActionsVisibleIfNotFromSubtree, setActionsInvisibleIfNotFromSubtree]);\n\n return {\n components: {\n root: 'div',\n expandIcon: 'div',\n iconBefore: 'div',\n main: 'div',\n iconAfter: 'div',\n actions: 'div',\n aside: 'div',\n // Casting here to a union between checkbox and radio\n selector: (selectionMode === 'multiselect' ? Checkbox : Radio) as React.ElementType<CheckboxProps | RadioProps>,\n },\n buttonContextValue: { size: 'small' },\n root: slot.always(\n getIntrinsicElementProps('div', {\n ...props,\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: useMergedRefs(ref, layoutRef) as React.Ref<HTMLDivElement>,\n }),\n {\n elementType: 'div',\n },\n ),\n iconBefore: slot.optional(iconBefore, { elementType: 'div' }),\n main: slot.always(main, { elementType: 'div' }),\n iconAfter: slot.optional(iconAfter, { elementType: 'div' }),\n aside: !isActionsVisible ? slot.optional(props.aside, { elementType: 'div' }) : undefined,\n actions,\n expandIcon,\n selector: slot.optional(props.selector, {\n renderByDefault: selectionMode !== 'none',\n defaultProps: {\n checked,\n tabIndex: -1,\n 'aria-hidden': true,\n ref: selectionRef,\n // casting here to a union between checkbox and radio\n // since ref is not present on the selector signature\n // FIXME: look into Slot type to see if we can make this work\n } as CheckboxProps | RadioProps,\n elementType: (selectionMode === 'multiselect' ? Checkbox : Radio) as React.ElementType<\n CheckboxProps | RadioProps\n >,\n }),\n };\n};\n\nfunction assertIsRefObject<Value>(ref?: React.Ref<Value>): asserts ref is React.RefObject<Value> {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof ref !== 'object' || ref === null || !('current' in ref)) {\n throw new Error(`\n @fluentui/react-tree [${useTreeItemLayout_unstable.name}]:\n Internal Error: contextual ref is not a RefObject! Please report this bug immediately, as contextual refs should be RefObjects.\n `);\n }\n }\n}\n"],"names":["React","getIntrinsicElementProps","isResolvedShorthand","useMergedRefs","slot","useEventCallback","elementContains","useControllableState","useTreeItemContext_unstable","useTreeContext_unstable","Checkbox","Radio","TreeItemChevron","useArrowNavigationGroup","useIsNavigatingWithKeyboard","useFluent_unstable","useFluent","useTreeItemLayout_unstable","props","ref","main","iconAfter","iconBefore","layoutRef","ctx","selectionMode","navigationMode","isActionsVisibleFromProps","onActionVisibilityChange","actions","visible","onVisibilityChange","undefined","isActionsVisible","setIsActionsVisible","state","initialState","selectionRef","expandIconRef","actionsRef","actionsRefInternal","useRef","treeItemRef","subtreeRef","checked","isBranch","itemType","assertIsRefObject","setActionsVisibleIfNotFromSubtree","useCallback","event","isTargetFromSubtree","Boolean","current","target","type","defaultPrevented","targetDocument","isNavigatingWithKeyboard","setActionsInvisibleIfNotFromSubtree","isRelatedTargetFromActions","relatedTarget","isRelatedTargetFromTreeItem","isTargetFromActions","contains","activeElement","expandIcon","optional","renderByDefault","defaultProps","children","elementType","expandIconRefs","arrowNavigationProps","circular","axis","role","actionsRefs","handleActionsBlur","onBlur","currentTarget","hasActions","useEffect","treeItemElement","handleMouseOver","handleMouseOut","handleFocus","handleBlur","addEventListener","removeEventListener","components","root","aside","selector","buttonContextValue","size","always","tabIndex","process","env","NODE_ENV","Error","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TreeItemLayout/useTreeItemLayout.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n getIntrinsicElementProps,\n isResolvedShorthand,\n useMergedRefs,\n slot,\n useEventCallback,\n elementContains,\n useControllableState,\n} from '@fluentui/react-utilities';\nimport { useTreeItemContext_unstable, useTreeContext_unstable } from '../../contexts';\nimport type {\n TreeItemLayoutActionSlotProps,\n TreeItemLayoutActionVisibilityChangeData,\n TreeItemLayoutProps,\n TreeItemLayoutState,\n} from './TreeItemLayout.types';\nimport type { CheckboxProps } from '@fluentui/react-checkbox';\nimport { Checkbox } from '@fluentui/react-checkbox';\nimport type { RadioProps } from '@fluentui/react-radio';\nimport { Radio } from '@fluentui/react-radio';\nimport { TreeItemChevron } from '../TreeItemChevron';\nimport { useArrowNavigationGroup, useIsNavigatingWithKeyboard } from '@fluentui/react-tabster';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\n\n/**\n * Create the state required to render TreeItemLayout.\n *\n * The returned state can be modified with hooks such as useTreeItemLayoutStyles_unstable,\n * before being passed to renderTreeItemLayout_unstable.\n *\n * @param props - props from this instance of TreeItemLayout\n * @param ref - reference to root HTMLElement of TreeItemLayout\n */\nexport const useTreeItemLayout_unstable = (\n props: TreeItemLayoutProps,\n ref: React.Ref<HTMLElement>,\n): TreeItemLayoutState => {\n 'use no memo';\n\n const { main, iconAfter, iconBefore } = props;\n\n const layoutRef = useTreeItemContext_unstable(ctx => ctx.layoutRef);\n const selectionMode = useTreeContext_unstable(ctx => ctx.selectionMode);\n const navigationMode = useTreeContext_unstable(ctx => ctx.navigationMode ?? 'tree');\n\n const [isActionsVisibleFromProps, onActionVisibilityChange]: [\n TreeItemLayoutActionSlotProps['visible'],\n TreeItemLayoutActionSlotProps['onVisibilityChange'],\n ] = isResolvedShorthand(props.actions)\n ? // .visible .onVisibilityChange prop should not be propagated to the DOM\n [props.actions.visible, props.actions.onVisibilityChange]\n : [undefined, undefined];\n\n const [isActionsVisible, setIsActionsVisible] = useControllableState({\n state: isActionsVisibleFromProps,\n initialState: false,\n });\n\n const selectionRef = useTreeItemContext_unstable(ctx => ctx.selectionRef);\n const expandIconRef = useTreeItemContext_unstable(ctx => ctx.expandIconRef);\n const actionsRef = useTreeItemContext_unstable(ctx => ctx.actionsRef);\n const actionsRefInternal = React.useRef<HTMLDivElement>(null);\n const treeItemRef = useTreeItemContext_unstable(ctx => ctx.treeItemRef);\n const subtreeRef = useTreeItemContext_unstable(ctx => ctx.subtreeRef);\n const checked = useTreeItemContext_unstable(ctx => ctx.checked);\n const isBranch = useTreeItemContext_unstable(ctx => ctx.itemType === 'branch');\n\n // FIXME: Asserting is required here, as converting this to RefObject on context type would be a breaking change\n assertIsRefObject(treeItemRef);\n // FIXME: Asserting is required here, as converting this to RefObject on context type would be a breaking change\n assertIsRefObject(subtreeRef);\n\n const setActionsVisibleIfNotFromSubtree = React.useCallback(\n (event: MouseEvent | FocusEvent) => {\n const isTargetFromSubtree = Boolean(\n subtreeRef.current && elementContains(subtreeRef.current, event.target as Node),\n );\n if (!isTargetFromSubtree) {\n onActionVisibilityChange?.(event, {\n visible: true,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(true);\n }\n },\n [subtreeRef, setIsActionsVisible, onActionVisibilityChange],\n );\n\n const { targetDocument } = useFluent();\n const isNavigatingWithKeyboard = useIsNavigatingWithKeyboard();\n\n const setActionsInvisibleIfNotFromSubtree = React.useCallback(\n (event: FocusEvent | MouseEvent) => {\n const isRelatedTargetFromActions = () =>\n Boolean(actionsRefInternal.current && elementContains(actionsRefInternal.current, event.relatedTarget as Node));\n const isRelatedTargetFromTreeItem = () =>\n Boolean(treeItemRef.current && elementContains(treeItemRef.current, event.relatedTarget as Node));\n const isTargetFromActions = () => Boolean(actionsRefInternal.current?.contains(event.target as Node));\n if (isRelatedTargetFromActions()) {\n onActionVisibilityChange?.(event, {\n visible: true,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(true);\n return;\n }\n if (isTargetFromActions() && isRelatedTargetFromTreeItem()) {\n return;\n }\n // when a mouseout event happens during keyboard interaction\n // we should not hide the actions if the activeElement is the treeitem or an action\n // as the focus on the treeitem takes precedence over the mouseout event\n if (\n event.type === 'mouseout' &&\n isNavigatingWithKeyboard() &&\n (targetDocument?.activeElement === treeItemRef.current ||\n elementContains(actionsRefInternal.current, targetDocument?.activeElement as Node))\n ) {\n return;\n }\n onActionVisibilityChange?.(event, {\n visible: false,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n if (event.defaultPrevented) {\n return;\n }\n setIsActionsVisible(false);\n },\n [setIsActionsVisible, onActionVisibilityChange, treeItemRef, isNavigatingWithKeyboard, targetDocument],\n );\n\n const expandIcon = slot.optional(props.expandIcon, {\n renderByDefault: isBranch,\n defaultProps: {\n children: <TreeItemChevron />,\n 'aria-hidden': true,\n },\n elementType: 'div',\n });\n const expandIconRefs = useMergedRefs(expandIcon?.ref, expandIconRef);\n if (expandIcon) {\n expandIcon.ref = expandIconRefs;\n }\n const arrowNavigationProps = useArrowNavigationGroup({ circular: navigationMode === 'tree', axis: 'horizontal' });\n const actions = isActionsVisible\n ? slot.optional(props.actions, {\n defaultProps: { ...arrowNavigationProps, role: 'toolbar' },\n elementType: 'div',\n })\n : undefined;\n delete actions?.visible;\n delete actions?.onVisibilityChange;\n\n const actionsRefs = useMergedRefs(actions?.ref, actionsRef, actionsRefInternal);\n const handleActionsBlur = useEventCallback((event: React.FocusEvent<HTMLDivElement>) => {\n if (isResolvedShorthand(props.actions)) {\n props.actions.onBlur?.(event);\n }\n const isRelatedTargetFromActions = Boolean(elementContains(event.currentTarget, event.relatedTarget as Node));\n onActionVisibilityChange?.(event, {\n visible: isRelatedTargetFromActions,\n event,\n type: event.type,\n } as Extract<TreeItemLayoutActionVisibilityChangeData, { event: typeof event }>);\n setIsActionsVisible(isRelatedTargetFromActions);\n });\n if (actions) {\n actions.ref = actionsRefs;\n actions.onBlur = handleActionsBlur;\n }\n\n const hasActions = Boolean(props.actions);\n\n React.useEffect(() => {\n if (treeItemRef.current && hasActions) {\n const treeItemElement = treeItemRef.current;\n\n const handleMouseOver = setActionsVisibleIfNotFromSubtree;\n const handleMouseOut = setActionsInvisibleIfNotFromSubtree;\n const handleFocus = setActionsVisibleIfNotFromSubtree;\n const handleBlur = setActionsInvisibleIfNotFromSubtree;\n\n treeItemElement.addEventListener('mouseover', handleMouseOver);\n treeItemElement.addEventListener('mouseout', handleMouseOut);\n treeItemElement.addEventListener('focus', handleFocus);\n treeItemElement.addEventListener('blur', handleBlur);\n\n return () => {\n treeItemElement.removeEventListener('mouseover', handleMouseOver);\n treeItemElement.removeEventListener('mouseout', handleMouseOut);\n treeItemElement.removeEventListener('focus', handleFocus);\n treeItemElement.removeEventListener('blur', handleBlur);\n };\n }\n }, [hasActions, treeItemRef, setActionsVisibleIfNotFromSubtree, setActionsInvisibleIfNotFromSubtree]);\n\n return {\n components: {\n root: 'div',\n expandIcon: 'div',\n iconBefore: 'div',\n main: 'div',\n iconAfter: 'div',\n actions: 'div',\n aside: 'div',\n // Casting here to a union between checkbox and radio\n selector: (selectionMode === 'multiselect' ? Checkbox : Radio) as React.ElementType<CheckboxProps | RadioProps>,\n },\n buttonContextValue: { size: 'small' },\n root: slot.always(\n getIntrinsicElementProps('div', {\n ...props,\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: useMergedRefs(ref, layoutRef) as React.Ref<HTMLDivElement>,\n }),\n {\n elementType: 'div',\n },\n ),\n iconBefore: slot.optional(iconBefore, { elementType: 'div' }),\n main: slot.always(main, { elementType: 'div' }),\n iconAfter: slot.optional(iconAfter, { elementType: 'div' }),\n aside: !isActionsVisible ? slot.optional(props.aside, { elementType: 'div' }) : undefined,\n actions,\n expandIcon,\n selector: slot.optional(props.selector, {\n renderByDefault: selectionMode !== 'none',\n defaultProps: {\n checked,\n tabIndex: -1,\n 'aria-hidden': true,\n ref: selectionRef,\n // casting here to a union between checkbox and radio\n // since ref is not present on the selector signature\n // FIXME: look into Slot type to see if we can make this work\n } as CheckboxProps | RadioProps,\n elementType: (selectionMode === 'multiselect' ? Checkbox : Radio) as React.ElementType<\n CheckboxProps | RadioProps\n >,\n }),\n };\n};\n\nfunction assertIsRefObject<Value>(ref?: React.Ref<Value>): asserts ref is React.RefObject<Value> {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof ref !== 'object' || ref === null || !('current' in ref)) {\n throw new Error(`\n @fluentui/react-tree [${useTreeItemLayout_unstable.name}]:\n Internal Error: contextual ref is not a RefObject! Please report this bug immediately, as contextual refs should be RefObjects.\n `);\n }\n }\n}\n"],"names":["React","getIntrinsicElementProps","isResolvedShorthand","useMergedRefs","slot","useEventCallback","elementContains","useControllableState","useTreeItemContext_unstable","useTreeContext_unstable","Checkbox","Radio","TreeItemChevron","useArrowNavigationGroup","useIsNavigatingWithKeyboard","useFluent_unstable","useFluent","useTreeItemLayout_unstable","props","ref","main","iconAfter","iconBefore","layoutRef","ctx","selectionMode","navigationMode","isActionsVisibleFromProps","onActionVisibilityChange","actions","visible","onVisibilityChange","undefined","isActionsVisible","setIsActionsVisible","state","initialState","selectionRef","expandIconRef","actionsRef","actionsRefInternal","useRef","treeItemRef","subtreeRef","checked","isBranch","itemType","assertIsRefObject","setActionsVisibleIfNotFromSubtree","useCallback","event","isTargetFromSubtree","Boolean","current","target","type","defaultPrevented","targetDocument","isNavigatingWithKeyboard","setActionsInvisibleIfNotFromSubtree","isRelatedTargetFromActions","relatedTarget","isRelatedTargetFromTreeItem","isTargetFromActions","contains","activeElement","expandIcon","optional","renderByDefault","defaultProps","children","elementType","expandIconRefs","arrowNavigationProps","circular","axis","role","actionsRefs","handleActionsBlur","onBlur","currentTarget","hasActions","useEffect","treeItemElement","handleMouseOver","handleMouseOut","handleFocus","handleBlur","addEventListener","removeEventListener","components","root","aside","selector","buttonContextValue","size","always","tabIndex","process","env","NODE_ENV","Error","name"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/TreeItemPersonaLayout/TreeItemPersonaLayout.types.ts"],"sourcesContent":["import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\nimport type { AvatarContextValue, AvatarSize } from '@fluentui/react-avatar';\nimport { ButtonContextValue } from '@fluentui/react-button';\nimport { TreeItemLayoutSlots } from '../TreeItemLayout/TreeItemLayout.types';\n\nexport type TreeItemPersonaLayoutContextValues = {\n avatar: AvatarContextValue;\n};\n\nexport type TreeItemPersonaLayoutSlots = Pick<TreeItemLayoutSlots, 'actions' | 'aside' | 'expandIcon' | 'selector'> & {\n root: NonNullable<Slot<'div'>>;\n /**\n * Avatar to display.\n */\n media: NonNullable<Slot<'div'>>;\n /**\n * Content. Children of the root slot are automatically rendered here\n */\n main: NonNullable<Slot<'div'>>;\n /**\n * Secondary text that describes or complements the content\n */\n description?: Slot<'div'>;\n};\n\n/**\n * TreeItemPersonaLayout Props\n */\nexport type TreeItemPersonaLayoutProps = ComponentProps<Partial<TreeItemPersonaLayoutSlots>>;\n\n/**\n * State used in rendering TreeItemPersonaLayout\n */\nexport type TreeItemPersonaLayoutState = ComponentState<TreeItemPersonaLayoutSlots> & {\n avatarSize: AvatarSize;\n buttonContextValue: ButtonContextValue;\n};\n"],"names":[],"mappings":"AA8BA;;CAEC,GACD,WAGE"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TreeItemPersonaLayout/TreeItemPersonaLayout.types.ts"],"sourcesContent":["import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\nimport type { AvatarContextValue, AvatarSize } from '@fluentui/react-avatar';\nimport type { ButtonContextValue } from '@fluentui/react-button';\nimport type { TreeItemLayoutSlots } from '../TreeItemLayout/TreeItemLayout.types';\n\nexport type TreeItemPersonaLayoutContextValues = {\n avatar: AvatarContextValue;\n};\n\nexport type TreeItemPersonaLayoutSlots = Pick<TreeItemLayoutSlots, 'actions' | 'aside' | 'expandIcon' | 'selector'> & {\n root: NonNullable<Slot<'div'>>;\n /**\n * Avatar to display.\n */\n media: NonNullable<Slot<'div'>>;\n /**\n * Content. Children of the root slot are automatically rendered here\n */\n main: NonNullable<Slot<'div'>>;\n /**\n * Secondary text that describes or complements the content\n */\n description?: Slot<'div'>;\n};\n\n/**\n * TreeItemPersonaLayout Props\n */\nexport type TreeItemPersonaLayoutProps = ComponentProps<Partial<TreeItemPersonaLayoutSlots>>;\n\n/**\n * State used in rendering TreeItemPersonaLayout\n */\nexport type TreeItemPersonaLayoutState = ComponentState<TreeItemPersonaLayoutSlots> & {\n avatarSize: AvatarSize;\n buttonContextValue: ButtonContextValue;\n};\n"],"names":[],"mappings":"AA8BA;;CAEC,GACD,WAGE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { TreeItemPersonaLayoutProps, TreeItemPersonaLayoutState } from './TreeItemPersonaLayout.types';\nimport { slot } from '@fluentui/react-utilities';\nimport { useTreeContext_unstable } from '../../contexts';\nimport { treeAvatarSize } from '../../utils/tokens';\nimport { useTreeItemLayout_unstable } from '../TreeItemLayout/useTreeItemLayout';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/components/TreeItemPersonaLayout/useTreeItemPersonaLayout.ts"],"sourcesContent":["'use client';\n\nimport type * as React from 'react';\nimport type { TreeItemPersonaLayoutProps, TreeItemPersonaLayoutState } from './TreeItemPersonaLayout.types';\nimport { slot } from '@fluentui/react-utilities';\nimport { useTreeContext_unstable } from '../../contexts';\nimport { treeAvatarSize } from '../../utils/tokens';\nimport { useTreeItemLayout_unstable } from '../TreeItemLayout/useTreeItemLayout';\nimport type { CheckboxProps } from '@fluentui/react-checkbox';\nimport { Checkbox } from '@fluentui/react-checkbox';\nimport type { RadioProps } from '@fluentui/react-radio';\nimport { Radio } from '@fluentui/react-radio';\n\n/**\n * Create the state required to render TreeItemPersonaLayout.\n *\n * The returned state can be modified with hooks such as useTreeItemPersonaLayoutStyles_unstable,\n * before being passed to renderTreeItemPersonaLayout_unstable.\n *\n * @param props - props from this instance of TreeItemPersonaLayout\n * @param ref - reference to root HTMLElement of TreeItemPersonaLayout\n */\nexport const useTreeItemPersonaLayout_unstable = (\n props: TreeItemPersonaLayoutProps,\n ref: React.Ref<HTMLSpanElement>,\n): TreeItemPersonaLayoutState => {\n const { media, children, main, description } = props;\n\n const treeItemLayoutState = useTreeItemLayout_unstable(\n {\n ...props,\n iconBefore: null,\n iconAfter: null,\n },\n ref,\n );\n\n const size = useTreeContext_unstable(ctx => ctx.size);\n const selectionMode = useTreeContext_unstable(ctx => ctx.selectionMode);\n\n return {\n ...treeItemLayoutState,\n components: {\n expandIcon: 'div',\n main: 'div',\n description: 'div',\n root: 'div',\n media: 'div',\n aside: 'div',\n actions: 'div',\n // Casting here to a union between checkbox and radio\n selector: (selectionMode === 'multiselect' ? Checkbox : Radio) as React.ElementType<CheckboxProps | RadioProps>,\n },\n avatarSize: treeAvatarSize[size],\n main: slot.always(main, { defaultProps: { children }, elementType: 'div' }),\n media: slot.always(media, { elementType: 'div' }),\n description: slot.optional(description, { elementType: 'div' }),\n };\n};\n"],"names":["slot","useTreeContext_unstable","treeAvatarSize","useTreeItemLayout_unstable","Checkbox","Radio","useTreeItemPersonaLayout_unstable","props","ref","media","children","main","description","treeItemLayoutState","iconBefore","iconAfter","size","ctx","selectionMode","components","expandIcon","root","aside","actions","selector","avatarSize","always","defaultProps","elementType","optional"],"mappings":"AAAA;AAIA,SAASA,IAAI,QAAQ,4BAA4B;AACjD,SAASC,uBAAuB,QAAQ,iBAAiB;AACzD,SAASC,cAAc,QAAQ,qBAAqB;AACpD,SAASC,0BAA0B,QAAQ,sCAAsC;AAEjF,SAASC,QAAQ,QAAQ,2BAA2B;AAEpD,SAASC,KAAK,QAAQ,wBAAwB;AAE9C;;;;;;;;CAQC,GACD,OAAO,MAAMC,oCAAoC,CAC/CC,OACAC;IAEA,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGL;IAE/C,MAAMM,sBAAsBV,2BAC1B;QACE,GAAGI,KAAK;QACRO,YAAY;QACZC,WAAW;IACb,GACAP;IAGF,MAAMQ,OAAOf,wBAAwBgB,CAAAA,MAAOA,IAAID,IAAI;IACpD,MAAME,gBAAgBjB,wBAAwBgB,CAAAA,MAAOA,IAAIC,aAAa;IAEtE,OAAO;QACL,GAAGL,mBAAmB;QACtBM,YAAY;YACVC,YAAY;YACZT,MAAM;YACNC,aAAa;YACbS,MAAM;YACNZ,OAAO;YACPa,OAAO;YACPC,SAAS;YACT,qDAAqD;YACrDC,UAAWN,kBAAkB,gBAAgBd,WAAWC;QAC1D;QACAoB,YAAYvB,cAAc,CAACc,KAAK;QAChCL,MAAMX,KAAK0B,MAAM,CAACf,MAAM;YAAEgB,cAAc;gBAAEjB;YAAS;YAAGkB,aAAa;QAAM;QACzEnB,OAAOT,KAAK0B,MAAM,CAACjB,OAAO;YAAEmB,aAAa;QAAM;QAC/ChB,aAAaZ,KAAK6B,QAAQ,CAACjB,aAAa;YAAEgB,aAAa;QAAM;IAC/D;AACF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/TreeProvider.tsx"],"sourcesContent":["import * as React from 'react';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/components/TreeProvider.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { SubtreeContextValue, TreeContextValue } from '../contexts';\nimport { SubtreeContext, TreeContext } from '../contexts';\nimport type { JSXElement } from '@fluentui/react-utilities';\n\n/**\n * @internal\n */\nconst rootSubtreeContextValue: SubtreeContextValue = {\n level: 1,\n contextType: 'subtree',\n};\nexport const TreeProvider = (props: React.ProviderProps<TreeContextValue | SubtreeContextValue>): JSXElement => {\n if (props.value.contextType === 'subtree') {\n return <SubtreeContext.Provider value={props.value}>{props.children}</SubtreeContext.Provider>;\n }\n return (\n <TreeContext.Provider value={props.value}>\n <SubtreeContext.Provider value={rootSubtreeContextValue}>{props.children}</SubtreeContext.Provider>\n </TreeContext.Provider>\n );\n};\n\nTreeProvider.displayName = 'TreeProvider';\n\nexport type TreeRootResetProps = {\n children?: React.ReactNode;\n};\nexport const TreeRootReset = (props: TreeRootResetProps): JSXElement => (\n <SubtreeContext.Provider value={undefined as unknown as SubtreeContextValue}>\n {props.children}\n </SubtreeContext.Provider>\n);\n"],"names":["React","SubtreeContext","TreeContext","rootSubtreeContextValue","level","contextType","TreeProvider","props","value","Provider","children","displayName","TreeRootReset","undefined"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,cAAc,EAAEC,WAAW,QAAQ,cAAc;AAG1D;;CAEC,GACD,MAAMC,0BAA+C;IACnDC,OAAO;IACPC,aAAa;AACf;AACA,OAAO,MAAMC,eAAe,CAACC;IAC3B,IAAIA,MAAMC,KAAK,CAACH,WAAW,KAAK,WAAW;QACzC,qBAAO,oBAACJ,eAAeQ,QAAQ;YAACD,OAAOD,MAAMC,KAAK;WAAGD,MAAMG,QAAQ;IACrE;IACA,qBACE,oBAACR,YAAYO,QAAQ;QAACD,OAAOD,MAAMC,KAAK;qBACtC,oBAACP,eAAeQ,QAAQ;QAACD,OAAOL;OAA0BI,MAAMG,QAAQ;AAG9E,EAAE;AAEFJ,aAAaK,WAAW,GAAG;AAK3B,OAAO,MAAMC,gBAAgB,CAACL,sBAC5B,oBAACN,eAAeQ,QAAQ;QAACD,OAAOK;OAC7BN,MAAMG,QAAQ,EAEjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contexts/treeContext.ts"],"sourcesContent":["'use client';\n\nimport { Context, ContextSelector
|
|
1
|
+
{"version":3,"sources":["../src/contexts/treeContext.ts"],"sourcesContent":["'use client';\n\nimport type { Context, ContextSelector } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\nimport type { TreeItemType, TreeItemValue } from '../TreeItem';\nimport type { SelectionMode, DistributiveOmit } from '@fluentui/react-utilities';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport { ImmutableMap } from '../utils/ImmutableMap';\nimport type { TreeCheckedChangeData, TreeNavigationData_unstable, TreeOpenChangeData } from '../Tree';\n\nexport type TreeContextValue = {\n contextType?: 'root';\n level: number;\n treeType: 'nested' | 'flat';\n selectionMode: 'none' | SelectionMode;\n appearance: 'subtle' | 'subtle-alpha' | 'transparent';\n size: 'small' | 'medium';\n openItems: ImmutableSet<TreeItemValue>;\n checkedItems: ImmutableMap<TreeItemValue, 'mixed' | boolean>;\n /**\n * requests root Tree component to respond to some tree item event,\n */\n requestTreeResponse(request: TreeItemRequest): void;\n // FIXME: this is only marked as optional to avoid breaking changes\n // it should always be provided internally\n forceUpdateRovingTabIndex?(): void;\n // FIXME: this is only marked as optional to avoid breaking changes\n // it should always be provided internally\n navigationMode?: 'tree' | 'treegrid';\n};\n\nexport type TreeItemRequest = { itemType: TreeItemType } & (\n | (DistributiveOmit<TreeOpenChangeData, 'openItems'> & { requestType: 'open' })\n | (TreeNavigationData_unstable & { requestType: 'navigate' })\n | (DistributiveOmit<TreeCheckedChangeData, 'selectionMode' | 'checkedItems'> & { requestType: 'selection' })\n);\n\n/**\n * @internal\n */\nconst defaultTreeContextValue: TreeContextValue = {\n level: 0,\n contextType: 'root',\n treeType: 'nested',\n selectionMode: 'none',\n openItems: ImmutableSet.empty,\n checkedItems: ImmutableMap.empty,\n requestTreeResponse: noop,\n forceUpdateRovingTabIndex: noop,\n appearance: 'subtle',\n size: 'medium',\n navigationMode: 'tree',\n};\n\nfunction noop() {\n /* noop */\n}\n\n/**\n * @internal\n */\nexport const TreeContext: Context<TreeContextValue> = createContext<TreeContextValue | undefined>(\n undefined,\n) as Context<TreeContextValue>;\n\nexport const useTreeContext_unstable = <T>(selector: ContextSelector<TreeContextValue, T>): T =>\n useContextSelector(TreeContext, (ctx = defaultTreeContextValue) => selector(ctx));\n"],"names":["createContext","useContextSelector","ImmutableSet","ImmutableMap","defaultTreeContextValue","level","contextType","treeType","selectionMode","openItems","empty","checkedItems","requestTreeResponse","noop","forceUpdateRovingTabIndex","appearance","size","navigationMode","TreeContext","undefined","useTreeContext_unstable","selector","ctx"],"mappings":"AAAA;AAGA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,mCAAmC;AAGrF,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,YAAY,QAAQ,wBAAwB;AA8BrD;;CAEC,GACD,MAAMC,0BAA4C;IAChDC,OAAO;IACPC,aAAa;IACbC,UAAU;IACVC,eAAe;IACfC,WAAWP,aAAaQ,KAAK;IAC7BC,cAAcR,aAAaO,KAAK;IAChCE,qBAAqBC;IACrBC,2BAA2BD;IAC3BE,YAAY;IACZC,MAAM;IACNC,gBAAgB;AAClB;AAEA,SAASJ;AACP,QAAQ,GACV;AAEA;;CAEC,GACD,OAAO,MAAMK,cAAyClB,cACpDmB,WAC6B;AAE/B,OAAO,MAAMC,0BAA0B,CAAIC,WACzCpB,mBAAmBiB,aAAa,CAACI,MAAMlB,uBAAuB,GAAKiB,SAASC,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contexts/treeItemContext.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Context, ContextSelector
|
|
1
|
+
{"version":3,"sources":["../src/contexts/treeItemContext.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { Context, ContextSelector } from '@fluentui/react-context-selector';\nimport { createContext, useContextSelector } from '@fluentui/react-context-selector';\nimport type { TreeItemType, TreeItemValue } from '../TreeItem';\nimport { headlessTreeRootId } from '../utils/createHeadlessTree';\nimport type { TreeSelectionValue } from '../Tree';\n\nexport type TreeItemContextValue = {\n /**\n * @deprecated - this value is irrelevant for the tree item\n */\n isActionsVisible: boolean;\n /**\n * @deprecated - this value is irrelevant for the tree item\n */\n isAsideVisible: boolean;\n selectionRef: React.Ref<HTMLInputElement>;\n actionsRef: React.Ref<HTMLDivElement>;\n expandIconRef: React.Ref<HTMLDivElement>;\n layoutRef: React.Ref<HTMLDivElement>;\n // FIXME: this should be React.RefObject<HTMLDivElement>,\n // but as it would be a breaking change, we need to keep it as is for now\n subtreeRef: React.Ref<HTMLDivElement>;\n // FIXME: this is only marked as optional to avoid breaking changes\n // it should always be provided internally\n treeItemRef?: React.RefObject<HTMLDivElement | null>;\n itemType: TreeItemType;\n value: TreeItemValue;\n open: boolean;\n checked: TreeSelectionValue;\n};\n\nconst defaultContextValue: TreeItemContextValue = {\n value: headlessTreeRootId,\n selectionRef: React.createRef(),\n layoutRef: React.createRef(),\n treeItemRef: React.createRef(),\n subtreeRef: React.createRef(),\n actionsRef: React.createRef(),\n expandIconRef: React.createRef(),\n isActionsVisible: false,\n isAsideVisible: false,\n itemType: 'leaf',\n open: false,\n checked: false,\n};\n\nconst TreeItemContext: Context<TreeItemContextValue | undefined> = createContext<TreeItemContextValue | undefined>(\n undefined,\n);\n\nexport const { Provider: TreeItemProvider } = TreeItemContext;\nexport const useTreeItemContext_unstable = <T>(selector: ContextSelector<TreeItemContextValue, T>): T =>\n useContextSelector(TreeItemContext, (ctx = defaultContextValue) => selector(ctx));\n"],"names":["React","createContext","useContextSelector","headlessTreeRootId","defaultContextValue","value","selectionRef","createRef","layoutRef","treeItemRef","subtreeRef","actionsRef","expandIconRef","isActionsVisible","isAsideVisible","itemType","open","checked","TreeItemContext","undefined","Provider","TreeItemProvider","useTreeItemContext_unstable","selector","ctx"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,aAAa,EAAEC,kBAAkB,QAAQ,mCAAmC;AAErF,SAASC,kBAAkB,QAAQ,8BAA8B;AA4BjE,MAAMC,sBAA4C;IAChDC,OAAOF;IACPG,cAAcN,MAAMO,SAAS;IAC7BC,WAAWR,MAAMO,SAAS;IAC1BE,aAAaT,MAAMO,SAAS;IAC5BG,YAAYV,MAAMO,SAAS;IAC3BI,YAAYX,MAAMO,SAAS;IAC3BK,eAAeZ,MAAMO,SAAS;IAC9BM,kBAAkB;IAClBC,gBAAgB;IAChBC,UAAU;IACVC,MAAM;IACNC,SAAS;AACX;AAEA,MAAMC,kBAA6DjB,cACjEkB;AAGF,OAAO,MAAM,EAAEC,UAAUC,gBAAgB,EAAE,GAAGH,gBAAgB;AAC9D,OAAO,MAAMI,8BAA8B,CAAIC,WAC7CrB,mBAAmBgB,iBAAiB,CAACM,MAAMpB,mBAAmB,GAAKmB,SAASC,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useControllableOpenItems.ts"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport type { TreeItemValue } from '../components/TreeItem/TreeItem.types';\nimport { TreeOpenChangeData, TreeProps } from '../Tree';\n\n/**\n * @internal\n */\nexport function useControllableOpenItems(\n props: Pick<TreeProps, 'openItems' | 'defaultOpenItems'>,\n): [ImmutableSet<TreeItemValue>, React.Dispatch<React.SetStateAction<ImmutableSet<TreeItemValue>>>] {\n return useControllableState({\n state: React.useMemo(() => props.openItems && ImmutableSet.from(props.openItems), [props.openItems]),\n defaultState: props.defaultOpenItems && (() => ImmutableSet.from(props.defaultOpenItems)),\n initialState: ImmutableSet.empty,\n });\n}\n\n/**\n * @internal\n */\nexport function createNextOpenItems(\n data: Pick<TreeOpenChangeData, 'value' | 'open'>,\n previousOpenItems: ImmutableSet<TreeItemValue>,\n): ImmutableSet<TreeItemValue> {\n return data.open ? previousOpenItems.add(data.value) : previousOpenItems.delete(data.value);\n}\n"],"names":["useControllableState","React","ImmutableSet","useControllableOpenItems","props","state","useMemo","openItems","from","defaultState","defaultOpenItems","initialState","empty","createNextOpenItems","data","previousOpenItems","open","add","value","delete"],"mappings":"AAAA;AAEA,SAASA,oBAAoB,QAAQ,4BAA4B;AACjE,YAAYC,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,wBAAwB;AAIrD;;CAEC,GACD,OAAO,SAASC,yBACdC,KAAwD;IAExD,OAAOJ,qBAAqB;QAC1BK,OAAOJ,MAAMK,OAAO,CAAC,IAAMF,MAAMG,SAAS,IAAIL,aAAaM,IAAI,CAACJ,MAAMG,SAAS,GAAG;YAACH,MAAMG,SAAS;SAAC;QACnGE,cAAcL,MAAMM,gBAAgB,IAAK,CAAA,IAAMR,aAAaM,IAAI,CAACJ,MAAMM,gBAAgB,CAAA;QACvFC,cAAcT,aAAaU,KAAK;IAClC;AACF;AAEA;;CAEC,GACD,OAAO,SAASC,oBACdC,IAAgD,EAChDC,iBAA8C;IAE9C,OAAOD,KAAKE,IAAI,GAAGD,kBAAkBE,GAAG,CAACH,KAAKI,KAAK,IAAIH,kBAAkBI,MAAM,CAACL,KAAKI,KAAK;AAC5F"}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useControllableOpenItems.ts"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport type { TreeItemValue } from '../components/TreeItem/TreeItem.types';\nimport type { TreeOpenChangeData, TreeProps } from '../Tree';\n\n/**\n * @internal\n */\nexport function useControllableOpenItems(\n props: Pick<TreeProps, 'openItems' | 'defaultOpenItems'>,\n): [ImmutableSet<TreeItemValue>, React.Dispatch<React.SetStateAction<ImmutableSet<TreeItemValue>>>] {\n return useControllableState({\n state: React.useMemo(() => props.openItems && ImmutableSet.from(props.openItems), [props.openItems]),\n defaultState: props.defaultOpenItems && (() => ImmutableSet.from(props.defaultOpenItems)),\n initialState: ImmutableSet.empty,\n });\n}\n\n/**\n * @internal\n */\nexport function createNextOpenItems(\n data: Pick<TreeOpenChangeData, 'value' | 'open'>,\n previousOpenItems: ImmutableSet<TreeItemValue>,\n): ImmutableSet<TreeItemValue> {\n return data.open ? previousOpenItems.add(data.value) : previousOpenItems.delete(data.value);\n}\n"],"names":["useControllableState","React","ImmutableSet","useControllableOpenItems","props","state","useMemo","openItems","from","defaultState","defaultOpenItems","initialState","empty","createNextOpenItems","data","previousOpenItems","open","add","value","delete"],"mappings":"AAAA;AAEA,SAASA,oBAAoB,QAAQ,4BAA4B;AACjE,YAAYC,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,wBAAwB;AAIrD;;CAEC,GACD,OAAO,SAASC,yBACdC,KAAwD;IAExD,OAAOJ,qBAAqB;QAC1BK,OAAOJ,MAAMK,OAAO,CAAC,IAAMF,MAAMG,SAAS,IAAIL,aAAaM,IAAI,CAACJ,MAAMG,SAAS,GAAG;YAACH,MAAMG,SAAS;SAAC;QACnGE,cAAcL,MAAMM,gBAAgB,IAAK,CAAA,IAAMR,aAAaM,IAAI,CAACJ,MAAMM,gBAAgB,CAAA;QACvFC,cAAcT,aAAaU,KAAK;IAClC;AACF;AAEA;;CAEC,GACD,OAAO,SAASC,oBACdC,IAAgD,EAChDC,iBAA8C;IAE9C,OAAOD,KAAKE,IAAI,GAAGD,kBAAkBE,GAAG,CAACH,KAAKI,KAAK,IAAIH,kBAAkBI,MAAM,CAACL,KAAKI,KAAK;AAC5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useFlatTreeNavigation.ts"],"sourcesContent":["'use client';\n\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { TreeNavigationData_unstable } from '../Tree';\nimport { nextTypeAheadElement } from '../utils/nextTypeAheadElement';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useRovingTabIndex } from './useRovingTabIndexes';\nimport { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport { TreeItemValue } from '../TreeItem';\nimport { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement';\nimport * as React from 'react';\nimport { useHTMLElementWalkerRef } from './useHTMLElementWalkerRef';\nimport { TreeNavigationMode } from '../components/Tree/Tree.types';\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { treeItemLayoutClassNames } from '../TreeItemLayout';\n\nexport function useFlatTreeNavigation(navigationMode: TreeNavigationMode = 'tree'): {\n navigate: (data: TreeNavigationData_unstable) => void;\n rootRef: React.RefCallback<HTMLElement>;\n forceUpdateRovingTabIndex: () => void;\n} {\n 'use no memo';\n\n const { walkerRef, rootRef: walkerRootRef } = useHTMLElementWalkerRef();\n const { rove, forceUpdate: forceUpdateRovingTabIndex, initialize: initializeRovingTabIndex } = useRovingTabIndex();\n const { findFirstFocusable } = useFocusFinders();\n\n const rootRefCallback: React.RefCallback<HTMLElement> = React.useCallback(\n root => {\n if (walkerRef.current && root) {\n initializeRovingTabIndex(walkerRef.current);\n }\n },\n [initializeRovingTabIndex, walkerRef],\n );\n\n function getNextElement(data: TreeNavigationData_unstable) {\n if (!walkerRef.current) {\n return null;\n }\n switch (data.type) {\n case treeDataTypes.Click:\n return data.target;\n case treeDataTypes.TypeAhead:\n walkerRef.current.currentElement = data.target;\n return nextTypeAheadElement(walkerRef.current, data.event.key);\n case treeDataTypes.ArrowLeft: {\n const actions = queryActions(data.target);\n if (navigationMode === 'treegrid' && actions?.contains(data.target.ownerDocument.activeElement)) {\n return data.target;\n }\n const nextElement = parentElement(data.parentValue, walkerRef.current);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n /* #__DE-INDENT__ */ `\n @fluentui/react-tree [useFlatTreeNavigation]:\n \\'ArrowLeft\\' navigation was not possible.\n No parent element found for the current element:\n `,\n data.target,\n );\n }\n return nextElement;\n }\n case treeDataTypes.ArrowRight: {\n if (navigationMode === 'treegrid') {\n const actions = queryActions(data.target);\n if (actions) {\n findFirstFocusable(actions)?.focus();\n }\n return null;\n }\n walkerRef.current.currentElement = data.target;\n const nextElement = firstChild(data.target, walkerRef.current);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n const ariaLevel = Number(data.target.getAttribute('aria-level'));\n // eslint-disable-next-line no-console\n console.warn(\n /* #__DE-INDENT__ */ `\n @fluentui/react-tree [useFlatTreeNavigation]:\n \\'ArrowRight\\' navigation was not possible.\n No element with \"aria-posinset=1\" and \"aria-level=${ariaLevel + 1}\"\n was found after the current element!\n `,\n data.target,\n );\n }\n return nextElement;\n }\n case treeDataTypes.End:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.lastChild();\n case treeDataTypes.Home:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.firstChild();\n case treeDataTypes.ArrowDown:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.nextElement();\n case treeDataTypes.ArrowUp:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.previousElement();\n }\n }\n const navigate = useEventCallback((data: TreeNavigationData_unstable) => {\n const nextElement = getNextElement(data);\n if (nextElement) {\n rove(nextElement);\n }\n });\n return {\n navigate,\n rootRef: useMergedRefs<HTMLElement>(walkerRootRef, rootRefCallback),\n forceUpdateRovingTabIndex,\n } as const;\n}\n\nfunction firstChild(target: HTMLElement, treeWalker: HTMLElementWalker): HTMLElement | null {\n const nextElement = treeWalker.nextElement();\n if (!nextElement) {\n return null;\n }\n const nextElementAriaPosInSet = nextElement.getAttribute('aria-posinset');\n const nextElementAriaLevel = nextElement.getAttribute('aria-level');\n const targetAriaLevel = target.getAttribute('aria-level');\n if (nextElementAriaPosInSet === '1' && Number(nextElementAriaLevel) === Number(targetAriaLevel) + 1) {\n return nextElement;\n }\n return null;\n}\n\nfunction parentElement(parentValue: TreeItemValue | undefined, treeWalker: HTMLElementWalker) {\n if (parentValue === undefined) {\n return null;\n }\n return treeWalker.root.querySelector<HTMLElement>(`[${dataTreeItemValueAttrName}=\"${parentValue}\"]`);\n}\n\nconst queryActions = (target: HTMLElement) =>\n target.querySelector<HTMLElement>(\n `:scope > .${treeItemLayoutClassNames.root} > .${treeItemLayoutClassNames.actions}`,\n );\n"],"names":["useEventCallback","useMergedRefs","nextTypeAheadElement","treeDataTypes","useRovingTabIndex","dataTreeItemValueAttrName","React","useHTMLElementWalkerRef","useFocusFinders","treeItemLayoutClassNames","useFlatTreeNavigation","navigationMode","walkerRef","rootRef","walkerRootRef","rove","forceUpdate","forceUpdateRovingTabIndex","initialize","initializeRovingTabIndex","findFirstFocusable","rootRefCallback","useCallback","root","current","getNextElement","data","type","Click","target","TypeAhead","currentElement","event","key","ArrowLeft","actions","queryActions","contains","ownerDocument","activeElement","nextElement","parentElement","parentValue","process","env","NODE_ENV","console","warn","ArrowRight","focus","firstChild","ariaLevel","Number","getAttribute","End","lastChild","Home","ArrowDown","ArrowUp","previousElement","navigate","treeWalker","nextElementAriaPosInSet","nextElementAriaLevel","targetAriaLevel","undefined","querySelector"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useFlatTreeNavigation.ts"],"sourcesContent":["'use client';\n\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport type { TreeNavigationData_unstable } from '../Tree';\nimport { nextTypeAheadElement } from '../utils/nextTypeAheadElement';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useRovingTabIndex } from './useRovingTabIndexes';\nimport type { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport type { TreeItemValue } from '../TreeItem';\nimport { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement';\nimport * as React from 'react';\nimport { useHTMLElementWalkerRef } from './useHTMLElementWalkerRef';\nimport type { TreeNavigationMode } from '../components/Tree/Tree.types';\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { treeItemLayoutClassNames } from '../TreeItemLayout';\n\nexport function useFlatTreeNavigation(navigationMode: TreeNavigationMode = 'tree'): {\n navigate: (data: TreeNavigationData_unstable) => void;\n rootRef: React.RefCallback<HTMLElement>;\n forceUpdateRovingTabIndex: () => void;\n} {\n 'use no memo';\n\n const { walkerRef, rootRef: walkerRootRef } = useHTMLElementWalkerRef();\n const { rove, forceUpdate: forceUpdateRovingTabIndex, initialize: initializeRovingTabIndex } = useRovingTabIndex();\n const { findFirstFocusable } = useFocusFinders();\n\n const rootRefCallback: React.RefCallback<HTMLElement> = React.useCallback(\n root => {\n if (walkerRef.current && root) {\n initializeRovingTabIndex(walkerRef.current);\n }\n },\n [initializeRovingTabIndex, walkerRef],\n );\n\n function getNextElement(data: TreeNavigationData_unstable) {\n if (!walkerRef.current) {\n return null;\n }\n switch (data.type) {\n case treeDataTypes.Click:\n return data.target;\n case treeDataTypes.TypeAhead:\n walkerRef.current.currentElement = data.target;\n return nextTypeAheadElement(walkerRef.current, data.event.key);\n case treeDataTypes.ArrowLeft: {\n const actions = queryActions(data.target);\n if (navigationMode === 'treegrid' && actions?.contains(data.target.ownerDocument.activeElement)) {\n return data.target;\n }\n const nextElement = parentElement(data.parentValue, walkerRef.current);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n /* #__DE-INDENT__ */ `\n @fluentui/react-tree [useFlatTreeNavigation]:\n \\'ArrowLeft\\' navigation was not possible.\n No parent element found for the current element:\n `,\n data.target,\n );\n }\n return nextElement;\n }\n case treeDataTypes.ArrowRight: {\n if (navigationMode === 'treegrid') {\n const actions = queryActions(data.target);\n if (actions) {\n findFirstFocusable(actions)?.focus();\n }\n return null;\n }\n walkerRef.current.currentElement = data.target;\n const nextElement = firstChild(data.target, walkerRef.current);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n const ariaLevel = Number(data.target.getAttribute('aria-level'));\n // eslint-disable-next-line no-console\n console.warn(\n /* #__DE-INDENT__ */ `\n @fluentui/react-tree [useFlatTreeNavigation]:\n \\'ArrowRight\\' navigation was not possible.\n No element with \"aria-posinset=1\" and \"aria-level=${ariaLevel + 1}\"\n was found after the current element!\n `,\n data.target,\n );\n }\n return nextElement;\n }\n case treeDataTypes.End:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.lastChild();\n case treeDataTypes.Home:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.firstChild();\n case treeDataTypes.ArrowDown:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.nextElement();\n case treeDataTypes.ArrowUp:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.previousElement();\n }\n }\n const navigate = useEventCallback((data: TreeNavigationData_unstable) => {\n const nextElement = getNextElement(data);\n if (nextElement) {\n rove(nextElement);\n }\n });\n return {\n navigate,\n rootRef: useMergedRefs<HTMLElement>(walkerRootRef, rootRefCallback),\n forceUpdateRovingTabIndex,\n } as const;\n}\n\nfunction firstChild(target: HTMLElement, treeWalker: HTMLElementWalker): HTMLElement | null {\n const nextElement = treeWalker.nextElement();\n if (!nextElement) {\n return null;\n }\n const nextElementAriaPosInSet = nextElement.getAttribute('aria-posinset');\n const nextElementAriaLevel = nextElement.getAttribute('aria-level');\n const targetAriaLevel = target.getAttribute('aria-level');\n if (nextElementAriaPosInSet === '1' && Number(nextElementAriaLevel) === Number(targetAriaLevel) + 1) {\n return nextElement;\n }\n return null;\n}\n\nfunction parentElement(parentValue: TreeItemValue | undefined, treeWalker: HTMLElementWalker) {\n if (parentValue === undefined) {\n return null;\n }\n return treeWalker.root.querySelector<HTMLElement>(`[${dataTreeItemValueAttrName}=\"${parentValue}\"]`);\n}\n\nconst queryActions = (target: HTMLElement) =>\n target.querySelector<HTMLElement>(\n `:scope > .${treeItemLayoutClassNames.root} > .${treeItemLayoutClassNames.actions}`,\n );\n"],"names":["useEventCallback","useMergedRefs","nextTypeAheadElement","treeDataTypes","useRovingTabIndex","dataTreeItemValueAttrName","React","useHTMLElementWalkerRef","useFocusFinders","treeItemLayoutClassNames","useFlatTreeNavigation","navigationMode","walkerRef","rootRef","walkerRootRef","rove","forceUpdate","forceUpdateRovingTabIndex","initialize","initializeRovingTabIndex","findFirstFocusable","rootRefCallback","useCallback","root","current","getNextElement","data","type","Click","target","TypeAhead","currentElement","event","key","ArrowLeft","actions","queryActions","contains","ownerDocument","activeElement","nextElement","parentElement","parentValue","process","env","NODE_ENV","console","warn","ArrowRight","focus","firstChild","ariaLevel","Number","getAttribute","End","lastChild","Home","ArrowDown","ArrowUp","previousElement","navigate","treeWalker","nextElementAriaPosInSet","nextElementAriaLevel","targetAriaLevel","undefined","querySelector"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useHTMLElementWalkerRef.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport { HTMLElementWalker
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useHTMLElementWalkerRef.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport type { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport { createHTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport { treeItemFilter } from '../utils/treeItemFilter';\n\nexport function useHTMLElementWalkerRef(): {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n walkerRef: React.MutableRefObject<HTMLElementWalker | undefined>;\n rootRef: React.Ref<HTMLElement>;\n} {\n const { targetDocument } = useFluent_unstable();\n\n const walkerRef = React.useRef<HTMLElementWalker>(undefined);\n\n const rootRef: React.Ref<HTMLElement> = React.useCallback(\n (root: HTMLElement) => {\n walkerRef.current =\n targetDocument && root ? createHTMLElementWalker(root, targetDocument, treeItemFilter) : undefined;\n },\n [targetDocument],\n );\n return { walkerRef, rootRef } as const;\n}\n"],"names":["React","useFluent_unstable","createHTMLElementWalker","treeItemFilter","useHTMLElementWalkerRef","targetDocument","walkerRef","useRef","undefined","rootRef","useCallback","root","current"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,kBAAkB,QAAQ,kCAAkC;AAErE,SAASC,uBAAuB,QAAQ,mCAAmC;AAC3E,SAASC,cAAc,QAAQ,0BAA0B;AAEzD,OAAO,SAASC;IAKd,MAAM,EAAEC,cAAc,EAAE,GAAGJ;IAE3B,MAAMK,YAAYN,MAAMO,MAAM,CAAoBC;IAElD,MAAMC,UAAkCT,MAAMU,WAAW,CACvD,CAACC;QACCL,UAAUM,OAAO,GACfP,kBAAkBM,OAAOT,wBAAwBS,MAAMN,gBAAgBF,kBAAkBK;IAC7F,GACA;QAACH;KAAe;IAElB,OAAO;QAAEC;QAAWG;IAAQ;AAC9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useRootTree.ts"],"sourcesContent":["'use client';\n\nimport { getIntrinsicElementProps, useEventCallback, slot } from '@fluentui/react-utilities';\nimport type { TreeCheckedChangeData, TreeProps, TreeState } from '../Tree';\nimport * as React from 'react';\nimport { Collapse } from '@fluentui/react-motion-components-preview';\nimport { TreeContextValue, TreeItemRequest } from '../contexts/treeContext';\nimport { createCheckedItems } from '../utils/createCheckedItems';\nimport { treeDataTypes } from '../utils/tokens';\nimport { createNextOpenItems } from './useControllableOpenItems';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport { ImmutableMap } from '../utils/ImmutableMap';\n\n/**\n * Create the state required to render the root level tree.\n *\n * @param props - props from this instance of tree\n * @param ref - reference to root HTMLElement of tree\n */\nexport function useRootTree(\n props: TreeProps,\n ref: React.Ref<HTMLElement>,\n): Omit<TreeState & TreeContextValue, 'treeType'> {\n warnIfNoProperPropsRootTree(props);\n\n const { appearance = 'subtle', size = 'medium', selectionMode = 'none' } = props;\n\n const openItems = React.useMemo(() => ImmutableSet.from(props.openItems), [props.openItems]);\n const checkedItems = React.useMemo(() => createCheckedItems(props.checkedItems), [props.checkedItems]);\n\n const requestOpenChange = (request: Extract<TreeItemRequest, { requestType: 'open' }>) => {\n props.onOpenChange?.(request.event, {\n ...request,\n openItems: ImmutableSet.dangerouslyGetInternalSet(createNextOpenItems(request, openItems)),\n });\n };\n\n const requestCheckedChange = (request: Extract<TreeItemRequest, { requestType: 'selection' }>) => {\n if (selectionMode === 'none') {\n return;\n }\n props.onCheckedChange?.(request.event, {\n ...request,\n selectionMode,\n checkedItems: ImmutableMap.dangerouslyGetInternalMap(checkedItems),\n // Casting is required here due to selection | multiselection spreading the union problem\n } as TreeCheckedChangeData);\n };\n\n const requestNavigation = (request: Extract<TreeItemRequest, { requestType: 'navigate' }>) => {\n let isScrollPrevented = false;\n props.onNavigation?.(request.event, {\n ...request,\n preventScroll: () => {\n isScrollPrevented = true;\n },\n isScrollPrevented: () => isScrollPrevented,\n });\n switch (request.type) {\n case treeDataTypes.ArrowDown:\n case treeDataTypes.ArrowUp:\n case treeDataTypes.Home:\n case treeDataTypes.End:\n // stop the default behavior of the event\n // which is to scroll the page\n request.event.preventDefault();\n }\n };\n\n const requestTreeResponse = useEventCallback((request: TreeItemRequest) => {\n switch (request.requestType) {\n case 'navigate':\n return requestNavigation(request);\n case 'open':\n return requestOpenChange(request);\n case 'selection':\n return requestCheckedChange(request);\n }\n });\n\n return {\n components: {\n root: 'div',\n collapseMotion: Collapse,\n },\n contextType: 'root',\n selectionMode,\n navigationMode: props.navigationMode ?? 'tree',\n open: true,\n appearance,\n size,\n level: 1,\n openItems,\n checkedItems,\n requestTreeResponse,\n forceUpdateRovingTabIndex: () => {\n // noop\n },\n root: slot.always(\n getIntrinsicElementProps('div', {\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: ref as React.Ref<HTMLDivElement>,\n role: 'tree',\n 'aria-multiselectable': selectionMode === 'multiselect' ? true : undefined,\n ...props,\n }),\n { elementType: 'div' },\n ),\n collapseMotion: undefined,\n };\n}\n\nfunction warnIfNoProperPropsRootTree(props: Pick<TreeProps, 'aria-label' | 'aria-labelledby'>) {\n if (process.env.NODE_ENV === 'development') {\n if (!props['aria-label'] && !props['aria-labelledby']) {\n // eslint-disable-next-line no-console\n console.warn(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useRootTree]:\n Tree must have either a \\`aria-label\\` or \\`aria-labelledby\\` property defined\n `);\n }\n }\n}\n"],"names":["getIntrinsicElementProps","useEventCallback","slot","React","Collapse","createCheckedItems","treeDataTypes","createNextOpenItems","ImmutableSet","ImmutableMap","useRootTree","props","ref","warnIfNoProperPropsRootTree","appearance","size","selectionMode","openItems","useMemo","from","checkedItems","requestOpenChange","request","onOpenChange","event","dangerouslyGetInternalSet","requestCheckedChange","onCheckedChange","dangerouslyGetInternalMap","requestNavigation","isScrollPrevented","onNavigation","preventScroll","type","ArrowDown","ArrowUp","Home","End","preventDefault","requestTreeResponse","requestType","components","root","collapseMotion","contextType","navigationMode","open","level","forceUpdateRovingTabIndex","always","role","undefined","elementType","process","env","NODE_ENV","console","warn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useRootTree.ts"],"sourcesContent":["'use client';\n\nimport { getIntrinsicElementProps, useEventCallback, slot } from '@fluentui/react-utilities';\nimport type { TreeCheckedChangeData, TreeProps, TreeState } from '../Tree';\nimport * as React from 'react';\nimport { Collapse } from '@fluentui/react-motion-components-preview';\nimport type { TreeContextValue, TreeItemRequest } from '../contexts/treeContext';\nimport { createCheckedItems } from '../utils/createCheckedItems';\nimport { treeDataTypes } from '../utils/tokens';\nimport { createNextOpenItems } from './useControllableOpenItems';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport { ImmutableMap } from '../utils/ImmutableMap';\n\n/**\n * Create the state required to render the root level tree.\n *\n * @param props - props from this instance of tree\n * @param ref - reference to root HTMLElement of tree\n */\nexport function useRootTree(\n props: TreeProps,\n ref: React.Ref<HTMLElement>,\n): Omit<TreeState & TreeContextValue, 'treeType'> {\n warnIfNoProperPropsRootTree(props);\n\n const { appearance = 'subtle', size = 'medium', selectionMode = 'none' } = props;\n\n const openItems = React.useMemo(() => ImmutableSet.from(props.openItems), [props.openItems]);\n const checkedItems = React.useMemo(() => createCheckedItems(props.checkedItems), [props.checkedItems]);\n\n const requestOpenChange = (request: Extract<TreeItemRequest, { requestType: 'open' }>) => {\n props.onOpenChange?.(request.event, {\n ...request,\n openItems: ImmutableSet.dangerouslyGetInternalSet(createNextOpenItems(request, openItems)),\n });\n };\n\n const requestCheckedChange = (request: Extract<TreeItemRequest, { requestType: 'selection' }>) => {\n if (selectionMode === 'none') {\n return;\n }\n props.onCheckedChange?.(request.event, {\n ...request,\n selectionMode,\n checkedItems: ImmutableMap.dangerouslyGetInternalMap(checkedItems),\n // Casting is required here due to selection | multiselection spreading the union problem\n } as TreeCheckedChangeData);\n };\n\n const requestNavigation = (request: Extract<TreeItemRequest, { requestType: 'navigate' }>) => {\n let isScrollPrevented = false;\n props.onNavigation?.(request.event, {\n ...request,\n preventScroll: () => {\n isScrollPrevented = true;\n },\n isScrollPrevented: () => isScrollPrevented,\n });\n switch (request.type) {\n case treeDataTypes.ArrowDown:\n case treeDataTypes.ArrowUp:\n case treeDataTypes.Home:\n case treeDataTypes.End:\n // stop the default behavior of the event\n // which is to scroll the page\n request.event.preventDefault();\n }\n };\n\n const requestTreeResponse = useEventCallback((request: TreeItemRequest) => {\n switch (request.requestType) {\n case 'navigate':\n return requestNavigation(request);\n case 'open':\n return requestOpenChange(request);\n case 'selection':\n return requestCheckedChange(request);\n }\n });\n\n return {\n components: {\n root: 'div',\n collapseMotion: Collapse,\n },\n contextType: 'root',\n selectionMode,\n navigationMode: props.navigationMode ?? 'tree',\n open: true,\n appearance,\n size,\n level: 1,\n openItems,\n checkedItems,\n requestTreeResponse,\n forceUpdateRovingTabIndex: () => {\n // noop\n },\n root: slot.always(\n getIntrinsicElementProps('div', {\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: ref as React.Ref<HTMLDivElement>,\n role: 'tree',\n 'aria-multiselectable': selectionMode === 'multiselect' ? true : undefined,\n ...props,\n }),\n { elementType: 'div' },\n ),\n collapseMotion: undefined,\n };\n}\n\nfunction warnIfNoProperPropsRootTree(props: Pick<TreeProps, 'aria-label' | 'aria-labelledby'>) {\n if (process.env.NODE_ENV === 'development') {\n if (!props['aria-label'] && !props['aria-labelledby']) {\n // eslint-disable-next-line no-console\n console.warn(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useRootTree]:\n Tree must have either a \\`aria-label\\` or \\`aria-labelledby\\` property defined\n `);\n }\n }\n}\n"],"names":["getIntrinsicElementProps","useEventCallback","slot","React","Collapse","createCheckedItems","treeDataTypes","createNextOpenItems","ImmutableSet","ImmutableMap","useRootTree","props","ref","warnIfNoProperPropsRootTree","appearance","size","selectionMode","openItems","useMemo","from","checkedItems","requestOpenChange","request","onOpenChange","event","dangerouslyGetInternalSet","requestCheckedChange","onCheckedChange","dangerouslyGetInternalMap","requestNavigation","isScrollPrevented","onNavigation","preventScroll","type","ArrowDown","ArrowUp","Home","End","preventDefault","requestTreeResponse","requestType","components","root","collapseMotion","contextType","navigationMode","open","level","forceUpdateRovingTabIndex","always","role","undefined","elementType","process","env","NODE_ENV","console","warn"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useRovingTabIndexes.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport { useFocusedElementChange } from '@fluentui/react-tabster';\n\nconst findTreeItemRoot = (element: HTMLElement) => {\n let parent = element.parentElement;\n while (parent && parent.getAttribute('role') !== 'tree') {\n parent = parent.parentElement;\n }\n return parent;\n};\n\n/**\n * https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex\n *\n * @internal\n */\nexport function useRovingTabIndex(): {\n rove: (nextElement: HTMLElement, focusOptions?: FocusOptions) => void;\n initialize: (walker: HTMLElementWalker) => void;\n forceUpdate: () => void;\n} {\n const currentElementRef = React.useRef<HTMLElement | null>(null);\n const walkerRef = React.useRef<HTMLElementWalker | null>(null);\n const { targetDocument } = useFluent();\n\n useFocusedElementChange(element => {\n if (element?.getAttribute('role') === 'treeitem' && walkerRef.current && walkerRef.current.root.contains(element)) {\n const treeitemRoot = findTreeItemRoot(element);\n if (walkerRef.current.root !== treeitemRoot) {\n return;\n }\n rove(element);\n }\n });\n\n const initialize = React.useCallback((walker: HTMLElementWalker) => {\n walkerRef.current = walker;\n walker.currentElement = walker.root;\n let tabbableChild = walker.firstChild(element =>\n element.tabIndex === 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP,\n );\n walker.currentElement = walker.root;\n tabbableChild ??= walker.firstChild();\n if (!tabbableChild) {\n return;\n }\n tabbableChild.tabIndex = 0;\n currentElementRef.current = tabbableChild;\n let nextElement: HTMLElement | null = null;\n while ((nextElement = walker.nextElement()) && nextElement !== tabbableChild) {\n nextElement.tabIndex = -1;\n }\n }, []);\n const rove = React.useCallback((nextElement: HTMLElement, focusOptions?: FocusOptions) => {\n if (!currentElementRef.current) {\n return;\n }\n currentElementRef.current.tabIndex = -1;\n nextElement.tabIndex = 0;\n nextElement.focus(focusOptions);\n currentElementRef.current = nextElement;\n }, []);\n\n const forceUpdate = React.useCallback(() => {\n if (\n (currentElementRef.current === null || !targetDocument?.body.contains(currentElementRef.current)) &&\n walkerRef.current\n ) {\n initialize(walkerRef.current);\n }\n }, [targetDocument, initialize]);\n\n return {\n rove,\n initialize,\n forceUpdate,\n };\n}\n"],"names":["React","useFluent_unstable","useFluent","useFocusedElementChange","findTreeItemRoot","element","parent","parentElement","getAttribute","useRovingTabIndex","currentElementRef","useRef","walkerRef","targetDocument","current","root","contains","treeitemRoot","rove","initialize","useCallback","walker","currentElement","tabbableChild","firstChild","tabIndex","NodeFilter","FILTER_ACCEPT","FILTER_SKIP","nextElement","focusOptions","focus","forceUpdate","body"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,sBAAsBC,SAAS,QAAQ,kCAAkC;AAElF,SAASC,uBAAuB,QAAQ,0BAA0B;AAElE,MAAMC,mBAAmB,CAACC;IACxB,IAAIC,SAASD,QAAQE,aAAa;IAClC,MAAOD,UAAUA,OAAOE,YAAY,CAAC,YAAY,OAAQ;QACvDF,SAASA,OAAOC,aAAa;IAC/B;IACA,OAAOD;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASG;IAKd,MAAMC,oBAAoBV,MAAMW,MAAM,CAAqB;IAC3D,MAAMC,YAAYZ,MAAMW,MAAM,CAA2B;IACzD,MAAM,EAAEE,cAAc,EAAE,GAAGX;IAE3BC,wBAAwBE,CAAAA;QACtB,IAAIA,CAAAA,oBAAAA,8BAAAA,QAASG,YAAY,CAAC,aAAY,cAAcI,UAAUE,OAAO,IAAIF,UAAUE,OAAO,CAACC,IAAI,CAACC,QAAQ,CAACX,UAAU;YACjH,MAAMY,eAAeb,iBAAiBC;YACtC,IAAIO,UAAUE,OAAO,CAACC,IAAI,KAAKE,cAAc;gBAC3C;YACF;YACAC,KAAKb;QACP;IACF;IAEA,MAAMc,aAAanB,MAAMoB,WAAW,CAAC,CAACC;QACpCT,UAAUE,OAAO,GAAGO;QACpBA,OAAOC,cAAc,GAAGD,OAAON,IAAI;QACnC,IAAIQ,gBAAgBF,OAAOG,UAAU,CAACnB,CAAAA,UACpCA,QAAQoB,QAAQ,KAAK,IAAIC,WAAWC,aAAa,GAAGD,WAAWE,WAAW;QAE5EP,OAAOC,cAAc,GAAGD,OAAON,IAAI;QACnCQ,0BAAAA,2BAAAA,gBAAAA,gBAAkBF,OAAOG,UAAU;QACnC,IAAI,CAACD,eAAe;YAClB;QACF;QACAA,cAAcE,QAAQ,GAAG;QACzBf,kBAAkBI,OAAO,GAAGS;QAC5B,IAAIM,cAAkC;QACtC,MAAO,AAACA,CAAAA,cAAcR,OAAOQ,WAAW,EAAC,KAAMA,gBAAgBN,cAAe;YAC5EM,YAAYJ,QAAQ,GAAG,CAAC;QAC1B;IACF,GAAG,EAAE;IACL,MAAMP,OAAOlB,MAAMoB,WAAW,CAAC,CAACS,aAA0BC;QACxD,IAAI,CAACpB,kBAAkBI,OAAO,EAAE;YAC9B;QACF;QACAJ,kBAAkBI,OAAO,CAACW,QAAQ,GAAG,CAAC;QACtCI,YAAYJ,QAAQ,GAAG;QACvBI,YAAYE,KAAK,CAACD;QAClBpB,kBAAkBI,OAAO,GAAGe;IAC9B,GAAG,EAAE;IAEL,MAAMG,cAAchC,MAAMoB,WAAW,CAAC;QACpC,IACE,AAACV,CAAAA,kBAAkBI,OAAO,KAAK,QAAQ,EAACD,2BAAAA,qCAAAA,eAAgBoB,IAAI,CAACjB,QAAQ,CAACN,kBAAkBI,OAAO,EAAA,KAC/FF,UAAUE,OAAO,EACjB;YACAK,WAAWP,UAAUE,OAAO;QAC9B;IACF,GAAG;QAACD;QAAgBM;KAAW;IAE/B,OAAO;QACLD;QACAC;QACAa;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useRovingTabIndexes.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport type { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport { useFocusedElementChange } from '@fluentui/react-tabster';\n\nconst findTreeItemRoot = (element: HTMLElement) => {\n let parent = element.parentElement;\n while (parent && parent.getAttribute('role') !== 'tree') {\n parent = parent.parentElement;\n }\n return parent;\n};\n\n/**\n * https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex\n *\n * @internal\n */\nexport function useRovingTabIndex(): {\n rove: (nextElement: HTMLElement, focusOptions?: FocusOptions) => void;\n initialize: (walker: HTMLElementWalker) => void;\n forceUpdate: () => void;\n} {\n const currentElementRef = React.useRef<HTMLElement | null>(null);\n const walkerRef = React.useRef<HTMLElementWalker | null>(null);\n const { targetDocument } = useFluent();\n\n useFocusedElementChange(element => {\n if (element?.getAttribute('role') === 'treeitem' && walkerRef.current && walkerRef.current.root.contains(element)) {\n const treeitemRoot = findTreeItemRoot(element);\n if (walkerRef.current.root !== treeitemRoot) {\n return;\n }\n rove(element);\n }\n });\n\n const initialize = React.useCallback((walker: HTMLElementWalker) => {\n walkerRef.current = walker;\n walker.currentElement = walker.root;\n let tabbableChild = walker.firstChild(element =>\n element.tabIndex === 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP,\n );\n walker.currentElement = walker.root;\n tabbableChild ??= walker.firstChild();\n if (!tabbableChild) {\n return;\n }\n tabbableChild.tabIndex = 0;\n currentElementRef.current = tabbableChild;\n let nextElement: HTMLElement | null = null;\n while ((nextElement = walker.nextElement()) && nextElement !== tabbableChild) {\n nextElement.tabIndex = -1;\n }\n }, []);\n const rove = React.useCallback((nextElement: HTMLElement, focusOptions?: FocusOptions) => {\n if (!currentElementRef.current) {\n return;\n }\n currentElementRef.current.tabIndex = -1;\n nextElement.tabIndex = 0;\n nextElement.focus(focusOptions);\n currentElementRef.current = nextElement;\n }, []);\n\n const forceUpdate = React.useCallback(() => {\n if (\n (currentElementRef.current === null || !targetDocument?.body.contains(currentElementRef.current)) &&\n walkerRef.current\n ) {\n initialize(walkerRef.current);\n }\n }, [targetDocument, initialize]);\n\n return {\n rove,\n initialize,\n forceUpdate,\n };\n}\n"],"names":["React","useFluent_unstable","useFluent","useFocusedElementChange","findTreeItemRoot","element","parent","parentElement","getAttribute","useRovingTabIndex","currentElementRef","useRef","walkerRef","targetDocument","current","root","contains","treeitemRoot","rove","initialize","useCallback","walker","currentElement","tabbableChild","firstChild","tabIndex","NodeFilter","FILTER_ACCEPT","FILTER_SKIP","nextElement","focusOptions","focus","forceUpdate","body"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,sBAAsBC,SAAS,QAAQ,kCAAkC;AAElF,SAASC,uBAAuB,QAAQ,0BAA0B;AAElE,MAAMC,mBAAmB,CAACC;IACxB,IAAIC,SAASD,QAAQE,aAAa;IAClC,MAAOD,UAAUA,OAAOE,YAAY,CAAC,YAAY,OAAQ;QACvDF,SAASA,OAAOC,aAAa;IAC/B;IACA,OAAOD;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASG;IAKd,MAAMC,oBAAoBV,MAAMW,MAAM,CAAqB;IAC3D,MAAMC,YAAYZ,MAAMW,MAAM,CAA2B;IACzD,MAAM,EAAEE,cAAc,EAAE,GAAGX;IAE3BC,wBAAwBE,CAAAA;QACtB,IAAIA,CAAAA,oBAAAA,8BAAAA,QAASG,YAAY,CAAC,aAAY,cAAcI,UAAUE,OAAO,IAAIF,UAAUE,OAAO,CAACC,IAAI,CAACC,QAAQ,CAACX,UAAU;YACjH,MAAMY,eAAeb,iBAAiBC;YACtC,IAAIO,UAAUE,OAAO,CAACC,IAAI,KAAKE,cAAc;gBAC3C;YACF;YACAC,KAAKb;QACP;IACF;IAEA,MAAMc,aAAanB,MAAMoB,WAAW,CAAC,CAACC;QACpCT,UAAUE,OAAO,GAAGO;QACpBA,OAAOC,cAAc,GAAGD,OAAON,IAAI;QACnC,IAAIQ,gBAAgBF,OAAOG,UAAU,CAACnB,CAAAA,UACpCA,QAAQoB,QAAQ,KAAK,IAAIC,WAAWC,aAAa,GAAGD,WAAWE,WAAW;QAE5EP,OAAOC,cAAc,GAAGD,OAAON,IAAI;QACnCQ,0BAAAA,2BAAAA,gBAAAA,gBAAkBF,OAAOG,UAAU;QACnC,IAAI,CAACD,eAAe;YAClB;QACF;QACAA,cAAcE,QAAQ,GAAG;QACzBf,kBAAkBI,OAAO,GAAGS;QAC5B,IAAIM,cAAkC;QACtC,MAAO,AAACA,CAAAA,cAAcR,OAAOQ,WAAW,EAAC,KAAMA,gBAAgBN,cAAe;YAC5EM,YAAYJ,QAAQ,GAAG,CAAC;QAC1B;IACF,GAAG,EAAE;IACL,MAAMP,OAAOlB,MAAMoB,WAAW,CAAC,CAACS,aAA0BC;QACxD,IAAI,CAACpB,kBAAkBI,OAAO,EAAE;YAC9B;QACF;QACAJ,kBAAkBI,OAAO,CAACW,QAAQ,GAAG,CAAC;QACtCI,YAAYJ,QAAQ,GAAG;QACvBI,YAAYE,KAAK,CAACD;QAClBpB,kBAAkBI,OAAO,GAAGe;IAC9B,GAAG,EAAE;IAEL,MAAMG,cAAchC,MAAMoB,WAAW,CAAC;QACpC,IACE,AAACV,CAAAA,kBAAkBI,OAAO,KAAK,QAAQ,EAACD,2BAAAA,qCAAAA,eAAgBoB,IAAI,CAACjB,QAAQ,CAACN,kBAAkBI,OAAO,EAAA,KAC/FF,UAAUE,OAAO,EACjB;YACAK,WAAWP,UAAUE,OAAO;QAC9B;IACF,GAAG;QAACD;QAAgBM;KAAW;IAE/B,OAAO;QACLD;QACAC;QACAa;IACF;AACF"}
|
package/lib/hooks/useSubtree.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import * as React from 'react';
|
|
3
2
|
import { useSubtreeContext_unstable, useTreeItemContext_unstable } from '../contexts/index';
|
|
4
3
|
import { getIntrinsicElementProps, useMergedRefs, slot } from '@fluentui/react-utilities';
|
|
5
4
|
import { Collapse } from '@fluentui/react-motion-components-preview';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useSubtree.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { TreeProps, TreeState } from '../Tree';\nimport { SubtreeContextValue
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useSubtree.ts"],"sourcesContent":["'use client';\n\nimport type * as React from 'react';\nimport type { TreeProps, TreeState } from '../Tree';\nimport type { SubtreeContextValue } from '../contexts/index';\nimport { useSubtreeContext_unstable, useTreeItemContext_unstable } from '../contexts/index';\nimport { getIntrinsicElementProps, useMergedRefs, slot } from '@fluentui/react-utilities';\nimport { Collapse } from '@fluentui/react-motion-components-preview';\nimport { presenceMotionSlot } from '@fluentui/react-motion';\n\n/**\n * Create the state required to render a sub-level tree.\n *\n * @param props - props from this instance of tree\n * @param ref - reference to root HTMLElement of tree\n */\nexport function useSubtree(\n props: TreeProps,\n ref: React.Ref<HTMLElement>,\n): Omit<TreeState & SubtreeContextValue, 'treeType'> {\n const subtreeRef = useTreeItemContext_unstable(ctx => ctx.subtreeRef);\n\n const { level: parentLevel } = useSubtreeContext_unstable();\n\n const open = useTreeItemContext_unstable(ctx => ctx.open);\n\n return {\n contextType: 'subtree',\n open,\n components: {\n root: 'div',\n collapseMotion: Collapse,\n },\n level: parentLevel + 1,\n root: slot.always(\n getIntrinsicElementProps('div', {\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: useMergedRefs(ref, subtreeRef) as React.Ref<HTMLDivElement>,\n role: 'group',\n ...props,\n }),\n { elementType: 'div' },\n ),\n collapseMotion: presenceMotionSlot(props.collapseMotion, {\n elementType: Collapse,\n defaultProps: {\n visible: open,\n unmountOnExit: true,\n },\n }),\n };\n}\n"],"names":["useSubtreeContext_unstable","useTreeItemContext_unstable","getIntrinsicElementProps","useMergedRefs","slot","Collapse","presenceMotionSlot","useSubtree","props","ref","subtreeRef","ctx","level","parentLevel","open","contextType","components","root","collapseMotion","always","role","elementType","defaultProps","visible","unmountOnExit"],"mappings":"AAAA;AAKA,SAASA,0BAA0B,EAAEC,2BAA2B,QAAQ,oBAAoB;AAC5F,SAASC,wBAAwB,EAAEC,aAAa,EAAEC,IAAI,QAAQ,4BAA4B;AAC1F,SAASC,QAAQ,QAAQ,4CAA4C;AACrE,SAASC,kBAAkB,QAAQ,yBAAyB;AAE5D;;;;;CAKC,GACD,OAAO,SAASC,WACdC,KAAgB,EAChBC,GAA2B;IAE3B,MAAMC,aAAaT,4BAA4BU,CAAAA,MAAOA,IAAID,UAAU;IAEpE,MAAM,EAAEE,OAAOC,WAAW,EAAE,GAAGb;IAE/B,MAAMc,OAAOb,4BAA4BU,CAAAA,MAAOA,IAAIG,IAAI;IAExD,OAAO;QACLC,aAAa;QACbD;QACAE,YAAY;YACVC,MAAM;YACNC,gBAAgBb;QAClB;QACAO,OAAOC,cAAc;QACrBI,MAAMb,KAAKe,MAAM,CACfjB,yBAAyB,OAAO;YAC9B,SAAS;YACT,4EAA4E;YAC5E,4FAA4F;YAC5FO,KAAKN,cAAcM,KAAKC;YACxBU,MAAM;YACN,GAAGZ,KAAK;QACV,IACA;YAAEa,aAAa;QAAM;QAEvBH,gBAAgBZ,mBAAmBE,MAAMU,cAAc,EAAE;YACvDG,aAAahB;YACbiB,cAAc;gBACZC,SAAST;gBACTU,eAAe;YACjB;QACF;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useTreeNavigation.ts"],"sourcesContent":["'use client';\n\nimport { TreeNavigationData_unstable, TreeNavigationMode } from '../components/Tree/Tree.types';\nimport { nextTypeAheadElement } from '../utils/nextTypeAheadElement';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useRovingTabIndex } from './useRovingTabIndexes';\nimport { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport * as React from 'react';\nimport { useHTMLElementWalkerRef } from './useHTMLElementWalkerRef';\nimport { useMergedRefs } from '@fluentui/react-utilities';\nimport { treeItemLayoutClassNames } from '../TreeItemLayout';\nimport { useFocusFinders } from '@fluentui/react-tabster';\n\n/***\n * Hook used to manage navigation in the tree.\n *\n * @param navigationMode - the navigation mode of the tree, 'tree' (default) or 'treegrid'\n */\nexport function useTreeNavigation(navigationMode: TreeNavigationMode = 'tree'): {\n navigate: (data: TreeNavigationData_unstable, focusOptions?: FocusOptions) => HTMLElement | null;\n treeRef: React.RefCallback<HTMLElement>;\n forceUpdateRovingTabIndex: () => void;\n} {\n 'use no memo';\n\n const { rove, initialize: initializeRovingTabIndex, forceUpdate: forceUpdateRovingTabIndex } = useRovingTabIndex();\n const { findFirstFocusable } = useFocusFinders();\n const { walkerRef, rootRef: walkerRootRef } = useHTMLElementWalkerRef();\n\n const rootRefCallback: React.RefCallback<HTMLElement> = React.useCallback(\n root => {\n if (root && walkerRef.current) {\n initializeRovingTabIndex(walkerRef.current);\n }\n },\n [walkerRef, initializeRovingTabIndex],\n );\n\n const getNextElement = (data: TreeNavigationData_unstable) => {\n if (!walkerRef.current) {\n return null;\n }\n switch (data.type) {\n case treeDataTypes.Click:\n return data.target;\n case treeDataTypes.TypeAhead:\n walkerRef.current.currentElement = data.target;\n return nextTypeAheadElement(walkerRef.current, data.event.key);\n case treeDataTypes.ArrowLeft: {\n const actions = queryActions(data.target);\n if (navigationMode === 'treegrid' && actions?.contains(data.target.ownerDocument.activeElement)) {\n return data.target;\n }\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.parentElement();\n }\n case treeDataTypes.ArrowRight:\n if (navigationMode === 'treegrid') {\n const actions = queryActions(data.target);\n if (actions) {\n findFirstFocusable(actions)?.focus();\n }\n return null;\n }\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.firstChild();\n case treeDataTypes.End:\n walkerRef.current.currentElement = walkerRef.current.root;\n return lastChildRecursive(walkerRef.current);\n case treeDataTypes.Home:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.firstChild();\n case treeDataTypes.ArrowDown:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.nextElement();\n case treeDataTypes.ArrowUp:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.previousElement();\n }\n };\n function navigate(data: TreeNavigationData_unstable, focusOptions?: FocusOptions) {\n const nextElement = getNextElement(data);\n if (nextElement) {\n rove(nextElement, focusOptions);\n }\n return nextElement;\n }\n return {\n navigate,\n treeRef: useMergedRefs(walkerRootRef, rootRefCallback) as React.RefCallback<HTMLElement>,\n forceUpdateRovingTabIndex,\n } as const;\n}\n\nfunction lastChildRecursive(walker: HTMLElementWalker) {\n let lastElement: HTMLElement | null = null;\n let nextElement: HTMLElement | null = null;\n while ((nextElement = walker.lastChild())) {\n lastElement = nextElement;\n }\n return lastElement;\n}\n\nconst queryActions = (target: HTMLElement) =>\n target.querySelector<HTMLElement>(\n `:scope > .${treeItemLayoutClassNames.root} > .${treeItemLayoutClassNames.actions}`,\n );\n"],"names":["nextTypeAheadElement","treeDataTypes","useRovingTabIndex","React","useHTMLElementWalkerRef","useMergedRefs","treeItemLayoutClassNames","useFocusFinders","useTreeNavigation","navigationMode","rove","initialize","initializeRovingTabIndex","forceUpdate","forceUpdateRovingTabIndex","findFirstFocusable","walkerRef","rootRef","walkerRootRef","rootRefCallback","useCallback","root","current","getNextElement","data","type","Click","target","TypeAhead","currentElement","event","key","ArrowLeft","actions","queryActions","contains","ownerDocument","activeElement","parentElement","ArrowRight","focus","firstChild","End","lastChildRecursive","Home","ArrowDown","nextElement","ArrowUp","previousElement","navigate","focusOptions","treeRef","walker","lastElement","lastChild","querySelector"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useTreeNavigation.ts"],"sourcesContent":["'use client';\n\nimport type { TreeNavigationData_unstable, TreeNavigationMode } from '../components/Tree/Tree.types';\nimport { nextTypeAheadElement } from '../utils/nextTypeAheadElement';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useRovingTabIndex } from './useRovingTabIndexes';\nimport type { HTMLElementWalker } from '../utils/createHTMLElementWalker';\nimport * as React from 'react';\nimport { useHTMLElementWalkerRef } from './useHTMLElementWalkerRef';\nimport { useMergedRefs } from '@fluentui/react-utilities';\nimport { treeItemLayoutClassNames } from '../TreeItemLayout';\nimport { useFocusFinders } from '@fluentui/react-tabster';\n\n/***\n * Hook used to manage navigation in the tree.\n *\n * @param navigationMode - the navigation mode of the tree, 'tree' (default) or 'treegrid'\n */\nexport function useTreeNavigation(navigationMode: TreeNavigationMode = 'tree'): {\n navigate: (data: TreeNavigationData_unstable, focusOptions?: FocusOptions) => HTMLElement | null;\n treeRef: React.RefCallback<HTMLElement>;\n forceUpdateRovingTabIndex: () => void;\n} {\n 'use no memo';\n\n const { rove, initialize: initializeRovingTabIndex, forceUpdate: forceUpdateRovingTabIndex } = useRovingTabIndex();\n const { findFirstFocusable } = useFocusFinders();\n const { walkerRef, rootRef: walkerRootRef } = useHTMLElementWalkerRef();\n\n const rootRefCallback: React.RefCallback<HTMLElement> = React.useCallback(\n root => {\n if (root && walkerRef.current) {\n initializeRovingTabIndex(walkerRef.current);\n }\n },\n [walkerRef, initializeRovingTabIndex],\n );\n\n const getNextElement = (data: TreeNavigationData_unstable) => {\n if (!walkerRef.current) {\n return null;\n }\n switch (data.type) {\n case treeDataTypes.Click:\n return data.target;\n case treeDataTypes.TypeAhead:\n walkerRef.current.currentElement = data.target;\n return nextTypeAheadElement(walkerRef.current, data.event.key);\n case treeDataTypes.ArrowLeft: {\n const actions = queryActions(data.target);\n if (navigationMode === 'treegrid' && actions?.contains(data.target.ownerDocument.activeElement)) {\n return data.target;\n }\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.parentElement();\n }\n case treeDataTypes.ArrowRight:\n if (navigationMode === 'treegrid') {\n const actions = queryActions(data.target);\n if (actions) {\n findFirstFocusable(actions)?.focus();\n }\n return null;\n }\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.firstChild();\n case treeDataTypes.End:\n walkerRef.current.currentElement = walkerRef.current.root;\n return lastChildRecursive(walkerRef.current);\n case treeDataTypes.Home:\n walkerRef.current.currentElement = walkerRef.current.root;\n return walkerRef.current.firstChild();\n case treeDataTypes.ArrowDown:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.nextElement();\n case treeDataTypes.ArrowUp:\n walkerRef.current.currentElement = data.target;\n return walkerRef.current.previousElement();\n }\n };\n function navigate(data: TreeNavigationData_unstable, focusOptions?: FocusOptions) {\n const nextElement = getNextElement(data);\n if (nextElement) {\n rove(nextElement, focusOptions);\n }\n return nextElement;\n }\n return {\n navigate,\n treeRef: useMergedRefs(walkerRootRef, rootRefCallback) as React.RefCallback<HTMLElement>,\n forceUpdateRovingTabIndex,\n } as const;\n}\n\nfunction lastChildRecursive(walker: HTMLElementWalker) {\n let lastElement: HTMLElement | null = null;\n let nextElement: HTMLElement | null = null;\n while ((nextElement = walker.lastChild())) {\n lastElement = nextElement;\n }\n return lastElement;\n}\n\nconst queryActions = (target: HTMLElement) =>\n target.querySelector<HTMLElement>(\n `:scope > .${treeItemLayoutClassNames.root} > .${treeItemLayoutClassNames.actions}`,\n );\n"],"names":["nextTypeAheadElement","treeDataTypes","useRovingTabIndex","React","useHTMLElementWalkerRef","useMergedRefs","treeItemLayoutClassNames","useFocusFinders","useTreeNavigation","navigationMode","rove","initialize","initializeRovingTabIndex","forceUpdate","forceUpdateRovingTabIndex","findFirstFocusable","walkerRef","rootRef","walkerRootRef","rootRefCallback","useCallback","root","current","getNextElement","data","type","Click","target","TypeAhead","currentElement","event","key","ArrowLeft","actions","queryActions","contains","ownerDocument","activeElement","parentElement","ArrowRight","focus","firstChild","End","lastChildRecursive","Home","ArrowDown","nextElement","ArrowUp","previousElement","navigate","focusOptions","treeRef","walker","lastElement","lastChild","querySelector"],"mappings":"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"}
|
package/lib/utils/assert.js
CHANGED
package/lib/utils/assert.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/assert.ts"],"sourcesContent":["import * as React from 'react';\n\nexport function assertIsDefinedRef<V>(\n refObject: React.RefObject<V | null | undefined>,\n msg = `assertIsDefinedRef: reference not properly defined ${refObject}`,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n): asserts refObject is React.MutableRefObject<V> {\n // eslint-disable-next-line eqeqeq\n if (refObject.current == undefined && process.env.NODE_ENV === 'development') {\n throw new TypeError(msg);\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../src/utils/assert.ts"],"sourcesContent":["import type * as React from 'react';\n\nexport function assertIsDefinedRef<V>(\n refObject: React.RefObject<V | null | undefined>,\n msg = `assertIsDefinedRef: reference not properly defined ${refObject}`,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n): asserts refObject is React.MutableRefObject<V> {\n // eslint-disable-next-line eqeqeq\n if (refObject.current == undefined && process.env.NODE_ENV === 'development') {\n throw new TypeError(msg);\n }\n}\n"],"names":["assertIsDefinedRef","refObject","msg","current","undefined","process","env","NODE_ENV","TypeError"],"mappings":"AAEA,OAAO,SAASA,mBACdC,SAAgD,EAChDC,MAAM,CAAC,mDAAmD,EAAED,WAAW;IAGvE,kCAAkC;IAClC,IAAIA,UAAUE,OAAO,IAAIC,aAAaC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC5E,MAAM,IAAIC,UAAUN;IACtB;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/createHeadlessTree.ts"],"sourcesContent":["import { TreeItemProps, TreeItemType, TreeItemValue } from '../TreeItem';\nimport { ImmutableSet } from './ImmutableSet';\n\nexport type HeadlessTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> & {\n value: TreeItemValue;\n itemType?: TreeItemType;\n parentValue?: TreeItemValue;\n};\n\n/**\n * The item that is returned by `createHeadlessTree`, it represents a wrapper around the properties provided to\n * `createHeadlessTree` but with extra information that might be useful on virtual tree scenarios\n */\nexport type HeadlessTreeItem<Props extends HeadlessTreeItemProps> = {\n level: number;\n index: number;\n position: number;\n childrenValues: TreeItemValue[];\n value: TreeItemValue;\n parentValue: TreeItemValue | undefined;\n itemType: TreeItemType;\n getTreeItemProps(): Required<Pick<Props, 'value' | 'aria-setsize' | 'aria-level' | 'aria-posinset' | 'itemType'>> &\n Props;\n};\n\n/**\n * @internal\n */\nexport type HeadlessTree<Props extends HeadlessTreeItemProps> = {\n /**\n * the number of items in the virtual tree\n */\n readonly size: number;\n /**\n * the root item of the virtual tree\n */\n root: HeadlessTreeItem<HeadlessTreeItemProps>;\n /**\n * method to get a virtual tree item by its value\n * @param key - the key of the item to get\n */\n get(value: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n /**\n * method to check if a virtual tree item exists by its value\n * @param value - the value of the item to check if exists\n */\n has(value: TreeItemValue): boolean;\n /**\n * method to add a new virtual tree item to the virtual tree\n * @param props - the props of the item to add\n */\n add(props: Props): void;\n /**\n * method to remove a virtual tree item from the virtual tree.\n * When an item is removed:\n * 1. all its children are also removed\n * 2. all its siblings are repositioned\n * @param value - the value of the item to remove\n */\n // remove(value: TreeItemValue): void;\n /**\n * method to get the parent of a virtual tree item by its value\n * @param value - the value of the item to get the parent from\n */\n getParent(value: TreeItemValue): HeadlessTreeItem<Props>;\n /**\n * method to get the subtree of a virtual tree item by its value\n * @param value - the value of the item to get the subtree from\n */\n subtree(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the children of a virtual tree item by its value\n * @param value - the value of the item to get the children from\n */\n children(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the visible items of a virtual tree\n * @param openItems - the open items of the tree\n */\n visibleItems(openItems: ImmutableSet<TreeItemValue>): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the ancestors of a virtual tree item by its value\n * @param value - the value of the item to get the ancestors from\n */\n ancestors(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\n/**\n * creates a list of virtual tree items\n * and provides a map to access each item by id\n */\nexport function createHeadlessTree<Props extends HeadlessTreeItemProps>(\n initialProps: Props[] = [],\n): HeadlessTree<Props> {\n const root = createHeadlessTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, HeadlessTreeItem<HeadlessTreeItemProps>>([[root.value, root]]);\n\n const headlessTree: HeadlessTree<HeadlessTreeItemProps> = {\n root,\n get size() {\n return itemsPerValue.size;\n },\n getParent: key => itemsPerValue.get(itemsPerValue.get(key)?.parentValue ?? root.value) ?? root,\n get: key => itemsPerValue.get(key),\n has: key => itemsPerValue.has(key),\n add(props) {\n const { parentValue = headlessTreeRootId, ...propsWithoutParentValue } = props;\n const parentItem = itemsPerValue.get(parentValue);\n if (!parentItem) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n TreeItem \"${props.value}\" is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized, parents should come before children\n `);\n }\n return;\n }\n parentItem.itemType = 'branch';\n\n const item: HeadlessTreeItem<HeadlessTreeItemProps> = {\n value: props.value,\n getTreeItemProps: () => ({\n ...propsWithoutParentValue,\n parentValue,\n 'aria-level': item.level,\n 'aria-posinset': item.position,\n 'aria-setsize': parentItem.childrenValues.length,\n itemType: item.itemType,\n }),\n itemType: propsWithoutParentValue.itemType ?? 'leaf',\n level: parentItem.level + 1,\n parentValue,\n childrenValues: [],\n index: -1,\n position: parentItem.childrenValues.push(props.value),\n };\n itemsPerValue.set(item.value, item);\n },\n subtree: key => HeadlessTreeSubtreeGenerator(key, headlessTree),\n children: key => HeadlessTreeChildrenGenerator(key, headlessTree),\n ancestors: key => HeadlessTreeAncestorsGenerator(key, headlessTree),\n visibleItems: openItems => HeadlessTreeVisibleItemsGenerator(openItems, headlessTree),\n };\n\n initialProps.forEach(headlessTree.add);\n\n return headlessTree as HeadlessTree<Props>;\n}\n\nexport const headlessTreeRootId = '__fuiHeadlessTreeRoot';\n\nfunction createHeadlessTreeRootItem(): HeadlessTreeItem<HeadlessTreeItemProps> {\n return {\n parentValue: undefined,\n value: headlessTreeRootId,\n itemType: 'branch',\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return {\n id: headlessTreeRootId,\n parentValue: undefined,\n value: headlessTreeRootId,\n 'aria-setsize': -1,\n 'aria-level': -1,\n 'aria-posinset': -1,\n itemType: 'branch',\n };\n },\n childrenValues: [],\n get index() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return -1;\n },\n get position() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return -1;\n },\n level: 0,\n };\n}\n\n/**\n * Generator that returns all subtree of a given virtual tree item\n * @param key - the key of the item to get the subtree from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeSubtreeGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n yield* HeadlessTreeSubtreeGenerator(childValue, virtualTreeItems);\n }\n}\n\n/**\n * Generator that returns all children of a given virtual tree item\n * @param key - the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeChildrenGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n }\n}\n\n/**\n * Generator that returns all ancestors of a given virtual tree item\n * @param key - the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeAncestorsGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let parent = virtualTreeItems.getParent(key);\n while (parent !== virtualTreeItems.root) {\n yield parent;\n parent = virtualTreeItems.getParent(parent.value);\n }\n}\n\n/**\n * Generator that returns all visible items of a given virtual tree\n * @param openItems - the open items of the tree\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeVisibleItemsGenerator<Props extends HeadlessTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let index = 0;\n for (const item of recursiveVisibleItems(virtualTreeItems.root.value, openItems, virtualTreeItems)) {\n item.index = index++;\n yield item;\n }\n}\n\nfunction* recursiveVisibleItems<Props extends HeadlessTreeItemProps>(\n parentValue: TreeItemValue,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const parent = virtualTreeItems.get(parentValue);\n if (!parent || parent.childrenValues.length === 0) {\n return;\n }\n\n for (const childValue of parent.childrenValues) {\n const child = virtualTreeItems.get(childValue);\n if (!child) {\n continue;\n }\n\n if (isItemVisible(child, openItems, virtualTreeItems)) {\n yield child;\n\n // Process children only as long as their parents are open.\n // This makes it possible to have large trees with good performance as\n // long as most branches are not expanded.\n if (openItems.has(childValue)) {\n yield* recursiveVisibleItems(childValue, openItems, virtualTreeItems);\n }\n }\n }\n}\n\nfunction isItemVisible(\n item: HeadlessTreeItem<HeadlessTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== virtualTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = virtualTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createHeadlessTree","initialProps","root","createHeadlessTreeRootItem","itemsPerValue","Map","value","headlessTree","size","getParent","key","get","parentValue","has","add","props","headlessTreeRootId","propsWithoutParentValue","parentItem","process","env","NODE_ENV","console","error","itemType","item","getTreeItemProps","level","position","childrenValues","length","index","push","set","subtree","HeadlessTreeSubtreeGenerator","children","HeadlessTreeChildrenGenerator","ancestors","HeadlessTreeAncestorsGenerator","visibleItems","openItems","HeadlessTreeVisibleItemsGenerator","forEach","undefined","id","virtualTreeItems","childValue","parent","recursiveVisibleItems","child","isItemVisible"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/utils/createHeadlessTree.ts"],"sourcesContent":["import type { TreeItemProps, TreeItemType, TreeItemValue } from '../TreeItem';\nimport type { ImmutableSet } from './ImmutableSet';\n\nexport type HeadlessTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> & {\n value: TreeItemValue;\n itemType?: TreeItemType;\n parentValue?: TreeItemValue;\n};\n\n/**\n * The item that is returned by `createHeadlessTree`, it represents a wrapper around the properties provided to\n * `createHeadlessTree` but with extra information that might be useful on virtual tree scenarios\n */\nexport type HeadlessTreeItem<Props extends HeadlessTreeItemProps> = {\n level: number;\n index: number;\n position: number;\n childrenValues: TreeItemValue[];\n value: TreeItemValue;\n parentValue: TreeItemValue | undefined;\n itemType: TreeItemType;\n getTreeItemProps(): Required<Pick<Props, 'value' | 'aria-setsize' | 'aria-level' | 'aria-posinset' | 'itemType'>> &\n Props;\n};\n\n/**\n * @internal\n */\nexport type HeadlessTree<Props extends HeadlessTreeItemProps> = {\n /**\n * the number of items in the virtual tree\n */\n readonly size: number;\n /**\n * the root item of the virtual tree\n */\n root: HeadlessTreeItem<HeadlessTreeItemProps>;\n /**\n * method to get a virtual tree item by its value\n * @param key - the key of the item to get\n */\n get(value: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n /**\n * method to check if a virtual tree item exists by its value\n * @param value - the value of the item to check if exists\n */\n has(value: TreeItemValue): boolean;\n /**\n * method to add a new virtual tree item to the virtual tree\n * @param props - the props of the item to add\n */\n add(props: Props): void;\n /**\n * method to remove a virtual tree item from the virtual tree.\n * When an item is removed:\n * 1. all its children are also removed\n * 2. all its siblings are repositioned\n * @param value - the value of the item to remove\n */\n // remove(value: TreeItemValue): void;\n /**\n * method to get the parent of a virtual tree item by its value\n * @param value - the value of the item to get the parent from\n */\n getParent(value: TreeItemValue): HeadlessTreeItem<Props>;\n /**\n * method to get the subtree of a virtual tree item by its value\n * @param value - the value of the item to get the subtree from\n */\n subtree(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the children of a virtual tree item by its value\n * @param value - the value of the item to get the children from\n */\n children(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the visible items of a virtual tree\n * @param openItems - the open items of the tree\n */\n visibleItems(openItems: ImmutableSet<TreeItemValue>): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the ancestors of a virtual tree item by its value\n * @param value - the value of the item to get the ancestors from\n */\n ancestors(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\n/**\n * creates a list of virtual tree items\n * and provides a map to access each item by id\n */\nexport function createHeadlessTree<Props extends HeadlessTreeItemProps>(\n initialProps: Props[] = [],\n): HeadlessTree<Props> {\n const root = createHeadlessTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, HeadlessTreeItem<HeadlessTreeItemProps>>([[root.value, root]]);\n\n const headlessTree: HeadlessTree<HeadlessTreeItemProps> = {\n root,\n get size() {\n return itemsPerValue.size;\n },\n getParent: key => itemsPerValue.get(itemsPerValue.get(key)?.parentValue ?? root.value) ?? root,\n get: key => itemsPerValue.get(key),\n has: key => itemsPerValue.has(key),\n add(props) {\n const { parentValue = headlessTreeRootId, ...propsWithoutParentValue } = props;\n const parentItem = itemsPerValue.get(parentValue);\n if (!parentItem) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n TreeItem \"${props.value}\" is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized, parents should come before children\n `);\n }\n return;\n }\n parentItem.itemType = 'branch';\n\n const item: HeadlessTreeItem<HeadlessTreeItemProps> = {\n value: props.value,\n getTreeItemProps: () => ({\n ...propsWithoutParentValue,\n parentValue,\n 'aria-level': item.level,\n 'aria-posinset': item.position,\n 'aria-setsize': parentItem.childrenValues.length,\n itemType: item.itemType,\n }),\n itemType: propsWithoutParentValue.itemType ?? 'leaf',\n level: parentItem.level + 1,\n parentValue,\n childrenValues: [],\n index: -1,\n position: parentItem.childrenValues.push(props.value),\n };\n itemsPerValue.set(item.value, item);\n },\n subtree: key => HeadlessTreeSubtreeGenerator(key, headlessTree),\n children: key => HeadlessTreeChildrenGenerator(key, headlessTree),\n ancestors: key => HeadlessTreeAncestorsGenerator(key, headlessTree),\n visibleItems: openItems => HeadlessTreeVisibleItemsGenerator(openItems, headlessTree),\n };\n\n initialProps.forEach(headlessTree.add);\n\n return headlessTree as HeadlessTree<Props>;\n}\n\nexport const headlessTreeRootId = '__fuiHeadlessTreeRoot';\n\nfunction createHeadlessTreeRootItem(): HeadlessTreeItem<HeadlessTreeItemProps> {\n return {\n parentValue: undefined,\n value: headlessTreeRootId,\n itemType: 'branch',\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return {\n id: headlessTreeRootId,\n parentValue: undefined,\n value: headlessTreeRootId,\n 'aria-setsize': -1,\n 'aria-level': -1,\n 'aria-posinset': -1,\n itemType: 'branch',\n };\n },\n childrenValues: [],\n get index() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return -1;\n },\n get position() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return -1;\n },\n level: 0,\n };\n}\n\n/**\n * Generator that returns all subtree of a given virtual tree item\n * @param key - the key of the item to get the subtree from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeSubtreeGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n yield* HeadlessTreeSubtreeGenerator(childValue, virtualTreeItems);\n }\n}\n\n/**\n * Generator that returns all children of a given virtual tree item\n * @param key - the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeChildrenGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n }\n}\n\n/**\n * Generator that returns all ancestors of a given virtual tree item\n * @param key - the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeAncestorsGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let parent = virtualTreeItems.getParent(key);\n while (parent !== virtualTreeItems.root) {\n yield parent;\n parent = virtualTreeItems.getParent(parent.value);\n }\n}\n\n/**\n * Generator that returns all visible items of a given virtual tree\n * @param openItems - the open items of the tree\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeVisibleItemsGenerator<Props extends HeadlessTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let index = 0;\n for (const item of recursiveVisibleItems(virtualTreeItems.root.value, openItems, virtualTreeItems)) {\n item.index = index++;\n yield item;\n }\n}\n\nfunction* recursiveVisibleItems<Props extends HeadlessTreeItemProps>(\n parentValue: TreeItemValue,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const parent = virtualTreeItems.get(parentValue);\n if (!parent || parent.childrenValues.length === 0) {\n return;\n }\n\n for (const childValue of parent.childrenValues) {\n const child = virtualTreeItems.get(childValue);\n if (!child) {\n continue;\n }\n\n if (isItemVisible(child, openItems, virtualTreeItems)) {\n yield child;\n\n // Process children only as long as their parents are open.\n // This makes it possible to have large trees with good performance as\n // long as most branches are not expanded.\n if (openItems.has(childValue)) {\n yield* recursiveVisibleItems(childValue, openItems, virtualTreeItems);\n }\n }\n }\n}\n\nfunction isItemVisible(\n item: HeadlessTreeItem<HeadlessTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== virtualTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = virtualTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createHeadlessTree","initialProps","root","createHeadlessTreeRootItem","itemsPerValue","Map","value","headlessTree","size","getParent","key","get","parentValue","has","add","props","headlessTreeRootId","propsWithoutParentValue","parentItem","process","env","NODE_ENV","console","error","itemType","item","getTreeItemProps","level","position","childrenValues","length","index","push","set","subtree","HeadlessTreeSubtreeGenerator","children","HeadlessTreeChildrenGenerator","ancestors","HeadlessTreeAncestorsGenerator","visibleItems","openItems","HeadlessTreeVisibleItemsGenerator","forEach","undefined","id","virtualTreeItems","childValue","parent","recursiveVisibleItems","child","isItemVisible"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/flattenTree.ts"],"sourcesContent":["import { HeadlessFlatTreeItemProps } from '../FlatTree';\nimport { TreeItemProps, TreeItemValue } from '../TreeItem';\n\nexport type FlattenTreeItem<Props extends TreeItemProps> = Omit<Props, 'subtree' | 'itemType'> & {\n value: TreeItemValue;\n subtree?: FlattenTreeItem<Props>[];\n};\n\nexport type FlattenedTreeItem<Props extends TreeItemProps> = HeadlessFlatTreeItemProps & Props;\n\nfunction flattenTreeRecursive<Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n parent?: HeadlessFlatTreeItemProps & Props,\n level = 1,\n): FlattenedTreeItem<Props>[] {\n return items.reduce<FlattenedTreeItem<Props>[]>((acc, { subtree, ...item }, index) => {\n const flatTreeItem = {\n 'aria-level': level,\n 'aria-posinset': index + 1,\n 'aria-setsize': items.length,\n parentValue: parent?.value,\n ...item,\n } as FlattenedTreeItem<Props>;\n acc.push(flatTreeItem);\n if (subtree !== undefined) {\n acc.push(...flattenTreeRecursive<Props>(subtree, flatTreeItem, level + 1));\n }\n return acc;\n }, []);\n}\n\n/**\n * Converts a nested structure to a flat one which can be consumed by `useFlatTreeItems`\n * @example\n * ```tsx\n * const defaultItems = flattenTree_unstable([\n * {\n * children: <TreeItemLayout>level 1, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 2</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 3</TreeItemLayout>,\n * },\n * ],\n * },\n * {\n * children: <TreeItemLayout>level 1, item 2</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 3, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 4, item 1</TreeItemLayout>,\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * },\n * ]);\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const flattenTree_unstable = <Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n): FlattenedTreeItem<Props>[] => flattenTreeRecursive(items);\n"],"names":["flattenTreeRecursive","items","parent","level","reduce","acc","subtree","item","index","flatTreeItem","length","parentValue","value","push","undefined","flattenTree_unstable"],"mappings":"AAUA,SAASA,qBACPC,KAA+B,EAC/BC,MAA0C,EAC1CC,QAAQ,CAAC;IAET,OAAOF,MAAMG,MAAM,CAA6B,CAACC,KAAK,EAAEC,OAAO,EAAE,GAAGC,MAAM,EAAEC;QAC1E,MAAMC,eAAe;YACnB,cAAcN;YACd,iBAAiBK,QAAQ;YACzB,gBAAgBP,MAAMS,MAAM;YAC5BC,WAAW,EAAET,mBAAAA,6BAAAA,OAAQU,KAAK;YAC1B,GAAGL,IAAI;QACT;QACAF,IAAIQ,IAAI,CAACJ;QACT,IAAIH,YAAYQ,WAAW;YACzBT,IAAIQ,IAAI,IAAIb,qBAA4BM,SAASG,cAAcN,QAAQ;QACzE;QACA,OAAOE;IACT,GAAG,EAAE;AACP;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GACD,gEAAgE;AAChE,OAAO,MAAMU,uBAAuB,CAClCd,QAC+BD,qBAAqBC,OAAO"}
|
|
1
|
+
{"version":3,"sources":["../src/utils/flattenTree.ts"],"sourcesContent":["import type { HeadlessFlatTreeItemProps } from '../FlatTree';\nimport type { TreeItemProps, TreeItemValue } from '../TreeItem';\n\nexport type FlattenTreeItem<Props extends TreeItemProps> = Omit<Props, 'subtree' | 'itemType'> & {\n value: TreeItemValue;\n subtree?: FlattenTreeItem<Props>[];\n};\n\nexport type FlattenedTreeItem<Props extends TreeItemProps> = HeadlessFlatTreeItemProps & Props;\n\nfunction flattenTreeRecursive<Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n parent?: HeadlessFlatTreeItemProps & Props,\n level = 1,\n): FlattenedTreeItem<Props>[] {\n return items.reduce<FlattenedTreeItem<Props>[]>((acc, { subtree, ...item }, index) => {\n const flatTreeItem = {\n 'aria-level': level,\n 'aria-posinset': index + 1,\n 'aria-setsize': items.length,\n parentValue: parent?.value,\n ...item,\n } as FlattenedTreeItem<Props>;\n acc.push(flatTreeItem);\n if (subtree !== undefined) {\n acc.push(...flattenTreeRecursive<Props>(subtree, flatTreeItem, level + 1));\n }\n return acc;\n }, []);\n}\n\n/**\n * Converts a nested structure to a flat one which can be consumed by `useFlatTreeItems`\n * @example\n * ```tsx\n * const defaultItems = flattenTree_unstable([\n * {\n * children: <TreeItemLayout>level 1, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 2</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 3</TreeItemLayout>,\n * },\n * ],\n * },\n * {\n * children: <TreeItemLayout>level 1, item 2</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 3, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 4, item 1</TreeItemLayout>,\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * },\n * ]);\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const flattenTree_unstable = <Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n): FlattenedTreeItem<Props>[] => flattenTreeRecursive(items);\n"],"names":["flattenTreeRecursive","items","parent","level","reduce","acc","subtree","item","index","flatTreeItem","length","parentValue","value","push","undefined","flattenTree_unstable"],"mappings":"AAUA,SAASA,qBACPC,KAA+B,EAC/BC,MAA0C,EAC1CC,QAAQ,CAAC;IAET,OAAOF,MAAMG,MAAM,CAA6B,CAACC,KAAK,EAAEC,OAAO,EAAE,GAAGC,MAAM,EAAEC;QAC1E,MAAMC,eAAe;YACnB,cAAcN;YACd,iBAAiBK,QAAQ;YACzB,gBAAgBP,MAAMS,MAAM;YAC5BC,WAAW,EAAET,mBAAAA,6BAAAA,OAAQU,KAAK;YAC1B,GAAGL,IAAI;QACT;QACAF,IAAIQ,IAAI,CAACJ;QACT,IAAIH,YAAYQ,WAAW;YACzBT,IAAIQ,IAAI,IAAIb,qBAA4BM,SAASG,cAAcN,QAAQ;QACzE;QACA,OAAOE;IACT,GAAG,EAAE;AACP;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GACD,gEAAgE;AAChE,OAAO,MAAMU,uBAAuB,CAClCd,QAC+BD,qBAAqBC,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/nextTypeAheadElement.ts"],"sourcesContent":["import { HTMLElementWalker } from './createHTMLElementWalker';\n\nexport function nextTypeAheadElement(treeWalker: HTMLElementWalker, key: string): HTMLElement | null {\n const keyToLowerCase = key.toLowerCase();\n const typeAheadFilter = (element: HTMLElement) => {\n return element.textContent?.trim().charAt(0).toLowerCase() === keyToLowerCase\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP;\n };\n let nextElement = treeWalker.nextElement(typeAheadFilter);\n if (!nextElement) {\n treeWalker.currentElement = treeWalker.root;\n nextElement = treeWalker.nextElement(typeAheadFilter);\n }\n return nextElement;\n}\n"],"names":["nextTypeAheadElement","treeWalker","key","keyToLowerCase","toLowerCase","typeAheadFilter","element","textContent","trim","charAt","NodeFilter","FILTER_ACCEPT","FILTER_SKIP","nextElement","currentElement","root"],"mappings":"AAEA,OAAO,SAASA,qBAAqBC,UAA6B,EAAEC,GAAW;IAC7E,MAAMC,iBAAiBD,IAAIE,WAAW;IACtC,MAAMC,kBAAkB,CAACC;YAChBA;QAAP,OAAOA,EAAAA,uBAAAA,QAAQC,WAAW,cAAnBD,2CAAAA,qBAAqBE,IAAI,GAAGC,MAAM,CAAC,GAAGL,WAAW,QAAOD,iBAC3DO,WAAWC,aAAa,GACxBD,WAAWE,WAAW;IAC5B;IACA,IAAIC,cAAcZ,WAAWY,WAAW,CAACR;IACzC,IAAI,CAACQ,aAAa;QAChBZ,WAAWa,cAAc,GAAGb,WAAWc,IAAI;QAC3CF,cAAcZ,WAAWY,WAAW,CAACR;IACvC;IACA,OAAOQ;AACT"}
|
|
1
|
+
{"version":3,"sources":["../src/utils/nextTypeAheadElement.ts"],"sourcesContent":["import type { HTMLElementWalker } from './createHTMLElementWalker';\n\nexport function nextTypeAheadElement(treeWalker: HTMLElementWalker, key: string): HTMLElement | null {\n const keyToLowerCase = key.toLowerCase();\n const typeAheadFilter = (element: HTMLElement) => {\n return element.textContent?.trim().charAt(0).toLowerCase() === keyToLowerCase\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP;\n };\n let nextElement = treeWalker.nextElement(typeAheadFilter);\n if (!nextElement) {\n treeWalker.currentElement = treeWalker.root;\n nextElement = treeWalker.nextElement(typeAheadFilter);\n }\n return nextElement;\n}\n"],"names":["nextTypeAheadElement","treeWalker","key","keyToLowerCase","toLowerCase","typeAheadFilter","element","textContent","trim","charAt","NodeFilter","FILTER_ACCEPT","FILTER_SKIP","nextElement","currentElement","root"],"mappings":"AAEA,OAAO,SAASA,qBAAqBC,UAA6B,EAAEC,GAAW;IAC7E,MAAMC,iBAAiBD,IAAIE,WAAW;IACtC,MAAMC,kBAAkB,CAACC;YAChBA;QAAP,OAAOA,EAAAA,uBAAAA,QAAQC,WAAW,cAAnBD,2CAAAA,qBAAqBE,IAAI,GAAGC,MAAM,CAAC,GAAGL,WAAW,QAAOD,iBAC3DO,WAAWC,aAAa,GACxBD,WAAWE,WAAW;IAC5B;IACA,IAAIC,cAAcZ,WAAWY,WAAW,CAACR;IACzC,IAAI,CAACQ,aAAa;QAChBZ,WAAWa,cAAc,GAAGb,WAAWc,IAAI;QAC3CF,cAAcZ,WAAWY,WAAW,CAACR;IACvC;IACA,OAAOQ;AACT"}
|
package/lib/utils/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/tokens.ts"],"sourcesContent":["import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Home, Enter } from '@fluentui/keyboard-keys';\nimport { TreeCheckedChangeData, TreeNavigationData_unstable, TreeOpenChangeData } from '../Tree';\n\nexport const treeItemLevelToken = '--fluent-TreeItem--level' as const;\n\nexport const treeAvatarSize = {\n medium: 32,\n small: 24,\n} as const;\n\nexport const treeDataTypes: {\n readonly [K in TreeOpenChangeData['type'] | TreeNavigationData_unstable['type'] | TreeCheckedChangeData['type']]: K;\n} = {\n ArrowLeft,\n ArrowRight,\n Enter,\n Click: 'Click',\n ExpandIconClick: 'ExpandIconClick',\n End,\n Home,\n ArrowUp,\n ArrowDown,\n TypeAhead: 'TypeAhead',\n Change: 'Change',\n};\n"],"names":["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","End","Home","Enter","treeItemLevelToken","treeAvatarSize","medium","small","treeDataTypes","Click","ExpandIconClick","TypeAhead","Change"],"mappings":"AAAA,SAASA,SAAS,EAAEC,SAAS,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,EAAEC,KAAK,QAAQ,0BAA0B;AAGtG,OAAO,MAAMC,qBAAqB,2BAAoC;AAEtE,OAAO,MAAMC,iBAAiB;IAC5BC,QAAQ;IACRC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,gBAET;IACFV;IACAC;IACAI;IACAM,OAAO;IACPC,iBAAiB;IACjBT;IACAC;IACAF;IACAH;IACAc,WAAW;IACXC,QAAQ;AACV,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../src/utils/tokens.ts"],"sourcesContent":["import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Home, Enter } from '@fluentui/keyboard-keys';\nimport type { TreeCheckedChangeData, TreeNavigationData_unstable, TreeOpenChangeData } from '../Tree';\n\nexport const treeItemLevelToken = '--fluent-TreeItem--level' as const;\n\nexport const treeAvatarSize = {\n medium: 32,\n small: 24,\n} as const;\n\nexport const treeDataTypes: {\n readonly [K in TreeOpenChangeData['type'] | TreeNavigationData_unstable['type'] | TreeCheckedChangeData['type']]: K;\n} = {\n ArrowLeft,\n ArrowRight,\n Enter,\n Click: 'Click',\n ExpandIconClick: 'ExpandIconClick',\n End,\n Home,\n ArrowUp,\n ArrowDown,\n TypeAhead: 'TypeAhead',\n Change: 'Change',\n};\n"],"names":["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","End","Home","Enter","treeItemLevelToken","treeAvatarSize","medium","small","treeDataTypes","Click","ExpandIconClick","TypeAhead","Change"],"mappings":"AAAA,SAASA,SAAS,EAAEC,SAAS,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,EAAEC,KAAK,QAAQ,0BAA0B;AAGtG,OAAO,MAAMC,qBAAqB,2BAAoC;AAEtE,OAAO,MAAMC,iBAAiB;IAC5BC,QAAQ;IACRC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,gBAET;IACFV;IACAC;IACAI;IACAM,OAAO;IACPC,iBAAiB;IACjBT;IACAC;IACAF;IACAH;IACAc,WAAW;IACXC,QAAQ;AACV,EAAE"}
|