UNPKG

@fluentui/react-northstar

Version:
252 lines (250 loc) 9 kB
import _invoke from "lodash/invoke"; import { treeItemBehavior } from '@fluentui/accessibility'; import { getElementType, useUnhandledProps, useAccessibility, useStyles, useTelemetry, useFluentContext } from '@fluentui/react-bindings'; import * as customPropTypes from '@fluentui/react-proptypes'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import { handleRef } from '@fluentui/react-component-ref'; import { childrenExist, createShorthandFactory, commonPropTypes, rtlTextContainer, shouldPreventDefaultOnKeyDown } from '../../utils'; import { TreeTitle } from './TreeTitle'; import { TreeContext } from './context'; export var treeItemClassName = 'ui-tree__item'; /** * A TreeItem renders an item of a Tree. * * @accessibility * Implements [ARIA TreeView](https://www.w3.org/TR/wai-aria-practices-1.1/#TreeView) design pattern. */ export var TreeItem = /*#__PURE__*/function () { var TreeItem = /*#__PURE__*/React.forwardRef(function (props, ref) { var context = useFluentContext(); var _useTelemetry = useTelemetry(TreeItem.displayName, context.telemetry), setStart = _useTelemetry.setStart, setEnd = _useTelemetry.setEnd; setStart(); var accessibility = props.accessibility, children = props.children, className = props.className, contentRef = props.contentRef, design = props.design, title = props.title, renderItemTitle = props.renderItemTitle, expanded = props.expanded, level = props.level, index = props.index, styles = props.styles, variables = props.variables, treeSize = props.treeSize, selectionIndicator = props.selectionIndicator, selectable = props.selectable, id = props.id, parent = props.parent; var _React$useContext = React.useContext(TreeContext), getItemById = _React$useContext.getItemById, registerItemRef = _React$useContext.registerItemRef, toggleItemActive = _React$useContext.toggleItemActive, focusItemById = _React$useContext.focusItemById, expandSiblings = _React$useContext.expandSiblings, toggleItemSelect = _React$useContext.toggleItemSelect, getToFocusIDByFirstCharacter = _React$useContext.getToFocusIDByFirstCharacter; var _getItemById = getItemById(id), selected = _getItemById.selected, hasSubtree = _getItemById.hasSubtree, childrenIds = _getItemById.childrenIds; var getA11Props = useAccessibility(accessibility, { actionHandlers: { performClick: function performClick(e) { if (shouldPreventDefaultOnKeyDown(e)) { e.preventDefault(); } e.stopPropagation(); toggleItemActive(e, id); _invoke(props, 'onTitleClick', e, props); }, focusParent: function focusParent(e) { e.preventDefault(); e.stopPropagation(); handleFocusParent(e); }, collapse: function collapse(e) { e.preventDefault(); e.stopPropagation(); toggleItemActive(e, id); }, expand: function expand(e) { e.preventDefault(); e.stopPropagation(); toggleItemActive(e, id); }, focusFirstChild: function focusFirstChild(e) { e.preventDefault(); e.stopPropagation(); handleFocusFirstChild(e); }, expandSiblings: function expandSiblings(e) { e.preventDefault(); e.stopPropagation(); handleSiblingsExpand(e); }, performSelection: function performSelection(e) { e.preventDefault(); e.stopPropagation(); handleSelection(e); } }, debugName: TreeItem.displayName, mapPropsToBehavior: function mapPropsToBehavior() { return { expanded: expanded, level: level, index: index, hasSubtree: hasSubtree, treeSize: treeSize, selected: selected === true, selectable: selectable, indeterminate: selected === 'indeterminate' }; }, rtl: context.rtl }); var _useStyles = useStyles(TreeItem.displayName, { className: treeItemClassName, mapPropsToStyles: function mapPropsToStyles() { return { level: level, selectable: selectable }; }, mapPropsToInlineStyles: function mapPropsToInlineStyles() { return { className: className, design: design, styles: styles, variables: variables }; }, rtl: context.rtl, unstyled: props.unstyled }), classes = _useStyles.classes; var handleSelection = function handleSelection(e) { if (selectable) { toggleItemSelect(e, id); } _invoke(props, 'onTitleClick', e, props); }; var handleFocusFirstChild = function handleFocusFirstChild(e) { _invoke(props, 'onFocusFirstChild', e, props); focusItemById(childrenIds == null ? void 0 : childrenIds[0]); }; var handleFocusParent = function handleFocusParent(e) { _invoke(props, 'onFocusParent', e, props); focusItemById(parent); }; var handleSiblingsExpand = function handleSiblingsExpand(e) { _invoke(props, 'onSiblingsExpand', e, props); expandSiblings(e, props.id); }; var handleTitleOverrides = function handleTitleOverrides(predefinedProps) { return { id: id, onClick: function onClick(e, titleProps) { _invoke(props, 'onTitleClick', e, props); _invoke(predefinedProps, 'onClick', e, titleProps); } }; }; var handleClick = function handleClick(e) { if (e.target === e.currentTarget) { // onClick listener for mouse click on treeItem DOM only, // which could be triggered by VO+space on selectable tree parent node handleSelection(e); } _invoke(props, 'onClick', e, props); }; var handleKeyDown = function handleKeyDown(e) { if (e.key && e.key.length === 1 && e.key.match(/\S/) && e.key !== '*' && !e.altKey && !e.ctrlKey && !e.metaKey) { e.preventDefault(); e.stopPropagation(); var toFocusID = getToFocusIDByFirstCharacter(e, props.id); if (toFocusID !== props.id) { focusItemById(toFocusID); } } _invoke(props, 'onKeyDown', e, props); }; var elementRef = React.useCallback(function (node) { registerItemRef(id, node); handleRef(contentRef, node); handleRef(ref, node); }, [id, contentRef, registerItemRef, ref]); var ElementType = getElementType(props); var unhandledProps = useUnhandledProps(TreeItem.handledProps, props); var element = /*#__PURE__*/React.createElement(ElementType, getA11Props('root', Object.assign({ className: classes.root, id: id, ref: elementRef, selected: selected === true, onClick: handleClick, onKeyDown: handleKeyDown }, rtlTextContainer.getAttributes({ forElements: [children] }), unhandledProps)), childrenExist(children) ? children : TreeTitle.create(title, { defaultProps: function defaultProps() { return getA11Props('title', Object.assign({ hasSubtree: hasSubtree, as: hasSubtree ? 'span' : 'a', level: level, treeSize: treeSize, expanded: expanded, index: index, selected: selected === true, selectable: selectable, parent: parent }, hasSubtree && { indeterminate: selected === 'indeterminate' }, { selectionIndicator: selectionIndicator })); }, render: renderItemTitle, overrideProps: handleTitleOverrides })); setEnd(); return element; }); TreeItem.displayName = 'TreeItem'; TreeItem.propTypes = Object.assign({}, commonPropTypes.createCommon({ content: false }), { contentRef: customPropTypes.ref, id: PropTypes.string.isRequired, index: PropTypes.number, items: customPropTypes.collectionShorthand, level: PropTypes.number, onFocusFirstChild: PropTypes.func, onFocusParent: PropTypes.func, onTitleClick: PropTypes.func, onSiblingsExpand: PropTypes.func, expanded: PropTypes.bool, parent: PropTypes.string, renderItemTitle: PropTypes.func, treeSize: PropTypes.number, title: customPropTypes.itemShorthand, selectionIndicator: customPropTypes.shorthandAllowingChildren, selectable: PropTypes.bool, unstyled: PropTypes.bool, onKeyDown: PropTypes.func }); TreeItem.defaultProps = { accessibility: treeItemBehavior, selectable: true }; TreeItem.handledProps = Object.keys(TreeItem.propTypes); TreeItem.create = createShorthandFactory({ Component: TreeItem, mappedProp: 'title' }); return TreeItem; }(); //# sourceMappingURL=TreeItem.js.map