From a111544000913643e8f96ea7fdba4cea3f725fad Mon Sep 17 00:00:00 2001 From: tristan Date: Sun, 3 Mar 2024 10:43:08 +0100 Subject: [PATCH] docs: duplicated example#2 & used it as a basis for the responsiveness example --- examples/responsive/.babelrc | 4 + examples/responsive/.gitignore | 25 ++++ examples/responsive/README.md | 5 + .../selectors/Button/ButtonSettings.tsx | 65 +++++++++ .../components/selectors/Button/index.tsx | 73 ++++++++++ .../selectors/Container/ContainerSettings.tsx | 125 ++++++++++++++++++ .../components/selectors/Container/index.tsx | 90 +++++++++++++ .../selectors/Text/TextSettings.tsx | 79 +++++++++++ .../components/selectors/Text/index.tsx | 69 ++++++++++ .../responsive/components/selectors/index.ts | 2 + examples/responsive/next-env.d.ts | 5 + examples/responsive/next.config.js | 4 + examples/responsive/package.json | 50 +++++++ examples/responsive/pages/_app.tsx | 21 +++ examples/responsive/pages/_document.tsx | 32 +++++ examples/responsive/pages/index.tsx | 102 ++++++++++++++ examples/responsive/postcss.config.js | 6 + examples/responsive/public/favicon.ico | Bin 0 -> 15086 bytes examples/responsive/public/icons/arrow-up.svg | 4 + examples/responsive/public/icons/arrow.svg | 4 + examples/responsive/public/icons/button.svg | 1 + examples/responsive/public/icons/check.svg | 5 + .../responsive/public/icons/customize.svg | 6 + examples/responsive/public/icons/delete.svg | 11 ++ examples/responsive/public/icons/edit.svg | 11 ++ examples/responsive/public/icons/layers.svg | 12 ++ examples/responsive/public/icons/move.svg | 11 ++ examples/responsive/public/icons/square.svg | 1 + .../public/icons/toolbox/button.svg | 12 ++ .../public/icons/toolbox/container.svg | 1 + .../responsive/public/icons/toolbox/link.svg | 1 + .../public/icons/toolbox/rectangle.svg | 11 ++ .../responsive/public/icons/toolbox/redo.svg | 4 + .../public/icons/toolbox/text-fill.svg | 1 + .../responsive/public/icons/toolbox/text.svg | 1 + .../responsive/public/icons/toolbox/undo.svg | 4 + .../public/icons/toolbox/video-fill.svg | 1 + .../public/icons/toolbox/video-line.svg | 1 + examples/responsive/public/icons/type.svg | 1 + examples/responsive/public/icons/youtube.svg | 1 + .../seo/googlee6ec608adf0c9ed0.html | 1 + examples/responsive/seo/sitemap.xml | 16 +++ examples/responsive/seo/urllist.txt | 1 + examples/responsive/styles/app.css | 41 ++++++ examples/responsive/tailwind.config.js | 20 +++ examples/responsive/tsconfig.json | 38 ++++++ examples/responsive/types/svg.d.ts | 4 + examples/responsive/utils/numToMeasurement.ts | 32 +++++ examples/responsive/utils/text.ts | 4 + yarn.lock | 53 ++++++++ 50 files changed, 1072 insertions(+) create mode 100644 examples/responsive/.babelrc create mode 100644 examples/responsive/.gitignore create mode 100644 examples/responsive/README.md create mode 100644 examples/responsive/components/selectors/Button/ButtonSettings.tsx create mode 100644 examples/responsive/components/selectors/Button/index.tsx create mode 100644 examples/responsive/components/selectors/Container/ContainerSettings.tsx create mode 100644 examples/responsive/components/selectors/Container/index.tsx create mode 100644 examples/responsive/components/selectors/Text/TextSettings.tsx create mode 100644 examples/responsive/components/selectors/Text/index.tsx create mode 100644 examples/responsive/components/selectors/index.ts create mode 100644 examples/responsive/next-env.d.ts create mode 100644 examples/responsive/next.config.js create mode 100644 examples/responsive/package.json create mode 100644 examples/responsive/pages/_app.tsx create mode 100644 examples/responsive/pages/_document.tsx create mode 100644 examples/responsive/pages/index.tsx create mode 100644 examples/responsive/postcss.config.js create mode 100644 examples/responsive/public/favicon.ico create mode 100644 examples/responsive/public/icons/arrow-up.svg create mode 100644 examples/responsive/public/icons/arrow.svg create mode 100644 examples/responsive/public/icons/button.svg create mode 100644 examples/responsive/public/icons/check.svg create mode 100644 examples/responsive/public/icons/customize.svg create mode 100644 examples/responsive/public/icons/delete.svg create mode 100644 examples/responsive/public/icons/edit.svg create mode 100644 examples/responsive/public/icons/layers.svg create mode 100644 examples/responsive/public/icons/move.svg create mode 100644 examples/responsive/public/icons/square.svg create mode 100644 examples/responsive/public/icons/toolbox/button.svg create mode 100644 examples/responsive/public/icons/toolbox/container.svg create mode 100644 examples/responsive/public/icons/toolbox/link.svg create mode 100644 examples/responsive/public/icons/toolbox/rectangle.svg create mode 100644 examples/responsive/public/icons/toolbox/redo.svg create mode 100644 examples/responsive/public/icons/toolbox/text-fill.svg create mode 100644 examples/responsive/public/icons/toolbox/text.svg create mode 100644 examples/responsive/public/icons/toolbox/undo.svg create mode 100644 examples/responsive/public/icons/toolbox/video-fill.svg create mode 100644 examples/responsive/public/icons/toolbox/video-line.svg create mode 100644 examples/responsive/public/icons/type.svg create mode 100644 examples/responsive/public/icons/youtube.svg create mode 100644 examples/responsive/seo/googlee6ec608adf0c9ed0.html create mode 100644 examples/responsive/seo/sitemap.xml create mode 100755 examples/responsive/seo/urllist.txt create mode 100644 examples/responsive/styles/app.css create mode 100644 examples/responsive/tailwind.config.js create mode 100644 examples/responsive/tsconfig.json create mode 100644 examples/responsive/types/svg.d.ts create mode 100644 examples/responsive/utils/numToMeasurement.ts create mode 100644 examples/responsive/utils/text.ts diff --git a/examples/responsive/.babelrc b/examples/responsive/.babelrc new file mode 100644 index 000000000..a6f4434e2 --- /dev/null +++ b/examples/responsive/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["next/babel"], + "plugins": ["inline-react-svg"] +} diff --git a/examples/responsive/.gitignore b/examples/responsive/.gitignore new file mode 100644 index 000000000..922d92a57 --- /dev/null +++ b/examples/responsive/.gitignore @@ -0,0 +1,25 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +.env* + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/examples/responsive/README.md b/examples/responsive/README.md new file mode 100644 index 000000000..7513716f5 --- /dev/null +++ b/examples/responsive/README.md @@ -0,0 +1,5 @@ +# Landing + +This is the source code for the landing page demo seen [here](https://craft.js.org/) + +> The code is admittedly a bit messy and is scheduled for a clean up. In the mean time, feel free to submit an issue if you encounter any confusing/weird/wtf bits ... or even better, submit a pull request! :clap: diff --git a/examples/responsive/components/selectors/Button/ButtonSettings.tsx b/examples/responsive/components/selectors/Button/ButtonSettings.tsx new file mode 100644 index 000000000..2f2ba3658 --- /dev/null +++ b/examples/responsive/components/selectors/Button/ButtonSettings.tsx @@ -0,0 +1,65 @@ +import React from 'react'; + +import { ToolbarSection, ToolbarItem } from '../../editor'; +import { ToolbarRadio } from '../../editor/Toolbar/ToolbarRadio'; + +export const ButtonSettings = () => { + return ( + + { + return ( +
+
+

