UNPKG

@wordpress/components

Version:
167 lines (162 loc) 5.66 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.getColorLocations = getColorLocations; exports.getGradientAngle = getGradientAngle; exports.getGradientBaseColors = getGradientBaseColors; exports.getGradientColorGroup = getGradientColorGroup; var _reactNative = require("react-native"); var _reactNativeLinearGradient = _interopRequireDefault(require("react-native-linear-gradient")); var _gradientParser = _interopRequireDefault(require("gradient-parser")); var _primitives = require("@wordpress/primitives"); var _compose = require("@wordpress/compose"); var _element = require("@wordpress/element"); var _style = _interopRequireDefault(require("./style.scss")); var _utils = require("../color-settings/utils"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ function getGradientAngle(gradientValue) { const angleBase = 45; const matchAngle = /\(((\d+deg)|(to\s[^,]+))/; const angle = matchAngle.exec(gradientValue) ? matchAngle.exec(gradientValue)[1] : '180deg'; const angleType = angle.includes('deg') ? 'angle' : 'sideOrCorner'; if (angleType === 'sideOrCorner') { switch (angle) { case 'to top': return 0; case 'to top right': case 'to right top': return angleBase; case 'to right': return 2 * angleBase; case 'to bottom right': case 'to right bottom': return 3 * angleBase; case 'to bottom': return 4 * angleBase; case 'to bottom left': case 'to left bottom': return 5 * angleBase; case 'to left': return 6 * angleBase; case 'to top left': case 'to left top': return 7 * angleBase; } } else if (angleType === 'angle') { return parseFloat(angle); } else { return 4 * angleBase; } } function getGradientColorGroup(gradientValue) { const colorNeedParenthesis = ['rgb', 'rgba']; const excludeSideOrCorner = /linear-gradient\(to\s+([a-z\s]+,)/; // Parser has some difficulties with angle defined as a side or corner (e.g. `to left`) // so it's going to be excluded in order to matching color groups. const modifiedGradientValue = gradientValue.replace(excludeSideOrCorner, 'linear-gradient('); return [].concat(..._gradientParser.default.parse(modifiedGradientValue)?.map(gradient => gradient.colorStops?.map((color, index) => { const { type, value, length } = color; const fallbackLength = `${100 * (index / (gradient.colorStops.length - 1))}%`; const colorLength = length ? `${length.value}${length.type}` : fallbackLength; if (colorNeedParenthesis.includes(type)) { return [`${type}(${value.join(',')})`, colorLength]; } else if (type === 'literal') { return [value, colorLength]; } return [`#${value}`, colorLength]; }))); } function getGradientBaseColors(colorGroup) { return colorGroup.map(color => color[0]); } function getColorLocations(colorGroup) { return colorGroup.map(location => Number(location[1].replace('%', '')) / 100); } function Gradient({ gradientValue, style, angleCenter = { x: 0.5, y: 0.5 }, children, ...otherProps }) { const [resizeObserver, sizes] = (0, _compose.useResizeObserver)(); const { width = 0, height = 0 } = sizes || {}; const { isGradient, getGradientType, gradients } = _utils.colorsUtils; const colorGroup = (0, _element.useMemo)(() => getGradientColorGroup(gradientValue), [gradientValue]); const locations = (0, _element.useMemo)(() => getColorLocations(colorGroup), [colorGroup]); const colors = (0, _element.useMemo)(() => getGradientBaseColors(colorGroup), [colorGroup]); if (!gradientValue || !isGradient(gradientValue)) { return null; } const isLinearGradient = getGradientType(gradientValue) === gradients.linear; if (isLinearGradient) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeLinearGradient.default, { colors: colors, useAngle: true, angle: getGradientAngle(gradientValue), locations: locations, angleCenter: angleCenter, style: style, ...otherProps, children: children }); } return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [style, _style.default.overflow], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: _style.default.radialGradientContent, children: children }), resizeObserver, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_primitives.SVG, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Defs, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.RadialGradient // eslint-disable-next-line no-restricted-syntax , { id: "radialGradient", gradientUnits: "userSpaceOnUse", rx: "70%", ry: "70%", cy: _reactNative.Platform.OS === 'android' ? width / 2 : '50%', children: colorGroup.map(group => { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Stop, { offset: group[1], stopColor: group[0], stopOpacity: "1" }, `${group[1]}-${group[0]}`); }) }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Rect, { height: height, width: width, fill: "url(#radialGradient)" })] })] }); } var _default = exports.default = Gradient; //# sourceMappingURL=index.native.js.map