UNPKG

7.36 kBJavaScriptView Raw
1import { __rest } from "tslib";
2import * as React from 'react';
3import { useState } from 'react';
4import styles from '@patternfly/react-styles/css/components/Label/label';
5import labelGrpStyles from '@patternfly/react-styles/css/components/LabelGroup/label-group';
6import { Button } from '../Button';
7import { Tooltip } from '../Tooltip';
8import { css } from '@patternfly/react-styles';
9import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
10import { useIsomorphicLayoutEffect } from '../../helpers';
11const colorStyles = {
12 blue: styles.modifiers.blue,
13 cyan: styles.modifiers.cyan,
14 green: styles.modifiers.green,
15 orange: styles.modifiers.orange,
16 purple: styles.modifiers.purple,
17 red: styles.modifiers.red,
18 grey: ''
19};
20export const Label = (_a) => {
21 var { children, className = '', color = 'grey', variant = 'filled', isCompact = false, isEditable = false, editableProps, isTruncated = false, tooltipPosition, icon, onClose, onEditCancel, onEditComplete, closeBtn, closeBtnAriaLabel, closeBtnProps, href, isOverflowLabel, render } = _a, props = __rest(_a, ["children", "className", "color", "variant", "isCompact", "isEditable", "editableProps", "isTruncated", "tooltipPosition", "icon", "onClose", "onEditCancel", "onEditComplete", "closeBtn", "closeBtnAriaLabel", "closeBtnProps", "href", "isOverflowLabel", "render"]);
22 const [isEditableActive, setIsEditableActive] = useState(false);
23 const [currValue, setCurrValue] = useState(children);
24 const editableButtonRef = React.useRef();
25 const editableInputRef = React.useRef();
26 React.useEffect(() => {
27 document.addEventListener('click', onDocClick);
28 document.addEventListener('keydown', onKeyDown);
29 return () => {
30 document.removeEventListener('click', onDocClick);
31 document.removeEventListener('keydown', onKeyDown);
32 };
33 });
34 const onDocClick = (event) => {
35 if (isEditableActive &&
36 editableInputRef &&
37 editableInputRef.current &&
38 !editableInputRef.current.contains(event.target)) {
39 if (editableInputRef.current.value) {
40 onEditComplete && onEditComplete(editableInputRef.current.value);
41 }
42 setIsEditableActive(false);
43 }
44 };
45 const onKeyDown = (event) => {
46 const key = event.key;
47 if ((!isEditableActive &&
48 (!editableButtonRef ||
49 !editableButtonRef.current ||
50 !editableButtonRef.current.contains(event.target))) ||
51 (isEditableActive &&
52 (!editableInputRef || !editableInputRef.current || !editableInputRef.current.contains(event.target)))) {
53 return;
54 }
55 if (isEditableActive && (key === 'Enter' || key === 'Tab')) {
56 event.preventDefault();
57 event.stopImmediatePropagation();
58 if (editableInputRef.current.value) {
59 onEditComplete && onEditComplete(editableInputRef.current.value);
60 }
61 setIsEditableActive(false);
62 }
63 if (isEditableActive && key === 'Escape') {
64 event.preventDefault();
65 event.stopImmediatePropagation();
66 // Reset div text to initial children prop - pre-edit
67 if (editableInputRef.current.value) {
68 editableInputRef.current.value = children;
69 onEditCancel && onEditCancel(children);
70 }
71 setIsEditableActive(false);
72 }
73 if (!isEditableActive && key === 'Enter') {
74 event.preventDefault();
75 event.stopImmediatePropagation();
76 setIsEditableActive(true);
77 // Set cursor position to end of text
78 const el = event.target;
79 const range = document.createRange();
80 const sel = window.getSelection();
81 range.selectNodeContents(el);
82 range.collapse(false);
83 sel.removeAllRanges();
84 sel.addRange(range);
85 }
86 };
87 const LabelComponent = (isOverflowLabel ? 'button' : 'span');
88 const button = closeBtn ? (closeBtn) : (React.createElement(Button, Object.assign({ type: "button", variant: "plain", onClick: onClose, "aria-label": closeBtnAriaLabel || `Close ${children}` }, closeBtnProps),
89 React.createElement(TimesIcon, null)));
90 const textRef = React.createRef();
91 // ref to apply tooltip when rendered is used
92 const componentRef = React.useRef();
93 const [isTooltipVisible, setIsTooltipVisible] = React.useState(false);
94 useIsomorphicLayoutEffect(() => {
95 const currTextRef = isEditable ? editableButtonRef : textRef;
96 if (!isEditableActive) {
97 setIsTooltipVisible(currTextRef.current && currTextRef.current.offsetWidth < currTextRef.current.scrollWidth);
98 }
99 }, [isEditableActive]);
100 const content = (React.createElement(React.Fragment, null,
101 icon && React.createElement("span", { className: css(styles.labelIcon) }, icon),
102 isTruncated && (React.createElement("span", { ref: textRef, className: css(styles.labelText) }, children)),
103 !isTruncated && children));
104 React.useEffect(() => {
105 if (isEditableActive && editableInputRef) {
106 editableInputRef.current && editableInputRef.current.focus();
107 }
108 }, [editableInputRef, isEditableActive]);
109 const updateVal = () => {
110 setCurrValue(editableInputRef.current.value);
111 };
112 let labelComponentChild = React.createElement("span", { className: css(styles.labelContent) }, content);
113 if (href) {
114 labelComponentChild = (React.createElement("a", { className: css(styles.labelContent), href: href }, content));
115 }
116 else if (isEditable) {
117 labelComponentChild = (React.createElement("button", Object.assign({ ref: editableButtonRef, className: css(styles.labelContent), onClick: (e) => {
118 setIsEditableActive(true);
119 e.stopPropagation();
120 } }, editableProps), content));
121 }
122 if (render) {
123 labelComponentChild = (React.createElement(React.Fragment, null,
124 isTooltipVisible && React.createElement(Tooltip, { reference: componentRef, content: children, position: tooltipPosition }),
125 render({
126 className: styles.labelContent,
127 content,
128 componentRef
129 })));
130 }
131 else if (isTooltipVisible) {
132 labelComponentChild = (React.createElement(Tooltip, { content: children, position: tooltipPosition }, labelComponentChild));
133 }
134 return (React.createElement(LabelComponent, Object.assign({}, props, { className: css(styles.label, colorStyles[color], variant === 'outline' && styles.modifiers.outline, isOverflowLabel && styles.modifiers.overflow, isCompact && styles.modifiers.compact, isEditable && labelGrpStyles.modifiers.editable, isEditableActive && styles.modifiers.editableActive, className) }),
135 !isEditableActive && labelComponentChild,
136 !isEditableActive && onClose && button,
137 isEditableActive && (React.createElement("input", Object.assign({ className: css(styles.labelContent), type: "text", id: "editable-input", ref: editableInputRef, value: currValue, onChange: updateVal }, editableProps)))));
138};
139Label.displayName = 'Label';
140//# sourceMappingURL=Label.js.map
\No newline at end of file