+ T +

+
+
+ ); + }} + > + + +
+ { + return `${margin[0] || 0}px ${margin[1] || 0}px ${margin[2] || 0}px ${ + margin[3] || 0 + }px`; + }} + > + + + + + + + + + + + +
+ ); +}; diff --git a/examples/responsive/components/selectors/Button/index.tsx b/examples/responsive/components/selectors/Button/index.tsx new file mode 100644 index 000000000..aa21c6366 --- /dev/null +++ b/examples/responsive/components/selectors/Button/index.tsx @@ -0,0 +1,73 @@ +import { UserComponent, useNode } from '@craftjs/core'; +import cx from 'classnames'; +import React from 'react'; +import styled from 'styled-components'; + +import { ButtonSettings } from './ButtonSettings'; + +import { Text } from '../Text'; + +type ButtonProps = { + background?: Record<'r' | 'g' | 'b' | 'a', number>; + color?: Record<'r' | 'g' | 'b' | 'a', number>; + buttonStyle?: string; + margin?: any[]; + text?: string; + textComponent?: any; +}; + +const StyledButton = styled.button` + background: ${(props) => + props.buttonStyle === 'full' + ? `rgba(${Object.values(props.background)})` + : 'transparent'}; + border: 2px solid transparent; + border-color: ${(props) => + props.buttonStyle === 'outline' + ? `rgba(${Object.values(props.background)})` + : 'transparent'}; + margin: ${({ margin }) => + `${margin[0]}px ${margin[1]}px ${margin[2]}px ${margin[3]}px`}; +`; + +export const Button: UserComponent = (props: any) => { + const { + connectors: { connect }, + } = useNode((node) => ({ + selected: node.events.selected, + })); + + const { text, textComponent, color, ...otherProps } = props; + return ( + + + + ); +}; + +Button.craft = { + displayName: 'Button', + props: { + background: { r: 255, g: 255, b: 255, a: 0.5 }, + color: { r: 92, g: 90, b: 90, a: 1 }, + buttonStyle: 'full', + text: 'Button', + margin: ['5', '0', '5', '0'], + textComponent: { + ...Text.craft.props, + textAlign: 'center', + }, + }, + related: { + toolbar: ButtonSettings, + }, +}; diff --git a/examples/responsive/components/selectors/Container/ContainerSettings.tsx b/examples/responsive/components/selectors/Container/ContainerSettings.tsx new file mode 100644 index 000000000..618c54e96 --- /dev/null +++ b/examples/responsive/components/selectors/Container/ContainerSettings.tsx @@ -0,0 +1,125 @@ +import React from 'react'; + +import { ToolbarSection, ToolbarItem } from '../../editor'; +import { ToolbarRadio } from '../../editor/Toolbar/ToolbarRadio'; + +export const ContainerSettings = () => { + return ( + + { + return `${width || 0} x ${height || 0}`; + }} + > + + + + { + return ( +
+
+

+ T +

+
+
+ ); + }} + > + + +
+ { + return `${margin[0] || 0}px ${margin[1] || 0}px ${margin[2] || 0}px ${ + margin[3] || 0 + }px`; + }} + > + + + + + + { + return `${padding[0] || 0}px ${padding[1] || 0}px ${ + padding[2] || 0 + }px ${padding[3] || 0}px`; + }} + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; diff --git a/examples/responsive/components/selectors/Container/index.tsx b/examples/responsive/components/selectors/Container/index.tsx new file mode 100644 index 000000000..a64b865c1 --- /dev/null +++ b/examples/responsive/components/selectors/Container/index.tsx @@ -0,0 +1,90 @@ +import React from 'react'; + +import { ContainerSettings } from './ContainerSettings'; + +export type ContainerProps = { + background: Record<'r' | 'g' | 'b' | 'a', number>; + color: Record<'r' | 'g' | 'b' | 'a', number>; + flexDirection: string; + alignItems: string; + justifyContent: string; + fillSpace: string; + width: string; + height: string; + padding: string[]; + margin: string[]; + marginTop: number; + marginLeft: number; + marginBottom: number; + marginRight: number; + shadow: number; + children: React.ReactNode; + radius: number; +}; + +const defaultProps = { + flexDirection: 'column', + alignItems: 'flex-start', + justifyContent: 'flex-start', + fillSpace: 'no', + padding: ['0', '0', '0', '0'], + margin: ['0', '0', '0', '0'], + background: { r: 255, g: 255, b: 255, a: 1 }, + color: { r: 0, g: 0, b: 0, a: 1 }, + shadow: 0, + radius: 0, + width: '100%', + height: 'auto', +}; + +export const Container = (props: Partial) => { + props = { + ...defaultProps, + ...props, + }; + const { + flexDirection, + alignItems, + justifyContent, + fillSpace, + background, + color, + padding, + margin, + shadow, + radius, + children, + } = props; + return ( +
+ {children} +
+ ); +}; + +Container.craft = { + displayName: 'Container', + props: defaultProps, + rules: { + canDrag: () => true, + }, + related: { + toolbar: ContainerSettings, + }, +}; diff --git a/examples/responsive/components/selectors/Text/TextSettings.tsx b/examples/responsive/components/selectors/Text/TextSettings.tsx new file mode 100644 index 000000000..b26a18f62 --- /dev/null +++ b/examples/responsive/components/selectors/Text/TextSettings.tsx @@ -0,0 +1,79 @@ +import React from 'react'; + +import { capitalize, weightDescription } from '../../../utils/text'; +import { ToolbarSection, ToolbarItem } from '../../editor'; +import { ToolbarRadio } from '../../editor/Toolbar/ToolbarRadio'; + +export const TextSettings = () => { + return ( + + { + return `${fontSize || ''}, ${weightDescription( + fontWeight + )}, ${capitalize(textAlign)}`; + }} + > + + + + + + + + + + + + + { + return `${margin[0] || 0}px ${margin[1] || 0}px ${margin[2] || 0}px ${ + margin[3] || 0 + }px`; + }} + > + + + + + + { + return ( +
+

+ T +

+
+ ); + }} + > + + +
+
+ ); +}; diff --git a/examples/responsive/components/selectors/Text/index.tsx b/examples/responsive/components/selectors/Text/index.tsx new file mode 100644 index 000000000..6bef80b20 --- /dev/null +++ b/examples/responsive/components/selectors/Text/index.tsx @@ -0,0 +1,69 @@ +import { useNode, useEditor } from '@craftjs/core'; +import React from 'react'; +import ContentEditable from 'react-contenteditable'; + +import { TextSettings } from './TextSettings'; + +export type TextProps = { + fontSize: string; + textAlign: string; + fontWeight: string; + color: Record<'r' | 'g' | 'b' | 'a', string>; + shadow: number; + text: string; + margin: [string, string, string, string]; +}; + +export const Text = ({ + fontSize, + textAlign, + fontWeight, + color, + shadow, + text, + margin, +}: Partial) => { + const { + connectors: { connect }, + setProp, + } = useNode(); + const { enabled } = useEditor((state) => ({ + enabled: state.options.enabled, + })); + return ( + { + setProp((prop) => (prop.text = e.target.value), 500); + }} // use true to disable editing + tagName="h2" // Use a custom HTML tag (uses a div by default) + style={{ + width: '100%', + margin: `${margin[0]}px ${margin[1]}px ${margin[2]}px ${margin[3]}px`, + color: `rgba(${Object.values(color)})`, + fontSize: `${fontSize}px`, + textShadow: `0px 0px 2px rgba(0,0,0,${(shadow || 0) / 100})`, + fontWeight, + textAlign, + }} + /> + ); +}; + +Text.craft = { + displayName: 'Text', + props: { + fontSize: '15', + textAlign: 'left', + fontWeight: '500', + color: { r: 92, g: 90, b: 90, a: 1 }, + margin: [0, 0, 0, 0], + shadow: 0, + text: 'Text', + }, + related: { + toolbar: TextSettings, + }, +}; diff --git a/examples/responsive/components/selectors/index.ts b/examples/responsive/components/selectors/index.ts new file mode 100644 index 000000000..8dd533d20 --- /dev/null +++ b/examples/responsive/components/selectors/index.ts @@ -0,0 +1,2 @@ +export * from './Container'; +export * from './Text'; diff --git a/examples/responsive/next-env.d.ts b/examples/responsive/next-env.d.ts new file mode 100644 index 000000000..4f11a03dc --- /dev/null +++ b/examples/responsive/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/responsive/next.config.js b/examples/responsive/next.config.js new file mode 100644 index 000000000..ea48d4656 --- /dev/null +++ b/examples/responsive/next.config.js @@ -0,0 +1,4 @@ +module.exports = { + assetPrefix: + process.env.NODE_ENV === 'production' ? '/examples/landing' : '/', +}; diff --git a/examples/responsive/package.json b/examples/responsive/package.json new file mode 100644 index 000000000..a6da0d08d --- /dev/null +++ b/examples/responsive/package.json @@ -0,0 +1,50 @@ +{ + "name": "example-responsive", + "version": "0.2.0", + "private": true, + "scripts": { + "start": "next dev -p 3002", + "build": "next build", + "export": "next export", + "clean": "rimraf lib .next out dist" + }, + "dependencies": { + "@craftjs/core": "workspace:*", + "@craftjs/layers": "workspace:*", + "@material-ui/core": "4.5.2", + "@material-ui/icons": "4.5.1", + "autoprefixer": "latest", + "classnames": "2.2.6", + "cssnano": "4.1.10", + "debounce": "1.2.0", + "lzutf8": "0.5.5", + "next": "13.1.6", + "next-seo": "4.24.0", + "postcss": "latest", + "re-resizable": "6.1.0", + "react": "18.2.0", + "react-color": "2.17.3", + "react-contenteditable": "3.3.2", + "react-dom": "18.2.0", + "react-frame-component": "^5.2.6", + "react-loading": "2.0.3", + "react-rnd": "10.1.1", + "react-youtube": "7.9.0", + "styled-components": "4.4.1" + }, + "devDependencies": { + "@babel/core": "7.7.5", + "@fullhuman/postcss-purgecss": "1.3.0", + "@types/classnames": "2.2.9", + "@types/node": "12.12.5", + "@types/react": "18.0.27", + "@types/react-color": "3.0.1", + "@types/styled-components": "4.4.1", + "babel-plugin-inline-react-svg": "2.0.1", + "cross-env": "6.0.3", + "postcss-import": "12.0.1", + "postcss-preset-env": "6.7.0", + "tailwindcss": "latest", + "typescript": "4.9.5" + } +} diff --git a/examples/responsive/pages/_app.tsx b/examples/responsive/pages/_app.tsx new file mode 100644 index 000000000..97a6c4d58 --- /dev/null +++ b/examples/responsive/pages/_app.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import '../styles/app.css'; + +function MyApp({ Component, pageProps }) { + return ; +} + +// Only uncomment this method if you have blocking data requirements for +// every single page in your application. This disables the ability to +// perform automatic static optimization, causing every page in your app to +// be server-side rendered. +// +// MyApp.getInitialProps = async (appContext) => { +// // calls page's `getInitialProps` and fills `appProps.pageProps` +// const appProps = await App.getInitialProps(appContext); +// +// return { ...appProps } +// } + +export default MyApp; diff --git a/examples/responsive/pages/_document.tsx b/examples/responsive/pages/_document.tsx new file mode 100644 index 000000000..0da52da1b --- /dev/null +++ b/examples/responsive/pages/_document.tsx @@ -0,0 +1,32 @@ +import Document, { DocumentContext, DocumentInitialProps } from 'next/document'; +import { ServerStyleSheet } from 'styled-components'; + +export default class MyDocument extends Document { + static async getInitialProps( + ctx: DocumentContext + ): Promise { + const sheet = new ServerStyleSheet(); + const originalRenderPage = ctx.renderPage; + + try { + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => + sheet.collectStyles(), + }); + + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {sheet.getStyleElement()} + + ), + }; + } finally { + sheet.seal(); + } + } +} diff --git a/examples/responsive/pages/index.tsx b/examples/responsive/pages/index.tsx new file mode 100644 index 000000000..016384e53 --- /dev/null +++ b/examples/responsive/pages/index.tsx @@ -0,0 +1,102 @@ +import { Editor, Frame, Element } from '@craftjs/core'; +import { Button, ButtonGroup, createMuiTheme } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; +import React, { useState } from 'react'; + +import { Container, Text } from '../components/selectors'; +import IFrame from 'react-frame-component'; + +const theme = createMuiTheme({ + typography: { + fontFamily: [ + 'acumin-pro', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + ].join(','), + }, +}); + +function App() { + const breakpoints = { + sm: '640px', // small devices i.e phones + md: '1280px', // medium devices i.e tablets + lg: '1536px', // large devices i.e computers,laptops... + }; + + const [breakpoint, setBreakpoint] = useState('lg'); + + return ( + +
+ +
+ + + + + +
+ +
+ +
+
+
+
+ ); +} + +import type { ReactNode } from 'react'; +import { useFrame } from 'react-frame-component'; +import { useLayoutEffect } from 'react'; +function AddStyles({ children }: { children: ReactNode }) { + const { document: doc } = useFrame(); //