@wordpress/block-editor
Version:
437 lines (422 loc) • 18.1 kB
JavaScript
"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