import React from "react" import { useActiveObject, useEditor } from "@layerhub-io/react" // import getSelectionType from "~/utils/get-selection-type" import { Input } from "baseui/input" import { Block } from "baseui/block" import { ChevronDown } from "baseui/icon" import { Box, IconButton } from 'gestalt' import Common from "./Common" import TextColor from "~/components/Icons/TextColor" import Bold from "~/components/Icons/Bold" import Italic from "~/components/Icons/Italic" import Underline from "~/components/Icons/Underline" import TextAlignCenter from "~/components/Icons/TextAlignCenter" import useEyeDropper from 'use-eye-dropper' import { useWindowSize } from "~/hooks/useWindowSize" import { useMediaQuery } from 'react-responsive' import { Button, SIZE, KIND } from "baseui/button" import { StatefulTooltip, PLACEMENT } from "baseui/tooltip" import LetterCase from "~/components/Icons/LetterCase" import Spacing from "~/components/Icons/Spacing" import { StatefulPopover } from "baseui/popover" import TextAlignJustify from "~/components/Icons/TextAlignJustify" import TextAlignLeft from "~/components/Icons/TextAlignLeft" import TextAlignRight from "~/components/Icons/TextAlignRight" import { Slider } from "baseui/slider" import useAppContext from "~/hooks/useAppContext" import { FONT_SIZES, SAMPLE_FONTS } from "~/constants/editor" import getSelectionType from "~/utils/get-selection-type" import { IStaticText } from "@layerhub-io/types" import { getTextProperties } from "../../utils/text" import { loadFonts } from "~/utils/fonts" import Scrollbar from "@layerhub-io/react-custom-scrollbar" interface TextState { color: string bold: boolean italic: boolean underline: boolean family: string styleOptions: StyleOptions } interface StyleOptions { hasItalic: boolean hasBold: boolean options: any[] } const initialOptions: TextState = { family: "CoreLang", bold: false, italic: false, underline: false, color: "#00000", styleOptions: { hasBold: true, hasItalic: true, options: [], }, } export default function (props) { const { has_common = false, has_toolbox = false } = props const { width, height } = useWindowSize() const [state, setState] = React.useState(initialOptions) const activeObject = useActiveObject() as Required const { setActiveSubMenu, fonts } = useAppContext() const editor = useEditor() const isTabletOrMobile = useMediaQuery({ query: '(max-width: 1224px)' }) const { open, close, isSupported } = useEyeDropper() React.useEffect(() => { if (activeObject && activeObject.type === "StaticText") { const textProperties = getTextProperties(activeObject, fonts) setState({ ...state, ...textProperties }) if(!isTabletOrMobile) setActiveSubMenu("FontSelector") } }, [activeObject]) React.useEffect(() => { let watcher = async () => { if (activeObject && activeObject.type === "StaticText") { const textProperties = getTextProperties(activeObject, fonts) setState({ ...state, ...textProperties }) } } if (editor) { editor.on("history:changed", watcher) } return () => { if (editor) { editor.off("history:changed", watcher) } } }, [editor, activeObject]) const pickColor = () => { open() .then(color => { //changeBackgroundColor(color.sRGBHex) if (activeObject) { editor.objects.update({ fill: color.sRGBHex }) } }) .catch(e => { }) } const makeBold = React.useCallback(async () => { if (state.bold) { let desiredFont if (state.italic) { // look for regular italic desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Italic$/) }) } else { // look for regular desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Regular$/) }) } const font = { name: desiredFont.postscript_name, url: desiredFont.url, } await loadFonts([font]) editor.objects.update({ fontFamily: desiredFont.postscript_name, fontURL: font.url, }) setState({ ...state, bold: false }) } else { let desiredFont if (state.italic) { // look for bold italic desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^BoldItalic$/) }) } else { // look for bold desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Bold$/) }) } const font = { name: desiredFont.postscript_name, url: desiredFont.url, } await loadFonts([font]) editor.objects.update({ fontFamily: desiredFont.postscript_name, fontURL: font.url, }) setState({ ...state, bold: true }) } }, [editor, state]) const makeItalic = React.useCallback(async () => { if (state.italic) { let desiredFont if (state.bold) { // Search bold regular desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Bold$/) }) } else { // Search regular desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Regular$/) }) } const font = { name: desiredFont.postscript_name, url: desiredFont.url, } await loadFonts([font]) editor.objects.update({ fontFamily: desiredFont.postscript_name, fontURL: font.url, }) setState({ ...state, italic: false }) } else { let desiredFont if (state.bold) { // search italic bold desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^BoldItalic$/) }) } else { // search regular italic desiredFont = state.styleOptions.options.find((option) => { const postscript_names = option.postscript_name.split("-") return postscript_names[postscript_names.length - 1].match(/^Italic$/) }) } const font = { name: desiredFont.postscript_name, url: desiredFont.url, } await loadFonts([font]) editor.objects.update({ fontFamily: desiredFont.postscript_name, fontURL: font.url, }) setState({ ...state, italic: true }) } }, [editor, state]) const makeUnderline = React.useCallback(() => { editor.objects.update({ underline: !state.underline, }) setState({ ...state, underline: !state.underline }) }, [editor, state]) return ( { has_toolbox && ( setActiveSubMenu("FontSelector")} $style={{ border: "1px solid rgb(185,185,185)", borderRadius: "4px", padding: "0.2rem 0.45rem", cursor: "pointer", fontFamily: state.family, fontWeight: 500, fontSize: "10px", gap: "0.5rem", }} height={"24px"} display={"flex"} alignItems={"center"} > {state.family} { false && } {/* */} {/* */} ) } { has_common && } ) } function TextFontSize() { const editor = useEditor() const activeObject = useActiveObject() const [value, setValue] = React.useState(12) React.useEffect(() => { // @ts-ignore if (activeObject && activeObject.type === "StaticText") { // @ts-ignore setValue(activeObject.fontSize) } }, [activeObject]) const onChange = (size: number) => { editor.objects.update({ fontSize: size }) setValue(size) } return ( ( {FONT_SIZES.map((size, index) => ( { onChange(size) close() }} $style={{ height: "32px", fontSize: "14px", cursor: "pointer", padding: "0 20px", display: "flex", alignItems: "center", ":hover": { background: "rgb(243,243,243)", }, }} key={index} > {size} ))} )} > onChange(e.target.value)} endEnhancer={} overrides={{ Input: { style: { backgroundColor: "#ffffff", paddingRight: 0, fontWeight: 500, fontFamily: "Uber Move Text", fontSize: "14px", }, }, EndEnhancer: { style: { paddingRight: "8px", paddingLeft: 0, backgroundColor: "#ffffff", }, }, Root: { style: { paddingRight: 0, borderTopWidth: "1px", borderBottomWidth: "1px", borderRightWidth: "1px", borderLeftWidth: "1px", borderBottomColor: "rgb(185,185,185)", borderTopColor: "rgb(185,185,185)", borderRightColor: "rgb(185,185,185)", borderLeftColor: "rgb(185,185,185)", borderEndEndRadius: "4px", borderTopLeftRadius: "4px", borderTopRightRadius: "4px", borderStartEndRadius: "4px", borderBottomLeftRadius: "4px", backgroundColor: "#ffffff", }, }, }} type="number" size={SIZE.mini} /> ) } function TextLetterCase() { const [state, setState] = React.useState<{ upper: boolean }>({ upper: false }) const editor = useEditor() return ( ) } function TextSpacing() { const editor = useEditor() const activeObject = useActiveObject() const [state, setState] = React.useState<{ charSpacing: number lineHeight: number }>({ charSpacing: 0, lineHeight: 0 }) React.useEffect(() => { if (activeObject) { // @ts-ignore const { charSpacing, lineHeight } = activeObject setState({ ...state, charSpacing: charSpacing / 10, lineHeight: lineHeight * 10 }) } }, [activeObject]) const handleChange = (type: string, value: number[]) => { if (editor) { if (type === "charSpacing") { setState({ ...state, [type]: value[0] }) // @ts-ignore editor.objects.update({ [type]: value[0] * 10, }) } else { setState({ ...state, [type]: value[0] }) // @ts-ignore editor.objects.update({ [type]: value[0] / 10, }) } } } return ( ( Line height {}} value={Math.round(state.lineHeight)} /> null, ThumbValue: () => null, TickBar: () => null, Track: { style: { paddingRight: 0, paddingLeft: 0, }, }, Thumb: { style: { height: "12px", width: "12px", }, }, }} min={0} max={100} // step marks={false} value={[state.lineHeight]} onChange={({ value }) => handleChange("lineHeight", value)} /> Char spacing {}} value={Math.round(state.charSpacing)} /> null, ThumbValue: () => null, TickBar: () => null, Track: { style: { paddingRight: 0, paddingLeft: 0, }, }, Thumb: { style: { height: "12px", width: "12px", }, }, }} min={-20} max={100} marks={false} value={[state.charSpacing]} onChange={({ value }) => handleChange("charSpacing", value)} /> )} > ) } const TEXT_ALIGNS = ["left", "center", "right", "justify"] function TextAlign() { const editor = useEditor() const activeObject = useActiveObject() const [state, setState] = React.useState<{ align: string }>({ align: "left" }) React.useEffect(() => { if (activeObject) { // @ts-ignore setState({ align: activeObject.textAlign }) } }, [activeObject]) return ( ( )} returnFocus autoFocus > ) }