import * as React from "react"; import { BaseLayoutProps } from "./layout.pc"; import { memoize, getParentTreeNode } from "tandem-common"; import { cssPropertyChangeCompleted, cssPropertyChanged } from "../../../../../../../actions"; import { DropdownMenuOption, dropdownMenuOptionFromValue } from "../../../../../../inputs/dropdown/controller"; import { DependencyGraph, getPCNodeModule, isPCContentNode, computeStyleInfo, InspectorNode, isTextLikePCNode, InspectorTreeNodeName, PCVariant, ComputedStyleInfo } from "paperclip"; import { Dispatch } from "redux"; const BASE_DISPLAY_VALUES = ["block", "inline-block", "none", "inline"]; export const DISPLAY_MENU_OPTIONS: DropdownMenuOption[] = [ undefined, ...BASE_DISPLAY_VALUES, "flex", "inline-flex" ].map(dropdownMenuOptionFromValue); export const TEXT_DISPLAY_MENU_OPTIONS: DropdownMenuOption[] = [ undefined, ...BASE_DISPLAY_VALUES ].map(dropdownMenuOptionFromValue); export const POSITION_MENU_OPTIONS: DropdownMenuOption[] = [ undefined, "static", "relative", "absolute", "fixed" ].map(dropdownMenuOptionFromValue); export const WHITESPACE_MENU_OPTIONS: DropdownMenuOption[] = [ undefined, "normal", "nowrap", "pre", "pre-wrap", "pre-line", "inherit" ].map(dropdownMenuOptionFromValue); const FLEX_WRAP_OPTIONS: DropdownMenuOption[] = [ undefined, "nowrap", "wrap", "wrap-reverse" ].map(dropdownMenuOptionFromValue); const FLEX_DIRECTION_OPTIONS: DropdownMenuOption[] = [ undefined, "row", "row-reverse", "column", "column-reverse" ].map(dropdownMenuOptionFromValue); const JUSTIFY_CONTENT_OPTIONS: DropdownMenuOption[] = [ undefined, "flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly" ].map(dropdownMenuOptionFromValue); const ALIGN_ITEMS_OPTIONS: DropdownMenuOption[] = [ undefined, "flex-start", "flex-end", "center", "stretch", "baseline" ].map(dropdownMenuOptionFromValue); const ALIGN_CONTENT_OPTIONS: DropdownMenuOption[] = [ undefined, "flex-start", "flex-end", "center", "space-between", "space-around", "stretch" ].map(dropdownMenuOptionFromValue); const ALIGN_SELF_OPTIONS: DropdownMenuOption[] = [ undefined, "flex-start", "flex-end", "center", "baseline", "stretch" ].map(dropdownMenuOptionFromValue); export type Props = { dispatch: Dispatch; graph: DependencyGraph; selectedVariant: PCVariant; rootInspectorNode: InspectorNode; computedStyleInfo: ComputedStyleInfo; selectedInspectorNodes: InspectorNode[]; }; export type InnerProps = { onPropertyChangeComplete: any; onPropertyChange: any; } & Props; export default (Base: React.ComponentClass) => class LayoutController extends React.PureComponent { onClick = () => {}; onPropertyChange = (name, value) => { this.props.dispatch(cssPropertyChanged(name, value)); }; onPropertyChangeComplete = (name, value) => { this.props.dispatch(cssPropertyChangeCompleted(name, value)); }; render() { const { computedStyleInfo, rootInspectorNode, selectedVariant, selectedInspectorNodes, graph, ...rest } = this.props; const { sourceNode } = computedStyleInfo; const { onPropertyChange, onPropertyChangeComplete } = this; const node = computedStyleInfo.sourceNode; if (!node) { return null; } const inspectorNode = selectedInspectorNodes[0]; const module = getPCNodeModule(node.id, graph); const showMoveInputs = isPCContentNode(node, graph) || /fixed|relative|absolute/.test( computedStyleInfo.style.position || "static" ); const showSizeInputs = showMoveInputs || /block|inline-block|flex|inline-flex/.test( computedStyleInfo.style.display || "inline" ); const showParentFlexInputs = computedStyleInfo.style.display === "flex" || computedStyleInfo.style.display === "inline-flex"; let parentInspectorNode: InspectorNode; let currentInspectorNode: InspectorNode = inspectorNode; while (1) { parentInspectorNode = getParentTreeNode( currentInspectorNode.id, rootInspectorNode ); if (parentInspectorNode.name === InspectorTreeNodeName.SOURCE_REP) { break; } currentInspectorNode = parentInspectorNode; } const parentComputedInfo = parentInspectorNode && computeStyleInfo( parentInspectorNode, rootInspectorNode, selectedVariant, graph ); const showChildFlexInputs = parentInspectorNode && (parentComputedInfo.style.display === "flex" || parentComputedInfo.style.display === "inline-flex"); return ( ); } }; const propertyChangeCallback = memoize((name: string, listener) => value => listener(name, value) );