@wordpress/components
Version:
UI components for WordPress.
193 lines (189 loc) • 7.62 kB
JavaScript
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { settings } from '@wordpress/icons';
import { useState, forwardRef } from '@wordpress/element';
import { useInstanceId } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { Button } from '../button';
import RangeControl from '../range-control';
import { Flex, FlexItem } from '../flex';
import { default as UnitControl, parseQuantityAndUnitFromRawValue, useCustomUnits } from '../unit-control';
import { Container, Header, HeaderLabel, HeaderToggle } from './styles';
import { Spacer } from '../spacer';
import FontSizePickerSelect from './font-size-picker-select';
import FontSizePickerToggleGroup from './font-size-picker-toggle-group';
import { maybeWarnDeprecated36pxSize } from '../utils/deprecated-36px-size';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const DEFAULT_UNITS = ['px', 'em', 'rem', 'vw', 'vh'];
const MAX_TOGGLE_GROUP_SIZES = 5;
const UnforwardedFontSizePicker = (props, ref) => {
const {
__next40pxDefaultSize = false,
fallbackFontSize,
fontSizes = [],
disableCustomFontSizes = false,
onChange,
size = 'default',
units: unitsProp = DEFAULT_UNITS,
value,
withSlider = false,
withReset = true
} = props;
const labelId = useInstanceId(UnforwardedFontSizePicker, 'font-size-picker-label');
const units = useCustomUnits({
availableUnits: unitsProp
});
const selectedFontSize = fontSizes.find(fontSize => fontSize.size === value);
const isCustomValue = !!value && !selectedFontSize;
// Initially request a custom picker if the value is not from the predef list.
const [userRequestedCustom, setUserRequestedCustom] = useState(isCustomValue);
let currentPickerType;
if (!disableCustomFontSizes && userRequestedCustom) {
// While showing the custom value picker, switch back to predef only if
// `disableCustomFontSizes` is set to `true`.
currentPickerType = 'custom';
} else {
currentPickerType = fontSizes.length > MAX_TOGGLE_GROUP_SIZES ? 'select' : 'togglegroup';
}
if (fontSizes.length === 0 && disableCustomFontSizes) {
return null;
}
// If neither the value or first font size is a string, then FontSizePicker
// operates in a legacy "unitless" mode where UnitControl can only be used
// to select px values and onChange() is always called with number values.
const hasUnits = typeof value === 'string' || typeof fontSizes[0]?.size === 'string';
const [valueQuantity, valueUnit] = parseQuantityAndUnitFromRawValue(value, units);
const isValueUnitRelative = !!valueUnit && ['em', 'rem', 'vw', 'vh'].includes(valueUnit);
const isDisabled = value === undefined;
maybeWarnDeprecated36pxSize({
componentName: 'FontSizePicker',
__next40pxDefaultSize,
size
});
return /*#__PURE__*/_jsxs(Container, {
ref: ref,
className: "components-font-size-picker"
// This Container component renders a fieldset element that needs to be labeled.
,
"aria-labelledby": labelId,
children: [/*#__PURE__*/_jsx(Spacer, {
children: /*#__PURE__*/_jsxs(Header, {
className: "components-font-size-picker__header",
children: [/*#__PURE__*/_jsx(HeaderLabel, {
id: labelId,
children: __('Font size')
}), !disableCustomFontSizes && /*#__PURE__*/_jsx(HeaderToggle, {
label: currentPickerType === 'custom' ? __('Use size preset') : __('Set custom size'),
icon: settings,
onClick: () => setUserRequestedCustom(!userRequestedCustom),
isPressed: currentPickerType === 'custom',
size: "small"
})]
})
}), /*#__PURE__*/_jsxs("div", {
children: [currentPickerType === 'select' && /*#__PURE__*/_jsx(FontSizePickerSelect, {
__next40pxDefaultSize: __next40pxDefaultSize,
fontSizes: fontSizes,
value: value,
disableCustomFontSizes: disableCustomFontSizes,
size: size,
onChange: newValue => {
if (newValue === undefined) {
onChange?.(undefined);
} else {
onChange?.(hasUnits ? newValue : Number(newValue), fontSizes.find(fontSize => fontSize.size === newValue));
}
},
onSelectCustom: () => setUserRequestedCustom(true)
}), currentPickerType === 'togglegroup' && /*#__PURE__*/_jsx(FontSizePickerToggleGroup, {
fontSizes: fontSizes,
value: value,
__next40pxDefaultSize: __next40pxDefaultSize,
size: size,
onChange: newValue => {
if (newValue === undefined) {
onChange?.(undefined);
} else {
onChange?.(hasUnits ? newValue : Number(newValue), fontSizes.find(fontSize => fontSize.size === newValue));
}
}
}), currentPickerType === 'custom' && /*#__PURE__*/_jsxs(Flex, {
className: "components-font-size-picker__custom-size-control",
children: [/*#__PURE__*/_jsx(FlexItem, {
isBlock: true,
children: /*#__PURE__*/_jsx(UnitControl, {
__next40pxDefaultSize: __next40pxDefaultSize,
__shouldNotWarnDeprecated36pxSize: true,
label: __('Font size'),
labelPosition: "top",
hideLabelFromVision: true,
value: value,
onChange: newValue => {
setUserRequestedCustom(true);
if (newValue === undefined) {
onChange?.(undefined);
} else {
onChange?.(hasUnits ? newValue : parseInt(newValue, 10));
}
},
size: size,
units: hasUnits ? units : [],
min: 0
})
}), withSlider && /*#__PURE__*/_jsx(FlexItem, {
isBlock: true,
children: /*#__PURE__*/_jsx(Spacer, {
marginX: 2,
marginBottom: 0,
children: /*#__PURE__*/_jsx(RangeControl, {
__nextHasNoMarginBottom: true,
__next40pxDefaultSize: __next40pxDefaultSize,
__shouldNotWarnDeprecated36pxSize: true,
className: "components-font-size-picker__custom-input",
label: __('Font size'),
hideLabelFromVision: true,
value: valueQuantity,
initialPosition: fallbackFontSize,
withInputField: false,
onChange: newValue => {
setUserRequestedCustom(true);
if (newValue === undefined) {
onChange?.(undefined);
} else if (hasUnits) {
onChange?.(newValue + (valueUnit !== null && valueUnit !== void 0 ? valueUnit : 'px'));
} else {
onChange?.(newValue);
}
},
min: 0,
max: isValueUnitRelative ? 10 : 100,
step: isValueUnitRelative ? 0.1 : 1
})
})
}), withReset && /*#__PURE__*/_jsx(FlexItem, {
children: /*#__PURE__*/_jsx(Button, {
disabled: isDisabled,
accessibleWhenDisabled: true,
onClick: () => {
onChange?.(undefined);
},
variant: "secondary",
__next40pxDefaultSize: true,
size: size === '__unstable-large' || props.__next40pxDefaultSize ? 'default' : 'small',
children: __('Reset')
})
})]
})]
})]
});
};
export const FontSizePicker = forwardRef(UnforwardedFontSizePicker);
export default FontSizePicker;
//# sourceMappingURL=index.js.map