From 077e84b25aceb199a4aa7d30157131f8df8bf82d Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:49:19 +0800 Subject: [PATCH 1/7] style(website): Make Playground Mobile Responsive --- modelina-website/package-lock.json | 14 ++ modelina-website/package.json | 1 + .../components/contexts/PlaygroundContext.tsx | 157 ++++++++------- .../src/components/playground/Content.tsx | 122 ++++++----- .../src/components/playground/Playground.tsx | 189 ++++++++++++------ .../src/components/playground/Sidebar.tsx | 85 +++++--- modelina-website/src/pages/playground.tsx | 38 +--- 7 files changed, 367 insertions(+), 239 deletions(-) diff --git a/modelina-website/package-lock.json b/modelina-website/package-lock.json index 343dfd77d8..e7e7b17513 100644 --- a/modelina-website/package-lock.json +++ b/modelina-website/package-lock.json @@ -13,6 +13,7 @@ "@tailwindcss/line-clamp": "^0.4.0", "@tailwindcss/typography": "^0.5.9", "@tippyjs/react": "^4.2.6", + "clsx": "^2.1.1", "cssnano": "^5.1.14", "js-base64": "^3.7.4", "lodash": "^4.17.21", @@ -1231,6 +1232,14 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7692,6 +7701,11 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", diff --git a/modelina-website/package.json b/modelina-website/package.json index 4806ccb794..6fe2494e0b 100644 --- a/modelina-website/package.json +++ b/modelina-website/package.json @@ -21,6 +21,7 @@ "@tailwindcss/line-clamp": "^0.4.0", "@tailwindcss/typography": "^0.5.9", "@tippyjs/react": "^4.2.6", + "clsx": "^2.1.1", "cssnano": "^5.1.14", "js-base64": "^3.7.4", "lodash": "^4.17.21", diff --git a/modelina-website/src/components/contexts/PlaygroundContext.tsx b/modelina-website/src/components/contexts/PlaygroundContext.tsx index 9ed959ec20..d9f2553166 100644 --- a/modelina-website/src/components/contexts/PlaygroundContext.tsx +++ b/modelina-website/src/components/contexts/PlaygroundContext.tsx @@ -20,6 +20,8 @@ interface LoadedState { } interface PlaygroundContextProps { + showInputEditor: boolean; + setShowInputEditor: Dispatch>; showOptions: boolean; setShowOptions: Dispatch>; showOutputNavigation: boolean; @@ -50,9 +52,13 @@ interface PlaygroundContextProps { setRenderModels: (models: React.ReactNode) => void; } -const PlaygroundContext = createContext(undefined); +const PlaygroundContext = createContext( + undefined +); -export const PlaygroundContextProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { +export const PlaygroundContextProvider: React.FC<{ + children: React.ReactNode; +}> = ({ children }) => { const defaultConfig: ModelinaOptions = { language: 'typescript', propertyNamingFormat: 'default', @@ -94,15 +100,18 @@ export const PlaygroundContextProvider: React.FC<{ children: React.ReactNode; }> kotlinPackageName: 'asyncapi.models' }; - const [showOptions, setShowOptions] = useState(true); - const [showOutputNavigation, setShowOutputNavigation] = useState(true); + const [showInputEditor, setShowInputEditor] = useState(false); + const [showOptions, setShowOptions] = useState(false); + const [showOutputNavigation, setShowOutputNavigation] = useState(false); const [config, setConfig] = useState(defaultConfig); - const [input, setInput] = useState(JSON.stringify(defaultAsyncapiDocument, null, 4)); + const [input, setInput] = useState( + JSON.stringify(defaultAsyncapiDocument, null, 4) + ); const [models, setModels] = useState([]); const [generatorCode, setGeneratorCode] = useState(''); const [loaded, setLoaded] = useState({ editorLoaded: false, - hasReceivedCode: false, + hasReceivedCode: false }); const [showGeneratorCode, setShowGeneratorCode] = useState(false); const [error, setError] = useState(false); @@ -110,79 +119,89 @@ export const PlaygroundContextProvider: React.FC<{ children: React.ReactNode; }> const [errorMessage, setErrorMessage] = useState('Bad Request'); const [isLoaded, setIsLoaded] = useState(false); const [hasLoadedQuery, setHasLoadedQuery] = useState(false); - const [renderModels, setRenderModels] = React.useState(null); + const [renderModels, setRenderModels] = + React.useState(null); - const contextValue = useMemo(() => ({ - showOptions, - setShowOptions, - showOutputNavigation, - setShowOutputNavigation, - config, - setConfig, - input, - setInput, - models, - setModels, - generatorCode, - setGeneratorCode, - loaded, - setLoaded, - showGeneratorCode, - setShowGeneratorCode, - error, - setError, - statusCode, - setStatusCode, - errorMessage, - setErrorMessage, - isLoaded, - setIsLoaded, - hasLoadedQuery, - setHasLoadedQuery, - renderModels, - setRenderModels - }), [ - showOptions, - setShowOptions, - showOutputNavigation, - setShowOutputNavigation, - config, - setConfig, - input, - setInput, - models, - setModels, - generatorCode, - setGeneratorCode, - loaded, - setLoaded, - showGeneratorCode, - setShowGeneratorCode, - error, - setError, - statusCode, - setStatusCode, - errorMessage, - setErrorMessage, - isLoaded, - setIsLoaded, - hasLoadedQuery, - setHasLoadedQuery, - renderModels, - setRenderModels, - ]); + const contextValue = useMemo( + () => ({ + showInputEditor, + setShowInputEditor, + showOptions, + setShowOptions, + showOutputNavigation, + setShowOutputNavigation, + config, + setConfig, + input, + setInput, + models, + setModels, + generatorCode, + setGeneratorCode, + loaded, + setLoaded, + showGeneratorCode, + setShowGeneratorCode, + error, + setError, + statusCode, + setStatusCode, + errorMessage, + setErrorMessage, + isLoaded, + setIsLoaded, + hasLoadedQuery, + setHasLoadedQuery, + renderModels, + setRenderModels + }), + [ + showInputEditor, + setShowInputEditor, + showOptions, + setShowOptions, + showOutputNavigation, + setShowOutputNavigation, + config, + setConfig, + input, + setInput, + models, + setModels, + generatorCode, + setGeneratorCode, + loaded, + setLoaded, + showGeneratorCode, + setShowGeneratorCode, + error, + setError, + statusCode, + setStatusCode, + errorMessage, + setErrorMessage, + isLoaded, + setIsLoaded, + hasLoadedQuery, + setHasLoadedQuery, + renderModels, + setRenderModels + ] + ); return ( {children} ); -} +}; export const usePlaygroundContext = () => { const context = useContext(PlaygroundContext); if (!context) { - throw new Error('Playground was unable to load the context to display, please report this problem on GitHub.'); + throw new Error( + 'Playground was unable to load the context to display, please report this problem on GitHub.' + ); } return context; -}; \ No newline at end of file +}; diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx index 6e6f457185..31195ace6d 100644 --- a/modelina-website/src/components/playground/Content.tsx +++ b/modelina-website/src/components/playground/Content.tsx @@ -8,17 +8,27 @@ import CustomError from '../CustomError'; import OutputNavigation from './OutputNavigation'; import { OptionsNavigation } from './OptionsNavigation'; import GeneratedModelsComponent from './GeneratedModels'; +import clsx from 'clsx'; interface ContentProps { - setNewConfig: (config: string, configValue: any, updateCode?: boolean) => void; + setNewConfig: ( + config: string, + configValue: any, + updateCode?: boolean + ) => void; setNewQuery: (queryKey: string, queryValue: any) => void; generateNewCode: (input: string) => void; } -export const Content: FunctionComponent = ({ setNewConfig, setNewQuery, generateNewCode }) => { +export const Content: FunctionComponent = ({ + setNewConfig, + setNewQuery, + generateNewCode +}) => { const { config, input, + showInputEditor, setInput, models, loaded, @@ -27,62 +37,78 @@ export const Content: FunctionComponent = ({ setNewConfig, setNewQ statusCode, errorMessage, showOptions, - showOutputNavigation, + showOutputNavigation } = usePlaygroundContext(); - const PlaygroundGeneratedContextValue = useMemo(() => ({ - language: config.language, - models: models - }), [config.language, models]); + const PlaygroundGeneratedContextValue = useMemo( + () => ({ + language: config.language, + models + }), + [config.language, models] + ); return (
- {/* OPTIONS & EDITOR */} -
- { - showOptions &&
+ {/* OPTIONS */} +
+ {showOptions && ( +
- } -
-
-
- { - setInput(change); - generateNewCode(change); - }} - editorDidMount={() => { - setLoaded({ ...loaded, editorLoaded: true }); - }} - language="json" - /> -
-
-
-
- - {/* OUTPUT NAVIGATION AND OUTPUTS */} -
- { - showOutputNavigation &&
+ )} + {showOutputNavigation && ( +
- } -
-
- {error ? ( - - ) : ( - - - - )} + )} + {/* Editor Input/Output */} + {showInputEditor ? ( +
+
+
+ { + setInput(change); + generateNewCode(change); + }} + editorDidMount={() => { + setLoaded({ ...loaded, editorLoaded: true }); + }} + language="json" + /> +
+
+
+ ) : ( +
+
+
+ {error ? ( + + ) : ( + + + + )} +
+
-
+ )}
); diff --git a/modelina-website/src/components/playground/Playground.tsx b/modelina-website/src/components/playground/Playground.tsx index fae6a49957..4c0f1f5f24 100644 --- a/modelina-website/src/components/playground/Playground.tsx +++ b/modelina-website/src/components/playground/Playground.tsx @@ -1,11 +1,7 @@ import React, { useEffect, useState } from 'react'; import Router, { withRouter, NextRouter } from 'next/router'; import { encode } from 'js-base64'; -import { - ModelinaQueryOptions, - GenerateMessage, - UpdateMessage -} from '@/types'; +import { ModelinaQueryOptions, GenerateMessage, UpdateMessage } from '@/types'; import { getTypeScriptGeneratorCode } from '@/helpers/GeneratorCode/TypeScriptGenerator'; import { getJavaScriptGeneratorCode } from '@/helpers/GeneratorCode/JavaScriptGenerator'; import { getJavaGeneratorCode } from '@/helpers/GeneratorCode/JavaGenerator'; @@ -44,7 +40,7 @@ const Playground: React.FC = (props) => { isLoaded, setIsLoaded, hasLoadedQuery, - setHasLoadedQuery, + setHasLoadedQuery } = usePlaygroundContext(); // To avoid hydration error @@ -64,16 +60,28 @@ const Playground: React.FC = (props) => { setConfig({ ...config, language: query.language as any }); } if (query.enumKeyNamingFormat !== undefined) { - setConfig({ ...config, enumKeyNamingFormat: query.enumKeyNamingFormat as any }); + setConfig({ + ...config, + enumKeyNamingFormat: query.enumKeyNamingFormat as any + }); } if (query.propertyNamingFormat !== undefined) { - setConfig({ ...config, propertyNamingFormat: query.propertyNamingFormat as any }); + setConfig({ + ...config, + propertyNamingFormat: query.propertyNamingFormat as any + }); } if (query.modelNamingFormat !== undefined) { - setConfig({ ...config, modelNamingFormat: query.modelNamingFormat as any }); + setConfig({ + ...config, + modelNamingFormat: query.modelNamingFormat as any + }); } if (query.showTypeMappingExample !== undefined) { - setConfig({ ...config, showTypeMappingExample: query.showTypeMappingExample === 'true' }); + setConfig({ + ...config, + showTypeMappingExample: query.showTypeMappingExample === 'true' + }); } if (query.indentationType !== undefined) { setConfig({ ...config, indentationType: query.indentationType as any }); @@ -91,37 +99,64 @@ const Playground: React.FC = (props) => { setConfig({ ...config, tsMapType: query.tsMapType as any }); } if (query.tsIncludeDescriptions !== undefined) { - setConfig({ ...config, tsIncludeDescriptions: query.tsIncludeDescriptions === 'true' }); + setConfig({ + ...config, + tsIncludeDescriptions: query.tsIncludeDescriptions === 'true' + }); } if (query.tsIncludeJsonBinPack !== undefined) { - setConfig({ ...config, tsIncludeJsonBinPack: query.tsIncludeJsonBinPack === 'true' }); + setConfig({ + ...config, + tsIncludeJsonBinPack: query.tsIncludeJsonBinPack === 'true' + }); } if (query.tsIncludeExampleFunction !== undefined) { - setConfig({ ...config, tsIncludeExampleFunction: query.tsIncludeExampleFunction === 'true' }); + setConfig({ + ...config, + tsIncludeExampleFunction: query.tsIncludeExampleFunction === 'true' + }); } if (query.csharpArrayType !== undefined) { setConfig({ ...config, csharpArrayType: query.csharpArrayType as any }); } if (query.csharpAutoImplemented !== undefined) { - setConfig({ ...config, csharpAutoImplemented: query.csharpAutoImplemented === 'true' }); + setConfig({ + ...config, + csharpAutoImplemented: query.csharpAutoImplemented === 'true' + }); } if (query.csharpOverwriteHashcode !== undefined) { - setConfig({ ...config, csharpOverwriteHashcode: query.csharpOverwriteHashcode === 'true' }); + setConfig({ + ...config, + csharpOverwriteHashcode: query.csharpOverwriteHashcode === 'true' + }); } if (query.phpIncludeDescriptions !== undefined) { - setConfig({ ...config, phpIncludeDescriptions: query.phpIncludeDescriptions === 'true' }); + setConfig({ + ...config, + phpIncludeDescriptions: query.phpIncludeDescriptions === 'true' + }); } if (query.phpNamespace !== undefined) { setConfig({ ...config, phpNamespace: query.phpNamespace }); } if (query.csharpIncludeJson !== undefined) { - setConfig({ ...config, csharpIncludeJson: query.csharpIncludeJson === 'true' }); + setConfig({ + ...config, + csharpIncludeJson: query.csharpIncludeJson === 'true' + }); } if (query.csharpOverwriteEqual !== undefined) { - setConfig({ ...config, csharpOverwriteEqual: query.csharpOverwriteEqual === 'true' }); + setConfig({ + ...config, + csharpOverwriteEqual: query.csharpOverwriteEqual === 'true' + }); } if (query.csharpIncludeNewtonsoft !== undefined) { - setConfig({ ...config, csharpIncludeNewtonsoft: query.csharpIncludeNewtonsoft === 'true' }); + setConfig({ + ...config, + csharpIncludeNewtonsoft: query.csharpIncludeNewtonsoft === 'true' + }); } if (query.csharpNamespace !== undefined) { setConfig({ ...config, csharpNamespace: query.csharpNamespace }); @@ -136,28 +171,46 @@ const Playground: React.FC = (props) => { setConfig({ ...config, javaPackageName: query.javaPackageName }); } if (query.javaIncludeJackson !== undefined) { - setConfig({ ...config, javaIncludeJackson: query.javaIncludeJackson === 'true' }); + setConfig({ + ...config, + javaIncludeJackson: query.javaIncludeJackson === 'true' + }); } if (query.javaIncludeMarshaling !== undefined) { - setConfig({ ...config, javaIncludeMarshaling: query.javaIncludeMarshaling === 'true' }); + setConfig({ + ...config, + javaIncludeMarshaling: query.javaIncludeMarshaling === 'true' + }); } if (query.javaArrayType !== undefined) { setConfig({ ...config, javaArrayType: query.javaArrayType as any }); } if (query.javaOverwriteHashcode !== undefined) { - setConfig({ ...config, javaOverwriteHashcode: query.javaOverwriteHashcode === 'true' }); + setConfig({ + ...config, + javaOverwriteHashcode: query.javaOverwriteHashcode === 'true' + }); } if (query.javaOverwriteEqual !== undefined) { - setConfig({ ...config, javaOverwriteEqual: query.javaOverwriteEqual === 'true' }); + setConfig({ + ...config, + javaOverwriteEqual: query.javaOverwriteEqual === 'true' + }); } if (query.javaOverwriteToString !== undefined) { - setConfig({ ...config, javaOverwriteToString: query.javaOverwriteToString === 'true' }); + setConfig({ + ...config, + javaOverwriteToString: query.javaOverwriteToString === 'true' + }); } if (query.javaJavaDocs !== undefined) { setConfig({ ...config, javaJavaDocs: query.javaJavaDocs === 'true' }); } if (query.javaJavaxAnnotation !== undefined) { - setConfig({ ...config, javaJavaxAnnotation: query.javaJavaxAnnotation === 'true' }); + setConfig({ + ...config, + javaJavaxAnnotation: query.javaJavaxAnnotation === 'true' + }); } if (query.goPackageName !== undefined) { setConfig({ ...config, goPackageName: query.goPackageName }); @@ -185,7 +238,11 @@ const Playground: React.FC = (props) => { } }, [props.router.isReady, hasLoadedQuery]); - const setNewConfig = (configName: string, configValue: any, updateCode?: boolean) => { + const setNewConfig = ( + configName: string, + configValue: any, + updateCode?: boolean + ) => { setNewQuery(configName, configValue); /* eslint-disable-next-line security/detect-object-injection */ (config as any)[configName] = configValue; @@ -248,32 +305,38 @@ const Playground: React.FC = (props) => { fetch(`${process.env.NEXT_PUBLIC_API_PATH}/generate`, { body: JSON.stringify(message), method: 'POST' - }).then(async (res) => { - if (!res.ok) { - throw new Error(res.statusText); - } + }) + .then(async (res) => { + if (!res.ok) { + throw new Error(res.statusText); + } - const response: UpdateMessage = await res.json(); - setGeneratorCode(generatorCode); - setModels(response.models); - setLoaded({ - ...loaded, - hasReceivedCode: true + const response: UpdateMessage = await res.json(); + setGeneratorCode(generatorCode); + setModels(response.models); + setLoaded({ + ...loaded, + hasReceivedCode: true + }); + setError(false); + setStatusCode(200); + setErrorMessage(''); + }) + .catch((error) => { + console.error(error); + setError(true); + setErrorMessage( + 'Input is not a correct AsyncAPI document, so it cannot be processed.' + ); + setStatusCode(500); }); - setError(false); - setStatusCode(200); - setErrorMessage(''); - }).catch(error => { - console.error(error); - setError(true); - setErrorMessage("Input is not a correct AsyncAPI document, so it cannot be processed."); - setStatusCode(500); - }); } } catch (e: any) { console.error(e); setError(true); - setErrorMessage("Input is not a correct AsyncAPI document, so it cannot be processed."); + setErrorMessage( + 'Input is not a correct AsyncAPI document, so it cannot be processed.' + ); setStatusCode(400); } }; @@ -284,24 +347,26 @@ const Playground: React.FC = (props) => { return (
- { - isLoaded - ? -
- Loading Modelina Playground. Rendering playground components... -
- : -
-
-
- -
-
- -
+ {isLoaded ? ( +
+ Loading Modelina Playground. Rendering playground components... +
+ ) : ( +
+
+
+ +
+
+
- } +
+ )}
); }; diff --git a/modelina-website/src/components/playground/Sidebar.tsx b/modelina-website/src/components/playground/Sidebar.tsx index 45e91a1424..307ea8c7c6 100644 --- a/modelina-website/src/components/playground/Sidebar.tsx +++ b/modelina-website/src/components/playground/Sidebar.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { IoOptionsOutline } from 'react-icons/io5'; import { VscListSelection } from 'react-icons/vsc'; +import { LuFileInput, LuFileOutput } from 'react-icons/lu'; import { Tooltip } from './Tooltip'; import { usePlaygroundContext } from '../contexts/PlaygroundContext'; @@ -8,6 +9,7 @@ interface SidebarItem { name: string; title: string; isActive: boolean; + isShow: boolean; onClick: () => void; icon: React.ReactNode; tooltip: React.ReactNode; @@ -16,15 +18,40 @@ interface SidebarItem { interface SidebarProps {} export const Sidebar: React.FunctionComponent = () => { - const { setShowOptions, setShowOutputNavigation } = usePlaygroundContext(); + const { + setShowOptions, + setShowOutputNavigation, + setShowInputEditor, + showInputEditor, + showOptions + } = usePlaygroundContext(); const sidebarItems: SidebarItem[] = [ + // Input/Output Editor + { + name: 'input-editor', + title: 'Input Editor', + isActive: false, + isShow: true, + onClick: () => { + setShowInputEditor((prevShowOptions) => !prevShowOptions); + setShowOutputNavigation(false); + }, + icon: showInputEditor ? ( + + ) : ( + + ), + tooltip: `Show ${showInputEditor ? 'Input Editor' : 'Output Editor'}` + }, // Options { name: 'options', title: 'Options', - isActive: false, + isActive: showOptions, + isShow: true, onClick: () => { setShowOptions((prevShowOptions) => !prevShowOptions); + setShowOutputNavigation(false); }, icon: , tooltip: 'Show or hide all the options' @@ -34,8 +61,12 @@ export const Sidebar: React.FunctionComponent = () => { name: 'outputExplorer', title: 'Output', isActive: false, + isShow: !showInputEditor, onClick: () => { - setShowOutputNavigation((prevShowOutputNavigation) => !prevShowOutputNavigation); + setShowOutputNavigation( + (prevShowOutputNavigation) => !prevShowOutputNavigation + ); + setShowOptions(false); }, icon: , tooltip: 'Show or hide the list of output models' @@ -45,31 +76,33 @@ export const Sidebar: React.FunctionComponent = () => { return (
- {sidebarItems.map((item) => ( - - - - ))} +
+ {item.icon} +
+ + + ))}
); diff --git a/modelina-website/src/pages/playground.tsx b/modelina-website/src/pages/playground.tsx index 19c97605de..c7c414f685 100644 --- a/modelina-website/src/pages/playground.tsx +++ b/modelina-website/src/pages/playground.tsx @@ -1,35 +1,12 @@ -"use client" -import { useEffect, useState } from 'react'; +'use client'; import Playground from '@/components/playground/Playground'; import GenericLayout from '@/components/layouts/GenericLayout'; import { PlaygroundContextProvider } from '@/components/contexts/PlaygroundContext'; export default function PlaygroundPage() { - const [width, setWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 0); const description = 'Try out Modelina and see a fraction of what it can do.'; const image = '/img/social/modelina-card.jpg'; - // To avoid hydration error - const [isMounted, setIsMounted] = useState(false); - - useEffect(() => { - setIsMounted(true); - - const handleResize = () => { - setWidth(window.innerWidth); - } - - window.addEventListener('resize', handleResize); - - return () => { - window.removeEventListener('resize', handleResize); - } - }, []); - - if (!isMounted) { - return null; - } - return ( - { - width > 768 ? - - - - : -
- Please revisit from the desktop to use the Modelina Playground. -
- } + + +
); } From 9759f4380b1ade1572448221967a2f7fc3879305 Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Sat, 8 Jun 2024 02:43:44 +0800 Subject: [PATCH 2/7] fix!(website): fix ui bug not render costum theme on playground --- modelina-website/src/components/MonacoEditorWrapper.tsx | 9 ++++++--- .../src/components/contexts/PlaygroundContext.tsx | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modelina-website/src/components/MonacoEditorWrapper.tsx b/modelina-website/src/components/MonacoEditorWrapper.tsx index 18f58b853c..9747b2f6d1 100644 --- a/modelina-website/src/components/MonacoEditorWrapper.tsx +++ b/modelina-website/src/components/MonacoEditorWrapper.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import Editor, { useMonaco } from '@monaco-editor/react'; import { debounce } from 'lodash'; @@ -16,6 +16,7 @@ export default function MonacoEditorWrapper({ editorDidMount, ...props }: any) { + const [currentTheme, setTheme] = useState('vs-dark'); const monacoInstance = useMonaco(); const previousValue = useRef(value); const debouncedOnChange = debounce(onChange, 500); @@ -34,8 +35,9 @@ export default function MonacoEditorWrapper({ editorDidMount(editor.getValue, editor); }; + //Alias because Modelina uses cplusplus - if(language === 'cplusplus') { + if (language === 'cplusplus') { language = 'cpp'; } @@ -55,6 +57,7 @@ export default function MonacoEditorWrapper({ }, rules: [{ token: '', background: '#252f3f' }] }); + setTheme('asyncapi-theme'); } }, [monacoInstance]); @@ -62,7 +65,7 @@ export default function MonacoEditorWrapper({ (defaultConfig); From 02a5bfaadad17cd73a5efb7ff6362063f0dc75da Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Mon, 10 Jun 2024 00:43:24 +0800 Subject: [PATCH 3/7] style(website): refactor playground from using flex to grid and rollback desktop design --- .../src/components/MonacoEditorWrapper.tsx | 9 +- .../components/contexts/PlaygroundContext.tsx | 4 +- .../src/components/playground/Content.tsx | 114 +++++++------- .../src/components/playground/Playground.tsx | 20 +-- .../src/components/playground/Sidebar.tsx | 64 ++++---- modelina-website/tailwind.config.js | 142 +++++++++--------- 6 files changed, 178 insertions(+), 175 deletions(-) diff --git a/modelina-website/src/components/MonacoEditorWrapper.tsx b/modelina-website/src/components/MonacoEditorWrapper.tsx index 9747b2f6d1..18f58b853c 100644 --- a/modelina-website/src/components/MonacoEditorWrapper.tsx +++ b/modelina-website/src/components/MonacoEditorWrapper.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import Editor, { useMonaco } from '@monaco-editor/react'; import { debounce } from 'lodash'; @@ -16,7 +16,6 @@ export default function MonacoEditorWrapper({ editorDidMount, ...props }: any) { - const [currentTheme, setTheme] = useState('vs-dark'); const monacoInstance = useMonaco(); const previousValue = useRef(value); const debouncedOnChange = debounce(onChange, 500); @@ -35,9 +34,8 @@ export default function MonacoEditorWrapper({ editorDidMount(editor.getValue, editor); }; - //Alias because Modelina uses cplusplus - if (language === 'cplusplus') { + if(language === 'cplusplus') { language = 'cpp'; } @@ -57,7 +55,6 @@ export default function MonacoEditorWrapper({ }, rules: [{ token: '', background: '#252f3f' }] }); - setTheme('asyncapi-theme'); } }, [monacoInstance]); @@ -65,7 +62,7 @@ export default function MonacoEditorWrapper({ (defaultConfig); const [input, setInput] = useState( JSON.stringify(defaultAsyncapiDocument, null, 4) diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx index 31195ace6d..57aaa3c2db 100644 --- a/modelina-website/src/components/playground/Content.tsx +++ b/modelina-website/src/components/playground/Content.tsx @@ -49,65 +49,69 @@ export const Content: FunctionComponent = ({ ); return ( -
- {/* OPTIONS */} -
- {showOptions && ( -
- -
+
+
- -
+ > + +
+
-
-
- { - setInput(change); - generateNewCode(change); - }} - editorDidMount={() => { - setLoaded({ ...loaded, editorLoaded: true }); - }} - language="json" - /> -
-
-
+ > + +
+
+
+ { + setInput(change); + generateNewCode(change); + }} + editorDidMount={() => { + setLoaded({ ...loaded, editorLoaded: true }); + }} + language="json" + /> +
+
+
+ {error ? ( + ) : ( -
-
-
- {error ? ( - - ) : ( - - - - )} -
-
-
+ + )}
diff --git a/modelina-website/src/components/playground/Playground.tsx b/modelina-website/src/components/playground/Playground.tsx index 4c0f1f5f24..5f269da3af 100644 --- a/modelina-website/src/components/playground/Playground.tsx +++ b/modelina-website/src/components/playground/Playground.tsx @@ -352,19 +352,13 @@ const Playground: React.FC = (props) => { Loading Modelina Playground. Rendering playground components...
) : ( -
-
-
- -
-
- -
-
+
+ +
)}
diff --git a/modelina-website/src/components/playground/Sidebar.tsx b/modelina-website/src/components/playground/Sidebar.tsx index 307ea8c7c6..16f3496de1 100644 --- a/modelina-website/src/components/playground/Sidebar.tsx +++ b/modelina-website/src/components/playground/Sidebar.tsx @@ -4,12 +4,14 @@ import { VscListSelection } from 'react-icons/vsc'; import { LuFileInput, LuFileOutput } from 'react-icons/lu'; import { Tooltip } from './Tooltip'; import { usePlaygroundContext } from '../contexts/PlaygroundContext'; +import clsx from 'clsx'; interface SidebarItem { name: string; title: string; isActive: boolean; isShow: boolean; + mobileOnly: boolean; onClick: () => void; icon: React.ReactNode; tooltip: React.ReactNode; @@ -32,9 +34,11 @@ export const Sidebar: React.FunctionComponent = () => { title: 'Input Editor', isActive: false, isShow: true, + mobileOnly: true, onClick: () => { setShowInputEditor((prevShowOptions) => !prevShowOptions); setShowOutputNavigation(false); + setShowOptions(false); }, icon: showInputEditor ? ( @@ -49,9 +53,9 @@ export const Sidebar: React.FunctionComponent = () => { title: 'Options', isActive: showOptions, isShow: true, + mobileOnly: false, onClick: () => { setShowOptions((prevShowOptions) => !prevShowOptions); - setShowOutputNavigation(false); }, icon: , tooltip: 'Show or hide all the options' @@ -61,12 +65,12 @@ export const Sidebar: React.FunctionComponent = () => { name: 'outputExplorer', title: 'Output', isActive: false, - isShow: !showInputEditor, + isShow: showInputEditor, + mobileOnly: false, onClick: () => { setShowOutputNavigation( (prevShowOutputNavigation) => !prevShowOutputNavigation ); - setShowOptions(false); }, icon: , tooltip: 'Show or hide the list of output models' @@ -76,33 +80,37 @@ export const Sidebar: React.FunctionComponent = () => { return (
- {sidebarItems - .filter(({ isShow }) => isShow === true) - .map((item) => ( - ( + + - - ))} + {item.icon} +
+ + + ))}
); diff --git a/modelina-website/tailwind.config.js b/modelina-website/tailwind.config.js index f985c60a15..310e6f28d2 100644 --- a/modelina-website/tailwind.config.js +++ b/modelina-website/tailwind.config.js @@ -1,6 +1,6 @@ const colors = require('tailwindcss/colors'); -const defaultTheme = require('tailwindcss/defaultTheme') -const plugin = require('tailwindcss/plugin') +const defaultTheme = require('tailwindcss/defaultTheme'); +const plugin = require('tailwindcss/plugin'); // delete deprecated colors that we don't use delete colors['lightBlue']; @@ -25,7 +25,7 @@ const colorSecondary = { 400: '#80D9FF', 500: '#47BCEE', 600: '#1AA9C9' -} +}; const colorPink = { 50: '#FCE7F5', @@ -38,7 +38,7 @@ const colorPink = { 700: '#89085C', 800: '#5C063D', 900: '#2E031F' -} +}; const colorYellow = { 50: '#FFFAEC', @@ -51,7 +51,7 @@ const colorYellow = { 700: '#997E26', 800: '#665419', 900: '#332A0D' -} +}; const colorGray = { 50: '#F7F9FA', @@ -64,7 +64,7 @@ const colorGray = { 700: '#556061', 800: '#364042', 900: '#242929' -} +}; const colorRed = { 100: '#FFE6E6', @@ -76,21 +76,18 @@ const colorRed = { 700: '#990000', 800: '#660000', 900: '#330000' -} +}; function getColors(color, shades) { - const result = {} - shades.forEach(shade => { - result[shade] = color[shade] - }) - return result + const result = {}; + shades.forEach((shade) => { + result[shade] = color[shade]; + }); + return result; } module.exports = { - content: [ - "./src/pages/**/*.tsx", - "./src/components/**/*.tsx", - ], + content: ['./src/pages/**/*.tsx', './src/components/**/*.tsx'], theme: { fontWeight: { 'extra-light': 200, @@ -103,40 +100,40 @@ module.exports = { black: 900 }, fontFamily: { - 'sans': ['Inter', ...defaultTheme.fontFamily.sans], - 'heading': ['Work Sans', ...defaultTheme.fontFamily.sans], - 'body': ['Inter', ...defaultTheme.fontFamily.sans], - 'mono': ['Fira Code VF', 'Fira Code', ...defaultTheme.fontFamily.mono], + sans: ['Inter', ...defaultTheme.fontFamily.sans], + heading: ['Work Sans', ...defaultTheme.fontFamily.sans], + body: ['Inter', ...defaultTheme.fontFamily.sans], + mono: ['Fira Code VF', 'Fira Code', ...defaultTheme.fontFamily.mono] }, minWidth: { - '72': '18rem', - '40': '10rem', - '12': '3rem', + 72: '18rem', + 40: '10rem', + 12: '3rem' }, extend: { colors: { - 'gray': colorGray, - 'primary': colorPrimary, - 'secondary': colorSecondary, - 'pink': colorPink, - 'yellow': colorYellow, - 'red': colorRed, + gray: colorGray, + primary: colorPrimary, + secondary: colorSecondary, + pink: colorPink, + yellow: colorYellow, + red: colorRed, 'code-editor': { - 'dark': '#252f3f', - 'dark-highlight': '#3e4d64', + dark: '#252f3f', + 'dark-highlight': '#3e4d64' }, - 'dark': '#1B1130', + dark: '#1B1130', 'cool-gray': '#9C96A8', - 'hub': '#252f3f', - 'slack': '#371038', + hub: '#252f3f', + slack: '#371038', 'mac-window': { - 'close': '#ff5f56', - 'minimize': '#ffbd2e', - 'maximize': '#28c93f', - }, + close: '#ff5f56', + minimize: '#ffbd2e', + maximize: '#28c93f' + } }, scale: { - '25': '.25', + 25: '.25' }, padding: { '2ch': '2ch', @@ -145,56 +142,59 @@ module.exports = { '8ch': '8ch', '10ch': '10ch', '12ch': '12ch', - '14ch': '14ch', + '14ch': '14ch' }, width: { - 'fit': 'fit-content' + fit: 'fit-content' }, height: { - '88': '22rem', - '100': '25rem', - '104': '26rem', - '108': '27rem', - '112': '28rem', - '116': '29rem', - '120': '30rem', - 'half-screen': '50vh', + 88: '22rem', + 100: '25rem', + 104: '26rem', + 108: '27rem', + 112: '28rem', + 116: '29rem', + 120: '30rem', + 'half-screen': '50vh' }, maxWidth: { '(screen-16)': 'calc(100vw - 16rem)', '(screen-34)': 'calc(100vw - 34rem)', - '64': '16rem', - '164': '41rem', - '172': '43rem', - '184': '46rem', + 64: '16rem', + 164: '41rem', + 172: '43rem', + 184: '46rem' }, minHeight: { - '108': '27rem', + 108: '27rem' }, maxHeight: { '(screen-16)': 'calc(100vh - 4rem)', - '108': '27rem', + 108: '27rem', '(screen-14)': 'calc(100vh - 81px)', - '120': '37rem' + 120: '37rem' + }, + gridTemplateColumns: { + 'with-sidebar': 'minmax(50px, 5%) 1fr' }, margin: { - '36': '9rem' + 36: '9rem' }, borderRadius: { - 'xl': '1rem', + xl: '1rem' }, letterSpacing: { heading: '-0.03em', body: '-0.01em' }, zIndex: { - '60': 60, + 60: 60 }, rotate: { '-15': '-7deg' }, fontSize: { - 'xxs': ['0.6rem', '0.6rem'], + xxs: ['0.6rem', '0.6rem'], 'heading-xs': ['16px', '1.375'], 'heading-sm': ['20px', '1.375'], 'heading-md': ['24px', '1.375'], @@ -203,7 +203,7 @@ module.exports = { 'body-sm': ['14px', '1.625'], 'body-md': ['16px', '1.625'], 'body-lg': ['18px', '1.625'] - }, + } } }, plugins: [ @@ -214,26 +214,26 @@ module.exports = { plugin(({ addUtilities }) => { addUtilities({ '.hljs-asyncapi-file': { - 'color': colors.yellow[200], + color: colors.yellow[200] }, '.hljs-generator-template': { - 'color': colors.teal[400], + color: colors.teal[400] }, '.hljs-generator-param': { - 'color': colors.pink[400], + color: colors.pink[400] }, '.font-ligatures-contextual': { - 'font-variant-ligatures': 'contextual', + 'font-variant-ligatures': 'contextual' }, '.scroll-none': { 'scrollbar-width': 'none', - '-ms-overflow-style': 'none', + '-ms-overflow-style': 'none' }, '.scroll-none::-webkit-scrollbar': { - 'display': 'none', - 'scroll-behavior': 'smooth', + display: 'none', + 'scroll-behavior': 'smooth' } - }) + }); }) - ], -} + ] +}; From d32579c9c9df255c704ae9db54a581b84428645e Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:59:24 +0800 Subject: [PATCH 4/7] styles(website): make the sidebar playground more smaller in big screen --- modelina-website/tailwind.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modelina-website/tailwind.config.js b/modelina-website/tailwind.config.js index 310e6f28d2..017aa7d3d4 100644 --- a/modelina-website/tailwind.config.js +++ b/modelina-website/tailwind.config.js @@ -175,7 +175,7 @@ module.exports = { 120: '37rem' }, gridTemplateColumns: { - 'with-sidebar': 'minmax(50px, 5%) 1fr' + 'with-sidebar': 'minmax(50px, 3%) 1fr' }, margin: { 36: '9rem' From a82f36dd44ee792b8336840b684cf9131659eb4c Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:31:06 +0800 Subject: [PATCH 5/7] styles(website): make tailwind css playground more clean and remove unnecesary code --- .../src/components/playground/Content.tsx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx index 57aaa3c2db..c89838c184 100644 --- a/modelina-website/src/components/playground/Content.tsx +++ b/modelina-website/src/components/playground/Content.tsx @@ -52,7 +52,7 @@ export const Content: FunctionComponent = ({
= ({
= ({
{error ? ( From 47ee5e03fa2e1ffa830b8168f88fd27fe4bd9ec0 Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:35:58 +0800 Subject: [PATCH 6/7] styles(website): take space from output code editor and give to input code editor --- .../src/components/playground/Content.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx index c89838c184..1f05afe8e6 100644 --- a/modelina-website/src/components/playground/Content.tsx +++ b/modelina-website/src/components/playground/Content.tsx @@ -61,7 +61,7 @@ export const Content: FunctionComponent = ({
@@ -69,7 +69,7 @@ export const Content: FunctionComponent = ({
= ({
{error ? ( From c5330a74d6f9d102bdc67606c1e5839864083d86 Mon Sep 17 00:00:00 2001 From: jerensl <54782057+jerensl@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:54:47 +0800 Subject: [PATCH 7/7] styles(website): remove unnecessary overflow-visibile --- modelina-website/src/components/playground/Content.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx index 1f05afe8e6..465ed7bba3 100644 --- a/modelina-website/src/components/playground/Content.tsx +++ b/modelina-website/src/components/playground/Content.tsx @@ -49,7 +49,7 @@ export const Content: FunctionComponent = ({ ); return ( -
+