Skip to content

Commit

Permalink
feat: add position option (#118)
Browse files Browse the repository at this point in the history
* feat: add className and position option

* fix: remove className option

* fix: remove className

* chore: add test update readme

* chore: update
  • Loading branch information
hyoban authored Jan 13, 2024
1 parent 1aaab4b commit 9db1951
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 51 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ type DevToolsProps = {
store?: Store;
// Defaults to light
theme?: 'dark' | 'light';
// Defaults to 'bottom-left'
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
// Custom nonce to allowlist jotai-devtools specific inline styles via CSP
nonce?: string;
// We recommend keeping these options static. i.e. set it only once. Avoid connecting it to re-renderable state
Expand Down
18 changes: 18 additions & 0 deletions __tests__/devtools/basic.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@ describe('DevTools - basic', () => {
).toBeInTheDocument();
});

it('should be placed on the bottom left by default', async () => {
customRender(<DevTools />);
expect(screen.getByTitle('Open Jotai Devtools')).toHaveStyle({
bottom: '0.2rem',
left: '0.2rem',
});
});

it('should respect the position prop', async () => {
customRender(<DevTools position="top-right" />);
expect(screen.getByTitle('Open Jotai Devtools')).toHaveStyle({
top: '0.2rem',
right: '0.2rem',
bottom: 'unset',
left: 'unset',
});
});

it('should resize the devtools upon dragging the resize bar', async () => {
customRender(<DevTools isInitialOpen={true} />);

Expand Down
80 changes: 47 additions & 33 deletions src/DevTools/DevTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,15 @@ import {
import {
Extension,
ExtensionProps,
shellTriggerButtonStyles,
shellTriggerButtonClassName,
} from './Extension';
import { fontCss } from './fonts';
import { InternalDevToolsContext } from './internal-jotai-store';
import { createMemoizedEmotionCache } from './utils';

const theme: MantineThemeOverride = {
primaryColor: 'dark',
activeStyles: { transform: 'scale(1)' },
fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, Segoe, sans-serif',
fontFamilyMonospace:
'JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',
headings: {
fontFamily:
'Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji',
},
defaultRadius: 'md',
globalStyles: (theme) => ({
'.jotai-devtools-shell': {
'*, *::before, *::after': {
boxSizing: 'border-box',
},
...theme.fn.fontStyles(),
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
lineHeight: theme.lineHeight,
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale',
fontSize: theme.fontSizes.md,
},
...shellTriggerButtonStyles,
}),
};

export type DevToolsProps = ExtensionProps & {
theme?: 'dark' | 'light';
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
nonce?: string;
options?: DevToolsOptions;
};
Expand All @@ -58,6 +32,7 @@ const DevToolsMain = ({
store,
isInitialOpen = false,
theme: userColorScheme = 'light',
position = 'bottom-left',
nonce,
options,
}: DevToolsProps): JSX.Element => {
Expand All @@ -83,10 +58,49 @@ const DevToolsMain = ({
setDevToolsOptions(options);
}, [setDevToolsOptions, options]);

const theme_ = {
...theme,
colorScheme,
};
const theme: MantineThemeOverride = React.useMemo(() => {
return {
primaryColor: 'dark',
activeStyles: { transform: 'scale(1)' },
fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, Segoe, sans-serif',
fontFamilyMonospace:
'JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',
headings: {
fontFamily:
'Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji',
},
defaultRadius: 'md',
globalStyles: (theme) => ({
'.jotai-devtools-shell': {
'*, *::before, *::after': {
boxSizing: 'border-box',
},
...theme.fn.fontStyles(),
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
lineHeight: theme.lineHeight,
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale',
fontSize: theme.fontSizes.md,
},
[`.${shellTriggerButtonClassName}`]: {
position: 'fixed',
borderRadius: '50%',
borderWidth: 0,
width: '4rem',
height: '4rem',
zIndex: 99999,
img: {
height: '2rem',
},
left: position.includes('left') ? '0.2rem' : 'unset',
right: position.includes('right') ? '0.2rem' : 'unset',
top: position.includes('top') ? '0.2rem' : 'unset',
bottom: position.includes('bottom') ? '0.2rem' : 'unset',
},
}),
colorScheme,
};
}, [colorScheme, position]);

return (
<React.StrictMode>
Expand All @@ -95,7 +109,7 @@ const DevToolsMain = ({
toggleColorScheme={toggleColorScheme}
>
<MantineProvider
theme={theme_}
theme={theme}
emotionCache={jotaiDevtoolsEmotionCache.current}
>
<Global styles={fontCss} />
Expand Down
19 changes: 1 addition & 18 deletions src/DevTools/Extension/Extension.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { ActionIcon } from '@mantine/core';
import type { CSSObject } from '@mantine/core';
import { useAtom, useSetAtom } from 'jotai/react';
import { Store } from '../../types';
import { isShellOpenAtom } from '../atoms/is-shell-open-atom';
Expand All @@ -11,23 +10,7 @@ import { logo } from './assets/logo';
import { Shell } from './components/Shell';
import useSyncSnapshotHistory from './components/Shell/components/TimeTravel/useSyncSnapshotHistory';

const shellTriggerButtonClassName = 'jotai-devtools-trigger-button';

export const shellTriggerButtonStyles: CSSObject = {
[`.${shellTriggerButtonClassName}`]: {
position: 'fixed',
left: 10,
bottom: 10,
borderRadius: '50%',
borderWidth: 0,
width: '4rem',
height: '4rem',
zIndex: 99999,
img: {
height: '2rem',
},
},
};
export const shellTriggerButtonClassName = 'jotai-devtools-trigger-button';

const ShellTriggerButton = React.forwardRef<HTMLButtonElement>((_, ref) => {
const setIsShellOpen = useSetAtom(
Expand Down

0 comments on commit 9db1951

Please sign in to comment.