UNPKG

@wordpress/block-editor

Version:
437 lines (422 loc) 18.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TypographyPanel; exports.useHasTypographyPanel = useHasTypographyPanel; var _components = require("@wordpress/components"); var _i18n = require("@wordpress/i18n"); var _element = require("@wordpress/element"); var _fontFamily = _interopRequireDefault(require("../font-family")); var _fontAppearanceControl = _interopRequireDefault(require("../font-appearance-control")); var _lineHeightControl = _interopRequireDefault(require("../line-height-control")); var _letterSpacingControl = _interopRequireDefault(require("../letter-spacing-control")); var _textAlignmentControl = _interopRequireDefault(require("../text-alignment-control")); var _textTransformControl = _interopRequireDefault(require("../text-transform-control")); var _textDecorationControl = _interopRequireDefault(require("../text-decoration-control")); var _writingModeControl = _interopRequireDefault(require("../writing-mode-control")); var _utils = require("./utils"); var _object = require("../../utils/object"); var _typographyUtils = require("./typography-utils"); var _jsxRuntime = require("react/jsx-runtime"); /** * WordPress dependencies */ /** * Internal dependencies */ const MIN_TEXT_COLUMNS = 1; const MAX_TEXT_COLUMNS = 6; function useHasTypographyPanel(settings) { const hasFontFamily = useHasFontFamilyControl(settings); const hasLineHeight = useHasLineHeightControl(settings); const hasFontAppearance = useHasAppearanceControl(settings); const hasLetterSpacing = useHasLetterSpacingControl(settings); const hasTextAlign = useHasTextAlignmentControl(settings); const hasTextTransform = useHasTextTransformControl(settings); const hasTextDecoration = useHasTextDecorationControl(settings); const hasWritingMode = useHasWritingModeControl(settings); const hasTextColumns = useHasTextColumnsControl(settings); const hasFontSize = useHasFontSizeControl(settings); return hasFontFamily || hasLineHeight || hasFontAppearance || hasLetterSpacing || hasTextAlign || hasTextTransform || hasFontSize || hasTextDecoration || hasWritingMode || hasTextColumns; } function useHasFontSizeControl(settings) { return settings?.typography?.defaultFontSizes !== false && settings?.typography?.fontSizes?.default?.length || settings?.typography?.fontSizes?.theme?.length || settings?.typography?.fontSizes?.custom?.length || settings?.typography?.customFontSize; } function useHasFontFamilyControl(settings) { return ['default', 'theme', 'custom'].some(key => settings?.typography?.fontFamilies?.[key]?.length); } function useHasLineHeightControl(settings) { return settings?.typography?.lineHeight; } function useHasAppearanceControl(settings) { return settings?.typography?.fontStyle || settings?.typography?.fontWeight; } function useAppearanceControlLabel(settings) { if (!settings?.typography?.fontStyle) { return (0, _i18n.__)('Font weight'); } if (!settings?.typography?.fontWeight) { return (0, _i18n.__)('Font style'); } return (0, _i18n.__)('Appearance'); } function useHasLetterSpacingControl(settings) { return settings?.typography?.letterSpacing; } function useHasTextTransformControl(settings) { return settings?.typography?.textTransform; } function useHasTextAlignmentControl(settings) { return settings?.typography?.textAlign; } function useHasTextDecorationControl(settings) { return settings?.typography?.textDecoration; } function useHasWritingModeControl(settings) { return settings?.typography?.writingMode; } function useHasTextColumnsControl(settings) { return settings?.typography?.textColumns; } /** * Concatenate all the font sizes into a single list for the font size picker. * * @param {Object} settings The global styles settings. * * @return {Array} The merged font sizes. */ function getMergedFontSizes(settings) { var _fontSizes$custom, _fontSizes$theme, _fontSizes$default; const fontSizes = settings?.typography?.fontSizes; const defaultFontSizesEnabled = !!settings?.typography?.defaultFontSizes; return [...((_fontSizes$custom = fontSizes?.custom) !== null && _fontSizes$custom !== void 0 ? _fontSizes$custom : []), ...((_fontSizes$theme = fontSizes?.theme) !== null && _fontSizes$theme !== void 0 ? _fontSizes$theme : []), ...(defaultFontSizesEnabled ? (_fontSizes$default = fontSizes?.default) !== null && _fontSizes$default !== void 0 ? _fontSizes$default : [] : [])]; } function TypographyToolsPanel({ resetAllFilter, onChange, value, panelId, children }) { const dropdownMenuProps = (0, _utils.useToolsPanelDropdownMenuProps)(); const resetAll = () => { const updatedValue = resetAllFilter(value); onChange(updatedValue); }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanel, { label: (0, _i18n.__)('Typography'), resetAll: resetAll, panelId: panelId, dropdownMenuProps: dropdownMenuProps, children: children }); } const DEFAULT_CONTROLS = { fontFamily: true, fontSize: true, fontAppearance: true, lineHeight: true, letterSpacing: true, textAlign: true, textTransform: true, textDecoration: true, writingMode: true, textColumns: true }; function TypographyPanel({ as: Wrapper = TypographyToolsPanel, value, onChange, inheritedValue = value, settings, panelId, defaultControls = DEFAULT_CONTROLS }) { const decodeValue = rawValue => (0, _utils.getValueFromVariable)({ settings }, '', rawValue); // Font Family const hasFontFamilyEnabled = useHasFontFamilyControl(settings); const fontFamily = decodeValue(inheritedValue?.typography?.fontFamily); const { fontFamilies, fontFamilyFaces } = (0, _element.useMemo)(() => { return (0, _typographyUtils.getMergedFontFamiliesAndFontFamilyFaces)(settings, fontFamily); }, [settings, fontFamily]); const setFontFamily = newValue => { const slug = fontFamilies?.find(({ fontFamily: f }) => f === newValue)?.slug; onChange((0, _object.setImmutably)(value, ['typography', 'fontFamily'], slug ? `var:preset|font-family|${slug}` : newValue || undefined)); }; const hasFontFamily = () => !!value?.typography?.fontFamily; const resetFontFamily = () => setFontFamily(undefined); // Font Size const hasFontSizeEnabled = useHasFontSizeControl(settings); const disableCustomFontSizes = !settings?.typography?.customFontSize; const mergedFontSizes = getMergedFontSizes(settings); const fontSize = decodeValue(inheritedValue?.typography?.fontSize); const setFontSize = (newValue, metadata) => { const actualValue = !!metadata?.slug ? `var:preset|font-size|${metadata?.slug}` : newValue; onChange((0, _object.setImmutably)(value, ['typography', 'fontSize'], actualValue || undefined)); }; const hasFontSize = () => !!value?.typography?.fontSize; const resetFontSize = () => setFontSize(undefined); // Appearance const hasAppearanceControl = useHasAppearanceControl(settings); const appearanceControlLabel = useAppearanceControlLabel(settings); const hasFontStyles = settings?.typography?.fontStyle; const hasFontWeights = settings?.typography?.fontWeight; const fontStyle = decodeValue(inheritedValue?.typography?.fontStyle); const fontWeight = decodeValue(inheritedValue?.typography?.fontWeight); const { nearestFontStyle, nearestFontWeight } = (0, _typographyUtils.findNearestStyleAndWeight)(fontFamilyFaces, fontStyle, fontWeight); const setFontAppearance = (0, _element.useCallback)(({ fontStyle: newFontStyle, fontWeight: newFontWeight }) => { // Only update the font style and weight if they have changed. if (newFontStyle !== fontStyle || newFontWeight !== fontWeight) { onChange({ ...value, typography: { ...value?.typography, fontStyle: newFontStyle || undefined, fontWeight: newFontWeight || undefined } }); } }, [fontStyle, fontWeight, onChange, value]); const hasFontAppearance = () => !!value?.typography?.fontStyle || !!value?.typography?.fontWeight; const resetFontAppearance = (0, _element.useCallback)(() => { setFontAppearance({}); }, [setFontAppearance]); // Check if previous font style and weight values are available in the new font family. (0, _element.useEffect)(() => { if (nearestFontStyle && nearestFontWeight) { setFontAppearance({ fontStyle: nearestFontStyle, fontWeight: nearestFontWeight }); } else { // Reset font appearance if there are no available styles or weights. resetFontAppearance(); } }, [nearestFontStyle, nearestFontWeight, resetFontAppearance, setFontAppearance]); // Line Height const hasLineHeightEnabled = useHasLineHeightControl(settings); const lineHeight = decodeValue(inheritedValue?.typography?.lineHeight); const setLineHeight = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'lineHeight'], newValue || undefined)); }; const hasLineHeight = () => value?.typography?.lineHeight !== undefined; const resetLineHeight = () => setLineHeight(undefined); // Letter Spacing const hasLetterSpacingControl = useHasLetterSpacingControl(settings); const letterSpacing = decodeValue(inheritedValue?.typography?.letterSpacing); const setLetterSpacing = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'letterSpacing'], newValue || undefined)); }; const hasLetterSpacing = () => !!value?.typography?.letterSpacing; const resetLetterSpacing = () => setLetterSpacing(undefined); // Text Columns const hasTextColumnsControl = useHasTextColumnsControl(settings); const textColumns = decodeValue(inheritedValue?.typography?.textColumns); const setTextColumns = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'textColumns'], newValue || undefined)); }; const hasTextColumns = () => !!value?.typography?.textColumns; const resetTextColumns = () => setTextColumns(undefined); // Text Transform const hasTextTransformControl = useHasTextTransformControl(settings); const textTransform = decodeValue(inheritedValue?.typography?.textTransform); const setTextTransform = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'textTransform'], newValue || undefined)); }; const hasTextTransform = () => !!value?.typography?.textTransform; const resetTextTransform = () => setTextTransform(undefined); // Text Decoration const hasTextDecorationControl = useHasTextDecorationControl(settings); const textDecoration = decodeValue(inheritedValue?.typography?.textDecoration); const setTextDecoration = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'textDecoration'], newValue || undefined)); }; const hasTextDecoration = () => !!value?.typography?.textDecoration; const resetTextDecoration = () => setTextDecoration(undefined); // Text Orientation const hasWritingModeControl = useHasWritingModeControl(settings); const writingMode = decodeValue(inheritedValue?.typography?.writingMode); const setWritingMode = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'writingMode'], newValue || undefined)); }; const hasWritingMode = () => !!value?.typography?.writingMode; const resetWritingMode = () => setWritingMode(undefined); // Text Alignment const hasTextAlignmentControl = useHasTextAlignmentControl(settings); const textAlign = decodeValue(inheritedValue?.typography?.textAlign); const setTextAlign = newValue => { onChange((0, _object.setImmutably)(value, ['typography', 'textAlign'], newValue || undefined)); }; const hasTextAlign = () => !!value?.typography?.textAlign; const resetTextAlign = () => setTextAlign(undefined); const resetAllFilter = (0, _element.useCallback)(previousValue => { return { ...previousValue, typography: {} }; }, []); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Wrapper, { resetAllFilter: resetAllFilter, value: value, onChange: onChange, panelId: panelId, children: [hasFontFamilyEnabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { label: (0, _i18n.__)('Font'), hasValue: hasFontFamily, onDeselect: resetFontFamily, isShownByDefault: defaultControls.fontFamily, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontFamily.default, { fontFamilies: fontFamilies, value: fontFamily, onChange: setFontFamily, size: "__unstable-large", __nextHasNoMarginBottom: true }) }), hasFontSizeEnabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { label: (0, _i18n.__)('Size'), hasValue: hasFontSize, onDeselect: resetFontSize, isShownByDefault: defaultControls.fontSize, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.FontSizePicker, { value: fontSize, onChange: setFontSize, fontSizes: mergedFontSizes, disableCustomFontSizes: disableCustomFontSizes, withReset: false, withSlider: true, size: "__unstable-large" }) }), hasAppearanceControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: appearanceControlLabel, hasValue: hasFontAppearance, onDeselect: resetFontAppearance, isShownByDefault: defaultControls.fontAppearance, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fontAppearanceControl.default, { value: { fontStyle, fontWeight }, onChange: setFontAppearance, hasFontStyles: hasFontStyles, hasFontWeights: hasFontWeights, fontFamilyFaces: fontFamilyFaces, size: "__unstable-large" }) }), hasLineHeightEnabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: (0, _i18n.__)('Line height'), hasValue: hasLineHeight, onDeselect: resetLineHeight, isShownByDefault: defaultControls.lineHeight, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_lineHeightControl.default, { __unstableInputWidth: "auto", value: lineHeight, onChange: setLineHeight, size: "__unstable-large" }) }), hasLetterSpacingControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: (0, _i18n.__)('Letter spacing'), hasValue: hasLetterSpacing, onDeselect: resetLetterSpacing, isShownByDefault: defaultControls.letterSpacing, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_letterSpacingControl.default, { value: letterSpacing, onChange: setLetterSpacing, size: "__unstable-large", __unstableInputWidth: "auto" }) }), hasTextColumnsControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: (0, _i18n.__)('Columns'), hasValue: hasTextColumns, onDeselect: resetTextColumns, isShownByDefault: defaultControls.textColumns, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalNumberControl, { label: (0, _i18n.__)('Columns'), max: MAX_TEXT_COLUMNS, min: MIN_TEXT_COLUMNS, onChange: setTextColumns, size: "__unstable-large", spinControls: "custom", value: textColumns, initialPosition: 1 }) }), hasTextDecorationControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: (0, _i18n.__)('Decoration'), hasValue: hasTextDecoration, onDeselect: resetTextDecoration, isShownByDefault: defaultControls.textDecoration, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_textDecorationControl.default, { value: textDecoration, onChange: setTextDecoration, size: "__unstable-large", __unstableInputWidth: "auto" }) }), hasWritingModeControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { className: "single-column", label: (0, _i18n.__)('Orientation'), hasValue: hasWritingMode, onDeselect: resetWritingMode, isShownByDefault: defaultControls.writingMode, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_writingModeControl.default, { value: writingMode, onChange: setWritingMode, size: "__unstable-large", __nextHasNoMarginBottom: true }) }), hasTextTransformControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { label: (0, _i18n.__)('Letter case'), hasValue: hasTextTransform, onDeselect: resetTextTransform, isShownByDefault: defaultControls.textTransform, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_textTransformControl.default, { value: textTransform, onChange: setTextTransform, showNone: true, isBlock: true, size: "__unstable-large", __nextHasNoMarginBottom: true }) }), hasTextAlignmentControl && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { label: (0, _i18n.__)('Text alignment'), hasValue: hasTextAlign, onDeselect: resetTextAlign, isShownByDefault: defaultControls.textAlign, panelId: panelId, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_textAlignmentControl.default, { value: textAlign, onChange: setTextAlign, size: "__unstable-large", __nextHasNoMarginBottom: true }) })] }); } //# sourceMappingURL=typography-panel.js.map