mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-21 17:16:42 +03:00
[inspector-monitor] Replace jss with Emotion (#1560)
* Setup Emotion * Fix setup * Start conversion * actionList * actionListHeader * actionListRows * actionListHeaderSelector * actionListItem * actionListItemTime * actionListItemSelector * actionListItemName * actionListHeaderSearch * actionListHeaderWrapper * actionPreview * Remaining css * Format * Propagate Emotion dependencies * Fix tests * Remove styling prop * Remove jss * Remove themeState * Use color map as Emotion theme * Rework theme resolution * Inline CSS * Remove usage of className * Fix warning * Create large-spoons-yell.md
This commit is contained in:
parent
b54bc75cbb
commit
158ba2ce12
8
.changeset/large-spoons-yell.md
Normal file
8
.changeset/large-spoons-yell.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
'@redux-devtools/app': major
|
||||
'@redux-devtools/inspector-monitor-test-tab': major
|
||||
'@redux-devtools/inspector-monitor-trace-tab': major
|
||||
'@redux-devtools/inspector-monitor': major
|
||||
---
|
||||
|
||||
Replace jss with Emotion in inspector-monitor. `@emotion/react` is now a required peer dependency.
|
|
@ -24,6 +24,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/app": "^4.0.1",
|
||||
"@redux-devtools/core": "^3.13.2",
|
||||
"@redux-devtools/instrument": "^2.1.0",
|
||||
|
|
|
@ -40,16 +40,14 @@ describe('Chrome extension', function () {
|
|||
it("should contain inspector monitor's component", async () => {
|
||||
await delay(1000);
|
||||
const val = await driver
|
||||
.findElement(webdriver.By.xpath('//div[contains(@class, "inspector-")]'))
|
||||
.findElement(webdriver.By.xpath('//div[@data-testid="inspector"]'))
|
||||
.getText();
|
||||
expect(val).toBeDefined();
|
||||
});
|
||||
|
||||
it('should contain an empty actions list', async () => {
|
||||
const val = await driver
|
||||
.findElement(
|
||||
webdriver.By.xpath('//div[contains(@class, "actionListRows-")]'),
|
||||
)
|
||||
.findElement(webdriver.By.xpath('//div[@data-testid="actionListRows"]'))
|
||||
.getText();
|
||||
expect(val).toBe('');
|
||||
});
|
||||
|
@ -72,9 +70,7 @@ describe('Chrome extension', function () {
|
|||
|
||||
const result = await driver.wait(
|
||||
driver
|
||||
.findElement(
|
||||
webdriver.By.xpath('//div[contains(@class, "actionListRows-")]'),
|
||||
)
|
||||
.findElement(webdriver.By.xpath('//div[@data-testid="actionListRows"]'))
|
||||
.getText()
|
||||
.then((val) => {
|
||||
return actionsPattern.test(val);
|
||||
|
|
|
@ -89,7 +89,7 @@ describe('DevTools panel for Electron', function () {
|
|||
it('should contain INIT action', async () => {
|
||||
const element = await driver.wait(
|
||||
webdriver.until.elementLocated(
|
||||
webdriver.By.xpath('//div[contains(@class, "actionListRows-")]'),
|
||||
webdriver.By.xpath('//div[@data-testid="actionListRows"]'),
|
||||
),
|
||||
5000,
|
||||
'Element not found',
|
||||
|
@ -100,7 +100,7 @@ describe('DevTools panel for Electron', function () {
|
|||
|
||||
it("should contain Inspector monitor's component", async () => {
|
||||
const val = await driver
|
||||
.findElement(webdriver.By.xpath('//div[contains(@class, "inspector-")]'))
|
||||
.findElement(webdriver.By.xpath('//div[@data-testid="inspector"]'))
|
||||
.getText();
|
||||
expect(val).toBeDefined();
|
||||
});
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
"@babel/preset-env": "^7.23.5",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.23.3",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@rjsf/core": "^4.2.3",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
|
@ -115,6 +116,7 @@
|
|||
"webpack-dev-server": "^4.15.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"@types/styled-components": "^5.1.34",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@apollo/server": "^4.9.5",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/app": "^4.0.0",
|
||||
"@types/react": "^18.2.43",
|
||||
"body-parser": "^1.20.2",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/core": "^3.13.2",
|
||||
"@redux-devtools/dock-monitor": "^3.0.2",
|
||||
"@redux-devtools/inspector-monitor": "^4.0.1",
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import React from 'react';
|
||||
import { createDevTools } from '@redux-devtools/core';
|
||||
import {
|
||||
InspectorMonitor,
|
||||
base16Themes,
|
||||
Tab,
|
||||
} from '@redux-devtools/inspector-monitor';
|
||||
import { InspectorMonitor, Tab } from '@redux-devtools/inspector-monitor';
|
||||
import type { Base16ThemeName } from '@redux-devtools/inspector-monitor';
|
||||
import { DockMonitor } from '@redux-devtools/dock-monitor';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import getOptions from './getOptions';
|
||||
|
@ -20,7 +17,7 @@ export const getDevTools = (location: { search: string }) =>
|
|||
changeMonitorKey="ctrl-m"
|
||||
>
|
||||
<InspectorMonitor
|
||||
theme={getOptions(location).theme as keyof typeof base16Themes}
|
||||
theme={getOptions(location).theme as Base16ThemeName}
|
||||
invertTheme={!getOptions(location).dark}
|
||||
supportImmutable={getOptions(location).supportImmutable}
|
||||
tabs={(defaultTabs) =>
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
"@babel/preset-env": "^7.23.5",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.23.3",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/core": "^3.14.0",
|
||||
"@redux-devtools/inspector-monitor": "^4.1.0",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
|
@ -85,6 +86,7 @@
|
|||
"typescript": "~5.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@redux-devtools/inspector-monitor": "^4.0.0",
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"@types/styled-components": "^5.1.34",
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"@babel/preset-env": "^7.23.5",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.23.3",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/core": "^3.14.0",
|
||||
"@redux-devtools/inspector-monitor": "^4.1.0",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
|
@ -76,6 +77,7 @@
|
|||
"typescript": "~5.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@redux-devtools/inspector-monitor": "^4.0.0",
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
|
|
|
@ -8,6 +8,9 @@ module.exports = {
|
|||
tsconfigRootDir: __dirname,
|
||||
project: true,
|
||||
},
|
||||
rules: {
|
||||
'react/no-unknown-property': ['error', { ignore: ['css'] }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['demo/**/*.ts', 'demo/**/*.tsx'],
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
"presets": [
|
||||
["@babel/preset-env", { "targets": "defaults", "modules": false }],
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-typescript"
|
||||
"@babel/preset-typescript",
|
||||
"@emotion/babel-preset-css-prop"
|
||||
],
|
||||
"plugins": ["@babel/plugin-transform-runtime"]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
"presets": [
|
||||
["@babel/preset-env", { "targets": "defaults" }],
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-typescript"
|
||||
"@babel/preset-typescript",
|
||||
"@emotion/babel-preset-css-prop"
|
||||
],
|
||||
"plugins": ["@babel/plugin-transform-runtime"]
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/core": "^3.13.0",
|
||||
"@redux-devtools/dock-monitor": "^3.0.0",
|
||||
"@redux-devtools/inspector-monitor": "^4.0.0",
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import React from 'react';
|
||||
import { createDevTools } from '@redux-devtools/core';
|
||||
import { DockMonitor } from '@redux-devtools/dock-monitor';
|
||||
import {
|
||||
InspectorMonitor,
|
||||
base16Themes,
|
||||
} from '@redux-devtools/inspector-monitor';
|
||||
import { InspectorMonitor } from '@redux-devtools/inspector-monitor';
|
||||
import type { Base16ThemeName } from '@redux-devtools/inspector-monitor';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import getOptions from './getOptions';
|
||||
|
||||
|
@ -32,7 +30,7 @@ export const getDevTools = (location: { search: string }) =>
|
|||
changeMonitorKey="ctrl-m"
|
||||
>
|
||||
<InspectorMonitor
|
||||
theme={getOptions(location).theme as keyof typeof base16Themes}
|
||||
theme={getOptions(location).theme as Base16ThemeName}
|
||||
invertTheme={!getOptions(location).dark}
|
||||
supportImmutable={getOptions(location).supportImmutable}
|
||||
tabs={(defaultTabs) => [
|
||||
|
|
|
@ -47,8 +47,6 @@
|
|||
"immutable": "^4.3.4",
|
||||
"javascript-stringify": "^2.1.0",
|
||||
"jsondiffpatch": "^0.5.0",
|
||||
"jss": "^10.10.0",
|
||||
"jss-preset-default": "^10.10.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"react-base16-styling": "^0.9.1",
|
||||
"react-json-tree": "^0.18.0",
|
||||
|
@ -62,6 +60,8 @@
|
|||
"@babel/preset-env": "^7.23.5",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@babel/preset-typescript": "^7.23.3",
|
||||
"@emotion/babel-preset-css-prop": "^11.11.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@redux-devtools/core": "^3.14.0",
|
||||
"@types/dateformat": "^5.0.2",
|
||||
"@types/hex-rgba": "^1.0.3",
|
||||
|
@ -80,6 +80,7 @@
|
|||
"typescript": "~5.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@redux-devtools/core": "^3.0.0",
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { ReactNode, useCallback, useLayoutEffect, useRef } from 'react';
|
||||
import { Action } from 'redux';
|
||||
import { PerformAction } from '@redux-devtools/core';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import {
|
||||
closestCenter,
|
||||
DndContext,
|
||||
|
@ -51,7 +50,6 @@ interface Props<A extends Action<string>> {
|
|||
draggableActions: boolean;
|
||||
hideMainButtons: boolean | undefined;
|
||||
hideActionButtons: boolean | undefined;
|
||||
styling: StylingFunction;
|
||||
onSearch: (value: string) => void;
|
||||
onSelect: (e: React.MouseEvent<HTMLDivElement>, actionId: number) => void;
|
||||
onToggleAction: (actionId: number) => void;
|
||||
|
@ -64,7 +62,6 @@ interface Props<A extends Action<string>> {
|
|||
}
|
||||
|
||||
export default function ActionList<A extends Action<string>>({
|
||||
styling,
|
||||
actions,
|
||||
actionIds,
|
||||
isWideLayout,
|
||||
|
@ -150,13 +147,29 @@ export default function ActionList<A extends Action<string>>({
|
|||
<div
|
||||
key="actionList"
|
||||
data-testid="actionList"
|
||||
{...styling(
|
||||
['actionList', isWideLayout && 'actionListWide'],
|
||||
isWideLayout,
|
||||
)}
|
||||
css={[
|
||||
(theme) => ({
|
||||
flexBasis: '40%',
|
||||
flexShrink: 0,
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto',
|
||||
borderBottomWidth: '3px',
|
||||
borderBottomStyle: 'double',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
backgroundColor: theme.BACKGROUND_COLOR,
|
||||
borderColor: theme.LIST_BORDER_COLOR,
|
||||
}),
|
||||
isWideLayout && {
|
||||
flexBasis: '40%',
|
||||
borderBottom: 'none',
|
||||
borderRightWidth: '3px',
|
||||
borderRightStyle: 'double',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<ActionListHeader
|
||||
styling={styling}
|
||||
onSearch={onSearch}
|
||||
onCommit={onCommit}
|
||||
onSweep={onSweep}
|
||||
|
@ -167,7 +180,7 @@ export default function ActionList<A extends Action<string>>({
|
|||
/>
|
||||
<div
|
||||
data-testid="actionListRows"
|
||||
{...styling('actionListRows')}
|
||||
css={{ overflow: 'auto' }}
|
||||
ref={setNodeRef}
|
||||
>
|
||||
<DndContext
|
||||
|
@ -183,7 +196,6 @@ export default function ActionList<A extends Action<string>>({
|
|||
{filteredActionIds.map((actionId) => (
|
||||
<SortableItem key={actionId} actionId={actionId}>
|
||||
<ActionListRow
|
||||
styling={styling}
|
||||
actionId={actionId}
|
||||
isInitAction={!actionId}
|
||||
isSelected={
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import React, { FunctionComponent } from 'react';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import RightSlider from './RightSlider';
|
||||
import {
|
||||
selectorButtonCss,
|
||||
selectorButtonSmallCss,
|
||||
} from './utils/selectorButtonStyles';
|
||||
|
||||
const getActiveButtons = (hasSkippedActions: boolean): ('Sweep' | 'Commit')[] =>
|
||||
[hasSkippedActions && 'Sweep', 'Commit'].filter(
|
||||
|
@ -8,7 +11,6 @@ const getActiveButtons = (hasSkippedActions: boolean): ('Sweep' | 'Commit')[] =>
|
|||
);
|
||||
|
||||
interface Props {
|
||||
styling: StylingFunction;
|
||||
onSearch: (value: string) => void;
|
||||
onCommit: () => void;
|
||||
onSweep: () => void;
|
||||
|
@ -19,7 +21,6 @@ interface Props {
|
|||
}
|
||||
|
||||
const ActionListHeader: FunctionComponent<Props> = ({
|
||||
styling,
|
||||
onSearch,
|
||||
hasSkippedActions,
|
||||
hasStagedActions,
|
||||
|
@ -28,17 +29,45 @@ const ActionListHeader: FunctionComponent<Props> = ({
|
|||
hideMainButtons,
|
||||
searchValue,
|
||||
}) => (
|
||||
<div {...styling('actionListHeader')}>
|
||||
<div
|
||||
css={(theme) => ({
|
||||
display: 'flex',
|
||||
flex: '0 0 auto',
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: '1px',
|
||||
borderBottomStyle: 'solid',
|
||||
|
||||
borderColor: theme.LIST_BORDER_COLOR,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
{...styling('actionListHeaderSearch')}
|
||||
css={(theme) => ({
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
width: '100%',
|
||||
padding: '5px 10px',
|
||||
fontSize: '1em',
|
||||
fontFamily: 'monaco, Consolas, "Lucida Console", monospace',
|
||||
|
||||
backgroundColor: theme.BACKGROUND_COLOR,
|
||||
color: theme.TEXT_COLOR,
|
||||
|
||||
'&::-webkit-input-placeholder': {
|
||||
color: theme.TEXT_PLACEHOLDER_COLOR,
|
||||
},
|
||||
|
||||
'&::-moz-placeholder': {
|
||||
color: theme.TEXT_PLACEHOLDER_COLOR,
|
||||
},
|
||||
})}
|
||||
onChange={(e) => onSearch(e.target.value)}
|
||||
placeholder="filter..."
|
||||
value={searchValue}
|
||||
/>
|
||||
{!hideMainButtons && (
|
||||
<div {...styling('actionListHeaderWrapper')}>
|
||||
<RightSlider shown={hasStagedActions} styling={styling}>
|
||||
<div {...styling('actionListHeaderSelector')}>
|
||||
<div css={{ position: 'relative', height: '20px' }}>
|
||||
<RightSlider shown={hasStagedActions}>
|
||||
<div css={{ display: 'inline-flex', marginRight: '10px' }}>
|
||||
{getActiveButtons(hasSkippedActions).map((btn) => (
|
||||
<div
|
||||
key={btn}
|
||||
|
@ -48,11 +77,7 @@ const ActionListHeader: FunctionComponent<Props> = ({
|
|||
Sweep: onSweep,
|
||||
})[btn]()
|
||||
}
|
||||
{...styling(
|
||||
['selectorButton', 'selectorButtonSmall'],
|
||||
false,
|
||||
true,
|
||||
)}
|
||||
css={[selectorButtonCss, selectorButtonSmallCss]}
|
||||
>
|
||||
{btn}
|
||||
</div>
|
||||
|
|
|
@ -2,17 +2,33 @@ import React, { MouseEvent, MouseEventHandler, PureComponent } from 'react';
|
|||
import dateformat from 'dateformat';
|
||||
import type { DebouncedFunc } from 'lodash';
|
||||
import debounce from 'lodash.debounce';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import { Action } from 'redux';
|
||||
import type { Interpolation, Theme } from '@emotion/react';
|
||||
import RightSlider from './RightSlider';
|
||||
import {
|
||||
selectorButtonCss,
|
||||
selectorButtonSelectedCss,
|
||||
selectorButtonSmallCss,
|
||||
} from './utils/selectorButtonStyles';
|
||||
|
||||
const BUTTON_SKIP = 'Skip';
|
||||
const BUTTON_JUMP = 'Jump';
|
||||
|
||||
type Button = typeof BUTTON_SKIP | typeof BUTTON_JUMP;
|
||||
|
||||
const actionListItemTimeCss: Interpolation<Theme> = (theme) => ({
|
||||
display: 'inline',
|
||||
padding: '4px 6px',
|
||||
borderRadius: '3px',
|
||||
fontSize: '0.8em',
|
||||
lineHeight: '1em',
|
||||
flexShrink: 0,
|
||||
|
||||
backgroundColor: theme.ACTION_TIME_BACK_COLOR,
|
||||
color: theme.ACTION_TIME_COLOR,
|
||||
});
|
||||
|
||||
interface Props<A extends Action<string>> {
|
||||
styling: StylingFunction;
|
||||
actionId: number;
|
||||
isInitAction: boolean;
|
||||
isSelected: boolean;
|
||||
|
@ -38,7 +54,6 @@ export default class ActionListRow<
|
|||
|
||||
render() {
|
||||
const {
|
||||
styling,
|
||||
isSelected,
|
||||
action,
|
||||
actionId,
|
||||
|
@ -74,28 +89,44 @@ export default class ActionListRow<
|
|||
onMouseDown={this.handleMouseDown}
|
||||
onMouseUp={this.handleMouseEnter}
|
||||
data-id={actionId}
|
||||
{...styling(
|
||||
[
|
||||
'actionListItem',
|
||||
isSelected && 'actionListItemSelected',
|
||||
isSkipped && 'actionListItemSkipped',
|
||||
isInFuture && 'actionListFromFuture',
|
||||
],
|
||||
isSelected,
|
||||
action,
|
||||
)}
|
||||
css={[
|
||||
(theme) => ({
|
||||
borderBottomWidth: '1px',
|
||||
borderBottomStyle: 'solid',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
padding: '5px 10px',
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
|
||||
borderBottomColor: theme.BORDER_COLOR,
|
||||
}),
|
||||
isSelected &&
|
||||
((theme) => ({
|
||||
backgroundColor: theme.SELECTED_BACKGROUND_COLOR,
|
||||
})),
|
||||
isSkipped &&
|
||||
((theme) => ({
|
||||
backgroundColor: theme.SKIPPED_BACKGROUND_COLOR,
|
||||
})),
|
||||
isInFuture && { opacity: '0.6' },
|
||||
]}
|
||||
>
|
||||
<div
|
||||
{...styling([
|
||||
'actionListItemName',
|
||||
isSkipped && 'actionListItemNameSkipped',
|
||||
])}
|
||||
css={[
|
||||
{
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
lineHeight: '20px',
|
||||
},
|
||||
isSkipped && { textDecoration: 'line-through', opacity: 0.3 },
|
||||
]}
|
||||
>
|
||||
{actionType}
|
||||
</div>
|
||||
{hideActionButtons ? (
|
||||
<RightSlider styling={styling} shown>
|
||||
<div {...styling('actionListItemTime')}>
|
||||
<RightSlider shown>
|
||||
<div css={actionListItemTimeCss}>
|
||||
{timeDelta === 0
|
||||
? '+00:00:00'
|
||||
: dateformat(
|
||||
|
@ -105,9 +136,9 @@ export default class ActionListRow<
|
|||
</div>
|
||||
</RightSlider>
|
||||
) : (
|
||||
<div {...styling('actionListItemButtons')}>
|
||||
<RightSlider styling={styling} shown={!showButtons} rotate>
|
||||
<div {...styling('actionListItemTime')}>
|
||||
<div css={{ position: 'relative', height: '20px', display: 'flex' }}>
|
||||
<RightSlider shown={!showButtons} rotate>
|
||||
<div css={actionListItemTimeCss}>
|
||||
{timeDelta === 0
|
||||
? '+00:00:00'
|
||||
: dateformat(
|
||||
|
@ -116,23 +147,20 @@ export default class ActionListRow<
|
|||
)}
|
||||
</div>
|
||||
</RightSlider>
|
||||
<RightSlider styling={styling} shown={showButtons} rotate>
|
||||
<div {...styling('actionListItemSelector')}>
|
||||
<RightSlider shown={showButtons} rotate>
|
||||
<div css={{ display: 'inline-flex' }}>
|
||||
{([BUTTON_JUMP, BUTTON_SKIP] as const).map(
|
||||
(btn) =>
|
||||
(!isInitAction || btn !== BUTTON_SKIP) && (
|
||||
<div
|
||||
key={btn}
|
||||
onClick={(e) => this.handleButtonClick(btn, e)}
|
||||
{...styling(
|
||||
[
|
||||
'selectorButton',
|
||||
isButtonSelected(btn) && 'selectorButtonSelected',
|
||||
'selectorButtonSmall',
|
||||
],
|
||||
isButtonSelected(btn),
|
||||
true,
|
||||
)}
|
||||
css={[
|
||||
selectorButtonCss,
|
||||
isButtonSelected(btn) && selectorButtonSelectedCss,
|
||||
selectorButtonSmallCss,
|
||||
]}
|
||||
data-isselectorbutton={true}
|
||||
>
|
||||
{btn}
|
||||
</div>
|
||||
|
@ -177,12 +205,7 @@ export default class ActionListRow<
|
|||
}, 100);
|
||||
|
||||
handleMouseDown = (e: MouseEvent<HTMLDivElement>) => {
|
||||
if (
|
||||
(e.target as unknown as { className: string[] }).className.indexOf(
|
||||
'selectorButton',
|
||||
) === 0
|
||||
)
|
||||
return;
|
||||
if ((e.target as HTMLElement).dataset.isselectorbutton) return;
|
||||
this.handleMouseLeave();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Base16Theme } from 'redux-devtools-themes';
|
||||
import { Action } from 'redux';
|
||||
import type { StylingFunction } from 'react-base16-styling';
|
||||
import type { LabelRenderer } from 'react-json-tree';
|
||||
import { PerformAction } from '@redux-devtools/core';
|
||||
import { Delta } from 'jsondiffpatch';
|
||||
|
@ -13,7 +12,6 @@ import ActionTab from './tabs/ActionTab';
|
|||
|
||||
export interface TabComponentProps<S, A extends Action<string>> {
|
||||
labelRenderer: LabelRenderer;
|
||||
styling: StylingFunction;
|
||||
computedStates: { state: S; error?: string }[];
|
||||
actions: { [actionId: number]: PerformAction<A> };
|
||||
selectedActionId: number | null;
|
||||
|
@ -68,7 +66,6 @@ interface Props<S, A extends Action<string>> {
|
|||
dataTypeKey: string | symbol | undefined;
|
||||
monitorState: DevtoolsInspectorState;
|
||||
updateMonitorState: (monitorState: Partial<DevtoolsInspectorState>) => void;
|
||||
styling: StylingFunction;
|
||||
onInspectPath: (path: (string | number)[]) => void;
|
||||
inspectedPath: (string | number)[];
|
||||
onSelectTab: (tabName: string) => void;
|
||||
|
@ -85,7 +82,6 @@ class ActionPreview<S, A extends Action<string>> extends Component<
|
|||
|
||||
render() {
|
||||
const {
|
||||
styling,
|
||||
delta,
|
||||
error,
|
||||
nextState,
|
||||
|
@ -121,17 +117,34 @@ class ActionPreview<S, A extends Action<string>> extends Component<
|
|||
renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName)!;
|
||||
|
||||
return (
|
||||
<div key="actionPreview" {...styling('actionPreview')}>
|
||||
<div
|
||||
key="actionPreview"
|
||||
css={(theme) => ({
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexGrow: 1,
|
||||
overflowY: 'hidden',
|
||||
|
||||
'& pre': {
|
||||
border: 'inherit',
|
||||
borderRadius: '3px',
|
||||
lineHeight: 'inherit',
|
||||
color: 'inherit',
|
||||
},
|
||||
|
||||
backgroundColor: theme.BACKGROUND_COLOR,
|
||||
})}
|
||||
>
|
||||
<ActionPreviewHeader
|
||||
tabs={renderedTabs as unknown as Tab<unknown, Action<string>>[]}
|
||||
{...{ styling, inspectedPath, onInspectPath, tabName, onSelectTab }}
|
||||
{...{ inspectedPath, onInspectPath, tabName, onSelectTab }}
|
||||
/>
|
||||
{!error && (
|
||||
<div key="actionPreviewContent" {...styling('actionPreviewContent')}>
|
||||
<div key="actionPreviewContent" css={{ flex: 1, overflowY: 'auto' }}>
|
||||
<TabComponent
|
||||
labelRenderer={this.labelRenderer}
|
||||
{...{
|
||||
styling,
|
||||
computedStates,
|
||||
actions,
|
||||
selectedActionId,
|
||||
|
@ -151,19 +164,40 @@ class ActionPreview<S, A extends Action<string>> extends Component<
|
|||
/>
|
||||
</div>
|
||||
)}
|
||||
{error && <div {...styling('stateError')}>{error}</div>}
|
||||
{error && (
|
||||
<div
|
||||
css={(theme) => ({
|
||||
padding: '10px',
|
||||
marginLeft: '14px',
|
||||
fontWeight: 'bold',
|
||||
|
||||
color: theme.ERROR_COLOR,
|
||||
})}
|
||||
>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
labelRenderer: LabelRenderer = ([key, ...rest], nodeType, expanded) => {
|
||||
const { styling, onInspectPath, inspectedPath } = this.props;
|
||||
const { onInspectPath, inspectedPath } = this.props;
|
||||
|
||||
return (
|
||||
<span>
|
||||
<span {...styling('treeItemKey')}>{key}</span>
|
||||
<span>{key}</span>
|
||||
<span
|
||||
{...styling('treeItemPin')}
|
||||
css={(theme) => ({
|
||||
fontSize: '0.7em',
|
||||
paddingLeft: '5px',
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
|
||||
color: theme.PIN_COLOR,
|
||||
})}
|
||||
onClick={() =>
|
||||
onInspectPath([
|
||||
...inspectedPath.slice(0, inspectedPath.length - 1),
|
||||
|
|
|
@ -1,11 +1,30 @@
|
|||
import React, { FunctionComponent } from 'react';
|
||||
import { Action } from 'redux';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import { css } from '@emotion/react';
|
||||
import type { Interpolation, Theme } from '@emotion/react';
|
||||
import { Tab } from './ActionPreview';
|
||||
import {
|
||||
selectorButtonCss,
|
||||
selectorButtonSelectedCss,
|
||||
} from './utils/selectorButtonStyles';
|
||||
|
||||
const inspectedPathKeyCss = css({
|
||||
'&:not(:last-child):after': {
|
||||
content: '" > "',
|
||||
},
|
||||
});
|
||||
|
||||
const inspectedPathKeyLinkCss: Interpolation<Theme> = (theme) => ({
|
||||
cursor: 'pointer',
|
||||
color: theme.LINK_COLOR,
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
color: theme.LINK_HOVER_COLOR,
|
||||
},
|
||||
});
|
||||
|
||||
interface Props<S, A extends Action<string>> {
|
||||
tabs: Tab<S, A>[];
|
||||
styling: StylingFunction;
|
||||
inspectedPath: (string | number)[];
|
||||
onInspectPath: (path: (string | number)[]) => void;
|
||||
tabName: string;
|
||||
|
@ -14,32 +33,38 @@ interface Props<S, A extends Action<string>> {
|
|||
|
||||
const ActionPreviewHeader: FunctionComponent<
|
||||
Props<unknown, Action<string>>
|
||||
> = ({ styling, inspectedPath, onInspectPath, tabName, onSelectTab, tabs }) => (
|
||||
<div key="previewHeader" {...styling('previewHeader')}>
|
||||
<div {...styling('tabSelector')}>
|
||||
> = ({ inspectedPath, onInspectPath, tabName, onSelectTab, tabs }) => (
|
||||
<div
|
||||
key="previewHeader"
|
||||
css={(theme) => ({
|
||||
flex: '0 0 30px',
|
||||
padding: '5px 10px',
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: '1px',
|
||||
borderBottomStyle: 'solid',
|
||||
|
||||
backgroundColor: theme.HEADER_BACKGROUND_COLOR,
|
||||
borderBottomColor: theme.HEADER_BORDER_COLOR,
|
||||
})}
|
||||
>
|
||||
<div css={{ position: 'relative', display: 'inline-flex', float: 'right' }}>
|
||||
{tabs.map((tab) => (
|
||||
<div
|
||||
onClick={() => onSelectTab(tab.name)}
|
||||
key={tab.name}
|
||||
{...styling(
|
||||
[
|
||||
'selectorButton',
|
||||
tab.name === tabName && 'selectorButtonSelected',
|
||||
],
|
||||
tab.name === tabName,
|
||||
)}
|
||||
css={[
|
||||
selectorButtonCss,
|
||||
tab.name === tabName && selectorButtonSelectedCss,
|
||||
]}
|
||||
>
|
||||
{tab.name}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div {...styling('inspectedPath')}>
|
||||
<div css={{ padding: '6px 0' }}>
|
||||
{inspectedPath.length ? (
|
||||
<span {...styling('inspectedPathKey')}>
|
||||
<a
|
||||
onClick={() => onInspectPath([])}
|
||||
{...styling('inspectedPathKeyLink')}
|
||||
>
|
||||
<span css={inspectedPathKeyCss}>
|
||||
<a onClick={() => onInspectPath([])} css={inspectedPathKeyLinkCss}>
|
||||
{tabName}
|
||||
</a>
|
||||
</span>
|
||||
|
@ -50,10 +75,10 @@ const ActionPreviewHeader: FunctionComponent<
|
|||
idx === inspectedPath.length - 1 ? (
|
||||
<span key={key}>{key}</span>
|
||||
) : (
|
||||
<span key={key} {...styling('inspectedPathKey')}>
|
||||
<span key={key} css={inspectedPathKeyCss}>
|
||||
<a
|
||||
onClick={() => onInspectPath(inspectedPath.slice(0, idx + 1))}
|
||||
{...styling('inspectedPathKeyLink')}
|
||||
css={inspectedPathKeyLinkCss}
|
||||
>
|
||||
{key}
|
||||
</a>
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import { Base16Theme } from 'redux-devtools-themes';
|
||||
import {
|
||||
getBase16Theme,
|
||||
invertTheme,
|
||||
StylingFunction,
|
||||
} from 'react-base16-styling';
|
||||
import {
|
||||
ActionCreators,
|
||||
LiftedAction,
|
||||
|
@ -13,9 +8,10 @@ import {
|
|||
import { Action, Dispatch } from 'redux';
|
||||
import { Delta, DiffContext } from 'jsondiffpatch';
|
||||
import {
|
||||
createStylingFromTheme,
|
||||
base16Themes,
|
||||
} from './utils/createStylingFromTheme';
|
||||
createInspectorMonitorThemeFromBase16Theme,
|
||||
resolveBase16Theme,
|
||||
} from './utils/themes';
|
||||
import type { Base16ThemeName } from './utils/themes';
|
||||
import ActionList from './ActionList';
|
||||
import ActionPreview, { Tab } from './ActionPreview';
|
||||
import getInspectedState from './utils/getInspectedState';
|
||||
|
@ -26,6 +22,7 @@ import {
|
|||
reducer,
|
||||
updateMonitorState,
|
||||
} from './redux';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
|
||||
const {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
|
@ -125,17 +122,6 @@ function createIntermediateState<S, A extends Action<string>>(
|
|||
};
|
||||
}
|
||||
|
||||
function createThemeState<S, A extends Action<string>>(
|
||||
props: DevtoolsInspectorProps<S, A>,
|
||||
) {
|
||||
const base16Theme = getBase16Theme(props.theme, base16Themes)!;
|
||||
|
||||
const theme = props.invertTheme ? invertTheme(props.theme) : props.theme;
|
||||
const styling = createStylingFromTheme(theme);
|
||||
|
||||
return { base16Theme, styling };
|
||||
}
|
||||
|
||||
export interface ExternalProps<S, A extends Action<string>> {
|
||||
dispatch: Dispatch<
|
||||
DevtoolsInspectorAction | LiftedAction<S, A, DevtoolsInspectorState>
|
||||
|
@ -143,7 +129,7 @@ export interface ExternalProps<S, A extends Action<string>> {
|
|||
preserveScrollTop?: boolean;
|
||||
draggableActions: boolean;
|
||||
select: (state: S) => unknown;
|
||||
theme: keyof typeof base16Themes | Base16Theme;
|
||||
theme: Base16ThemeName | Base16Theme;
|
||||
supportImmutable: boolean;
|
||||
diffObjectHash?: (item: unknown, index: number) => string;
|
||||
diffPropertyFilter?: (name: string, context: DiffContext) => boolean;
|
||||
|
@ -160,7 +146,7 @@ interface DefaultProps {
|
|||
select: (state: unknown) => unknown;
|
||||
supportImmutable: boolean;
|
||||
draggableActions: boolean;
|
||||
theme: keyof typeof base16Themes;
|
||||
theme: Base16ThemeName;
|
||||
invertTheme: boolean;
|
||||
}
|
||||
|
||||
|
@ -172,7 +158,7 @@ export interface DevtoolsInspectorProps<S, A extends Action<string>>
|
|||
preserveScrollTop?: boolean;
|
||||
draggableActions: boolean;
|
||||
select: (state: S) => unknown;
|
||||
theme: keyof typeof base16Themes | Base16Theme;
|
||||
theme: Base16ThemeName | Base16Theme;
|
||||
supportImmutable: boolean;
|
||||
diffObjectHash?: (item: unknown, index: number) => string;
|
||||
diffPropertyFilter?: (name: string, context: DiffContext) => boolean;
|
||||
|
@ -191,7 +177,6 @@ interface State<S, A extends Action<string>> {
|
|||
action: A;
|
||||
error: string | undefined;
|
||||
isWideLayout: boolean;
|
||||
themeState: { base16Theme: Base16Theme; styling: StylingFunction };
|
||||
}
|
||||
|
||||
class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
|
||||
|
@ -201,7 +186,6 @@ class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
|
|||
state: State<S, A> = {
|
||||
...createIntermediateState(this.props, this.props.monitorState),
|
||||
isWideLayout: false,
|
||||
themeState: createThemeState(this.props),
|
||||
};
|
||||
|
||||
static update = reducer;
|
||||
|
@ -257,13 +241,6 @@ class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
|
|||
) {
|
||||
this.setState(createIntermediateState(nextProps, nextMonitorState));
|
||||
}
|
||||
|
||||
if (
|
||||
this.props.theme !== nextProps.theme ||
|
||||
this.props.invertTheme !== nextProps.invertTheme
|
||||
) {
|
||||
this.setState({ themeState: createThemeState(nextProps) });
|
||||
}
|
||||
}
|
||||
|
||||
inspectorCreateRef: React.RefCallback<HTMLDivElement> = (node) => {
|
||||
|
@ -277,6 +254,7 @@ class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
|
|||
computedStates,
|
||||
draggableActions,
|
||||
tabs,
|
||||
theme,
|
||||
invertTheme,
|
||||
skippedActionIds,
|
||||
currentStateIndex,
|
||||
|
@ -291,73 +269,88 @@ class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
|
|||
monitorState;
|
||||
const inspectedPathType =
|
||||
tabName === 'Action' ? 'inspectedActionPath' : 'inspectedStatePath';
|
||||
const { themeState, isWideLayout, action, nextState, delta, error } =
|
||||
this.state;
|
||||
const { base16Theme, styling } = themeState;
|
||||
const { isWideLayout, action, nextState, delta, error } = this.state;
|
||||
|
||||
const base16Theme = resolveBase16Theme(theme)!;
|
||||
const inspectorMonitorTheme = createInspectorMonitorThemeFromBase16Theme(
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
);
|
||||
return (
|
||||
<div
|
||||
key="inspector"
|
||||
data-testid="inspector"
|
||||
ref={this.inspectorCreateRef}
|
||||
{...styling(
|
||||
['inspector', isWideLayout && 'inspectorWide'],
|
||||
isWideLayout,
|
||||
)}
|
||||
>
|
||||
<ActionList
|
||||
{...{
|
||||
actions,
|
||||
actionIds,
|
||||
isWideLayout,
|
||||
searchValue,
|
||||
selectedActionId,
|
||||
startActionId,
|
||||
skippedActionIds,
|
||||
draggableActions,
|
||||
hideMainButtons,
|
||||
hideActionButtons,
|
||||
styling,
|
||||
}}
|
||||
onSearch={this.handleSearch}
|
||||
onSelect={this.handleSelectAction}
|
||||
onToggleAction={this.handleToggleAction}
|
||||
onJumpToState={this.handleJumpToState}
|
||||
onCommit={this.handleCommit}
|
||||
onSweep={this.handleSweep}
|
||||
onReorderAction={this.handleReorderAction}
|
||||
currentActionId={actionIds[currentStateIndex]}
|
||||
lastActionId={getLastActionId(this.props)}
|
||||
/>
|
||||
<ActionPreview
|
||||
{...{
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
isWideLayout,
|
||||
tabs,
|
||||
tabName,
|
||||
delta,
|
||||
error,
|
||||
nextState,
|
||||
computedStates,
|
||||
action,
|
||||
actions,
|
||||
selectedActionId,
|
||||
startActionId,
|
||||
dataTypeKey,
|
||||
sortStateTreeAlphabetically,
|
||||
disableStateTreeCollection,
|
||||
}}
|
||||
monitorState={this.props.monitorState}
|
||||
updateMonitorState={this.updateMonitorState}
|
||||
styling={styling}
|
||||
onInspectPath={(path: (string | number)[]) =>
|
||||
this.handleInspectPath(inspectedPathType, path)
|
||||
}
|
||||
inspectedPath={monitorState[inspectedPathType]}
|
||||
onSelectTab={this.handleSelectTab}
|
||||
/>
|
||||
</div>
|
||||
<ThemeProvider theme={inspectorMonitorTheme}>
|
||||
<div
|
||||
key="inspector"
|
||||
data-testid="inspector"
|
||||
ref={this.inspectorCreateRef}
|
||||
css={[
|
||||
(theme) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
fontFamily: 'monaco, Consolas, "Lucida Console", monospace',
|
||||
fontSize: '12px',
|
||||
WebkitFontSmoothing: 'antialiased',
|
||||
lineHeight: '1.5em',
|
||||
|
||||
backgroundColor: theme.BACKGROUND_COLOR,
|
||||
color: theme.TEXT_COLOR,
|
||||
}),
|
||||
isWideLayout && { flexDirection: 'row' },
|
||||
]}
|
||||
>
|
||||
<ActionList
|
||||
{...{
|
||||
actions,
|
||||
actionIds,
|
||||
isWideLayout,
|
||||
searchValue,
|
||||
selectedActionId,
|
||||
startActionId,
|
||||
skippedActionIds,
|
||||
draggableActions,
|
||||
hideMainButtons,
|
||||
hideActionButtons,
|
||||
}}
|
||||
onSearch={this.handleSearch}
|
||||
onSelect={this.handleSelectAction}
|
||||
onToggleAction={this.handleToggleAction}
|
||||
onJumpToState={this.handleJumpToState}
|
||||
onCommit={this.handleCommit}
|
||||
onSweep={this.handleSweep}
|
||||
onReorderAction={this.handleReorderAction}
|
||||
currentActionId={actionIds[currentStateIndex]}
|
||||
lastActionId={getLastActionId(this.props)}
|
||||
/>
|
||||
<ActionPreview
|
||||
{...{
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
isWideLayout,
|
||||
tabs,
|
||||
tabName,
|
||||
delta,
|
||||
error,
|
||||
nextState,
|
||||
computedStates,
|
||||
action,
|
||||
actions,
|
||||
selectedActionId,
|
||||
startActionId,
|
||||
dataTypeKey,
|
||||
sortStateTreeAlphabetically,
|
||||
disableStateTreeCollection,
|
||||
}}
|
||||
monitorState={this.props.monitorState}
|
||||
updateMonitorState={this.updateMonitorState}
|
||||
onInspectPath={(path: (string | number)[]) =>
|
||||
this.handleInspectPath(inspectedPathType, path)
|
||||
}
|
||||
inspectedPath={monitorState[inspectedPathType]}
|
||||
onSelectTab={this.handleSelectTab}
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,35 @@
|
|||
import React, { FunctionComponent } from 'react';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
|
||||
interface Props {
|
||||
styling: StylingFunction;
|
||||
shown?: boolean;
|
||||
children: React.ReactNode;
|
||||
rotate?: boolean;
|
||||
}
|
||||
|
||||
const RightSlider: FunctionComponent<Props> = ({
|
||||
styling,
|
||||
shown,
|
||||
children,
|
||||
rotate,
|
||||
}) => (
|
||||
const RightSlider: FunctionComponent<Props> = ({ shown, children, rotate }) => (
|
||||
<div
|
||||
{...styling([
|
||||
'rightSlider',
|
||||
shown && 'rightSliderShown',
|
||||
rotate && 'rightSliderRotate',
|
||||
rotate && shown && 'rightSliderRotateShown',
|
||||
])}
|
||||
css={[
|
||||
{
|
||||
WebkitFontSmoothing: 'subpixel-antialiased', // http://stackoverflow.com/a/21136111/4218591
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
transform: 'translateX(150%)',
|
||||
transition: 'transform 0.2s ease-in-out',
|
||||
},
|
||||
shown && {
|
||||
position: 'static',
|
||||
transform: 'translateX(0)',
|
||||
},
|
||||
rotate && {
|
||||
transform: 'rotateX(90deg)',
|
||||
transition: 'transform 0.2s ease-in-out 0.08s',
|
||||
},
|
||||
rotate &&
|
||||
shown && {
|
||||
transform: 'rotateX(0)',
|
||||
transition: 'transform 0.2s ease-in-out 0.18s',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
export type { StylingFunction } from 'react-base16-styling';
|
||||
export type { LabelRenderer } from 'react-json-tree';
|
||||
export { default as InspectorMonitor } from './DevtoolsInspector';
|
||||
export type { Tab, TabComponentProps } from './ActionPreview';
|
||||
export type { DevtoolsInspectorState } from './redux';
|
||||
export { base16Themes } from './utils/createStylingFromTheme';
|
||||
export type { Base16ThemeName } from './utils/themes';
|
||||
export * as inspectorThemes from './themes/index';
|
||||
export { default as ActionTab } from './tabs/ActionTab';
|
||||
export { default as DiffTab } from './tabs/DiffTab';
|
||||
|
|
|
@ -9,7 +9,6 @@ const ActionTab: FunctionComponent<
|
|||
TabComponentProps<unknown, Action<string>>
|
||||
> = ({
|
||||
action,
|
||||
styling,
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
labelRenderer,
|
||||
|
@ -21,7 +20,7 @@ const ActionTab: FunctionComponent<
|
|||
theme={getJsonTreeTheme(base16Theme)}
|
||||
data={action}
|
||||
getItemString={(type, data) =>
|
||||
getItemString(styling, type, data, dataTypeKey, isWideLayout)
|
||||
getItemString(type, data, dataTypeKey, isWideLayout)
|
||||
}
|
||||
invertTheme={invertTheme}
|
||||
hideRoot
|
||||
|
|
|
@ -7,7 +7,6 @@ const DiffTab: FunctionComponent<
|
|||
TabComponentProps<unknown, Action<string>>
|
||||
> = ({
|
||||
delta,
|
||||
styling,
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
labelRenderer,
|
||||
|
@ -17,7 +16,6 @@ const DiffTab: FunctionComponent<
|
|||
<JSONDiff
|
||||
{...{
|
||||
delta,
|
||||
styling,
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
labelRenderer,
|
||||
|
|
|
@ -3,8 +3,9 @@ import { JSONTree } from 'react-json-tree';
|
|||
import type { LabelRenderer, ShouldExpandNodeInitially } from 'react-json-tree';
|
||||
import { stringify } from 'javascript-stringify';
|
||||
import { Delta } from 'jsondiffpatch';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import { Base16Theme } from 'redux-devtools-themes';
|
||||
import { css } from '@emotion/react';
|
||||
import type { Interpolation, Theme } from '@emotion/react';
|
||||
import getItemString from './getItemString';
|
||||
import getJsonTreeTheme from './getJsonTreeTheme';
|
||||
|
||||
|
@ -46,9 +47,18 @@ function prepareDelta(value: any) {
|
|||
return value;
|
||||
}
|
||||
|
||||
const diffCss: Interpolation<Theme> = (theme) => ({
|
||||
padding: '2px 3px',
|
||||
borderRadius: '3px',
|
||||
position: 'relative',
|
||||
|
||||
color: theme.TEXT_COLOR,
|
||||
});
|
||||
|
||||
const diffWrapCss = css({ position: 'relative', zIndex: 1 });
|
||||
|
||||
interface Props {
|
||||
delta: Delta | null | undefined | false;
|
||||
styling: StylingFunction;
|
||||
base16Theme: Base16Theme;
|
||||
invertTheme: boolean;
|
||||
labelRenderer: LabelRenderer;
|
||||
|
@ -82,10 +92,19 @@ export default class JSONDiff extends Component<Props, State> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { styling, base16Theme, ...props } = this.props;
|
||||
const { base16Theme, ...props } = this.props;
|
||||
|
||||
if (!this.state.data) {
|
||||
return <div {...styling('stateDiffEmpty')}>(states are equal)</div>;
|
||||
return (
|
||||
<div
|
||||
css={(theme) => ({
|
||||
padding: '10px',
|
||||
color: theme.TEXT_PLACEHOLDER_COLOR,
|
||||
})}
|
||||
>
|
||||
(states are equal)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -105,7 +124,6 @@ export default class JSONDiff extends Component<Props, State> {
|
|||
|
||||
getItemString = (type: string, data: any) =>
|
||||
getItemString(
|
||||
this.props.styling,
|
||||
type,
|
||||
data,
|
||||
this.props.dataTypeKey,
|
||||
|
@ -114,45 +132,71 @@ export default class JSONDiff extends Component<Props, State> {
|
|||
);
|
||||
|
||||
valueRenderer = (raw: any, value: any) => {
|
||||
const { styling, isWideLayout } = this.props;
|
||||
|
||||
function renderSpan(name: string, body: string) {
|
||||
return (
|
||||
<span key={name} {...styling(['diff', name])}>
|
||||
{body}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
const { isWideLayout } = this.props;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
switch (value.length) {
|
||||
case 1:
|
||||
return (
|
||||
<span {...styling('diffWrap')}>
|
||||
{renderSpan(
|
||||
'diffAdd',
|
||||
stringifyAndShrink(value[0], isWideLayout),
|
||||
)}
|
||||
<span css={diffWrapCss}>
|
||||
<span
|
||||
key="diffAdd"
|
||||
css={[
|
||||
diffCss,
|
||||
(theme) => ({ backgroundColor: theme.DIFF_ADD_COLOR }),
|
||||
]}
|
||||
>
|
||||
{stringifyAndShrink(value[0], isWideLayout)}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
case 2:
|
||||
return (
|
||||
<span {...styling('diffWrap')}>
|
||||
{renderSpan(
|
||||
'diffUpdateFrom',
|
||||
stringifyAndShrink(value[0], isWideLayout),
|
||||
)}
|
||||
{renderSpan('diffUpdateArrow', ' => ')}
|
||||
{renderSpan(
|
||||
'diffUpdateTo',
|
||||
stringifyAndShrink(value[1], isWideLayout),
|
||||
)}
|
||||
<span css={diffWrapCss}>
|
||||
<span
|
||||
key="diffUpdateFrom"
|
||||
css={[
|
||||
diffCss,
|
||||
(theme) => ({
|
||||
textDecoration: 'line-through',
|
||||
backgroundColor: theme.DIFF_REMOVE_COLOR,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
{stringifyAndShrink(value[0], isWideLayout)}
|
||||
</span>
|
||||
<span
|
||||
key="diffUpdateArrow"
|
||||
css={[diffCss, (theme) => ({ color: theme.DIFF_ARROW_COLOR })]}
|
||||
>
|
||||
{' => '}
|
||||
</span>
|
||||
<span
|
||||
key="diffUpdateTo"
|
||||
css={[
|
||||
diffCss,
|
||||
(theme) => ({ backgroundColor: theme.DIFF_ADD_COLOR }),
|
||||
]}
|
||||
>
|
||||
{stringifyAndShrink(value[1], isWideLayout)}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
case 3:
|
||||
return (
|
||||
<span {...styling('diffWrap')}>
|
||||
{renderSpan('diffRemove', stringifyAndShrink(value[0]))}
|
||||
<span css={diffWrapCss}>
|
||||
<span
|
||||
key="diffRemove"
|
||||
css={[
|
||||
diffCss,
|
||||
(theme) => ({
|
||||
textDecoration: 'line-through',
|
||||
backgroundColor: theme.DIFF_REMOVE_COLOR,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
{stringifyAndShrink(value[0])}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ const StateTab: React.FunctionComponent<
|
|||
TabComponentProps<any, Action<string>>
|
||||
> = ({
|
||||
nextState,
|
||||
styling,
|
||||
base16Theme,
|
||||
invertTheme,
|
||||
labelRenderer,
|
||||
|
@ -23,7 +22,7 @@ const StateTab: React.FunctionComponent<
|
|||
theme={getJsonTreeTheme(base16Theme)}
|
||||
data={nextState}
|
||||
getItemString={(type, data) =>
|
||||
getItemString(styling, type, data, dataTypeKey, isWideLayout)
|
||||
getItemString(type, data, dataTypeKey, isWideLayout)
|
||||
}
|
||||
invertTheme={invertTheme}
|
||||
hideRoot
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { isCollection, isIndexed, isKeyed } from 'immutable';
|
||||
import { StylingFunction } from 'react-base16-styling';
|
||||
import isIterable from '../utils/isIterable';
|
||||
|
||||
const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
|
||||
|
@ -72,14 +71,13 @@ function getText(
|
|||
}
|
||||
|
||||
const getItemString = (
|
||||
styling: StylingFunction,
|
||||
type: string,
|
||||
data: any,
|
||||
dataTypeKey: string | symbol | undefined,
|
||||
isWideLayout: boolean,
|
||||
isDiff?: boolean,
|
||||
) => (
|
||||
<span {...styling('treeItemHint')}>
|
||||
<span css={(theme) => ({ color: theme.ITEM_HINT_COLOR })}>
|
||||
{data[IS_IMMUTABLE_KEY] ? 'Immutable' : ''}
|
||||
{dataTypeKey && data[dataTypeKey] ? `${data[dataTypeKey] as string} ` : ''}
|
||||
{getText(type, data, isWideLayout, isDiff)}
|
||||
|
|
|
@ -1,394 +0,0 @@
|
|||
import jss, { StyleSheet } from 'jss';
|
||||
import preset from 'jss-preset-default';
|
||||
import { createStyling, StylingFunction, Theme } from 'react-base16-styling';
|
||||
import rgba from 'hex-rgba';
|
||||
import { Base16Theme } from 'redux-devtools-themes';
|
||||
import type { CurriedFunction1 } from 'lodash';
|
||||
import inspector from '../themes/inspector';
|
||||
import * as reduxThemes from 'redux-devtools-themes';
|
||||
import * as inspectorThemes from '../themes';
|
||||
|
||||
jss.setup(preset());
|
||||
|
||||
const colorMap = (theme: Base16Theme) => ({
|
||||
TEXT_COLOR: theme.base06,
|
||||
TEXT_PLACEHOLDER_COLOR: rgba(theme.base06, 60),
|
||||
BACKGROUND_COLOR: theme.base00,
|
||||
SELECTED_BACKGROUND_COLOR: rgba(theme.base03, 20),
|
||||
SKIPPED_BACKGROUND_COLOR: rgba(theme.base03, 10),
|
||||
HEADER_BACKGROUND_COLOR: rgba(theme.base03, 30),
|
||||
HEADER_BORDER_COLOR: rgba(theme.base03, 20),
|
||||
BORDER_COLOR: rgba(theme.base03, 50),
|
||||
LIST_BORDER_COLOR: rgba(theme.base03, 50),
|
||||
ACTION_TIME_BACK_COLOR: rgba(theme.base03, 20),
|
||||
ACTION_TIME_COLOR: theme.base04,
|
||||
PIN_COLOR: theme.base04,
|
||||
ITEM_HINT_COLOR: rgba(theme.base0F, 90),
|
||||
TAB_BACK_SELECTED_COLOR: rgba(theme.base03, 20),
|
||||
TAB_BACK_COLOR: rgba(theme.base00, 70),
|
||||
TAB_BACK_HOVER_COLOR: rgba(theme.base03, 40),
|
||||
TAB_BORDER_COLOR: rgba(theme.base03, 50),
|
||||
DIFF_ADD_COLOR: rgba(theme.base0B, 40),
|
||||
DIFF_REMOVE_COLOR: rgba(theme.base08, 40),
|
||||
DIFF_ARROW_COLOR: theme.base0E,
|
||||
LINK_COLOR: rgba(theme.base0E, 90),
|
||||
LINK_HOVER_COLOR: theme.base0E,
|
||||
ERROR_COLOR: theme.base08,
|
||||
});
|
||||
|
||||
type Color = keyof ReturnType<typeof colorMap>;
|
||||
type ColorMap = {
|
||||
[color in Color]: string;
|
||||
};
|
||||
|
||||
const getSheetFromColorMap = (map: ColorMap) => ({
|
||||
inspector: {
|
||||
display: 'flex',
|
||||
'flex-direction': 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
'font-family': 'monaco, Consolas, "Lucida Console", monospace',
|
||||
'font-size': '12px',
|
||||
'font-smoothing': 'antialiased',
|
||||
'line-height': '1.5em',
|
||||
|
||||
'background-color': map.BACKGROUND_COLOR,
|
||||
color: map.TEXT_COLOR,
|
||||
},
|
||||
|
||||
inspectorWide: {
|
||||
'flex-direction': 'row',
|
||||
},
|
||||
|
||||
actionList: {
|
||||
'flex-basis': '40%',
|
||||
'flex-shrink': 0,
|
||||
'overflow-x': 'hidden',
|
||||
'overflow-y': 'auto',
|
||||
'border-bottom-width': '3px',
|
||||
'border-bottom-style': 'double',
|
||||
display: 'flex',
|
||||
'flex-direction': 'column',
|
||||
|
||||
'background-color': map.BACKGROUND_COLOR,
|
||||
'border-color': map.LIST_BORDER_COLOR,
|
||||
},
|
||||
|
||||
actionListHeader: {
|
||||
display: 'flex',
|
||||
flex: '0 0 auto',
|
||||
'align-items': 'center',
|
||||
'border-bottom-width': '1px',
|
||||
'border-bottom-style': 'solid',
|
||||
|
||||
'border-color': map.LIST_BORDER_COLOR,
|
||||
},
|
||||
|
||||
actionListRows: {
|
||||
overflow: 'auto',
|
||||
},
|
||||
|
||||
actionListHeaderSelector: {
|
||||
display: 'inline-flex',
|
||||
'margin-right': '10px',
|
||||
},
|
||||
|
||||
actionListWide: {
|
||||
'flex-basis': '40%',
|
||||
'border-bottom': 'none',
|
||||
'border-right-width': '3px',
|
||||
'border-right-style': 'double',
|
||||
},
|
||||
|
||||
actionListItem: {
|
||||
'border-bottom-width': '1px',
|
||||
'border-bottom-style': 'solid',
|
||||
display: 'flex',
|
||||
'justify-content': 'space-between',
|
||||
padding: '5px 10px',
|
||||
cursor: 'pointer',
|
||||
'user-select': 'none',
|
||||
|
||||
'border-bottom-color': map.BORDER_COLOR,
|
||||
},
|
||||
|
||||
actionListItemSelected: {
|
||||
'background-color': map.SELECTED_BACKGROUND_COLOR,
|
||||
},
|
||||
|
||||
actionListItemSkipped: {
|
||||
'background-color': map.SKIPPED_BACKGROUND_COLOR,
|
||||
},
|
||||
|
||||
actionListFromFuture: {
|
||||
opacity: '0.6',
|
||||
},
|
||||
|
||||
actionListItemButtons: {
|
||||
position: 'relative',
|
||||
height: '20px',
|
||||
display: 'flex',
|
||||
},
|
||||
|
||||
actionListItemTime: {
|
||||
display: 'inline',
|
||||
padding: '4px 6px',
|
||||
'border-radius': '3px',
|
||||
'font-size': '0.8em',
|
||||
'line-height': '1em',
|
||||
'flex-shrink': 0,
|
||||
|
||||
'background-color': map.ACTION_TIME_BACK_COLOR,
|
||||
color: map.ACTION_TIME_COLOR,
|
||||
},
|
||||
|
||||
actionListItemSelector: {
|
||||
display: 'inline-flex',
|
||||
},
|
||||
|
||||
actionListItemName: {
|
||||
overflow: 'hidden',
|
||||
'text-overflow': 'ellipsis',
|
||||
'line-height': '20px',
|
||||
},
|
||||
|
||||
actionListItemNameSkipped: {
|
||||
'text-decoration': 'line-through',
|
||||
opacity: 0.3,
|
||||
},
|
||||
|
||||
actionListHeaderSearch: {
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
width: '100%',
|
||||
padding: '5px 10px',
|
||||
'font-size': '1em',
|
||||
'font-family': 'monaco, Consolas, "Lucida Console", monospace',
|
||||
|
||||
'background-color': map.BACKGROUND_COLOR,
|
||||
color: map.TEXT_COLOR,
|
||||
|
||||
'&::-webkit-input-placeholder': {
|
||||
color: map.TEXT_PLACEHOLDER_COLOR,
|
||||
},
|
||||
|
||||
'&::-moz-placeholder': {
|
||||
color: map.TEXT_PLACEHOLDER_COLOR,
|
||||
},
|
||||
},
|
||||
|
||||
actionListHeaderWrapper: {
|
||||
position: 'relative',
|
||||
height: '20px',
|
||||
},
|
||||
|
||||
actionPreview: {
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
'flex-direction': 'column',
|
||||
'flex-grow': 1,
|
||||
'overflow-y': 'hidden',
|
||||
|
||||
'& pre': {
|
||||
border: 'inherit',
|
||||
'border-radius': '3px',
|
||||
'line-height': 'inherit',
|
||||
color: 'inherit',
|
||||
},
|
||||
|
||||
'background-color': map.BACKGROUND_COLOR,
|
||||
},
|
||||
|
||||
actionPreviewContent: {
|
||||
flex: 1,
|
||||
'overflow-y': 'auto',
|
||||
},
|
||||
|
||||
stateDiff: {
|
||||
padding: '5px 0',
|
||||
},
|
||||
|
||||
stateDiffEmpty: {
|
||||
padding: '10px',
|
||||
|
||||
color: map.TEXT_PLACEHOLDER_COLOR,
|
||||
},
|
||||
|
||||
stateError: {
|
||||
padding: '10px',
|
||||
'margin-left': '14px',
|
||||
'font-weight': 'bold',
|
||||
|
||||
color: map.ERROR_COLOR,
|
||||
},
|
||||
|
||||
inspectedPath: {
|
||||
padding: '6px 0',
|
||||
},
|
||||
|
||||
inspectedPathKey: {
|
||||
'&:not(:last-child):after': {
|
||||
content: '" > "',
|
||||
},
|
||||
},
|
||||
|
||||
inspectedPathKeyLink: {
|
||||
cursor: 'pointer',
|
||||
color: map.LINK_COLOR,
|
||||
'&:hover': {
|
||||
'text-decoration': 'underline',
|
||||
color: map.LINK_HOVER_COLOR,
|
||||
},
|
||||
},
|
||||
|
||||
treeItemPin: {
|
||||
'font-size': '0.7em',
|
||||
'padding-left': '5px',
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
'text-decoration': 'underline',
|
||||
},
|
||||
|
||||
color: map.PIN_COLOR,
|
||||
},
|
||||
|
||||
treeItemHint: {
|
||||
color: map.ITEM_HINT_COLOR,
|
||||
},
|
||||
|
||||
previewHeader: {
|
||||
flex: '0 0 30px',
|
||||
padding: '5px 10px',
|
||||
'align-items': 'center',
|
||||
'border-bottom-width': '1px',
|
||||
'border-bottom-style': 'solid',
|
||||
|
||||
'background-color': map.HEADER_BACKGROUND_COLOR,
|
||||
'border-bottom-color': map.HEADER_BORDER_COLOR,
|
||||
},
|
||||
|
||||
tabSelector: {
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
float: 'right',
|
||||
},
|
||||
|
||||
selectorButton: {
|
||||
cursor: 'pointer',
|
||||
position: 'relative',
|
||||
padding: '5px 10px',
|
||||
'border-style': 'solid',
|
||||
'border-width': '1px',
|
||||
'border-left-width': 0,
|
||||
|
||||
'&:first-child': {
|
||||
'border-left-width': '1px',
|
||||
'border-top-left-radius': '3px',
|
||||
'border-bottom-left-radius': '3px',
|
||||
},
|
||||
|
||||
'&:last-child': {
|
||||
'border-top-right-radius': '3px',
|
||||
'border-bottom-right-radius': '3px',
|
||||
},
|
||||
|
||||
'background-color': map.TAB_BACK_COLOR,
|
||||
|
||||
'&:hover': {
|
||||
'background-color': map.TAB_BACK_HOVER_COLOR,
|
||||
},
|
||||
|
||||
'border-color': map.TAB_BORDER_COLOR,
|
||||
},
|
||||
|
||||
selectorButtonSmall: {
|
||||
padding: '0px 8px',
|
||||
'font-size': '0.8em',
|
||||
},
|
||||
|
||||
selectorButtonSelected: {
|
||||
'background-color': map.TAB_BACK_SELECTED_COLOR,
|
||||
},
|
||||
|
||||
diff: {
|
||||
padding: '2px 3px',
|
||||
'border-radius': '3px',
|
||||
position: 'relative',
|
||||
|
||||
color: map.TEXT_COLOR,
|
||||
},
|
||||
|
||||
diffWrap: {
|
||||
position: 'relative',
|
||||
'z-index': 1,
|
||||
},
|
||||
|
||||
diffAdd: {
|
||||
'background-color': map.DIFF_ADD_COLOR,
|
||||
},
|
||||
|
||||
diffRemove: {
|
||||
'text-decoration': 'line-through',
|
||||
'background-color': map.DIFF_REMOVE_COLOR,
|
||||
},
|
||||
|
||||
diffUpdateFrom: {
|
||||
'text-decoration': 'line-through',
|
||||
'background-color': map.DIFF_REMOVE_COLOR,
|
||||
},
|
||||
|
||||
diffUpdateTo: {
|
||||
'background-color': map.DIFF_ADD_COLOR,
|
||||
},
|
||||
|
||||
diffUpdateArrow: {
|
||||
color: map.DIFF_ARROW_COLOR,
|
||||
},
|
||||
|
||||
rightSlider: {
|
||||
'font-smoothing': 'subpixel-antialiased', // http://stackoverflow.com/a/21136111/4218591
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
transform: 'translateX(150%)',
|
||||
transition: 'transform 0.2s ease-in-out',
|
||||
},
|
||||
|
||||
rightSliderRotate: {
|
||||
transform: 'rotateX(90deg)',
|
||||
transition: 'transform 0.2s ease-in-out 0.08s',
|
||||
},
|
||||
|
||||
rightSliderShown: {
|
||||
position: 'static',
|
||||
transform: 'translateX(0)',
|
||||
},
|
||||
|
||||
rightSliderRotateShown: {
|
||||
transform: 'rotateX(0)',
|
||||
transition: 'transform 0.2s ease-in-out 0.18s',
|
||||
},
|
||||
});
|
||||
|
||||
let themeSheet: StyleSheet;
|
||||
|
||||
const getDefaultThemeStyling = (theme: Base16Theme) => {
|
||||
if (themeSheet) {
|
||||
themeSheet.detach();
|
||||
}
|
||||
|
||||
themeSheet = jss
|
||||
.createStyleSheet(getSheetFromColorMap(colorMap(theme)))
|
||||
.attach();
|
||||
|
||||
return themeSheet.classes;
|
||||
};
|
||||
|
||||
export const base16Themes = { ...reduxThemes, ...inspectorThemes };
|
||||
|
||||
export const createStylingFromTheme: CurriedFunction1<
|
||||
Theme | undefined,
|
||||
StylingFunction
|
||||
> = createStyling(getDefaultThemeStyling, {
|
||||
defaultBase16: inspector,
|
||||
base16Themes,
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
import { css } from '@emotion/react';
|
||||
import type { Interpolation, Theme } from '@emotion/react';
|
||||
|
||||
export const selectorButtonCss: Interpolation<Theme> = (theme) => ({
|
||||
cursor: 'pointer',
|
||||
position: 'relative',
|
||||
padding: '5px 10px',
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px',
|
||||
borderLeftWidth: 0,
|
||||
|
||||
'&:first-of-type': {
|
||||
borderLeftWidth: '1px',
|
||||
borderTopLeftRadius: '3px',
|
||||
borderBottomLeftRadius: '3px',
|
||||
},
|
||||
|
||||
'&:last-of-type': {
|
||||
borderTopRightRadius: '3px',
|
||||
borderBottomRightRadius: '3px',
|
||||
},
|
||||
|
||||
backgroundColor: theme.TAB_BACK_COLOR,
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: theme.TAB_BACK_HOVER_COLOR,
|
||||
},
|
||||
|
||||
borderColor: theme.TAB_BORDER_COLOR,
|
||||
});
|
||||
|
||||
export const selectorButtonSmallCss = css({
|
||||
padding: '0px 8px',
|
||||
fontSize: '0.8em',
|
||||
});
|
||||
|
||||
export const selectorButtonSelectedCss: Interpolation<Theme> = (theme) => ({
|
||||
backgroundColor: theme.TAB_BACK_SELECTED_COLOR,
|
||||
});
|
|
@ -0,0 +1,76 @@
|
|||
import rgba from 'hex-rgba';
|
||||
import { Base16Theme } from 'redux-devtools-themes';
|
||||
import * as reduxThemes from 'redux-devtools-themes';
|
||||
import * as inspectorThemes from '../themes';
|
||||
import { getBase16Theme, invertBase16Theme } from 'react-base16-styling';
|
||||
|
||||
const base16Themes = { ...reduxThemes, ...inspectorThemes };
|
||||
export type Base16ThemeName = keyof typeof base16Themes;
|
||||
|
||||
export function resolveBase16Theme(theme: Base16ThemeName | Base16Theme) {
|
||||
return getBase16Theme(theme, base16Themes);
|
||||
}
|
||||
|
||||
declare module '@emotion/react' {
|
||||
export interface Theme {
|
||||
TEXT_COLOR: string;
|
||||
TEXT_PLACEHOLDER_COLOR: string;
|
||||
BACKGROUND_COLOR: string;
|
||||
SELECTED_BACKGROUND_COLOR: string;
|
||||
SKIPPED_BACKGROUND_COLOR: string;
|
||||
HEADER_BACKGROUND_COLOR: string;
|
||||
HEADER_BORDER_COLOR: string;
|
||||
BORDER_COLOR: string;
|
||||
LIST_BORDER_COLOR: string;
|
||||
ACTION_TIME_BACK_COLOR: string;
|
||||
ACTION_TIME_COLOR: string;
|
||||
PIN_COLOR: string;
|
||||
ITEM_HINT_COLOR: string;
|
||||
TAB_BACK_SELECTED_COLOR: string;
|
||||
TAB_BACK_COLOR: string;
|
||||
TAB_BACK_HOVER_COLOR: string;
|
||||
TAB_BORDER_COLOR: string;
|
||||
DIFF_ADD_COLOR: string;
|
||||
DIFF_REMOVE_COLOR: string;
|
||||
DIFF_ARROW_COLOR: string;
|
||||
LINK_COLOR: string;
|
||||
LINK_HOVER_COLOR: string;
|
||||
ERROR_COLOR: string;
|
||||
}
|
||||
}
|
||||
|
||||
const colorMap = (theme: Base16Theme) => ({
|
||||
TEXT_COLOR: theme.base06,
|
||||
TEXT_PLACEHOLDER_COLOR: rgba(theme.base06, 60),
|
||||
BACKGROUND_COLOR: theme.base00,
|
||||
SELECTED_BACKGROUND_COLOR: rgba(theme.base03, 20),
|
||||
SKIPPED_BACKGROUND_COLOR: rgba(theme.base03, 10),
|
||||
HEADER_BACKGROUND_COLOR: rgba(theme.base03, 30),
|
||||
HEADER_BORDER_COLOR: rgba(theme.base03, 20),
|
||||
BORDER_COLOR: rgba(theme.base03, 50),
|
||||
LIST_BORDER_COLOR: rgba(theme.base03, 50),
|
||||
ACTION_TIME_BACK_COLOR: rgba(theme.base03, 20),
|
||||
ACTION_TIME_COLOR: theme.base04,
|
||||
PIN_COLOR: theme.base04,
|
||||
ITEM_HINT_COLOR: rgba(theme.base0F, 90),
|
||||
TAB_BACK_SELECTED_COLOR: rgba(theme.base03, 20),
|
||||
TAB_BACK_COLOR: rgba(theme.base00, 70),
|
||||
TAB_BACK_HOVER_COLOR: rgba(theme.base03, 40),
|
||||
TAB_BORDER_COLOR: rgba(theme.base03, 50),
|
||||
DIFF_ADD_COLOR: rgba(theme.base0B, 40),
|
||||
DIFF_REMOVE_COLOR: rgba(theme.base08, 40),
|
||||
DIFF_ARROW_COLOR: theme.base0E,
|
||||
LINK_COLOR: rgba(theme.base0E, 90),
|
||||
LINK_HOVER_COLOR: theme.base0E,
|
||||
ERROR_COLOR: theme.base08,
|
||||
});
|
||||
|
||||
export function createInspectorMonitorThemeFromBase16Theme(
|
||||
base16Theme: Base16Theme,
|
||||
invertTheme: boolean,
|
||||
) {
|
||||
const finalBase16Theme = invertTheme
|
||||
? invertBase16Theme(base16Theme)
|
||||
: base16Theme;
|
||||
return colorMap(finalBase16Theme);
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
"extends": "../../tsconfig.react.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib/types",
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "@emotion/react"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
|
@ -59,6 +59,9 @@ importers:
|
|||
'@babel/polyfill':
|
||||
specifier: ^7.12.1
|
||||
version: 7.12.1
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/app':
|
||||
specifier: ^4.0.1
|
||||
version: link:../packages/redux-devtools-app
|
||||
|
@ -1088,6 +1091,9 @@ importers:
|
|||
'@babel/preset-typescript':
|
||||
specifier: ^7.23.3
|
||||
version: 7.23.3(@babel/core@7.23.5)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@rjsf/core':
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(react@18.2.0)
|
||||
|
@ -1293,6 +1299,9 @@ importers:
|
|||
'@apollo/server':
|
||||
specifier: ^4.9.5
|
||||
version: 4.9.5(graphql@16.8.1)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/app':
|
||||
specifier: ^4.0.0
|
||||
version: link:../redux-devtools-app
|
||||
|
@ -1605,12 +1614,6 @@ importers:
|
|||
jsondiffpatch:
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0
|
||||
jss:
|
||||
specifier: ^10.10.0
|
||||
version: 10.10.0
|
||||
jss-preset-default:
|
||||
specifier: ^10.10.0
|
||||
version: 10.10.0
|
||||
lodash.debounce:
|
||||
specifier: ^4.0.8
|
||||
version: 4.0.8
|
||||
|
@ -1648,6 +1651,12 @@ importers:
|
|||
'@babel/preset-typescript':
|
||||
specifier: ^7.23.3
|
||||
version: 7.23.3(@babel/core@7.23.5)
|
||||
'@emotion/babel-preset-css-prop':
|
||||
specifier: ^11.11.0
|
||||
version: 11.11.0(@babel/core@7.23.5)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/core':
|
||||
specifier: ^3.14.0
|
||||
version: link:../redux-devtools
|
||||
|
@ -1751,6 +1760,9 @@ importers:
|
|||
'@babel/preset-typescript':
|
||||
specifier: ^7.23.3
|
||||
version: 7.23.3(@babel/core@7.23.5)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/core':
|
||||
specifier: ^3.14.0
|
||||
version: link:../redux-devtools
|
||||
|
@ -1823,6 +1835,9 @@ importers:
|
|||
|
||||
packages/redux-devtools-inspector-monitor-test-tab/demo:
|
||||
dependencies:
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/core':
|
||||
specifier: ^3.13.2
|
||||
version: link:../../redux-devtools
|
||||
|
@ -2002,6 +2017,9 @@ importers:
|
|||
'@babel/preset-typescript':
|
||||
specifier: ^7.23.3
|
||||
version: 7.23.3(@babel/core@7.23.5)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/core':
|
||||
specifier: ^3.14.0
|
||||
version: link:../redux-devtools
|
||||
|
@ -2086,6 +2104,9 @@ importers:
|
|||
|
||||
packages/redux-devtools-inspector-monitor/demo:
|
||||
dependencies:
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.43)(react@18.2.0)
|
||||
'@redux-devtools/core':
|
||||
specifier: ^3.13.0
|
||||
version: link:../../redux-devtools
|
||||
|
@ -6429,6 +6450,15 @@ packages:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@emotion/babel-plugin-jsx-pragmatic@0.2.1(@babel/core@7.23.5):
|
||||
resolution: {integrity: sha512-xy1SlgEJygAAIvIuC2idkGKJYa6v5iwoyILkvNKgk347bV+IImXrUat5Z86EmLGyWhEoTplVT9EHqTnHZG4HFw==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.5)
|
||||
dev: true
|
||||
|
||||
/@emotion/babel-plugin@11.11.0:
|
||||
resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==}
|
||||
dependencies:
|
||||
|
@ -6443,7 +6473,18 @@ packages:
|
|||
find-root: 1.1.0
|
||||
source-map: 0.5.7
|
||||
stylis: 4.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/babel-preset-css-prop@11.11.0(@babel/core@7.23.5):
|
||||
resolution: {integrity: sha512-+1Cba68IyBeltWzvbBSXcBWqP2eKQuQcSUpIu3ma4pOUeRol4EvwWrYS2Rv51aIVqg066fLB+Z9O/8NKR7uUlQ==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.23.5)
|
||||
'@babel/runtime': 7.23.5
|
||||
'@emotion/babel-plugin': 11.11.0
|
||||
'@emotion/babel-plugin-jsx-pragmatic': 0.2.1(@babel/core@7.23.5)
|
||||
dev: true
|
||||
|
||||
/@emotion/cache@11.11.0:
|
||||
resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==}
|
||||
|
@ -6453,11 +6494,9 @@ packages:
|
|||
'@emotion/utils': 1.2.1
|
||||
'@emotion/weak-memoize': 0.3.1
|
||||
stylis: 4.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/hash@0.9.1:
|
||||
resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==}
|
||||
dev: false
|
||||
|
||||
/@emotion/is-prop-valid@0.8.8:
|
||||
resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
|
||||
|
@ -6500,7 +6539,6 @@ packages:
|
|||
'@types/react': 18.2.43
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/serialize@1.1.2:
|
||||
resolution: {integrity: sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==}
|
||||
|
@ -6510,11 +6548,9 @@ packages:
|
|||
'@emotion/unitless': 0.8.1
|
||||
'@emotion/utils': 1.2.1
|
||||
csstype: 3.1.2
|
||||
dev: false
|
||||
|
||||
/@emotion/sheet@1.2.2:
|
||||
resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==}
|
||||
dev: false
|
||||
|
||||
/@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.43)(react@18.2.0):
|
||||
resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==}
|
||||
|
@ -6545,7 +6581,6 @@ packages:
|
|||
|
||||
/@emotion/unitless@0.8.1:
|
||||
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
|
||||
dev: false
|
||||
|
||||
/@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==}
|
||||
|
@ -6556,11 +6591,9 @@ packages:
|
|||
|
||||
/@emotion/utils@1.2.1:
|
||||
resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==}
|
||||
dev: false
|
||||
|
||||
/@emotion/weak-memoize@0.3.1:
|
||||
resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==}
|
||||
dev: false
|
||||
|
||||
/@esbuild/android-arm64@0.18.20:
|
||||
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
|
||||
|
@ -11565,7 +11598,6 @@ packages:
|
|||
'@babel/runtime': 7.23.5
|
||||
cosmiconfig: 7.1.0
|
||||
resolve: 1.22.8
|
||||
dev: false
|
||||
|
||||
/babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.5):
|
||||
resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==}
|
||||
|
@ -12371,7 +12403,6 @@ packages:
|
|||
|
||||
/convert-source-map@1.9.0:
|
||||
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
|
||||
dev: false
|
||||
|
||||
/convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
@ -14279,7 +14310,6 @@ packages:
|
|||
|
||||
/find-root@1.1.0:
|
||||
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
|
||||
dev: false
|
||||
|
||||
/find-up@3.0.0:
|
||||
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
|
||||
|
@ -19835,7 +19865,6 @@ packages:
|
|||
/source-map@0.5.7:
|
||||
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/source-map@0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
|
@ -20280,7 +20309,6 @@ packages:
|
|||
|
||||
/stylis@4.2.0:
|
||||
resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==}
|
||||
dev: false
|
||||
|
||||
/sumchecker@3.0.1:
|
||||
resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==}
|
||||
|
|
Loading…
Reference in New Issue
Block a user