import * as React from "react"; import * as cx from "classnames"; import { memoize } from "tandem-common"; import { ButtonBarOption } from "../../../../../../inputs/button-bar/controller"; import { DropdownMenuOption, dropdownMenuOptionFromValue, NO_OPTION } from "../../../../../../inputs/dropdown/controller"; import { cssPropertyChangeCompleted, cssPropertyChanged } from "../../../../../../../actions"; import { FontFamily, ProjectOptions } from "../../../../../../../state"; import { BaseTypographProps } from "./typography.pc"; import { Dispatch } from "redux"; import { PCVariable, filterVariablesByType, PCVariableType, ComputedStyleInfo, isTextLikePCNode, isElementLikePCNode, getNativeComponentName, DependencyGraph } from "paperclip"; import { mapVariablesToCSSVarDropdownOptions, getPrettyPaneColorSwatchOptionGroups } from "./utils"; const { TextLeftIcon, TextCenterIcon, TextJustifyIcon, TextRightIcon } = require("../../../../../../../icons/view.pc"); export const getFontFamilyOptions = memoize((fontFamiles: FontFamily[]) => fontFamiles .map(family => ({ label: family.name, value: family.name })) .sort((a, b) => (a.label > b.label ? 1 : -1)) ); const FONT_WEIGHTS: DropdownMenuOption[] = [ undefined, "100", "200", "300", "400", "500", "600", "700", "800" ].map(dropdownMenuOptionFromValue); const DECORATIONS: DropdownMenuOption[] = [ undefined, "underline", "overline", "line-through", "none" ].map(dropdownMenuOptionFromValue); const ALIGNMENTS: ButtonBarOption[] = [ { value: "left", icon: }, { value: "center", icon: }, { value: "justify", icon: }, { value: "right", icon: } ]; export type Props = { dispatch: Dispatch; computedStyleInfo: ComputedStyleInfo; fontFamilies: FontFamily[]; documentColors: string[]; graph: DependencyGraph; globalVariables: PCVariable[]; projectOptions: ProjectOptions; }; export default (Base: React.ComponentClass) => class TypographyController extends React.PureComponent { onPropertyChange = (name, value) => { this.props.dispatch(cssPropertyChanged(name, value)); }; onPropertyChangeComplete = (name, value) => { this.props.dispatch(cssPropertyChangeCompleted(name, value)); }; render() { const { onPropertyChange, onPropertyChangeComplete } = this; const { graph, fontFamilies, globalVariables, documentColors, dispatch, computedStyleInfo, projectOptions } = this.props; const { sourceNode } = computedStyleInfo; // Typography pane is only available to text nodes to prevent cascading styles, and void tags (like input) that // cannot have children if ( projectOptions.allowCascadeFonts === false && (!isTextLikePCNode(sourceNode) || (isElementLikePCNode(sourceNode) && getNativeComponentName(sourceNode, graph) !== "input")) ) { return null; } const fontVariables = filterVariablesByType( globalVariables, PCVariableType.FONT ); return ( ); } }; const propertyChangeCallback = memoize((name: string, listener) => value => listener(name, value) );