Inline CSS

This commit is contained in:
Nathan Bierema 2023-12-11 22:32:12 -05:00
parent fa5036a7a5
commit d0eaf738f0
13 changed files with 388 additions and 471 deletions

View File

@ -20,11 +20,6 @@ import {
import { CSS } from '@dnd-kit/utilities';
import ActionListRow from './ActionListRow';
import ActionListHeader from './ActionListHeader';
import {
actionListCss,
actionListRowsCss,
actionListWideCss,
} from './utils/createStylingFromTheme';
function getTimestamps<A extends Action<string>>(
actions: { [actionId: number]: PerformAction<A> },
@ -152,7 +147,27 @@ export default function ActionList<A extends Action<string>>({
<div
key="actionList"
data-testid="actionList"
css={[actionListCss, isWideLayout && actionListWideCss]}
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
onSearch={onSearch}
@ -165,7 +180,7 @@ export default function ActionList<A extends Action<string>>({
/>
<div
data-testid="actionListRows"
css={actionListRowsCss}
css={{ overflow: 'auto' }}
ref={setNodeRef}
>
<DndContext

View File

@ -1,13 +1,9 @@
import React, { FunctionComponent } from 'react';
import RightSlider from './RightSlider';
import {
actionListHeaderCss,
actionListHeaderSearchCss,
actionListHeaderSelectorCss,
actionListHeaderWrapperCss,
selectorButtonCss,
selectorButtonSmallCss,
} from './utils/createStylingFromTheme';
} from './utils/selectorButtonStyles';
const getActiveButtons = (hasSkippedActions: boolean): ('Sweep' | 'Commit')[] =>
[hasSkippedActions && 'Sweep', 'Commit'].filter(
@ -33,17 +29,45 @@ const ActionListHeader: FunctionComponent<Props> = ({
hideMainButtons,
searchValue,
}) => (
<div css={actionListHeaderCss}>
<div
css={(theme) => ({
display: 'flex',
flex: '0 0 auto',
alignItems: 'center',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
borderColor: theme.LIST_BORDER_COLOR,
})}
>
<input
css={actionListHeaderSearchCss}
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 css={actionListHeaderWrapperCss}>
<div css={{ position: 'relative', height: '20px' }}>
<RightSlider shown={hasStagedActions}>
<div css={actionListHeaderSelectorCss}>
<div css={{ display: 'inline-flex', marginRight: '10px' }}>
{getActiveButtons(hasSkippedActions).map((btn) => (
<div
key={btn}

View File

@ -3,27 +3,31 @@ import dateformat from 'dateformat';
import type { DebouncedFunc } from 'lodash';
import debounce from 'lodash.debounce';
import { Action } from 'redux';
import type { Interpolation, Theme } from '@emotion/react';
import RightSlider from './RightSlider';
import {
actionListFromFutureCss,
actionListItemButtonsCss,
actionListItemCss,
actionListItemNameCss,
actionListItemNameSkippedCss,
actionListItemSelectedCss,
actionListItemSelectorCss,
actionListItemSkippedCss,
actionListItemTimeCss,
selectorButtonCss,
selectorButtonSelectedCss,
selectorButtonSmallCss,
} from './utils/createStylingFromTheme';
} 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>> {
actionId: number;
isInitAction: boolean;
@ -86,16 +90,36 @@ export default class ActionListRow<
onMouseUp={this.handleMouseEnter}
data-id={actionId}
css={[
actionListItemCss,
isSelected && actionListItemSelectedCss,
isSkipped && actionListItemSkippedCss,
isInFuture && actionListFromFutureCss,
(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
css={[
actionListItemNameCss,
isSkipped && actionListItemNameSkippedCss,
{
overflow: 'hidden',
textOverflow: 'ellipsis',
lineHeight: '20px',
},
isSkipped && { textDecoration: 'line-through', opacity: 0.3 },
]}
>
{actionType}
@ -112,7 +136,7 @@ export default class ActionListRow<
</div>
</RightSlider>
) : (
<div css={actionListItemButtonsCss}>
<div css={{ position: 'relative', height: '20px', display: 'flex' }}>
<RightSlider shown={!showButtons} rotate>
<div css={actionListItemTimeCss}>
{timeDelta === 0
@ -124,7 +148,7 @@ export default class ActionListRow<
</div>
</RightSlider>
<RightSlider shown={showButtons} rotate>
<div css={actionListItemSelectorCss}>
<div css={{ display: 'inline-flex' }}>
{([BUTTON_JUMP, BUTTON_SKIP] as const).map(
(btn) =>
(!isInitAction || btn !== BUTTON_SKIP) && (

View File

@ -9,12 +9,6 @@ import ActionPreviewHeader from './ActionPreviewHeader';
import DiffTab from './tabs/DiffTab';
import StateTab from './tabs/StateTab';
import ActionTab from './tabs/ActionTab';
import {
actionPreviewContentCss,
actionPreviewCss,
stateErrorCss,
treeItemPinCss,
} from './utils/createStylingFromTheme';
export interface TabComponentProps<S, A extends Action<string>> {
labelRenderer: LabelRenderer;
@ -123,13 +117,31 @@ class ActionPreview<S, A extends Action<string>> extends Component<
renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName)!;
return (
<div key="actionPreview" css={actionPreviewCss}>
<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>>[]}
{...{ inspectedPath, onInspectPath, tabName, onSelectTab }}
/>
{!error && (
<div key="actionPreviewContent" css={actionPreviewContentCss}>
<div key="actionPreviewContent" css={{ flex: 1, overflowY: 'auto' }}>
<TabComponent
labelRenderer={this.labelRenderer}
{...{
@ -152,7 +164,19 @@ class ActionPreview<S, A extends Action<string>> extends Component<
/>
</div>
)}
{error && <div css={stateErrorCss}>{error}</div>}
{error && (
<div
css={(theme) => ({
padding: '10px',
marginLeft: '14px',
fontWeight: 'bold',
color: theme.ERROR_COLOR,
})}
>
{error}
</div>
)}
</div>
);
}
@ -164,7 +188,16 @@ class ActionPreview<S, A extends Action<string>> extends Component<
<span>
<span>{key}</span>
<span
css={treeItemPinCss}
css={(theme) => ({
fontSize: '0.7em',
paddingLeft: '5px',
cursor: 'pointer',
'&:hover': {
textDecoration: 'underline',
},
color: theme.PIN_COLOR,
})}
onClick={() =>
onInspectPath([
...inspectedPath.slice(0, inspectedPath.length - 1),

View File

@ -1,15 +1,27 @@
import React, { FunctionComponent } from 'react';
import { Action } from 'redux';
import { css } from '@emotion/react';
import type { Interpolation, Theme } from '@emotion/react';
import { Tab } from './ActionPreview';
import {
inspectedPathCss,
inspectedPathKeyCss,
inspectedPathKeyLinkCss,
previewHeaderCss,
selectorButtonCss,
selectorButtonSelectedCss,
tabSelectorCss,
} from './utils/createStylingFromTheme';
} 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>[];
@ -22,8 +34,20 @@ interface Props<S, A extends Action<string>> {
const ActionPreviewHeader: FunctionComponent<
Props<unknown, Action<string>>
> = ({ inspectedPath, onInspectPath, tabName, onSelectTab, tabs }) => (
<div key="previewHeader" css={previewHeaderCss}>
<div css={tabSelectorCss}>
<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)}
@ -37,7 +61,7 @@ const ActionPreviewHeader: FunctionComponent<
</div>
))}
</div>
<div css={inspectedPathCss}>
<div css={{ padding: '6px 0' }}>
{inspectedPath.length ? (
<span css={inspectedPathKeyCss}>
<a onClick={() => onInspectPath([])} css={inspectedPathKeyLinkCss}>

View File

@ -8,12 +8,10 @@ import {
import { Action, Dispatch } from 'redux';
import { Delta, DiffContext } from 'jsondiffpatch';
import {
Base16ThemeName,
createInspectorMonitorThemeFromBase16Theme,
inspectorCss,
inspectorWideCss,
resolveBase16Theme,
} from './utils/createStylingFromTheme';
} from './utils/themes';
import type { Base16ThemeName } from './utils/themes';
import ActionList from './ActionList';
import ActionPreview, { Tab } from './ActionPreview';
import getInspectedState from './utils/getInspectedState';
@ -284,7 +282,22 @@ class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
key="inspector"
data-testid="inspector"
ref={this.inspectorCreateRef}
css={[inspectorCss, isWideLayout && inspectorWideCss]}
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
{...{

View File

@ -1,10 +1,4 @@
import React, { FunctionComponent } from 'react';
import {
rightSliderCss,
rightSliderRotateCss,
rightSliderRotateShownCss,
rightSliderShownCss,
} from './utils/createStylingFromTheme';
interface Props {
shown?: boolean;
@ -15,10 +9,26 @@ interface Props {
const RightSlider: FunctionComponent<Props> = ({ shown, children, rotate }) => (
<div
css={[
rightSliderCss,
shown && rightSliderShownCss,
rotate && rightSliderRotateCss,
rotate && shown && rightSliderRotateShownCss,
{
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}

View File

@ -3,7 +3,7 @@ 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 type { Base16ThemeName } 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';

View File

@ -4,18 +4,10 @@ import type { LabelRenderer, ShouldExpandNodeInitially } from 'react-json-tree';
import { stringify } from 'javascript-stringify';
import { Delta } from 'jsondiffpatch';
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';
import {
diffAddCss,
diffCss,
diffRemoveCss,
diffUpdateArrowCss,
diffUpdateFromCss,
diffUpdateToCss,
diffWrapCss,
stateDiffEmptyCss,
} from '../utils/createStylingFromTheme';
function stringifyAndShrink(val: any, isWideLayout?: boolean) {
if (val === null) {
@ -55,6 +47,16 @@ 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;
base16Theme: Base16Theme;
@ -93,7 +95,16 @@ export default class JSONDiff extends Component<Props, State> {
const { base16Theme, ...props } = this.props;
if (!this.state.data) {
return <div css={stateDiffEmptyCss}>(states are equal)</div>;
return (
<div
css={(theme) => ({
padding: '10px',
color: theme.TEXT_PLACEHOLDER_COLOR,
})}
>
(states are equal)
</div>
);
}
return (
@ -128,7 +139,13 @@ export default class JSONDiff extends Component<Props, State> {
case 1:
return (
<span css={diffWrapCss}>
<span key="diffAdd" css={[diffCss, diffAddCss]}>
<span
key="diffAdd"
css={[
diffCss,
(theme) => ({ backgroundColor: theme.DIFF_ADD_COLOR }),
]}
>
{stringifyAndShrink(value[0], isWideLayout)}
</span>
</span>
@ -136,13 +153,31 @@ export default class JSONDiff extends Component<Props, State> {
case 2:
return (
<span css={diffWrapCss}>
<span key="diffUpdateFrom" css={[diffCss, diffUpdateFromCss]}>
<span
key="diffUpdateFrom"
css={[
diffCss,
(theme) => ({
textDecoration: 'line-through',
backgroundColor: theme.DIFF_REMOVE_COLOR,
}),
]}
>
{stringifyAndShrink(value[0], isWideLayout)}
</span>
<span key="diffUpdateArrow" css={[diffCss, diffUpdateArrowCss]}>
<span
key="diffUpdateArrow"
css={[diffCss, (theme) => ({ color: theme.DIFF_ARROW_COLOR })]}
>
{' => '}
</span>
<span key="diffUpdateTo" css={[diffCss, diffUpdateToCss]}>
<span
key="diffUpdateTo"
css={[
diffCss,
(theme) => ({ backgroundColor: theme.DIFF_ADD_COLOR }),
]}
>
{stringifyAndShrink(value[1], isWideLayout)}
</span>
</span>
@ -150,7 +185,16 @@ export default class JSONDiff extends Component<Props, State> {
case 3:
return (
<span css={diffWrapCss}>
<span key="diffRemove" css={[diffCss, diffRemoveCss]}>
<span
key="diffRemove"
css={[
diffCss,
(theme) => ({
textDecoration: 'line-through',
backgroundColor: theme.DIFF_REMOVE_COLOR,
}),
]}
>
{stringifyAndShrink(value[0])}
</span>
</span>

View File

@ -1,7 +1,6 @@
import React from 'react';
import { isCollection, isIndexed, isKeyed } from 'immutable';
import isIterable from '../utils/isIterable';
import { treeItemHintCss } from '../utils/createStylingFromTheme';
const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
@ -78,7 +77,7 @@ const getItemString = (
isWideLayout: boolean,
isDiff?: boolean,
) => (
<span css={treeItemHintCss}>
<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)}

View File

@ -1,384 +0,0 @@
import { css } from '@emotion/react';
import type { Interpolation, Theme } from '@emotion/react';
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';
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;
}
}
export 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 const inspectorCss: Interpolation<Theme> = (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,
});
export const inspectorWideCss = css({ flexDirection: 'row' });
export const actionListCss: Interpolation<Theme> = (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,
});
export const actionListWideCss = css({
flexBasis: '40%',
borderBottom: 'none',
borderRightWidth: '3px',
borderRightStyle: 'double',
});
export const actionListHeaderCss: Interpolation<Theme> = (theme) => ({
display: 'flex',
flex: '0 0 auto',
alignItems: 'center',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
borderColor: theme.LIST_BORDER_COLOR,
});
export const actionListRowsCss = css({ overflow: 'auto' });
export const actionListHeaderSelectorCss = css({
display: 'inline-flex',
marginRight: '10px',
});
export const actionListItemCss: Interpolation<Theme> = (theme) => ({
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
display: 'flex',
justifyContent: 'space-between',
padding: '5px 10px',
cursor: 'pointer',
userSelect: 'none',
borderBottomColor: theme.BORDER_COLOR,
});
export const actionListItemSelectedCss: Interpolation<Theme> = (theme) => ({
backgroundColor: theme.SELECTED_BACKGROUND_COLOR,
});
export const actionListItemSkippedCss: Interpolation<Theme> = (theme) => ({
backgroundColor: theme.SKIPPED_BACKGROUND_COLOR,
});
export const actionListFromFutureCss = css({ opacity: '0.6' });
export const actionListItemButtonsCss = css({
position: 'relative',
height: '20px',
display: 'flex',
});
export 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,
});
export const actionListItemSelectorCss = css({ display: 'inline-flex' });
export const actionListItemNameCss = css({
overflow: 'hidden',
textOverflow: 'ellipsis',
lineHeight: '20px',
});
export const actionListItemNameSkippedCss = css({
textDecoration: 'line-through',
opacity: 0.3,
});
export const actionListHeaderSearchCss: Interpolation<Theme> = (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,
},
});
export const actionListHeaderWrapperCss = css({
position: 'relative',
height: '20px',
});
export const actionPreviewCss: Interpolation<Theme> = (theme) => ({
flex: 1,
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
overflowY: 'hidden',
'& pre': {
border: 'inherit',
borderRadius: '3px',
lineHeight: 'inherit',
color: 'inherit',
},
backgroundColor: theme.BACKGROUND_COLOR,
});
export const actionPreviewContentCss = css({ flex: 1, overflowY: 'auto' });
export const stateDiffEmptyCss: Interpolation<Theme> = (theme) => ({
padding: '10px',
color: theme.TEXT_PLACEHOLDER_COLOR,
});
export const stateErrorCss: Interpolation<Theme> = (theme) => ({
padding: '10px',
marginLeft: '14px',
fontWeight: 'bold',
color: theme.ERROR_COLOR,
});
export const inspectedPathCss = css({ padding: '6px 0' });
export const inspectedPathKeyCss = css({
'&:not(:last-child):after': {
content: '" > "',
},
});
export const inspectedPathKeyLinkCss: Interpolation<Theme> = (theme) => ({
cursor: 'pointer',
color: theme.LINK_COLOR,
'&:hover': {
textDecoration: 'underline',
color: theme.LINK_HOVER_COLOR,
},
});
export const treeItemPinCss: Interpolation<Theme> = (theme) => ({
fontSize: '0.7em',
paddingLeft: '5px',
cursor: 'pointer',
'&:hover': {
textDecoration: 'underline',
},
color: theme.PIN_COLOR,
});
export const treeItemHintCss: Interpolation<Theme> = (theme) => ({
color: theme.ITEM_HINT_COLOR,
});
export const previewHeaderCss: Interpolation<Theme> = (theme) => ({
flex: '0 0 30px',
padding: '5px 10px',
alignItems: 'center',
borderBottomWidth: '1px',
borderBottomStyle: 'solid',
backgroundColor: theme.HEADER_BACKGROUND_COLOR,
borderBottomColor: theme.HEADER_BORDER_COLOR,
});
export const tabSelectorCss = css({
position: 'relative',
display: 'inline-flex',
float: 'right',
});
export const selectorButtonCss: Interpolation<Theme> = (theme) => ({
cursor: 'pointer',
position: 'relative',
padding: '5px 10px',
borderStyle: 'solid',
borderWidth: '1px',
borderLeftWidth: 0,
'&:first-child': {
borderLeftWidth: '1px',
borderTopLeftRadius: '3px',
borderBottomLeftRadius: '3px',
},
'&:last-child': {
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,
});
export const diffCss: Interpolation<Theme> = (theme) => ({
padding: '2px 3px',
borderRadius: '3px',
position: 'relative',
color: theme.TEXT_COLOR,
});
export const diffWrapCss = css({ position: 'relative', zIndex: 1 });
export const diffAddCss: Interpolation<Theme> = (theme) => ({
backgroundColor: theme.DIFF_ADD_COLOR,
});
export const diffRemoveCss: Interpolation<Theme> = (theme) => ({
textDecoration: 'line-through',
backgroundColor: theme.DIFF_REMOVE_COLOR,
});
export const diffUpdateFromCss: Interpolation<Theme> = (theme) => ({
textDecoration: 'line-through',
backgroundColor: theme.DIFF_REMOVE_COLOR,
});
export const diffUpdateToCss: Interpolation<Theme> = (theme) => ({
backgroundColor: theme.DIFF_ADD_COLOR,
});
export const diffUpdateArrowCss: Interpolation<Theme> = (theme) => ({
color: theme.DIFF_ARROW_COLOR,
});
export const rightSliderCss = css({
WebkitFontSmoothing: 'subpixel-antialiased', // http://stackoverflow.com/a/21136111/4218591
position: 'absolute',
right: 0,
transform: 'translateX(150%)',
transition: 'transform 0.2s ease-in-out',
});
export const rightSliderRotateCss = css({
transform: 'rotateX(90deg)',
transition: 'transform 0.2s ease-in-out 0.08s',
});
export const rightSliderShownCss = css({
position: 'static',
transform: 'translateX(0)',
});
export const rightSliderRotateShownCss = css({
transform: 'rotateX(0)',
transition: 'transform 0.2s ease-in-out 0.18s',
});
const base16Themes = { ...reduxThemes, ...inspectorThemes };
export type Base16ThemeName = keyof typeof base16Themes;
export function resolveBase16Theme(theme: Base16ThemeName | Base16Theme) {
return getBase16Theme(theme, base16Themes);
}
export function createInspectorMonitorThemeFromBase16Theme(
base16Theme: Base16Theme,
invertTheme: boolean,
) {
const finalBase16Theme = invertTheme
? invertBase16Theme(base16Theme)
: base16Theme;
return colorMap(finalBase16Theme);
}

View File

@ -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-child': {
borderLeftWidth: '1px',
borderTopLeftRadius: '3px',
borderBottomLeftRadius: '3px',
},
'&:last-child': {
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,
});

View File

@ -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);
}