feat(@lexical/devtools): Added styling to devtools panel (#5925) (#5929)

This commit is contained in:
Vlad Fedosov
2024-04-22 11:11:18 -04:00
committed by GitHub
parent 8b893c80f7
commit aa7c469e94
6 changed files with 3050 additions and 72 deletions

2958
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,9 +22,13 @@
"postinstall": "wxt prepare"
},
"dependencies": {
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@webext-pegasus/rpc": "^0.0.4",
"@webext-pegasus/store-zustand": "^0.0.4",
"@webext-pegasus/transport": "^0.0.4",
"framer-motion": "^11.1.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"zustand": "^4.5.1"

View File

@ -8,6 +8,7 @@
import type {IInjectedPegasusService} from '../entrypoints/injected/InjectedPegasusService';
import {Button} from '@chakra-ui/react';
import {getRPCService} from '@webext-pegasus/rpc';
import * as React from 'react';
import {useState} from 'react';
@ -38,9 +39,13 @@ function EditorsRefreshCTA({tabID, setErrorMessage}: Props) {
};
return (
<button onClick={handleRefreshClick} disabled={isRefreshing}>
<Button
colorScheme="gray"
size="xs"
onClick={handleRefreshClick}
disabled={isRefreshing}>
{isRefreshing ? 'Refreshing...' : 'Refresh'}
</button>
</Button>
);
}

View File

@ -11,6 +11,18 @@ import type {EditorState} from 'lexical';
import './App.css';
import {
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Alert,
AlertIcon,
Box,
Flex,
Spacer,
} from '@chakra-ui/react';
import {TreeView} from '@lexical/devtools-core';
import {getRPCService} from '@webext-pegasus/rpc';
import * as React from 'react';
@ -44,61 +56,90 @@ function App({tabID}: Props) {
return (
<>
<div>
<a href="https://lexical.dev" target="_blank">
<img
src={lexicalLogo}
className="logo"
width={150}
alt="Lexical logo"
/>
</a>
</div>
<Flex>
<Box p="2">
<a href="https://lexical.dev" target="_blank">
<img
src={lexicalLogo}
className="logo"
width={178}
height={40}
alt="Lexical logo"
/>
</a>
</Box>
<Spacer />
<Box p="4">
{states === undefined ? (
<span>Loading...</span>
) : (
<span>
Found <b>{lexicalCount}</b> editor
{lexicalCount > 1 || lexicalCount === 0 ? 's' : ''} on the page.
</span>
)}
</Box>
<Box p="4">
<EditorsRefreshCTA tabID={tabID} setErrorMessage={setErrorMessage} />
</Box>
</Flex>
{errorMessage !== '' ? (
<div className="card error">{errorMessage}</div>
) : null}
<div className="card">
{states === undefined ? (
<span>Loading...</span>
<Box mt={5}>
{lexicalCount > 0 ? (
<Accordion defaultIndex={[0]} allowMultiple={true}>
{Object.entries(states).map(([key, state]) => (
<AccordionItem key={key}>
<h2>
<AccordionButton>
<Box as="span" flex="1" textAlign="left">
ID: {key}
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<TreeView
viewClassName="tree-view-output"
treeTypeButtonClassName="debug-treetype-button"
timeTravelPanelClassName="debug-timetravel-panel"
timeTravelButtonClassName="debug-timetravel-button"
timeTravelPanelSliderClassName="debug-timetravel-panel-slider"
timeTravelPanelButtonClassName="debug-timetravel-panel-button"
setEditorReadOnly={(isReadonly) =>
injectedPegasusService
.setEditorReadOnly(key, isReadonly)
.catch((e) => setErrorMessage(e.stack))
}
editorState={state as EditorState}
setEditorState={(editorState) =>
injectedPegasusService
.setEditorState(
key,
editorState as SerializedRawEditorState,
)
.catch((e) => setErrorMessage(e.stack))
}
generateContent={(exportDOM) =>
injectedPegasusService.generateTreeViewContent(
key,
exportDOM,
)
}
/>
</AccordionPanel>
</AccordionItem>
))}
</Accordion>
) : (
<span>
Found <b>{lexicalCount}</b> editor{lexicalCount > 1 ? 's' : ''} on
the page.
</span>
<Alert status="info">
<AlertIcon />
No Lexical editor found on the page.
</Alert>
)}
<p>
<EditorsRefreshCTA tabID={tabID} setErrorMessage={setErrorMessage} />
</p>
</div>
{Object.entries(states).map(([key, state]) => (
<div key={key}>
<b>ID: {key}</b>
<br />
<TreeView
viewClassName="tree-view-output"
treeTypeButtonClassName="debug-treetype-button"
timeTravelPanelClassName="debug-timetravel-panel"
timeTravelButtonClassName="debug-timetravel-button"
timeTravelPanelSliderClassName="debug-timetravel-panel-slider"
timeTravelPanelButtonClassName="debug-timetravel-panel-button"
setEditorReadOnly={(isReadonly) =>
injectedPegasusService
.setEditorReadOnly(key, isReadonly)
.catch((e) => setErrorMessage(e.stack))
}
editorState={state as EditorState}
setEditorState={(editorState) =>
injectedPegasusService
.setEditorState(key, editorState as SerializedRawEditorState)
.catch((e) => setErrorMessage(e.stack))
}
generateContent={(exportDOM) =>
injectedPegasusService.generateTreeViewContent(key, exportDOM)
}
/>
<hr />
</div>
))}
</Box>
</>
);
}

View File

@ -6,6 +6,7 @@
*
*/
import {ChakraProvider} from '@chakra-ui/react';
import {initPegasusTransport} from '@webext-pegasus/transport/devtools';
import React from 'react';
import ReactDOM from 'react-dom/client';
@ -19,7 +20,9 @@ initPegasusTransport();
extensionStoreReady().then(() =>
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App tabID={tabID} />
<ChakraProvider>
<App tabID={tabID} />
</ChakraProvider>
</React.StrictMode>,
),
);

View File

@ -9,6 +9,7 @@ import type {ITabIDService} from '../background/getTabIDService';
import './style.css';
import {ChakraProvider} from '@chakra-ui/react';
import {getRPCService} from '@webext-pegasus/rpc';
import {initPegasusTransport} from '@webext-pegasus/transport/popup';
import React from 'react';
@ -24,7 +25,9 @@ getRPCService<ITabIDService>('getTabID', 'background')()
extensionStoreReady().then(() =>
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App tabID={tabID} />
<ChakraProvider>
<App tabID={tabID} />
</ChakraProvider>
</React.StrictMode>,
),
),