import * as React from 'react' import {sprintf} from '@wordpress/i18n' import { useState, createContext, useContext, } from '@wordpress/element' import { Modal, __experimentalVStack as VStack, ComboboxControl, } from '@wordpress/components' import type { TextControlProps, } from '@wordpress/components/build-types/text-control/types' import { Button, ButtonGroup, ArrayEditor, ArrayEditorProps, } from '@ska/components' import GoogleFont, { type GoogleFontControlsProps, } from './GoogleFont' import VariableGoogleFont, { type VariableGoogleFontControlsProps, } from './VariableGoogleFont' import './style.scss' export { GoogleFont, GoogleFontControlsProps, VariableGoogleFont, VariableGoogleFontControlsProps, } export interface FontControlStrings { editButtonText: string modalTitle: string localFontsLabel: string noExternalFontMessage: string unknownFontSourceMessage: string externalFontSourceLabel: string selectFontLabel: string variantsLabel: string minWghtLabel: string maxWghtLabel: string } export const FONT_CONTROL_STRINGS = { editButtonText: 'Edit', modalTitle: 'Edit font', localFontsLabel: 'Local fonts', noExternalFontMessage: 'No external font', unknownFontSourceMessage: 'Unknown font source: %s', externalFontSourceLabel: 'External font source', selectFontLabel: 'Select a font', variantsLabel: 'Variants', minWghtLabel: 'Minimum font-weight', maxWghtLabel: 'Maximum font-weight', } export const FontControlStringsContext = createContext(FONT_CONTROL_STRINGS) export const FontSourcesContext = createContext([]) export interface FontControlsProps { font: any value: Record onChange: (nextValue: FontControlsProps['value']) => void } export interface FontSource { id: string label: string fonts: any[] renderControls?: React.FC } export interface FontValue { source?: FontSource['id'] font?: string } interface FontPickerProps { value: FontValue onChange: (nextValue: FontValue) => void } const FontPicker: React.FC = ({ id, fonts, renderControls: Controls, value, onChange, }) => { const { selectFontLabel, } = useContext(FontControlStringsContext) const { font = '', } = value const options = fonts.map(({name}) => ({ label: name, value: name, })) const currentFont = font && fonts.find(f => f.name === font) return <> { onChange({ source: value.source, font: nextFont || '', }) }} __next40pxDefaultSize __nextHasNoMarginBottom /> {currentFont && Controls && ( )} } interface ExternalFontPickerProps { value: FontValue onChange: (nextValue: FontValue) => void } const ExternalFontPicker: React.FC = ({ value, onChange, }) => { const { noExternalFontMessage, unknownFontSourceMessage, externalFontSourceLabel, } = useContext(FontControlStringsContext) const sources = useContext(FontSourcesContext) const { source = '', } = value const selectedFontSource = sources.find(({id}) => id === source) const options = [{ label: noExternalFontMessage, value: 'default', }].concat( sources.map(({id, label}) => ({ label, value: id, })) ).concat([ ...(source && !selectedFontSource ? [{ label: sprintf(unknownFontSourceMessage, source), value: source, }] : []), ]) return <> { if(nextSource) { onChange({source: nextSource === 'default' ? '' : nextSource}) } }} /> {selectedFontSource && ( )} } export interface FontControlProps extends Omit { value: string disabled?: boolean arrayEditorProps?: Partial } const FontControl: React.FC = ({ value = '', onChange, disabled = false, arrayEditorProps = {}, }) => { const { editButtonText, modalTitle, localFontsLabel, } = useContext(FontControlStringsContext) const [isOpen, setIsOpen] = useState(false) const [externalFontJson, systemFonts] = (value.indexOf('[&]') === -1 ? `{}[&]${value}` : value).split('[&]') const externalFont = JSON.parse(externalFontJson) const fonts = systemFonts.split(',').map(v => v.trim()) return <>