From e4504678e04700e61d80be50cc12643b141c5a47 Mon Sep 17 00:00:00 2001 From: cohitre Date: Tue, 27 Feb 2024 13:25:33 -0800 Subject: [PATCH] Using block packages in the sample-editor (#29) --- .github/workflows/ci.yaml | 17 +- packages/document-core/package-lock.json | 4 +- packages/document-core/package.json | 2 +- ...ckComponent.ts => buildBlockComponent.tsx} | 3 +- packages/document-core/src/utils.ts | 3 +- packages/editor-sample/package-lock.json | 155 +++++++++++++++--- packages/editor-sample/package.json | 11 +- .../input-panels/AvatarSidebarPanel.tsx | 29 ++-- .../input-panels/ButtonSidebarPanel.tsx | 25 ++- .../input-panels/DividerSidebarPanel.tsx | 9 +- .../input-panels/HeadingSidebarPanel.tsx | 6 +- .../input-panels/HtmlSidebarPanel.tsx | 4 +- .../input-panels/ImageSidebarPanel.tsx | 9 +- .../input-panels/SpacerSidebarPanel.tsx | 4 +- .../input-panels/TextSidebarPanel.tsx | 4 +- .../src/documents/blocks/Avatar.tsx | 64 -------- .../src/documents/blocks/Button.tsx | 90 ---------- .../src/documents/blocks/Html.tsx | 32 ---- .../src/documents/blocks/Image.tsx | 50 ------ .../src/documents/blocks/Text.tsx | 38 ----- .../AddBlockMenu/buttons.tsx | 30 ++-- .../blocks/helpers/block-wrappers/index.tsx | 8 +- .../src/documents/editor/core.tsx | 40 +++-- .../src/documents/reader/core.tsx | 20 +-- .../sample/one-time-passcode.ts | 2 - .../sample/order-ecommerce.ts | 4 - .../sample/post-metrics-report.ts | 5 +- .../sample/reservation-reminder.ts | 7 +- .../getConfiguration/sample/reset-password.ts | 2 - .../sample/respond-to-message.ts | 2 - .../sample/subscription-receipt.ts | 4 - 31 files changed, 262 insertions(+), 421 deletions(-) rename packages/document-core/src/builders/{buildBlockComponent.ts => buildBlockComponent.tsx} (85%) delete mode 100644 packages/editor-sample/src/documents/blocks/Avatar.tsx delete mode 100644 packages/editor-sample/src/documents/blocks/Button.tsx delete mode 100644 packages/editor-sample/src/documents/blocks/Html.tsx delete mode 100644 packages/editor-sample/src/documents/blocks/Image.tsx delete mode 100644 packages/editor-sample/src/documents/blocks/Text.tsx diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8239bf7..74d3c2b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,10 +18,19 @@ jobs: with: node-version: 20 cache: 'npm' - - run: npm ci - - run: (cd ./packages/document-core;npm ci) - - run: (cd ./packages/editor-sample;npm ci) + cache-dependency-path: '**/package-lock.json' + - run: | + npm ci + (cd ./packages/block-avatar;pwd;npm ci) + (cd ./packages/block-button;pwd;npm ci) + (cd ./packages/block-divider;pwd;npm ci) + (cd ./packages/block-heading;pwd;npm ci) + (cd ./packages/block-html;pwd;npm ci) + (cd ./packages/block-image;pwd;npm ci) + (cd ./packages/block-spacer;pwd;npm ci) + (cd ./packages/block-text;pwd;npm ci) + (cd ./packages/document-core;pwd;npm ci) + (cd ./packages/editor-sample;pwd;npm ci) - run: npx eslint . - run: npx prettier . --check - - run: npx tsc --noEmit - run: npm test diff --git a/packages/document-core/package-lock.json b/packages/document-core/package-lock.json index 2084bc5..a90cee9 100644 --- a/packages/document-core/package-lock.json +++ b/packages/document-core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@usewaypoint/document-core", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@usewaypoint/document-core", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "peerDependencies": { "react": "^16 || ^17 || ^18", diff --git a/packages/document-core/package.json b/packages/document-core/package.json index 20b3316..2689af6 100644 --- a/packages/document-core/package.json +++ b/packages/document-core/package.json @@ -1,6 +1,6 @@ { "name": "@usewaypoint/document-core", - "version": "0.0.1", + "version": "0.0.2", "description": "Tools to render waypoint-style documents (core package)", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/document-core/src/builders/buildBlockComponent.ts b/packages/document-core/src/builders/buildBlockComponent.tsx similarity index 85% rename from packages/document-core/src/builders/buildBlockComponent.ts rename to packages/document-core/src/builders/buildBlockComponent.tsx index 40879eb..c49b360 100644 --- a/packages/document-core/src/builders/buildBlockComponent.ts +++ b/packages/document-core/src/builders/buildBlockComponent.tsx @@ -8,6 +8,7 @@ import { BaseZodDictionary, BlockConfiguration, DocumentBlocksDictionary } from */ export default function buildBlockComponent(blocks: DocumentBlocksDictionary) { return function BlockComponent({ type, data }: BlockConfiguration) { - return React.createElement(blocks[type].Component, data); + const Component = blocks[type].Component; + return ; }; } diff --git a/packages/document-core/src/utils.ts b/packages/document-core/src/utils.ts index 2233974..78e2a24 100644 --- a/packages/document-core/src/utils.ts +++ b/packages/document-core/src/utils.ts @@ -1,11 +1,10 @@ -import React from 'react'; import { z } from 'zod'; export type BaseZodDictionary = { [name: string]: z.AnyZodObject }; export type DocumentBlocksDictionary = { [K in keyof T]: { schema: T[K]; - Component: (props: z.infer) => React.ReactNode; + Component: (props: z.infer) => JSX.Element; }; }; diff --git a/packages/editor-sample/package-lock.json b/packages/editor-sample/package-lock.json index ee2169b..9b1da7b 100644 --- a/packages/editor-sample/package-lock.json +++ b/packages/editor-sample/package-lock.json @@ -12,9 +12,14 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", - "@usewaypoint/block-divider": "^0.0.1", - "@usewaypoint/block-heading": "^0.0.1", - "@usewaypoint/block-spacer": "^0.0.1", + "@usewaypoint/block-avatar": "^0.0.1", + "@usewaypoint/block-button": "^0.0.1", + "@usewaypoint/block-divider": "^0.0.3", + "@usewaypoint/block-heading": "^0.0.2", + "@usewaypoint/block-html": "^0.0.1", + "@usewaypoint/block-image": "^0.0.2", + "@usewaypoint/block-spacer": "^0.0.2", + "@usewaypoint/block-text": "^0.0.1", "@usewaypoint/document-core": "^0.0.1", "react": "^18.2.0", "react-colorful": "^5.6.1", @@ -36,6 +41,102 @@ "vite": "^5.1.0" } }, + "../block-avatar": { + "name": "@usewaypoint/block-avatar", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-button": { + "name": "@usewaypoint/block-button", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-divider": { + "name": "@usewaypoint/block-divider", + "version": "0.0.3", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-heading": { + "name": "@usewaypoint/block-heading", + "version": "0.0.2", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-html": { + "name": "@usewaypoint/block-html", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-image": { + "name": "@usewaypoint/block-image", + "version": "0.0.2", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-spacer": { + "name": "@usewaypoint/block-spacer", + "version": "0.0.2", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, + "../block-text": { + "name": "@usewaypoint/block-text", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@testing-library/react": "^14.2.1" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "zod": "^1 || ^2 || ^3" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -1841,33 +1942,37 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@usewaypoint/block-avatar": { + "resolved": "../block-avatar", + "link": true + }, + "node_modules/@usewaypoint/block-button": { + "resolved": "../block-button", + "link": true + }, "node_modules/@usewaypoint/block-divider": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@usewaypoint/block-divider/-/block-divider-0.0.1.tgz", - "integrity": "sha512-LB+bqtsrak6VKcETi5YphD7GBAPbDTCia3xiniisNT5ZUg2r8ts9Bcdig08o4l6/F+n5Q6zcX1dEHXZA5OAKpA==", - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "zod": "^1 || ^2 || ^3" - } + "resolved": "../block-divider", + "link": true }, "node_modules/@usewaypoint/block-heading": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@usewaypoint/block-heading/-/block-heading-0.0.1.tgz", - "integrity": "sha512-ceQTl/wUEYaXDBbI6aXdyAck+S/tiM/5RlBxvvAr/Z8+6hlaLPpTwPqztphF9d5sMl3SzCpTaPTye31Dj99JzQ==", - "peerDependencies": { - "@usewaypoint/document-core": "^0.0.1", - "react": "^16 || ^17 || ^18", - "zod": "^1 || ^2 || ^3" - } + "resolved": "../block-heading", + "link": true + }, + "node_modules/@usewaypoint/block-html": { + "resolved": "../block-html", + "link": true + }, + "node_modules/@usewaypoint/block-image": { + "resolved": "../block-image", + "link": true }, "node_modules/@usewaypoint/block-spacer": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@usewaypoint/block-spacer/-/block-spacer-0.0.1.tgz", - "integrity": "sha512-O+C0pw2NElaKac5SDMR3Cb4874Gs3ewrwjjLad37bjWnxFSqYSxBEciF7W9BwM4mNlcw1aldu7fd3eQ9XaaQfw==", - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "zod": "^1 || ^2 || ^3" - } + "resolved": "../block-spacer", + "link": true + }, + "node_modules/@usewaypoint/block-text": { + "resolved": "../block-text", + "link": true }, "node_modules/@usewaypoint/document-core": { "version": "0.0.1", diff --git a/packages/editor-sample/package.json b/packages/editor-sample/package.json index 234e58b..88f287b 100644 --- a/packages/editor-sample/package.json +++ b/packages/editor-sample/package.json @@ -12,9 +12,14 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", - "@usewaypoint/block-divider": "^0.0.1", - "@usewaypoint/block-heading": "^0.0.1", - "@usewaypoint/block-spacer": "^0.0.1", + "@usewaypoint/block-avatar": "^0.0.1", + "@usewaypoint/block-button": "^0.0.1", + "@usewaypoint/block-divider": "^0.0.3", + "@usewaypoint/block-heading": "^0.0.2", + "@usewaypoint/block-html": "^0.0.1", + "@usewaypoint/block-image": "^0.0.2", + "@usewaypoint/block-spacer": "^0.0.2", + "@usewaypoint/block-text": "^0.0.1", "@usewaypoint/document-core": "^0.0.1", "react": "^18.2.0", "react-colorful": "^5.6.1", diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/AvatarSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/AvatarSidebarPanel.tsx index 691ee40..0d97b7d 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/AvatarSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/AvatarSidebarPanel.tsx @@ -2,11 +2,9 @@ import React, { useState } from 'react'; import { AspectRatioOutlined } from '@mui/icons-material'; import { ToggleButton } from '@mui/material'; - -import { AvatarProps, AvatarPropsSchema } from '../../../../documents/blocks/Avatar'; +import { AvatarProps, AvatarPropsDefaults, AvatarPropsSchema } from '@usewaypoint/block-avatar'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; -import { NullableColorInput } from './helpers/inputs/ColorInput'; import RadioGroupInput from './helpers/inputs/RadioGroupInput'; import SliderInput from './helpers/inputs/SliderInput'; import TextInput from './helpers/inputs/TextInput'; @@ -28,6 +26,11 @@ export default function AvatarSidebarPanel({ data, setData }: AvatarSidebarPanel } }; + const size = data.props?.size ?? AvatarPropsDefaults.size; + const imageUrl = data.props?.imageUrl ?? AvatarPropsDefaults.imageUrl; + const alt = data.props?.alt ?? AvatarPropsDefaults.alt; + const shape = data.props?.shape ?? AvatarPropsDefaults.shape; + return ( { updateData({ ...data, props: { ...data.props, size } }); }} /> { updateData({ ...data, props: { ...data.props, shape } }); }} @@ -56,7 +59,7 @@ export default function AvatarSidebarPanel({ data, setData }: AvatarSidebarPanel { updateData({ ...data, props: { ...data.props, imageUrl } }); }} @@ -64,17 +67,9 @@ export default function AvatarSidebarPanel({ data, setData }: AvatarSidebarPanel { - updateData({ ...data, props: { ...data.props, fallbackText } }); - }} - /> - { - updateData({ ...data, props: { ...data.props, fallbackColor } }); + defaultValue={alt} + onChange={(alt) => { + updateData({ ...data, props: { ...data.props, alt } }); }} /> diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/ButtonSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/ButtonSidebarPanel.tsx index c0b2a48..0022f4e 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/ButtonSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/ButtonSidebarPanel.tsx @@ -1,8 +1,7 @@ import React, { useState } from 'react'; import { ToggleButton } from '@mui/material'; - -import { ButtonProps, ButtonPropsSchema } from '../../../../documents/blocks/Button'; +import { ButtonProps, ButtonPropsDefaults, ButtonPropsSchema } from '@usewaypoint/block-button'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; import ColorInput from './helpers/inputs/ColorInput'; @@ -27,21 +26,29 @@ export default function ButtonSidebarPanel({ data, setData }: ButtonSidebarPanel } }; + const text = data.props?.text ?? ButtonPropsDefaults.text; + const url = data.props?.url ?? ButtonPropsDefaults.url; + const fullWidth = data.props?.fullWidth ?? ButtonPropsDefaults.fullWidth; + const size = data.props?.size ?? ButtonPropsDefaults.size; + const buttonStyle = data.props?.buttonStyle ?? ButtonPropsDefaults.buttonStyle; + const buttonTextColor = data.props?.buttonTextColor ?? ButtonPropsDefaults.buttonTextColor; + const buttonBackgroundColor = data.props?.buttonBackgroundColor ?? ButtonPropsDefaults.buttonBackgroundColor; + return ( updateData({ ...data, props: { ...data.props, text } })} /> updateData({ ...data, props: { ...data.props, url } })} /> updateData({ ...data, props: { ...data.props, fullWidth: v === 'FULL_WIDTH' } })} > Full @@ -49,7 +56,7 @@ export default function ButtonSidebarPanel({ data, setData }: ButtonSidebarPanel updateData({ ...data, props: { ...data.props, size } })} > Xs @@ -59,7 +66,7 @@ export default function ButtonSidebarPanel({ data, setData }: ButtonSidebarPanel updateData({ ...data, props: { ...data.props, buttonStyle } })} > Rectangle @@ -68,13 +75,13 @@ export default function ButtonSidebarPanel({ data, setData }: ButtonSidebarPanel updateData({ ...data, props: { ...data.props, buttonTextColor } })} secondarySwatch={[]} /> updateData({ ...data, props: { ...data.props, buttonBackgroundColor } })} secondarySwatch={[]} /> diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/DividerSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/DividerSidebarPanel.tsx index dab2a6f..5831f53 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/DividerSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/DividerSidebarPanel.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { HeightOutlined } from '@mui/icons-material'; -import { DividerProps, DividerPropsSchema } from '@usewaypoint/block-divider'; +import { DividerProps, DividerPropsDefaults, DividerPropsSchema } from '@usewaypoint/block-divider'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; import ColorInput from './helpers/inputs/ColorInput'; @@ -24,11 +24,14 @@ export default function DividerSidebarPanel({ data, setData }: DividerSidebarPan } }; + const lineColor = data.props?.lineColor ?? DividerPropsDefaults.lineColor; + const lineHeight = data.props?.lineHeight ?? DividerPropsDefaults.lineHeight; + return ( updateData({ ...data, props: { ...data.props, lineColor } })} secondarySwatch={[]} /> @@ -39,7 +42,7 @@ export default function DividerSidebarPanel({ data, setData }: DividerSidebarPan step={1} min={1} max={24} - defaultValue={data.props?.lineHeight ?? 1} + defaultValue={lineHeight} onChange={(lineHeight) => updateData({ ...data, props: { ...data.props, lineHeight } })} /> { updateData({ ...data, props: { ...data.props, text } }); }} /> { updateData({ ...data, props: { ...data.props, level } }); }} diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/HtmlSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/HtmlSidebarPanel.tsx index 6a28c56..a2591be 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/HtmlSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/HtmlSidebarPanel.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -import { HtmlProps, HtmlPropsSchema } from '../../../../documents/blocks/Html'; +import { HtmlProps, HtmlPropsSchema } from '@usewaypoint/block-html'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; import TextInput from './helpers/inputs/TextInput'; @@ -28,7 +28,7 @@ export default function HtmlSidebarPanel({ data, setData }: HtmlSidebarPanelProp updateData({ ...data, props: { ...data.props, contents } })} /> updateData({ ...data, props: { ...data.props, contentAlignment } })} > @@ -50,12 +49,12 @@ export default function ImageSidebarPanel({ data, setData }: ImageSidebarPanelPr updateData({ ...data, props: { ...data.props, alt } })} /> { const linkHref = v.trim().length === 0 ? null : v.trim(); updateData({ ...data, props: { ...data.props, linkHref } }); diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/SpacerSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/SpacerSidebarPanel.tsx index b7fc53b..143ae32 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/SpacerSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/SpacerSidebarPanel.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { HeightOutlined } from '@mui/icons-material'; -import { SpacerProps, SpacerPropsSchema } from '@usewaypoint/block-spacer'; +import { SpacerProps, SpacerPropsDefaults, SpacerPropsSchema } from '@usewaypoint/block-spacer'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; import SliderInput from './helpers/inputs/SliderInput'; @@ -32,7 +32,7 @@ export default function SpacerSidebarPanel({ data, setData }: SpacerSidebarPanel step={4} min={4} max={128} - defaultValue={data.props.height ?? 16} + defaultValue={data.props?.height ?? SpacerPropsDefaults.height} onChange={(height) => updateData({ ...data, props: { ...data.props, height } })} /> diff --git a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/TextSidebarPanel.tsx b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/TextSidebarPanel.tsx index ee91fc2..126b60d 100644 --- a/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/TextSidebarPanel.tsx +++ b/packages/editor-sample/src/App/InspectorDrawer/ConfigurationPanel/input-panels/TextSidebarPanel.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -import { TextProps, TextPropsSchema } from '../../../../documents/blocks/Text'; +import { TextProps, TextPropsSchema } from '@usewaypoint/block-text'; import BaseSidebarPanel from './helpers/BaseSidebarPanel'; import TextInput from './helpers/inputs/TextInput'; @@ -28,7 +28,7 @@ export default function TextSidebarPanel({ data, setData }: TextSidebarPanelProp updateData({ ...data, props: { ...data.props, text } })} /> diff --git a/packages/editor-sample/src/documents/blocks/Avatar.tsx b/packages/editor-sample/src/documents/blocks/Avatar.tsx deleted file mode 100644 index a509708..0000000 --- a/packages/editor-sample/src/documents/blocks/Avatar.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { z } from 'zod'; - -import { zColor, zPadding, zTextAlign } from './helpers/zod'; - -export const AvatarPropsSchema = z.object({ - style: z - .object({ - textAlign: zTextAlign().optional().nullable().default(null), - padding: zPadding().optional().default({ - top: 16, - bottom: 16, - left: 16, - right: 16, - }), - }) - .default({}), - props: z.object({ - size: z.number().gt(0).default(64), - shape: z.enum(['circle', 'square', 'rounded']), - imageUrl: z.string().default(''), - fallbackText: z.string().optional().default(''), - fallbackColor: zColor().optional().nullable().default(null), - }), -}); - -export type AvatarProps = z.infer; - -function getBorderRadius({ shape, size }: AvatarProps['props']): number | undefined { - switch (shape) { - case 'rounded': - return size; - case 'circle': - return size; - case 'square': - default: - return undefined; - } -} - -export function Avatar({ props }: AvatarProps) { - const { size, imageUrl, fallbackText } = props; - return ( - {fallbackText} - ); -} diff --git a/packages/editor-sample/src/documents/blocks/Button.tsx b/packages/editor-sample/src/documents/blocks/Button.tsx deleted file mode 100644 index 2c00cbc..0000000 --- a/packages/editor-sample/src/documents/blocks/Button.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React, { CSSProperties } from 'react'; -import { z } from 'zod'; - -import { zColor, zFontFamily, zFontWeight, zPadding, zTextAlign } from './helpers/zod'; - -export const ButtonPropsSchema = z.object({ - style: z - .object({ - backgroundColor: zColor().nullable().default(null), - fontSize: z.number().min(0).default(16), - fontFamily: zFontFamily().nullable().default(null), - fontWeight: zFontWeight().nullable().default('bold'), - textAlign: zTextAlign().optional().nullable().default('center'), - padding: zPadding().optional().default({ - top: 16, - bottom: 16, - left: 24, - right: 24, - }), - }) - .default({}), - props: z.object({ - buttonBackgroundColor: zColor().default('#999999'), - buttonStyle: z.enum(['rectangle', 'pill', 'rounded']).default('rounded'), - buttonTextColor: zColor().default('#FFFFFF'), - fullWidth: z.boolean().default(false), - size: z.enum(['x-small', 'small', 'large', 'medium']).default('medium'), - text: z.string(), - url: z.string(), - }), -}); - -export type ButtonProps = z.infer; - -function getRoundedCorners(props: ButtonProps['props']) { - switch (props.buttonStyle) { - case 'rectangle': - return undefined; - case 'pill': - return 64; - case 'rounded': - default: - return 4; - } -} - -function getButtonSizePadding(props: ButtonProps['props']) { - switch (props.size) { - case 'x-small': - return [4, 8] as const; - case 'small': - return [8, 12] as const; - case 'large': - return [16, 32] as const; - case 'medium': - default: - return [12, 20] as const; - } -} - -export function Button({ props }: ButtonProps) { - const href = props.url; - const padding = getButtonSizePadding(props); - const textColor = props.buttonTextColor; - const textRaise = (padding[1] * 2 * 3) / 4; - const style: CSSProperties = { - color: textColor, - backgroundColor: props.buttonBackgroundColor, - borderRadius: getRoundedCorners(props), - display: 'inline-block', - padding: `${padding[0]}px ${padding[1]}px`, - textDecoration: 'none', - }; - - return ( - - `, - }} - /> - {props.text} - `, - }} - /> - - ); -} diff --git a/packages/editor-sample/src/documents/blocks/Html.tsx b/packages/editor-sample/src/documents/blocks/Html.tsx deleted file mode 100644 index 6f418e6..0000000 --- a/packages/editor-sample/src/documents/blocks/Html.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import { z } from 'zod'; - -import { zColor, zFontFamily, zPadding, zTextAlign } from './helpers/zod'; - -export const HtmlPropsSchema = z.object({ - style: z - .object({ - color: zColor().nullable().default(null), - backgroundColor: zColor().nullable().default(null), - fontFamily: zFontFamily().nullable().default(null), - fontSize: z.number().min(0).default(16), - textAlign: zTextAlign().optional().nullable().default(null), - padding: zPadding().optional().default({ - top: 16, - bottom: 16, - left: 24, - right: 24, - }), - }) - .default({}), - props: z.object({ - contents: z.string(), - }), -}); - -export type HtmlProps = z.infer; - -export function Html({ props: { contents } }: HtmlProps) { - const children = contents; - return
; -} diff --git a/packages/editor-sample/src/documents/blocks/Image.tsx b/packages/editor-sample/src/documents/blocks/Image.tsx deleted file mode 100644 index ae57bc3..0000000 --- a/packages/editor-sample/src/documents/blocks/Image.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import { z } from 'zod'; - -import { zColor, zPadding, zTextAlign } from './helpers/zod'; - -export const ImagePropsSchema = z.object({ - style: z - .object({ - padding: zPadding().default({ - top: 24, - bottom: 24, - left: 24, - right: 24, - }), - backgroundColor: zColor().nullable().default(null), - textAlign: zTextAlign().optional().nullable().default(null), - }) - .default({}), - props: z.object({ - height: z.number().nullable().default(null), - width: z.number().nullable(), - url: z.string(), - alt: z.string(), - linkHref: z.union([z.string(), z.null()]).default(null), - contentAlignment: z.enum(['top', 'middle', 'bottom']), - }), -}); - -export type ImageProps = z.infer; - -export function Image({ props: { height, width, url, alt, contentAlignment } }: ImageProps) { - return ( - {alt} - ); -} diff --git a/packages/editor-sample/src/documents/blocks/Text.tsx b/packages/editor-sample/src/documents/blocks/Text.tsx deleted file mode 100644 index e670172..0000000 --- a/packages/editor-sample/src/documents/blocks/Text.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import { z } from 'zod'; - -import { zColor, zFontFamily, zFontWeight, zPadding, zTextAlign } from './helpers/zod'; - -export const TextPropsSchema = z.object({ - style: z - .object({ - color: zColor().nullable().default(null), - backgroundColor: zColor().nullable().default(null), - fontSize: z.number().min(0).default(16), - fontFamily: zFontFamily().nullable().default(null), - fontWeight: zFontWeight().nullable().default('normal'), - textAlign: zTextAlign().optional().nullable().default(null), - padding: zPadding().optional().default({ - top: 16, - bottom: 16, - left: 24, - right: 24, - }), - }) - .default({}), - props: z - .object({ - text: z.string().default(''), - }) - .default({}), -}); - -export type TextProps = z.infer; - -/* TODO - * - process liquid - * - process markdown - */ -export function Text({ props: { text } }: TextProps) { - return
{text}
; -} diff --git a/packages/editor-sample/src/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/buttons.tsx b/packages/editor-sample/src/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/buttons.tsx index d5f376a..fbe85ff 100644 --- a/packages/editor-sample/src/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/buttons.tsx +++ b/packages/editor-sample/src/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/buttons.tsx @@ -12,16 +12,10 @@ import { SmartButtonOutlined, ViewColumnOutlined, } from '@mui/icons-material'; -import { HeadingPropsSchema } from '@usewaypoint/block-heading'; import { TEditorBlock } from '../../../../editor/core'; -import { AvatarPropsSchema } from '../../../Avatar'; -import { ButtonPropsSchema } from '../../../Button'; import ColumnsContainerPropsSchema from '../../../ColumnsContainer/ColumnsContainerPropsSchema'; import { ContainerPropsSchema } from '../../../Container/ContainerPropsSchema'; -import { HtmlPropsSchema } from '../../../Html'; -import { ImagePropsSchema } from '../../../Image'; -import { TextPropsSchema } from '../../../Text'; type TButtonProps = { label: string; @@ -34,12 +28,12 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Heading', - data: HeadingPropsSchema.parse({ + data: { props: { text: 'Hello friend' }, style: { padding: { top: 16, bottom: 16, left: 24, right: 24 }, }, - }), + }, }), }, { @@ -47,9 +41,9 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Text', - data: TextPropsSchema.parse({ + data: { props: { text: 'My new text block' }, - }), + }, }), }, @@ -58,12 +52,12 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Button', - data: ButtonPropsSchema.parse({ + data: { props: { text: 'Button', url: 'https://www.usewaypoint.com', }, - }), + }, }), }, { @@ -71,14 +65,14 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Image', - data: ImagePropsSchema.parse({ + data: { props: { url: 'https://logowik.com/content/uploads/images/street-fighter6886.jpg', alt: 'Street fighter', contentAlignment: 'middle', linkHref: null, }, - }), + }, }), }, { @@ -86,12 +80,12 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Avatar', - data: AvatarPropsSchema.parse({ + data: { props: { imageUrl: 'https://ui-avatars.com/api/?size=128', shape: 'circle', }, - }), + }, }), }, { @@ -122,7 +116,9 @@ export const BUTTONS: TButtonProps[] = [ icon: , block: () => ({ type: 'Html', - data: HtmlPropsSchema.parse({ props: { contents: 'Hello world' } }), + data: { + props: { contents: 'Hello world' }, + }, }), }, { diff --git a/packages/editor-sample/src/documents/blocks/helpers/block-wrappers/index.tsx b/packages/editor-sample/src/documents/blocks/helpers/block-wrappers/index.tsx index 4124542..e41c581 100644 --- a/packages/editor-sample/src/documents/blocks/helpers/block-wrappers/index.tsx +++ b/packages/editor-sample/src/documents/blocks/helpers/block-wrappers/index.tsx @@ -1,16 +1,14 @@ import React from 'react'; -import { TStyle } from '../TStyle'; - import EditorBlockWrapper from './EditorBlockWrapper'; import ReaderBlockWrapper from './ReaderBlockWrapper'; type TCommonProps = { props: Record; - style: TStyle; + style: Record; }; -export function addReaderBlockWrapper(ChildComponent: (props: TProps) => React.ReactNode) { +export function addReaderBlockWrapper(ChildComponent: (props: TProps) => JSX.Element) { return (props: TProps) => { return ( @@ -20,7 +18,7 @@ export function addReaderBlockWrapper(ChildComponen }; } -export function addEditorBlockWrapper(ChildComponent: (props: TProps) => React.ReactNode) { +export function addEditorBlockWrapper(ChildComponent: (props: TProps) => JSX.Element) { return (props: TProps) => { return ( diff --git a/packages/editor-sample/src/documents/editor/core.tsx b/packages/editor-sample/src/documents/editor/core.tsx index 35460ae..d686a64 100644 --- a/packages/editor-sample/src/documents/editor/core.tsx +++ b/packages/editor-sample/src/documents/editor/core.tsx @@ -1,13 +1,16 @@ import React from 'react'; import { z } from 'zod'; +import { Avatar, AvatarProps, AvatarPropsSchema } from '@usewaypoint/block-avatar'; +import { Button, ButtonProps, ButtonPropsSchema } from '@usewaypoint/block-button'; import { Divider, DividerProps, DividerPropsSchema } from '@usewaypoint/block-divider'; import { Heading, HeadingProps, HeadingPropsSchema } from '@usewaypoint/block-heading'; +import { Html, HtmlProps, HtmlPropsSchema } from '@usewaypoint/block-html'; +import { Image, ImageProps, ImagePropsSchema } from '@usewaypoint/block-image'; import { Spacer, SpacerProps, SpacerPropsSchema } from '@usewaypoint/block-spacer'; +import { Text, TextProps, TextPropsSchema } from '@usewaypoint/block-text'; import { buildBlockComponent, buildBlockConfigurationSchema } from '@usewaypoint/document-core'; -import { Avatar, AvatarPropsSchema } from '../blocks/Avatar'; -import { Button, ButtonPropsSchema } from '../blocks/Button'; import { EditorColumnsContainer } from '../blocks/ColumnsContainer'; import ColumnsContainerPropsSchema from '../blocks/ColumnsContainer/ColumnsContainerPropsSchema'; import { EditorContainer } from '../blocks/Container'; @@ -16,18 +19,23 @@ import { EditorEmailLayout, EmailLayoutProps } from '../blocks/EmailLayout'; import { EmailLayoutPropsSchema } from '../blocks/EmailLayout/EmailLayoutPropsSchema'; import { addEditorBlockWrapper } from '../blocks/helpers/block-wrappers'; import EditorBlockWrapper from '../blocks/helpers/block-wrappers/EditorBlockWrapper'; -import { Html, HtmlPropsSchema } from '../blocks/Html'; -import { Image, ImagePropsSchema } from '../blocks/Image'; -import { Text, TextPropsSchema } from '../blocks/Text'; const EDITOR_DICTIONARY = { Avatar: { schema: AvatarPropsSchema, - Component: addEditorBlockWrapper(Avatar), + Component: (props: AvatarProps) => ( + + + + ), }, Button: { schema: ButtonPropsSchema, - Component: addEditorBlockWrapper(Button), + Component: (props: ButtonProps) => ( + +