UNPKG

@vimeo/iris

Version:
131 lines (128 loc) 6.49 kB
import { b as __rest, _ as __read, c as __assign, d as __values } from '../../tslib.es6-7f0e734f.js'; import React__default, { useReducer, useRef, useEffect } from 'react'; import { Text, Input } from './Text.style.esm.js'; import { withIris } from '../../utils/HOCs/withIris.esm.js'; import { useLayoutStyles } from '../../utils/hooks/useLayoutStyles.esm.js'; import { geometry } from '../../utils/DOM/geometry.esm.js'; import { Focus } from '../../utils/css.esm.js'; import 'styled-components'; import 'polished'; import '../typography.esm.js'; import '../../tokens/core.esm.js'; import '../../tokens/color/index.esm.js'; import '../../tokens/color/background/background.esm.js'; import '../../tokens/util/readToken.esm.js'; import '../../color/colors.esm.js'; import '../../tokens/util/clamp.esm.js'; import '../../tokens/color/format/format.esm.js'; import '../../tokens/color/format/primary.esm.js'; import '../../tokens/color/format/secondary.esm.js'; import '../../tokens/color/format/tertiary.esm.js'; import '../../tokens/color/rainbow/rainbow.esm.js'; import '../../tokens/color/rainbow/conic/index.esm.js'; import '../../tokens/color/rainbow/conic/sm.esm.js'; import '../../tokens/color/rainbow/conic/xl.esm.js'; import '../../tokens/color/rainbow/linear/index.esm.js'; import '../../tokens/color/rainbow/linear/sm.esm.js'; import '../../tokens/color/rainbow/linear/xl.esm.js'; import '../../tokens/color/livestream/livestream.esm.js'; import '../../tokens/color/status/status.esm.js'; import '../../tokens/color/status/caution.esm.js'; import '../../tokens/color/status/negative.esm.js'; import '../../tokens/color/status/positive.esm.js'; import '../../tokens/color/stroke/stroke.esm.js'; import '../../tokens/color/surface/surface.esm.js'; import '../../tokens/color/text/text.esm.js'; import '../../tokens/util/round.esm.js'; import '../../tokens/color/upsell/upsell.esm.js'; import '../../tokens/color/upsell/sm.esm.js'; import '../../tokens/color/upsell/xl.esm.js'; import '../../tokens/color/upsell/new.esm.js'; import '../../tokens/edge/edge.esm.js'; import '../../tokens/space/space.esm.js'; import '../../tokens/typography/index.esm.js'; import '../../tokens/typography/size/size.esm.js'; var EditableText = withIris(EditableTextComponent); function EditableTextComponent(_a) { var children = _a.children, className = _a.className, _b = _a.element, element = _b === void 0 ? 'span' : _b, _c = _a.format, format = _c === void 0 ? 'soft' : _c, forwardRef = _a.forwardRef, onBlur = _a.onBlur, onChange = _a.onChange, onFocus = _a.onFocus, onKeyUp = _a.onKeyUp, placeholder = _a.placeholder, size = _a.size, style = _a.style, props = __rest(_a, ["children", "className", "element", "format", "forwardRef", "onBlur", "onChange", "onFocus", "onKeyUp", "placeholder", "size", "style"]); var _d = __read(useReducer(reducer, { text: children, width: 0, focus: false, }), 2), state = _d[0], dispatch = _d[1]; var text = state.text, width = state.width, focus = state.focus; var textRef = useRef(null); var inputRef = useRef(null); var _e = __read(useLayoutStyles(style), 2), layoutStyles = _e[0], displayStyles = _e[1]; useEffect(function () { var payload = geometry(textRef.current).width; if (width !== payload) dispatch(['widthSet', payload]); }, [text, width]); function doFocus(event) { var _a; onFocus && onFocus(event); dispatch(['focusSet', true]); (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); } function doBlur(event) { var _a; onBlur && onBlur(event); dispatch(['focusSet', false]); (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.blur(); } function doChange(event) { onChange && onChange(event); dispatch(['textSet', event.target.value]); } function doKeyUp(event) { var _a; onKeyUp && onKeyUp(event); if (event.key === 'Enter') (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.blur(); } return (React__default.createElement("div", { style: __assign({ position: 'relative', display: 'inline-block' }, layoutStyles), className: className }, React__default.createElement(Text, __assign({ as: element, children: text.length > 0 ? text : placeholder, className: className, format: format, onClick: doFocus, ref: textRef, size: size }, props, { style: __assign(__assign({}, displayStyles), { opacity: focus ? 0 : 1, margin: 0 }) })), React__default.createElement(Input, __assign({ className: className, defaultValue: text, format: format, onBlur: doBlur, onChange: doChange, onFocus: doFocus, onKeyUp: doKeyUp, ref: assignRefs(forwardRef, inputRef), size: size, type: "text" }, props, { style: __assign(__assign({}, displayStyles), { width: width, opacity: focus ? 1 : 0, margin: 0 }) })), React__default.createElement(Focus, { parent: Input }))); } function reducer(state, _a) { var _b = __read(_a, 2), type = _b[0], payload = _b[1]; switch (type) { case 'textSet': return __assign(__assign({}, state), { text: withSpaces(payload) }); case 'widthSet': return __assign(__assign({}, state), { width: payload }); case 'focusSet': return __assign(__assign({}, state), { focus: payload }); } } var withSpaces = function (string) { return string.replace(/ /g, '\u00a0'); }; function assignRefs() { var refs = []; for (var _i = 0; _i < arguments.length; _i++) { refs[_i] = arguments[_i]; } return function (node) { var e_1, _a; try { for (var refs_1 = __values(refs), refs_1_1 = refs_1.next(); !refs_1_1.done; refs_1_1 = refs_1.next()) { var ref = refs_1_1.value; if (typeof ref === 'function') { ref(node); } else if (ref) { ref.current = node; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (refs_1_1 && !refs_1_1.done && (_a = refs_1.return)) _a.call(refs_1); } finally { if (e_1) throw e_1.error; } } }; } export { EditableText };