UNPKG

@wordpress/components

Version:
328 lines (292 loc) 12.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_UNIT = exports.CSS_UNITS = exports.ALL_CSS_UNITS = void 0; exports.filterUnitsWithSettings = filterUnitsWithSettings; exports.getAccessibleLabelForUnit = getAccessibleLabelForUnit; exports.getParsedQuantityAndUnit = getParsedQuantityAndUnit; exports.getUnitsWithCurrentUnit = getUnitsWithCurrentUnit; exports.getValidParsedQuantityAndUnit = getValidParsedQuantityAndUnit; exports.hasUnits = hasUnits; exports.parseQuantityAndUnitFromRawValue = parseQuantityAndUnitFromRawValue; exports.useCustomUnits = void 0; var _i18n = require("@wordpress/i18n"); var _element = require("@wordpress/element"); /** * WordPress dependencies */ const isWeb = _element.Platform.OS === 'web'; const allUnits = { px: { value: 'px', label: isWeb ? 'px' : (0, _i18n.__)('Pixels (px)'), a11yLabel: (0, _i18n.__)('Pixels (px)'), step: 1 }, '%': { value: '%', label: isWeb ? '%' : (0, _i18n.__)('Percentage (%)'), a11yLabel: (0, _i18n.__)('Percent (%)'), step: 0.1 }, em: { value: 'em', label: isWeb ? 'em' : (0, _i18n.__)('Relative to parent font size (em)'), a11yLabel: (0, _i18n._x)('ems', 'Relative to parent font size (em)'), step: 0.01 }, rem: { value: 'rem', label: isWeb ? 'rem' : (0, _i18n.__)('Relative to root font size (rem)'), a11yLabel: (0, _i18n._x)('rems', 'Relative to root font size (rem)'), step: 0.01 }, vw: { value: 'vw', label: isWeb ? 'vw' : (0, _i18n.__)('Viewport width (vw)'), a11yLabel: (0, _i18n.__)('Viewport width (vw)'), step: 0.1 }, vh: { value: 'vh', label: isWeb ? 'vh' : (0, _i18n.__)('Viewport height (vh)'), a11yLabel: (0, _i18n.__)('Viewport height (vh)'), step: 0.1 }, vmin: { value: 'vmin', label: isWeb ? 'vmin' : (0, _i18n.__)('Viewport smallest dimension (vmin)'), a11yLabel: (0, _i18n.__)('Viewport smallest dimension (vmin)'), step: 0.1 }, vmax: { value: 'vmax', label: isWeb ? 'vmax' : (0, _i18n.__)('Viewport largest dimension (vmax)'), a11yLabel: (0, _i18n.__)('Viewport largest dimension (vmax)'), step: 0.1 }, ch: { value: 'ch', label: isWeb ? 'ch' : (0, _i18n.__)('Width of the zero (0) character (ch)'), a11yLabel: (0, _i18n.__)('Width of the zero (0) character (ch)'), step: 0.01 }, ex: { value: 'ex', label: isWeb ? 'ex' : (0, _i18n.__)('x-height of the font (ex)'), a11yLabel: (0, _i18n.__)('x-height of the font (ex)'), step: 0.01 }, cm: { value: 'cm', label: isWeb ? 'cm' : (0, _i18n.__)('Centimeters (cm)'), a11yLabel: (0, _i18n.__)('Centimeters (cm)'), step: 0.001 }, mm: { value: 'mm', label: isWeb ? 'mm' : (0, _i18n.__)('Millimeters (mm)'), a11yLabel: (0, _i18n.__)('Millimeters (mm)'), step: 0.1 }, in: { value: 'in', label: isWeb ? 'in' : (0, _i18n.__)('Inches (in)'), a11yLabel: (0, _i18n.__)('Inches (in)'), step: 0.001 }, pc: { value: 'pc', label: isWeb ? 'pc' : (0, _i18n.__)('Picas (pc)'), a11yLabel: (0, _i18n.__)('Picas (pc)'), step: 1 }, pt: { value: 'pt', label: isWeb ? 'pt' : (0, _i18n.__)('Points (pt)'), a11yLabel: (0, _i18n.__)('Points (pt)'), step: 1 } }; /** * An array of all available CSS length units. */ const ALL_CSS_UNITS = Object.values(allUnits); /** * Units of measurements. `a11yLabel` is used by screenreaders. */ exports.ALL_CSS_UNITS = ALL_CSS_UNITS; const CSS_UNITS = [allUnits.px, allUnits['%'], allUnits.em, allUnits.rem, allUnits.vw, allUnits.vh]; exports.CSS_UNITS = CSS_UNITS; const DEFAULT_UNIT = allUnits.px; /** * Handles legacy value + unit handling. * This component use to manage both incoming value and units separately. * * Moving forward, ideally the value should be a string that contains both * the value and unit, example: '10px' * * @param rawValue The raw value as a string (may or may not contain the unit) * @param fallbackUnit The unit used as a fallback, if not unit is detected in the `value` * @param allowedUnits Units to derive from. * @return The extracted quantity and unit. The quantity can be `undefined` in case the raw value * could not be parsed to a number correctly. The unit can be `undefined` in case the unit parse * from the raw value could not be matched against the list of allowed units. */ exports.DEFAULT_UNIT = DEFAULT_UNIT; function getParsedQuantityAndUnit(rawValue, fallbackUnit, allowedUnits) { const initialValue = fallbackUnit ? `${rawValue !== null && rawValue !== void 0 ? rawValue : ''}${fallbackUnit}` : rawValue; return parseQuantityAndUnitFromRawValue(initialValue, allowedUnits); } /** * Checks if units are defined. * * @param units List of units. * @return Whether the list actually contains any units. */ function hasUnits(units) { // Although the `isArray` check shouldn't be necessary (given the signature of // this typed function), it's better to stay on the side of caution, since // this function may be called from un-typed environments. return Array.isArray(units) && !!units.length; } /** * Parses a quantity and unit from a raw string value, given a list of allowed * units and otherwise falling back to the default unit. * * @param rawValue The raw value as a string (may or may not contain the unit) * @param allowedUnits Units to derive from. * @return The extracted quantity and unit. The quantity can be `undefined` in case the raw value * could not be parsed to a number correctly. The unit can be `undefined` in case the unit parsed * from the raw value could not be matched against the list of allowed units. */ function parseQuantityAndUnitFromRawValue(rawValue) { var _trimmedValue, _unitMatch$; let allowedUnits = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ALL_CSS_UNITS; let trimmedValue; let quantityToReturn; if (typeof rawValue !== 'undefined' || rawValue === null) { trimmedValue = `${rawValue}`.trim(); const parsedQuantity = parseFloat(trimmedValue); quantityToReturn = !isFinite(parsedQuantity) ? undefined : parsedQuantity; } const unitMatch = (_trimmedValue = trimmedValue) === null || _trimmedValue === void 0 ? void 0 : _trimmedValue.match(/[\d.\-\+]*\s*(.*)/); const matchedUnit = unitMatch === null || unitMatch === void 0 ? void 0 : (_unitMatch$ = unitMatch[1]) === null || _unitMatch$ === void 0 ? void 0 : _unitMatch$.toLowerCase(); let unitToReturn; if (hasUnits(allowedUnits)) { const match = allowedUnits.find(item => item.value === matchedUnit); unitToReturn = match === null || match === void 0 ? void 0 : match.value; } else { unitToReturn = DEFAULT_UNIT.value; } return [quantityToReturn, unitToReturn]; } /** * Parses quantity and unit from a raw value. Validates parsed value, using fallback * value if invalid. * * @param rawValue The next value. * @param allowedUnits Units to derive from. * @param fallbackQuantity The fallback quantity, used in case it's not possible to parse a valid quantity from the raw value. * @param fallbackUnit The fallback unit, used in case it's not possible to parse a valid unit from the raw value. * @return The extracted quantity and unit. The quantity can be `undefined` in case the raw value * could not be parsed to a number correctly, and the `fallbackQuantity` was also `undefined`. The * unit can be `undefined` only if the unit parsed from the raw value could not be matched against * the list of allowed units, the `fallbackQuantity` is also `undefined` and the list of * `allowedUnits` is passed empty. */ function getValidParsedQuantityAndUnit(rawValue, allowedUnits, fallbackQuantity, fallbackUnit) { const [parsedQuantity, parsedUnit] = parseQuantityAndUnitFromRawValue(rawValue, allowedUnits); // The parsed value from `parseQuantityAndUnitFromRawValue` should now be // either a real number or undefined. If undefined, use the fallback value. const quantityToReturn = parsedQuantity !== null && parsedQuantity !== void 0 ? parsedQuantity : fallbackQuantity; // If no unit is parsed from the raw value, or if the fallback unit is not // defined, use the first value from the list of allowed units as fallback. let unitToReturn = parsedUnit || fallbackUnit; if (!unitToReturn && hasUnits(allowedUnits)) { unitToReturn = allowedUnits[0].value; } return [quantityToReturn, unitToReturn]; } /** * Takes a unit value and finds the matching accessibility label for the * unit abbreviation. * * @param unit Unit value (example: `px`) * @return a11y label for the unit abbreviation */ function getAccessibleLabelForUnit(unit) { const match = ALL_CSS_UNITS.find(item => item.value === unit); return match !== null && match !== void 0 && match.a11yLabel ? match === null || match === void 0 ? void 0 : match.a11yLabel : match === null || match === void 0 ? void 0 : match.value; } /** * Filters available units based on values defined a list of allowed unit values. * * @param allowedUnitValues Collection of allowed unit value strings. * @param availableUnits Collection of available unit objects. * @return Filtered units. */ function filterUnitsWithSettings() { let allowedUnitValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; let availableUnits = arguments.length > 1 ? arguments[1] : undefined; // Although the `isArray` check shouldn't be necessary (given the signature of // this typed function), it's better to stay on the side of caution, since // this function may be called from un-typed environments. return Array.isArray(availableUnits) ? availableUnits.filter(unit => allowedUnitValues.includes(unit.value)) : []; } /** * Custom hook to retrieve and consolidate units setting from add_theme_support(). * TODO: ideally this hook shouldn't be needed * https://github.com/WordPress/gutenberg/pull/31822#discussion_r633280823 * * @param args An object containing units, settingPath & defaultUnits. * @param args.units Collection of all potentially available units. * @param args.availableUnits Collection of unit value strings for filtering available units. * @param args.defaultValues Collection of default values for defined units. Example: `{ px: 350, em: 15 }`. * * @return Filtered list of units, with their default values updated following the `defaultValues` * argument's property. */ const useCustomUnits = _ref => { let { units = ALL_CSS_UNITS, availableUnits = [], defaultValues } = _ref; const customUnitsToReturn = filterUnitsWithSettings(availableUnits, units); if (defaultValues) { customUnitsToReturn.forEach((unit, i) => { if (defaultValues[unit.value]) { const [parsedDefaultValue] = parseQuantityAndUnitFromRawValue(defaultValues[unit.value]); customUnitsToReturn[i].default = parsedDefaultValue; } }); } return customUnitsToReturn; }; /** * Get available units with the unit for the currently selected value * prepended if it is not available in the list of units. * * This is useful to ensure that the current value's unit is always * accurately displayed in the UI, even if the intention is to hide * the availability of that unit. * * @param rawValue Selected value to parse. * @param legacyUnit Legacy unit value, if rawValue needs it appended. * @param units List of available units. * * @return A collection of units containing the unit for the current value. */ exports.useCustomUnits = useCustomUnits; function getUnitsWithCurrentUnit(rawValue, legacyUnit) { let units = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ALL_CSS_UNITS; const unitsToReturn = Array.isArray(units) ? [...units] : []; const [, currentUnit] = getParsedQuantityAndUnit(rawValue, legacyUnit, ALL_CSS_UNITS); if (currentUnit && !unitsToReturn.some(unit => unit.value === currentUnit)) { if (allUnits[currentUnit]) { unitsToReturn.unshift(allUnits[currentUnit]); } } return unitsToReturn; } //# sourceMappingURL=utils.js.map