diff --git a/packages/core/src/_internals.ts b/packages/core/src/_internals.ts index 45bc630f..864a9d79 100644 --- a/packages/core/src/_internals.ts +++ b/packages/core/src/_internals.ts @@ -1,6 +1,5 @@ export { CompilationCache } from "./compiler/CompilationCache"; export type { CompilationCacheItemValue } from "./compiler/CompilationCache"; -export { compileBox, getBoxStyles } from "./compiler/box"; export { RichTextEditor } from "./compiler/builtins/$richText/$richText.editor"; export { TextEditor } from "./compiler/builtins/$text/$text.editor"; export { buildText } from "./compiler/builtins/$text/buildText"; @@ -16,7 +15,7 @@ export { export { normalize } from "./compiler/normalize"; export * from "./compiler/parsePath"; export type { PathInfo } from "./compiler/parsePath"; -export { scalarizeConfig } from "./compiler/resop"; +export { scalarizeConfig } from "./scalarizeConfig"; export * from "./compiler/schema"; export * from "./compiler/schema/buttonSchemaProps"; export { traverseComponents } from "./compiler/traverseComponents"; @@ -28,6 +27,7 @@ export type { InternalComponentDefinition, InternalRenderableComponentDefinition, } from "./compiler/types"; + export { EasyblocksMetadataProvider, useEasyblocksMetadata, diff --git a/packages/core/src/compiler/builtins/$richText/$richText.client.tsx b/packages/core/src/compiler/builtins/$richText/$richText.client.tsx index e98579fc..df5df63b 100644 --- a/packages/core/src/compiler/builtins/$richText/$richText.client.tsx +++ b/packages/core/src/compiler/builtins/$richText/$richText.client.tsx @@ -3,17 +3,18 @@ import React, { ReactElement, ReactNode } from "react"; interface RichTextProps { elements: Array; Root: ReactElement<{ children: ReactNode }>; + __textRootClasses: string; } function RichTextClient(props: RichTextProps) { const { elements: Elements, Root } = props; return ( - +
{Elements.map((Element, index) => { return ; })} - +
); } diff --git a/packages/core/src/compiler/builtins/$richText/$richText.editor.tsx b/packages/core/src/compiler/builtins/$richText/$richText.editor.tsx index 168eb913..0e5d247c 100644 --- a/packages/core/src/compiler/builtins/$richText/$richText.editor.tsx +++ b/packages/core/src/compiler/builtins/$richText/$richText.editor.tsx @@ -26,17 +26,13 @@ import type { RenderPlaceholderProps, } from "slate-react"; import { Editable, ReactEditor, Slate, withReact } from "slate-react"; -import { Box } from "../../../components/Box/Box"; import { ComponentBuilder, InternalNoCodeComponentProps, } from "../../../components/ComponentBuilder/ComponentBuilder"; import { RichTextChangedEvent } from "../../../events"; import { getFallbackForLocale } from "../../../locales"; -import { responsiveValueFill } from "../../../responsiveness"; -import { Devices, ResponsiveValue } from "../../../types"; -import { compileBox, getBoxStyles } from "../../box"; -import { getDevicesWidths } from "../../devices"; +import { ResponsiveValue } from "../../../types"; import { duplicateConfig } from "../../duplicateConfig"; import type { RichTextComponentConfig } from "./$richText"; import { @@ -59,6 +55,8 @@ import { getFocusedFieldsFromSlateSelection } from "./utils/getFocusedFieldsFrom import { getFocusedRichTextPartsConfigPaths } from "./utils/getFocusedRichTextPartsConfigPaths"; import { getRichTextComponentConfigFragment } from "./utils/getRichTextComponentConfigFragment"; import { NORMALIZED_IDS_TO_IDS, withEasyblocks } from "./withEasyblocks"; +import { liStyles, olStyles, paragraphStyles, ulStyles } from "./styles"; +import { useEasyblocksMetadata } from "../../../_internals"; interface RichTextProps extends InternalNoCodeComponentProps { elements: Array< @@ -81,11 +79,10 @@ function RichTextEditor(props: RichTextProps) { setFocussedField, } = editorContext; + const meta = useEasyblocksMetadata(); + const { - __easyblocks: { - path, - runtime: { resop, stitches, devices }, - }, + __easyblocks: { path }, align, } = props; @@ -364,43 +361,51 @@ function RichTextEditor(props: RichTextProps) { throw new Error("Missing element"); } - const compiledStyles = (() => { - if (Element._component === "@easyblocks/rich-text-block-element") { - if (Element.props.type === "bulleted-list") { - return Element.styled.BulletedList; - } else if (Element.props.type === "numbered-list") { - return Element.styled.NumberedList; - } else if (Element.props.type === "paragraph") { - return Element.styled.Paragraph; - } - } else if (Element._component === "@easyblocks/rich-text-line-element") { - if (element.type === "text-line") { - return Element.styled.TextLine; - } else if (element.type === "list-item") { - return Element.styled.ListItem; - } - } - })(); + if (Element._component === "@easyblocks/rich-text-block-element") { + if (Element.props.type === "bulleted-list") { + return ( + + ); + + // return Element.props.__styled.BulletedList; + } else if (Element.props.type === "numbered-list") { + return ( +
    + {children} +
+ ); + + // return Element.props.__styled.NumberedList; + } else if (Element.props.type === "paragraph") { + return React.createElement( + // @ts-ignore + Element.props.accessibilityRole, + attributes, + children + ); - if (compiledStyles === undefined) { - throw new Error("Unknown element type"); + // return Element.props.__styled.Paragraph; + } + } else if (Element._component === "@easyblocks/rich-text-line-element") { + if (element.type === "text-line") { + return ( +
+ {children} +
+ ); + } else if (element.type === "list-item") { + return ( +
  • + {children} +
  • + ); + // return Element.props.__styled.ListItem; + } } - return ( - - {element.type === "list-item" ?
    {children}
    : children} -
    - ); + throw new Error("Unknown element type"); } const TextParts = extractTextPartsFromCompiledComponents(props); @@ -425,17 +430,16 @@ function RichTextEditor(props: RichTextProps) { throw new Error("Missing part"); } + const __textPartClasses: string = meta.renderer.generateClassNames( + // @ts-ignore + TextPart.props.__textPart, + meta + ); + const TextPartComponent = ( - } + textAttributes={attributes} TextWrapper={ TextPart.components.TextWrapper[0] ? ( ) : undefined } + __textPartClasses={__textPartClasses} /> ); @@ -738,61 +743,30 @@ function RichTextEditor(props: RichTextProps) { } } - const contentEditableClassName = useMemo(() => { - const responsiveAlignmentStyles = mapResponsiveAlignmentToStyles(align, { - devices: editorContext.devices, - resop, - }); + const isFallbackValueShown = + localizedRichTextElements === undefined && + fallbackRichTextElements !== undefined; - const isFallbackValueShown = - localizedRichTextElements === undefined && - fallbackRichTextElements !== undefined; - - // When we make a selection of text within editable container and then blur - // sometimes the browser selection changes and shows incorrectly selected chunks. - const getStyles = stitches.css({ - display: "flex", - ...responsiveAlignmentStyles, - cursor: !isEnabled ? "inherit" : "text", - "& *": { - pointerEvents: isEnabled ? "auto" : "none", - userSelect: isEnabled ? "auto" : "none", - }, - "& *::selection": { - backgroundColor: "#b4d5fe", - }, - ...(isDecorationActive && { - "& *::selection": { - backgroundColor: "transparent", - }, - "& *[data-easyblocks-rich-text-selection]": { - backgroundColor: "#b4d5fe", - }, - }), - ...(isFallbackValueShown && { - opacity: 0.5, - }), - // Remove any text decoration from slate nodes that are elements. We only need text decoration on text elements. - "[data-slate-node]": { - textDecoration: "none", - }, - }); + const __textRootClasses: string = meta.renderer.generateClassNames( + // @ts-ignore + props.__textRoot, + meta + ); - return getStyles().className; - }, [ - align, - isDecorationActive, - localizedRichTextElements, - fallbackRichTextElements, - isEnabled, - ]); + const classes = `EasyblocksRichTextEditor_Root ${ + isEnabled ? "EasyblocksRichTextEditor_Root--enabled" : "" + } ${ + isFallbackValueShown ? "EasyblocksRichTextEditor_Root--fallbackValue" : "" + } ${ + isDecorationActive ? "EasyblocksRichTextEditor_Root--decorationActive" : "" + }`; return (
    {/* this wrapper div prevents from Chrome bug where "pointer-events: none" on contenteditable is ignored*/} , - { devices, resop }: { devices: Devices; resop: any } -) { - function mapAlignmentToFlexAlignment(align: Alignment) { - if (align === "center") { - return "center"; - } - - if (align === "right") { - return "flex-end"; - } - - return "flex-start"; - } - - const responsiveStyles = resop( - { - align: responsiveValueFill(align, devices, getDevicesWidths(devices)), - }, - (values: any) => { - return { - justifyContent: mapAlignmentToFlexAlignment(values.align), - textAlign: values.align, - }; - }, - devices - ); - - const compiledStyles = compileBox(responsiveStyles, devices); - - return getBoxStyles(compiledStyles, devices); -} - function createTextSelectionDecorator(editor: Editor) { return ([node, path]: NodeEntry) => { const decorations: Array = []; diff --git a/packages/core/src/compiler/builtins/$richText/$richText.styles.ts b/packages/core/src/compiler/builtins/$richText/$richText.styles.ts index c5351993..1722f5cb 100755 --- a/packages/core/src/compiler/builtins/$richText/$richText.styles.ts +++ b/packages/core/src/compiler/builtins/$richText/$richText.styles.ts @@ -2,7 +2,7 @@ import type { NoCodeComponentStylesFunctionInput, NoCodeComponentStylesFunctionResult, } from "../../../types"; -import { Alignment } from "./$richText.types"; +// import { Alignment } from "./$richText.types"; export function richTextStyles({ values, @@ -11,13 +11,15 @@ export function richTextStyles({ const align = params.passedAlign ?? values.align; return { - styled: { - Root: { - display: "flex", - justifyContent: mapAlignmentToFlexAlignment(align), - textAlign: align, - }, - }, + // styled: { + // Root: { + // // display: "flex", + // // justifyContent: mapAlignmentToFlexAlignment(align), + // // textAlign: align, + // // color: values.mainColor, + // // ...values.mainFont, + // }, + // }, components: { elements: { // We store values within $richText to allow for changing them from sidebar, but we use them inside of $richTextBlockElement. @@ -36,14 +38,14 @@ export function richTextStyles({ }; } -export function mapAlignmentToFlexAlignment(align: Alignment) { - if (align === "center") { - return "center"; - } +// export function mapAlignmentToFlexAlignment(align: Alignment) { +// if (align === "center") { +// return "center"; +// } - if (align === "right") { - return "flex-end"; - } +// if (align === "right") { +// return "flex-end"; +// } - return "flex-start"; -} +// return "flex-start"; +// } diff --git a/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.client.tsx b/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.client.tsx index 03ed0119..a52c0bd9 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.client.tsx +++ b/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.client.tsx @@ -1,6 +1,7 @@ import React, { ReactElement } from "react"; import type { CompiledNoCodeComponentProps } from "../../../types"; import type { RichTextBlockElementComponentConfig } from "./$richTextBlockElement"; +import { olStyles, ulStyles } from "../styles"; type RichTextBlockElementProps = CompiledNoCodeComponentProps< RichTextBlockElementComponentConfig["_component"], @@ -19,6 +20,7 @@ export function RichTextBlockElementClient(props: RichTextBlockElementProps) { elements: Elements, NumberedList, Paragraph, + accessibilityRole, } = props; const elements = Elements.map((Element, index) => ( @@ -26,24 +28,21 @@ export function RichTextBlockElementClient(props: RichTextBlockElementProps) { )); if (type === "paragraph") { - return {elements}; + return React.createElement(accessibilityRole, {}, elements); + // return {elements}; } if (type === "bulleted-list") { - return ( - {elements} - ); + return
      {elements}
    ; } if (type === "numbered-list") { - return ( - {elements} - ); + return
      {elements}
    ; } if (process.env.NODE_ENV === "development") { console.warn(`Unknown @easyblocks/rich-text-block-element type "${type}"`); } - return
    {elements}
    ; + return {elements}; } diff --git a/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.styles.ts b/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.styles.ts index dad844ce..90ac7c25 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.styles.ts +++ b/packages/core/src/compiler/builtins/$richText/$richTextBlockElement/$richTextBlockElement.styles.ts @@ -46,68 +46,85 @@ export function richTextBlockElementStyles({ RichTextBlockElementValues, RichTextBlockElementParams >): NoCodeComponentStylesFunctionResult { - const maxDigitsCount = elements.length.toString().length; + // const maxDigitsCount = elements.length.toString().length; - const paddingInline = `clamp(${px( - BULLETED_LIST_MIN_INLINE_SPACING - )}, calc(${px(mainFontSize)} * 0.5), ${px(mainFontSize)})`; + // const paddingInline = `clamp(${px( + // BULLETED_LIST_MIN_INLINE_SPACING + // )}, calc(${px(mainFontSize)} * 0.5), ${px(mainFontSize)})`; - const bulletedListMarkerStyles = { - paddingLeft: paddingInline, - paddingRight: paddingInline, - content: BULLET_CHARACTER, - }; + // const bulletedListMarkerStyles = { + // paddingLeft: paddingInline, + // paddingRight: paddingInline, + // content: BULLET_CHARACTER, + // }; - const numberedListMarkerStyles = { - minWidth: `calc(${maxDigitsCount} * 1ch + ${NUMBERED_LIST_DOT_CHARACTER_SAFE_WIDTH})`, - paddingRight: `clamp(${px( - NUMBERED_LIST_MIN_COUNTER_SPACING - )}, 0.5ch, ${NUMBERED_LIST_MAX_COUNTER_SPACING})`, - fontVariantNumeric: "tabular-nums", - textAlign: "right", - content: `counter(list-item)"."`, - }; + // const numberedListMarkerStyles = { + // minWidth: `calc(${maxDigitsCount} * 1ch + ${NUMBERED_LIST_DOT_CHARACTER_SAFE_WIDTH})`, + // paddingRight: `clamp(${px( + // NUMBERED_LIST_MIN_COUNTER_SPACING + // )}, 0.5ch, ${NUMBERED_LIST_MAX_COUNTER_SPACING})`, + // fontVariantNumeric: "tabular-nums", + // textAlign: "right", + // content: `counter(list-item)"."`, + // }; - const markerStyles = { - boxSizing: "content-box", - display: "flex", - alignItems: "center", - justifyContent: "flex-end", - flexGrow: 0, - flexShrink: 0, - fontSize: mainFontSize, - ...(type === "bulleted-list" - ? bulletedListMarkerStyles - : numberedListMarkerStyles), - }; + // const markerStyles = { + // boxSizing: "content-box", + // display: "flex", + // alignItems: "center", + // justifyContent: "flex-end", + // flexGrow: 0, + // flexShrink: 0, + // fontSize: mainFontSize, + // ...(type === "bulleted-list" + // ? bulletedListMarkerStyles + // : numberedListMarkerStyles), + // }; - const listStyles = { - counterSet: "list-item", - paddingLeft: 0, - listStyle: "none", - color: mainColor, - ...mainFont, - "& > li": { - color: mainColor, - ...mainFont, - // Instead of using ::marker pseudo-element, we use ::before because it gives us more control over its appearance. - "&::before": markerStyles, - }, - }; + // const listStyles = { + // counterSet: "list-item", + // paddingLeft: 0, + // listStyle: "none", + // color: mainColor, + // ...mainFont, + // "& > li": { + // color: mainColor, + // ...mainFont, + // // Instead of using ::marker pseudo-element, we use ::before because it gives us more control over its appearance. + // "&::before": markerStyles, + // }, + // }; return { - styled: { - Paragraph: { __as: accessibilityRole }, - BulletedList: { __as: "ul", ...listStyles }, - NumberedList: { __as: "ol", ...listStyles }, - }, + // styled: { + // Paragraph: { /*__as: accessibilityRole */ }, + // BulletedList: { + // // __as: "ul", + // // listStyle: "initial", + // // listStylePosition: "inside", + // // ...mainFont, + // // paddingInlineStart: "0.9em", + // }, // ...listStyles }, + // NumberedList: { + // // __as: "ol", + // // listStyle: "decimal", + // // listStylePosition: "inside", + // // ...mainFont, + // // paddingInlineStart: "4ch", + // }, // ...listStyles }, + // }, components: { elements: { itemProps: elements.map(() => ({ blockType: type, align, + mainColor, + mainFont, })), }, }, + props: { + accessibilityRole, + }, }; } diff --git a/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.client.tsx b/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.client.tsx index 0c13ccf9..ed98eb8e 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.client.tsx +++ b/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.client.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from "react"; import type { RichTextBlockElementType } from "../$richTextBlockElement/$richTextBlockElement"; - +import { liStyles, paragraphStyles } from "../styles"; type RichTextLineElementProps = { blockType: RichTextBlockElementType; elements: Array; @@ -15,15 +15,22 @@ export function RichTextLineElementClient(props: RichTextLineElementProps) { )); if (blockType === "paragraph") { - return {elements}; + return
    {elements}
    ; + // return {elements}; } if (blockType === "bulleted-list" || blockType === "numbered-list") { return ( - -
    {elements}
    -
    +
  • + {elements} +
  • ); + + // return ( + // + // {elements} + // + // ); } if (process.env.NODE_ENV === "development") { diff --git a/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.styles.ts b/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.styles.ts index 385b99ad..c9a5fee9 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.styles.ts +++ b/packages/core/src/compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.styles.ts @@ -1,4 +1,4 @@ -import { mapAlignmentToFlexAlignment } from "../$richText.styles"; +// import { mapAlignmentToFlexAlignment } from "../$richText.styles"; import { Alignment } from "../$richText.types"; import type { RichTextBlockElementType } from "../$richTextBlockElement/$richTextBlockElement"; import { @@ -22,27 +22,29 @@ export function richTextLineElementStyles({ RichTextLineParams >): NoCodeComponentStylesFunctionResult { return { - styled: { - TextLine: { - lineHeight: "initial", - wordBreak: "break-word", - }, - ListItem: { - __as: "li", - display: "flex", - justifyContent: mapAlignmentToFlexAlignment(values.align), - alignItems: "baseline", - paddingLeft: 0, - lineHeight: "initial", - wordBreak: "break-word", - listStyle: "none", - counterIncrement: "list-item", - // Allows flex items to break when text is overflowing - "& > *": { - minWidth: 0, - }, - }, - }, + // styled: { + // TextLine: { + // lineHeight: "initial", + // wordBreak: "break-word", + // }, + // ListItem: { + // __as: "li", + // // display: "flex", + // // justifyContent: mapAlignmentToFlexAlignment(values.align), + // // paddingLeft: 0, + // alignItems: "baseline", + // lineHeight: "inherit", + // wordBreak: "break-word", + // listStyle: "inherit", + // counterIncrement: "list-item", + + // // ...params.mainColor + // // Allows flex items to break when text is overflowing + // // "& > *": { + // // minWidth: 0, + // // }, + // }, + // }, props: { blockType: params.blockType, diff --git a/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.client.tsx b/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.client.tsx index 7d329786..1b95d698 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.client.tsx +++ b/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.client.tsx @@ -5,20 +5,33 @@ type RichTextPartProps = { TextWrapper: React.ReactElement<{ trigger: React.ReactElement }> | undefined; // ReactElement when editing, string when not value: string | ReactElement; - Text: React.ReactElement<{ children: ReactNode; style: Record }>; + // Text: React.ReactElement<{ children: ReactNode; style: Record }>; + __textPartClasses: string; + textAttributes: Record; }; export function RichTextPartClient(props: RichTextPartProps) { - const { value, Text, TextWrapper } = props; + const { + value, + // Text, + TextWrapper, + textAttributes = {}, + __textPartClasses, + } = props; const textValue = value || "\uFEFF"; if (TextWrapper) { return ( - + {textValue} - + ); } - return {textValue}; + return ( + + {textValue} + + ); + // return {textValue}; } diff --git a/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.styles.ts b/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.styles.ts index ad982cd7..73cc040d 100644 --- a/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.styles.ts +++ b/packages/core/src/compiler/builtins/$richText/$richTextPart/$richTextPart.styles.ts @@ -4,10 +4,11 @@ import type { NoCodeComponentStylesFunctionResult, } from "../../../../types"; -const DEFAULT_FONT_VALUES = { - fontWeight: "initial", - fontStyle: "initial", -}; +// const DEFAULT_FONT_VALUES = { +// fontWeight: "initial", +// fontStyle: "initial", +// lineHeight: "initial", +// }; export interface RichTextPartValues { color: string; @@ -20,17 +21,17 @@ export function richTextPartStyles({ values: { color, font, TextWrapper }, isEditing, }: NoCodeComponentStylesFunctionInput): NoCodeComponentStylesFunctionResult { - const fontWithDefaults = { - ...DEFAULT_FONT_VALUES, - ...font, - }; + // const fontWithDefaults = { + // ...DEFAULT_FONT_VALUES, + // ...font, + // }; const hasTextWrapper = TextWrapper.length > 0; const textStyles: Record = { __as: "span", - color, - ...fontWithDefaults, + // color, + // ...fontWithDefaults, }; if (hasTextWrapper && !isEditing) { @@ -49,8 +50,8 @@ export function richTextPartStyles({ } return { - styled: { - Text: textStyles, - }, + // styled: { + // // Text: textStyles, + // }, }; } diff --git a/packages/core/src/compiler/builtins/$richText/styles.ts b/packages/core/src/compiler/builtins/$richText/styles.ts new file mode 100644 index 00000000..053330fd --- /dev/null +++ b/packages/core/src/compiler/builtins/$richText/styles.ts @@ -0,0 +1,19 @@ +export const ulStyles: React.CSSProperties = { + listStyle: "initial", + listStylePosition: "inside", +}; +export const olStyles: React.CSSProperties = { + listStyle: "initial", + listStylePosition: "inside", +}; +export const liStyles: React.CSSProperties = { + alignItems: "baseline", + lineHeight: "inherit", + wordBreak: "break-word", + listStyle: "inherit", + counterIncrement: "list-item", +}; +export const paragraphStyles: React.CSSProperties = { + lineHeight: "initial", + wordBreak: "break-word", +}; diff --git a/packages/core/src/compiler/builtins/$text/$text.editor.tsx b/packages/core/src/compiler/builtins/$text/$text.editor.tsx index 7a588a8c..9528d483 100644 --- a/packages/core/src/compiler/builtins/$text/$text.editor.tsx +++ b/packages/core/src/compiler/builtins/$text/$text.editor.tsx @@ -13,7 +13,7 @@ function TextEditor(props: TextProps) { const { Text, value, - __easyblocks: { path, runtime }, + __easyblocks: { path }, } = props; const { form } = (window.parent as any).editorWindowAPI.editorContext; @@ -24,11 +24,7 @@ function TextEditor(props: TextProps) { return ( {isLocalTextReference ? ( - + ) : ( value ??   )} diff --git a/packages/core/src/compiler/builtins/$text/InlineTextarea.tsx b/packages/core/src/compiler/builtins/$text/InlineTextarea.tsx index 965dde1d..de8af7f3 100644 --- a/packages/core/src/compiler/builtins/$text/InlineTextarea.tsx +++ b/packages/core/src/compiler/builtins/$text/InlineTextarea.tsx @@ -7,14 +7,9 @@ import { useTextValue } from "../useTextValue"; interface InlineTextProps { path: string; placeholder?: string; - stitches: any; } -export function InlineTextarea({ - path, - placeholder, - stitches, -}: InlineTextProps) { +export function InlineTextarea({ path, placeholder }: InlineTextProps) { const [isEnabled, setIsEnabled] = useState(false); const textAreaRef = useRef>(null); @@ -36,35 +31,6 @@ export function InlineTextarea({ placeholder ); - const css = stitches.css({ - width: "100%", - wordWrap: "break-word", - display: "block", - fontSize: "inherit", - fontFamily: "inherit", - fontWeight: "inherit", - boxSizing: "border-box", - color: "inherit", - letterSpacing: "inherit", - lineHeight: "inherit", - margin: "0 auto", - maxWidth: "inherit", - textTransform: "inherit", - backgroundColor: "inherit", - textAlign: "inherit", - outline: "none", - resize: "none", - border: "none", - overflow: "visible", - position: "relative", - padding: 0, - "-ms-overflow-style": "none", - "&::-webkit-scrollbar": { - display: "none", - }, - pointerEvents: isEnabled ? "auto" : "none", - })(); - return (
    { @@ -80,7 +46,9 @@ export function InlineTextarea({ }} > { - if (!renderableComponentDefinition.styles) { - return {}; - } + const buildParams = { + values: compiledValues, + params: { ...ownPropsAfterAuto.params, $width, $widthAuto }, + isEditing: !!compilationContext.isEditing, + devices: compilationContext.devices, + definition: renderableComponentDefinition, + }; - const device = assertDefined( - compilationContext.devices.find( - (device) => device.id === breakpointIndex - ), - `Missing device "${breakpointIndex}"` - ); + const { props, components } = compilationContext.builder.build(buildParams); - const stylesInput: NoCodeComponentStylesFunctionInput = { - values, - params: { - ...params, - $width: assertDefined(responsiveValueAt($width, breakpointIndex)), - $widthAuto: assertDefined( - responsiveValueAt($widthAuto, breakpointIndex) - ), - }, - isEditing: !!compilationContext.isEditing, - device, - ...(componentDefinition!.id === "@easyblocks/rich-text-part" - ? { __COMPILATION_CONTEXT__: compilationContext } - : {}), - }; + if (componentDefinition.id === "@easyblocks/rich-text") { + props.__textRoot = compilationContext.builder.buildTextRoot({ + values: { + font: compiledValues.mainFont, + color: compiledValues.mainColor, + align: ownPropsAfterAuto.params.passedAlign ?? ownProps.values.align, + }, + isEditing: !!compilationContext.isEditing, + devices: compilationContext.devices, + definition: renderableComponentDefinition, + }); + } - return renderableComponentDefinition.styles(stylesInput); - }, - compilationContext.devices, - renderableComponentDefinition - ); + if (componentDefinition.id === "@easyblocks/rich-text-part") { + props.__textPart = compilationContext.builder.buildTextPart({ + values: { font: compiledValues.font, color: compiledValues.color }, + isEditing: !!compilationContext.isEditing, + devices: compilationContext.devices, + definition: renderableComponentDefinition, + }); + } + + // font and color + // if ( + // componentDefinition.id === "@easyblocks/rich-text" || + // componentDefinition.id === "@easyblocks/rich-text-part" + // ) { + // const isPart = componentDefinition.id === "@easyblocks/rich-text-part"; + + // const fontAndColorPseudoDefinition = { + // id: "__fontAndColor__", + // schema: [ + // { + // prop: "font", + // type: "font", + // }, + // { + // prop: "color", + // type: "color", + // }, + // ], + // }; + + // props.__fontAndColorArtifacts = buildFontAndColor({ + // values: isPart + // ? { font: compiledValues.font, color: compiledValues.color } + // : { font: compiledValues.mainFont, color: compiledValues.mainColor }, + // params: {}, + // isEditing: !!compilationContext.isEditing, + // devices: compilationContext.devices, + // definition: fontAndColorPseudoDefinition, + // }); + + // // console.log(`result for ${componentDefinition.id}`, fontAndColor); + // } validateStylesProps(props, componentDefinition); subcomponentsContextProps = components; - // Move all the boxes to _compiled - for (const key in styled) { - let styles: ScalarOrCollection> = styled[key]; - - if (Array.isArray(styles)) { - styles = styles.map((v) => { - return { ...v, __isBox: true }; - }); - } else { - styles = { ...styles, __isBox: true }; - } - - const schemaProp = componentDefinition.schema.find((x) => x.prop === key); - - // Context props processed below - if (schemaProp) { - continue; - } - - // If box - - compiled.styled[key] = compileBoxes(styles, compilationContext); - } - componentDefinition.schema.forEach((schemaProp: SchemaProp) => { if ("buildOnly" in schemaProp && schemaProp.buildOnly) { return; @@ -1362,36 +1369,6 @@ function mapResponsiveFontToResponsiveFontSize( ); } -function addStylesHash(styles: Record) { - if ("__hash" in styles) { - delete styles["__hash"]; - } - - const hash = CryptoJS.SHA1(JSON.stringify(styles)); - styles.__hash = hash.toString(); - return styles; -} - -function compileBoxes( - value: any, - compilationContext: CompilationContextType -): any { - if (Array.isArray(value)) { - return value.map((x: any) => compileBoxes(x, compilationContext)); - } else if (typeof value === "object" && value !== null) { - if (value.__isBox) { - return addStylesHash(compileBox(value, compilationContext.devices)); - } - - const ret: Record = {}; - for (const key in value) { - ret[key] = compileBoxes(value[key], compilationContext); - } - return ret; - } - return value; -} - function getDefaultFieldDefinition( schemaProp: SchemaProp, configPrefix: string, diff --git a/packages/core/src/compiler/createCompilationContext.ts b/packages/core/src/compiler/createCompilationContext.ts index a86b6dee..abbaf82a 100644 --- a/packages/core/src/compiler/createCompilationContext.ts +++ b/packages/core/src/compiler/createCompilationContext.ts @@ -1,5 +1,6 @@ import { responsiveValueMap } from "../responsiveness"; import { parseSpacing } from "../spacingToPx"; +import { stitchesBuilder } from "../stitches/stitches_build"; import { Config, ConfigDeviceRange, @@ -275,6 +276,7 @@ export function createCompilationContext( contextParams, locales: config.locales, rootComponent, + builder: config.builder ?? stitchesBuilder, }; return compilationContext; diff --git a/packages/core/src/compiler/types.ts b/packages/core/src/compiler/types.ts index eb570050..b99de300 100644 --- a/packages/core/src/compiler/types.ts +++ b/packages/core/src/compiler/types.ts @@ -1,6 +1,7 @@ import { PartialDeep, SetRequired } from "type-fest"; import { Locale } from "../locales"; import { + Builder, ComponentConfigBase, ComponentDefinitionShared, ContextParams, @@ -58,6 +59,7 @@ export type CompilationContextType = { strict?: boolean; locales: Array; rootComponent: NoCodeComponentDefinition; + builder: Builder; }; export type EditableComponentToComponentConfig< diff --git a/packages/core/src/components/Box/Box.tsx b/packages/core/src/components/Box/Box.tsx deleted file mode 100644 index 7d2a7565..00000000 --- a/packages/core/src/components/Box/Box.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useMemo } from "react"; -import { getBoxStyles } from "../../compiler/box"; -import { Devices } from "../../types"; - -const boxStyles = { - boxSizing: "border-box", - minWidth: "0px", - margin: 0, - padding: 0, - border: 0, - listStyle: "none", -}; - -type BoxProps = { - __compiled: any; - __name?: string; - devices: Devices; - stitches: any; - [key: string]: any; -}; - -const Box = React.forwardRef((props, ref) => { - /** - * passedProps - the props given in component code like (data-id is in passedProps) - * restProps - the props given by Shopstory (like from actionWrapper) - * - * They are merged into "realProps". - * - * I know those names sucks, this needs to be cleaned up. - */ - - const { __compiled, __name, passedProps, devices, stitches, ...restProps } = - props; - - const { __as, ...styles } = __compiled; - const realProps = { ...restProps, ...passedProps }; - - const { as, itemWrappers, className, ...restPassedProps } = realProps; - - const { boxClassName, componentClassName } = useMemo(() => { - /** - * Why parse+stringify? - * - * Because if we remove them some nested objects in styles (like media queries etc) don't work (although they exist in the object). - * Why? My bet is this: Stitches uses CSSOM to inject styles. Maybe (for some weird reason, maybe even browser bug) if some part of the object is not in iframe scope but in parent window scope then it's somehow ignored? Absolutely no idea right now, happy this works. - */ - const correctedStyles = getBoxStyles( - JSON.parse(JSON.stringify(styles)), - devices - ); - - const generateBoxClass = stitches.css(boxStyles); - const generateClassName = stitches.css(correctedStyles); - - return { - boxClassName: generateBoxClass(), - componentClassName: generateClassName(), - }; - }, [styles.__hash]); - - return React.createElement( - as || __as || "div", - { - ref, - ...restPassedProps, - className: [boxClassName, componentClassName, className] - .filter(Boolean) - .join(" "), - "data-testid": __name, - }, - props.children - ); -}); - -export { Box }; diff --git a/packages/core/src/components/ComponentBuilder/ComponentBuilder.tsx b/packages/core/src/components/ComponentBuilder/ComponentBuilder.tsx index e81f8232..17a29957 100644 --- a/packages/core/src/components/ComponentBuilder/ComponentBuilder.tsx +++ b/packages/core/src/components/ComponentBuilder/ComponentBuilder.tsx @@ -24,7 +24,6 @@ import { responsiveValueReduce, responsiveValueValues, } from "../../responsiveness"; -import { resop } from "../../responsiveness/resop"; import { CompilationMetadata, CompiledComponentConfig, @@ -42,41 +41,10 @@ import { NoCodeComponentProps, ResponsiveValue, } from "../../types"; -import { Box } from "../Box/Box"; +// import { Box } from "../Box/Box"; import { useEasyblocksExternalData } from "../EasyblocksExternalDataProvider"; import { useEasyblocksMetadata } from "../EasyblocksMetadataProvider"; - -function buildBoxes( - compiled: any, - name: string, - actionWrappers: { [key: string]: any }, - meta: any -): any { - if (Array.isArray(compiled)) { - return compiled.map((x: any, index: number) => - buildBoxes(x, `${name}.${index}`, actionWrappers, meta) - ); - } else if (typeof compiled === "object" && compiled !== null) { - if (compiled.__isBox) { - const boxProps = { - __compiled: compiled, - __name: name, - devices: meta.vars.devices, - stitches: meta.stitches, - }; - - return ; - } - - const ret: Record = {}; - - for (const key in compiled) { - ret[key] = buildBoxes(compiled[key], key, actionWrappers, meta); - } - return ret; - } - return compiled; -} +// import { buildBoxes } from "../Box/Box"; function getComponentDefinition( compiled: CompiledComponentConfig, @@ -400,13 +368,52 @@ function ComponentBuilder(props: ComponentBuilderProps): ReactElement | null { const shopstoryCompiledConfig = compiled as CompiledShopstoryComponentConfig; + const transformedProps = meta.renderer.transformProps + ? meta.renderer.transformProps(shopstoryCompiledConfig.props, meta) + : shopstoryCompiledConfig.props; + + const isRichText = componentDefinition.id === "@easyblocks/rich-text"; + const isRichTextPart = + componentDefinition.id === "@easyblocks/rich-text-part"; + + if (isRichText) { + transformedProps.__textRootClasses = meta.renderer.generateClassNames( + shopstoryCompiledConfig.props.__textRoot, + meta + ); + } + + if (isRichTextPart) { + transformedProps.__textPartClasses = meta.renderer.generateClassNames( + shopstoryCompiledConfig.props.__textPart, + meta + ); + } + + // if (isRichText || isRichTextPart) { + // const classNames = meta.generateClassNames( + // shopstoryCompiledConfig.props.__fontAndColorArtifacts, + // meta + // ); + + // transformedProps.__fontAndColorClassNames = classNames; + // } + + // console.log('--'); + // console.log('original props', shopstoryCompiledConfig.props); + // console.log('transformed props', transformedProps); + // Shopstory component - const styled: { [key: string]: any } = buildBoxes( - shopstoryCompiledConfig.styled, - "", - {}, - meta - ); + // const styled: { [key: string]: any } = buildBoxes( + // shopstoryCompiledConfig.props.__styled, + // "", + // {}, + // meta + // ); + + // console.log('styled', styled); + + const childrenComponents: { [key: string]: any } = {}; // Styled componentDefinition.schema.forEach((schemaProp) => { @@ -417,7 +424,7 @@ function ComponentBuilder(props: ComponentBuilderProps): ReactElement | null { const compiledChildren = shopstoryCompiledConfig.components[schemaProp.prop]; - styled[schemaProp.prop] = getCompiledSubcomponents( + childrenComponents[schemaProp.prop] = getCompiledSubcomponents( compiled._id, compiledChildren, contextProps, @@ -434,8 +441,6 @@ function ComponentBuilder(props: ComponentBuilderProps): ReactElement | null { const { ref, __isSelected, ...restPassedProps } = allPassedProps || {}; const runtime = { - stitches: meta.stitches, - resop: resop, devices: meta.vars.devices, }; @@ -448,6 +453,7 @@ function ComponentBuilder(props: ComponentBuilderProps): ReactElement | null { }; const componentProps = { + ...transformedProps, ...restPassedProps, ...mapExternalProps( shopstoryCompiledConfig.props, @@ -455,7 +461,7 @@ function ComponentBuilder(props: ComponentBuilderProps): ReactElement | null { componentDefinition, externalData ), - ...styled, + ...childrenComponents, __easyblocks: easyblocksProp, }; diff --git a/packages/core/src/components/Easyblocks.tsx b/packages/core/src/components/Easyblocks.tsx index 9a31d6f8..e1582c8f 100644 --- a/packages/core/src/components/Easyblocks.tsx +++ b/packages/core/src/components/Easyblocks.tsx @@ -5,7 +5,7 @@ import { RichTextBlockElementClient } from "../compiler/builtins/$richText/$rich import { RichTextLineElementClient } from "../compiler/builtins/$richText/$richTextLineElement/$richTextLineElement.client"; import { RichTextPartClient } from "../compiler/builtins/$richText/$richTextPart/$richTextPart.client"; import { TextClient } from "../compiler/builtins/$text/$text.client"; -import { ExternalData, RenderableDocument } from "../types"; +import { ExternalData, RenderableDocument, Renderer } from "../types"; import { ComponentBuilder, ComponentBuilderProps, @@ -19,6 +19,7 @@ export type EasyblocksProps = { externalData?: ExternalData; components?: Record>; componentOverrides?: ComponentOverrides; + renderer?: Renderer; }; export type ComponentOverrides = Record; @@ -33,6 +34,30 @@ const builtinComponents: ComponentBuilderProps["components"] = { "EditableComponentBuilder.client": ComponentBuilder, }; +// cursor: !isEnabled ? "inherit" : "text", +// "& *": { +// pointerEvents: isEnabled ? "auto" : "none", +// userSelect: isEnabled ? "auto" : "none", +// }, +// "& *::selection": { +// backgroundColor: "#b4d5fe", +// }, +// ...(isDecorationActive && { +// "& *::selection": { +// backgroundColor: "transparent", +// }, +// "& *[data-easyblocks-rich-text-selection]": { +// backgroundColor: "#b4d5fe", +// }, +// }), +// ...(isFallbackValueShown && { +// opacity: 0.5, +// }), +// // Remove any text decoration from slate nodes that are elements. We only need text decoration on text elements. +// "[data-slate-node]": { +// textDecoration: "none", +// }, + function Easyblocks({ renderableDocument, externalData, diff --git a/packages/core/src/components/EasyblocksMetadataProvider.tsx b/packages/core/src/components/EasyblocksMetadataProvider.tsx index 50b35188..f159c0f3 100644 --- a/packages/core/src/components/EasyblocksMetadataProvider.tsx +++ b/packages/core/src/components/EasyblocksMetadataProvider.tsx @@ -1,33 +1,32 @@ "use client"; -import { createStitches } from "@stitches/core"; import React, { createContext, ReactNode, useContext } from "react"; -import { easyblocksStitchesInstances } from "./ssr"; -import { CompilationMetadata } from "../types"; +import { CompilationMetadata, Renderer } from "../types"; +import { stitchesRenderer } from "../stitches/stitches_runtime"; const EasyblocksMetadataContext = createContext< - (CompilationMetadata & { stitches: any }) | undefined + | (CompilationMetadata & { + renderer: Renderer; + }) + | undefined >(undefined); type EasyblocksMetadataProviderProps = { children: ReactNode; meta: CompilationMetadata; + renderer?: Renderer; }; const EasyblocksMetadataProvider: React.FC = ({ meta, children, + renderer, }) => { - // Let's load stitches instance - if (easyblocksStitchesInstances.length === 0) { - easyblocksStitchesInstances.push(createStitches({})); - } - return ( {children} diff --git a/packages/core/src/components/ssr.tsx b/packages/core/src/components/ssr.tsx deleted file mode 100644 index c9a916f6..00000000 --- a/packages/core/src/components/ssr.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; - -export const easyblocksStitchesInstances: any[] = []; - -export function easyblocksGetCssText() { - return easyblocksStitchesInstances - .map((stitches) => stitches.getCssText()) - .join(" "); -} - -export function easyblocksGetStyleTag() { - return ( -