UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

333 lines (332 loc) 13.3 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.COPY_TOOLTIP_TIMEOUT = void 0; var _react = _interopRequireWildcard(require("react")); var _useMountEffect = _interopRequireDefault(require("../../shared/helpers/useMountEffect.js")); var _useIsomorphicLayoutEffect = require("../../shared/helpers/useIsomorphicLayoutEffect.js"); var _clsx = _interopRequireDefault(require("clsx")); var _withComponentMarkers = _interopRequireDefault(require("../../shared/helpers/withComponentMarkers.js")); var _Context = _interopRequireDefault(require("../../shared/Context.js")); var _useId = _interopRequireDefault(require("../../shared/helpers/useId.js")); var _componentHelper = require("../../shared/component-helper.js"); var _helpers = require("../../shared/helpers.js"); var _SpacingUtils = require("../space/SpacingUtils.js"); var _SkeletonHelper = require("../skeleton/SkeletonHelper.js"); var _Tooltip = _interopRequireWildcard(require("../tooltip/Tooltip.js")); var _index = require("./utils/index.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const COPY_TOOLTIP_TIMEOUT = exports.COPY_TOOLTIP_TIMEOUT = 3000; const numberFormatDefaultProps = { id: null, value: null, locale: null, prefix: null, suffix: null, currency: null, currencyDisplay: null, currencyPosition: null, compact: null, monospace: false, options: null, decimals: null, selectAll: true, alwaysSelectAll: false, copySelection: true, cleanCopyValue: false, rounding: null, clean: null, srLabel: null, element: 'span', tooltip: null, skeleton: null, className: null, children: null }; let hasiOSFix = false; function runFix(comp, className) { if (typeof comp === 'function') { comp = comp(); } if (_react.default.isValidElement(comp)) { const elemProps = comp.props; return _react.default.createElement(comp.type, { ...elemProps, className: (0, _clsx.default)(elemProps.className, className) }); } return (0, _jsxRuntime.jsx)("span", { className: className, children: comp }); } function NumberFormat(ownProps) { var _context$getTranslati3; const context = (0, _react.useContext)(_Context.default); const propsWithDefaults = { ...numberFormatDefaultProps, ...(0, _componentHelper.removeUndefinedProps)({ ...ownProps }) }; const propsWithDefaultsRef = (0, _react.useRef)(propsWithDefaults); propsWithDefaultsRef.current = propsWithDefaults; const elRef = (0, _react.useRef)(null); const selectionRef = (0, _react.useRef)(null); const generatedId = (0, _useId.default)(propsWithDefaults.id); const copyTooltipTimeoutRef = (0, _react.useRef)(null); const outsideClickRef = (0, _react.useRef)(null); const cleanedValueRef = (0, _react.useRef)(undefined); const [selected, setSelected] = (0, _react.useState)(false); const [hover, setHover] = (0, _react.useState)(false); const [copyTooltipActive, setCopyTooltipActive] = (0, _react.useState)(false); const [copyTooltipText, setCopyTooltipText] = (0, _react.useState)(null); const needsFocusRef = (0, _react.useRef)(false); (0, _useMountEffect.default)(() => { if (_helpers.IS_IOS && !hasiOSFix) { hasiOSFix = true; (0, _index.runIOSSelectionFix)(); } return () => { var _outsideClickRef$curr; (_outsideClickRef$curr = outsideClickRef.current) === null || _outsideClickRef$curr === void 0 || _outsideClickRef$curr.remove(); if (copyTooltipTimeoutRef.current) { clearTimeout(copyTooltipTimeoutRef.current); } }; }); const clearCopyTooltipTimeout = (0, _react.useCallback)(() => { if (copyTooltipTimeoutRef.current) { clearTimeout(copyTooltipTimeoutRef.current); copyTooltipTimeoutRef.current = null; } }, []); const onBlurHandler = (0, _react.useCallback)(() => { setSelected(false); }, []); const doSelectAll = (0, _react.useCallback)(() => { try { const elem = selectionRef.current || elRef.current; if (elem) { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(elem); selection.removeAllRanges(); selection.addRange(range); } } catch (e) { (0, _componentHelper.warn)(e); } }, []); const setFocus = (0, _react.useCallback)(() => { if ((0, _componentHelper.isTouchDevice)()) { return; } needsFocusRef.current = true; setSelected(true); }, []); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (selected && needsFocusRef.current) { var _selectionRef$current; needsFocusRef.current = false; (_selectionRef$current = selectionRef.current) === null || _selectionRef$current === void 0 || _selectionRef$current.focus({ preventScroll: true }); doSelectAll(); if (!propsWithDefaults.copySelection) { outsideClickRef.current = (0, _componentHelper.detectOutsideClick)(elRef.current, onBlurHandler); } } }, [selected, doSelectAll, onBlurHandler, propsWithDefaults.copySelection]); const showCopyTooltip = (0, _react.useCallback)(message => { var _context$getTranslati; const translations = (_context$getTranslati = context.getTranslation) === null || _context$getTranslati === void 0 || (_context$getTranslati = _context$getTranslati.call(context, propsWithDefaultsRef.current)) === null || _context$getTranslati === void 0 ? void 0 : _context$getTranslati.NumberFormat; const label = message || (translations === null || translations === void 0 ? void 0 : translations.clipboardCopy); if (!label) { return; } clearCopyTooltipTimeout(); setCopyTooltipActive(true); setCopyTooltipText(label); copyTooltipTimeoutRef.current = setTimeout(() => { setCopyTooltipActive(false); }, COPY_TOOLTIP_TIMEOUT); }, [context, clearCopyTooltipTimeout]); const shortcutHandler = (0, _react.useCallback)(() => { var _context$getTranslati2; const label = (_context$getTranslati2 = context.getTranslation) === null || _context$getTranslati2 === void 0 || (_context$getTranslati2 = _context$getTranslati2.call(context, propsWithDefaultsRef.current)) === null || _context$getTranslati2 === void 0 || (_context$getTranslati2 = _context$getTranslati2.NumberFormat) === null || _context$getTranslati2 === void 0 ? void 0 : _context$getTranslati2.clipboardCopy; showCopyTooltip(label); }, [context, showCopyTooltip]); const onContextMenuHandler = (0, _react.useCallback)(() => { if (!(0, _helpers.hasSelectedText)()) { setFocus(); } }, [setFocus]); const onClickHandler = (0, _react.useCallback)(() => { if ((propsWithDefaults.selectAll || propsWithDefaults.alwaysSelectAll) && !(0, _helpers.hasSelectedText)()) { setFocus(); } }, [propsWithDefaults.selectAll, propsWithDefaults.alwaysSelectAll, setFocus]); const onMouseEnter = (0, _react.useCallback)(() => { setHover(true); }, []); const onMouseLeave = (0, _react.useCallback)(() => { setHover(false); }, []); const translations = (_context$getTranslati3 = context.getTranslation) === null || _context$getTranslati3 === void 0 || (_context$getTranslati3 = _context$getTranslati3.call(context, propsWithDefaults)) === null || _context$getTranslati3 === void 0 ? void 0 : _context$getTranslati3.NumberFormat; const props = (0, _componentHelper.extendExistingPropsWithContext)(propsWithDefaults, numberFormatDefaultProps, translations, context === null || context === void 0 ? void 0 : context.NumberFormat); const { id, value: _value, prefix, suffix, children, currency, currencyDisplay, currencyPosition, compact, monospace, tooltip, skeleton, options, locale, decimals, rounding, signDisplay, clean, selectAll: selectAllProp, copySelection, cleanCopyValue, srLabel, element, className, alwaysSelectAll, __format, ..._rest } = props; let rest = _rest; let value = _value !== null && _value !== void 0 ? _value : null; if (value === null && children !== null) { value = children; } let usedCurrencyPosition = currencyPosition; if (currencyDisplay === 'code' && !usedCurrencyPosition) { usedCurrencyPosition = 'before'; } const formatOptions = { locale, currency, currencyDisplay, currencyPosition: usedCurrencyPosition, compact, decimals, rounding, signDisplay, options, clean: clean, cleanCopyValue: cleanCopyValue, returnAria: true, invalidAriaText: locale && locale !== context.locale ? null : translations === null || translations === void 0 ? void 0 : translations.notAvailable }; const useCtx = (0, _componentHelper.extendDeep)({ locale: null, currency: null }, context); if (useCtx) { if (useCtx.locale && !locale) { formatOptions.locale = useCtx.locale; } if (useCtx.currency && currency === true) { formatOptions.options = formatOptions.options ? { ...formatOptions.options } : {}; formatOptions.options.currency = useCtx.currency; } } const formatter = __format !== null && __format !== void 0 ? __format : currency === true || typeof currency === 'string' ? _index.formatCurrency : _index.formatNumber; const result = formatter(value, formatOptions); const { cleanedValue, locale: lang } = result; let { aria } = result; let display = result.number; cleanedValueRef.current = cleanedValue; if (prefix) { display = (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [runFix(prefix, 'dnb-number-format__prefix'), " ", display] }); aria = String(`${(0, _componentHelper.convertJsxToString)(runFix(prefix, 'dnb-number-format__prefix'))} ${aria}`); } if (suffix) { const suffixElement = runFix(suffix, 'dnb-number-format__suffix'); const suffixStartsWithSlash = typeof suffix === 'string' && suffix.startsWith('/'); const suffixSpace = suffixStartsWithSlash ? '' : ' '; display = (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [display, suffixSpace, suffixElement] }); aria = `${aria}${suffixSpace}${(0, _componentHelper.convertJsxToString)(suffixElement)}`; } if (tooltip) { rest = (0, _Tooltip.injectTooltipSemantic)(rest); } const attributes = (0, _SpacingUtils.applySpacing)(ownProps, { lang, ref: elRef, className: (0, _clsx.default)('dnb-number-format', className, (currency === true || typeof currency === 'string') && 'dnb-number-format--currency', selectAllProp && 'dnb-number-format--select-all', selected && 'dnb-number-format--selected', monospace && 'dnb-number-format--monospace'), onMouseEnter, onMouseLeave, ...rest }); const displayParams = {}; if (selectAllProp || copySelection) { displayParams.onClick = onClickHandler; displayParams.onContextMenu = onContextMenuHandler; } (0, _componentHelper.validateDOMAttributes)(ownProps, attributes); (0, _SkeletonHelper.skeletonDOMAttributes)(attributes, skeleton, context); const Element = element; return (0, _jsxRuntime.jsxs)(Element, { ...attributes, children: [(0, _jsxRuntime.jsx)("span", { className: (0, _clsx.default)('dnb-number-format__visible', (0, _SkeletonHelper.createSkeletonClass)('font', skeleton, context)), "aria-hidden": !hover, ...displayParams, children: display }), (0, _jsxRuntime.jsx)("span", { className: "dnb-sr-only", "data-text": srLabel ? `${(0, _componentHelper.convertJsxToString)(srLabel)}${'\u00a0'}${aria}` : aria }), copySelection && (0, _jsxRuntime.jsx)("span", { className: "dnb-number-format__selection dnb-no-focus", ref: selectionRef, tabIndex: -1, onBlur: onBlurHandler, onCopy: shortcutHandler, "aria-hidden": true, children: selected && cleanedValue }), tooltip && (0, _jsxRuntime.jsx)(_Tooltip.default, { id: generatedId + '-tooltip', targetElement: elRef, tooltip: tooltip }), copyTooltipActive && (0, _jsxRuntime.jsx)(_Tooltip.default, { open: copyTooltipActive, targetElement: elRef, showDelay: 0, hideDelay: 0, triggerOffset: 8, children: copyTooltipText })] }); } const MemoizedNumberFormat = _react.default.memo(NumberFormat); (0, _withComponentMarkers.default)(MemoizedNumberFormat, { _supportsSpacingProps: true }); var _default = exports.default = MemoizedNumberFormat; //# sourceMappingURL=NumberFormatBase.js.map