Adds dark mode
This commit is contained in:
parent
840532142e
commit
c353fd257f
11 changed files with 58 additions and 21 deletions
|
@ -23,11 +23,13 @@ interface CanvasProps<T extends TLShape> {
|
|||
hideBounds?: boolean
|
||||
hideHandles?: boolean
|
||||
hideIndicators?: boolean
|
||||
isDarkMode?: boolean
|
||||
}
|
||||
|
||||
export const Canvas = React.memo(function Canvas<T extends TLShape>({
|
||||
page,
|
||||
pageState,
|
||||
isDarkMode = false,
|
||||
hideHandles = false,
|
||||
hideBounds = false,
|
||||
hideIndicators = false,
|
||||
|
@ -56,6 +58,7 @@ export const Canvas = React.memo(function Canvas<T extends TLShape>({
|
|||
hideBounds={hideBounds}
|
||||
hideIndicators={hideIndicators}
|
||||
hideHandles={hideHandles}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
<Brush />
|
||||
</g>
|
||||
|
|
|
@ -13,6 +13,7 @@ interface PageProps<T extends TLShape> {
|
|||
hideBounds: boolean
|
||||
hideHandles: boolean
|
||||
hideIndicators: boolean
|
||||
isDarkMode: boolean
|
||||
}
|
||||
|
||||
export function Page<T extends TLShape>({
|
||||
|
@ -21,12 +22,13 @@ export function Page<T extends TLShape>({
|
|||
hideBounds,
|
||||
hideHandles,
|
||||
hideIndicators,
|
||||
isDarkMode,
|
||||
}: PageProps<T>): JSX.Element {
|
||||
const { callbacks, shapeUtils } = useTLContext()
|
||||
|
||||
useRenderOnResize()
|
||||
|
||||
const shapeTree = useShapeTree(page, pageState, shapeUtils, callbacks.onChange)
|
||||
const shapeTree = useShapeTree(page, pageState, shapeUtils, isDarkMode, callbacks.onChange)
|
||||
|
||||
const { shapeWithHandles } = useHandles(page, pageState)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ export interface RendererProps<T extends TLShape>
|
|||
hideBounds?: boolean
|
||||
hideHandles?: boolean
|
||||
hideIndicators?: boolean
|
||||
isDarkMode?: boolean
|
||||
}
|
||||
|
||||
export function Renderer<T extends TLShape>({
|
||||
|
@ -33,6 +34,7 @@ export function Renderer<T extends TLShape>({
|
|||
hideHandles = false,
|
||||
hideIndicators = false,
|
||||
hideBounds = false,
|
||||
isDarkMode = false,
|
||||
...rest
|
||||
}: RendererProps<T>): JSX.Element {
|
||||
useTLTheme(theme)
|
||||
|
@ -58,6 +60,7 @@ export function Renderer<T extends TLShape>({
|
|||
hideBounds={hideBounds}
|
||||
hideIndicators={hideIndicators}
|
||||
hideHandles={hideHandles}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
</TLContext.Provider>
|
||||
)
|
||||
|
|
|
@ -50,6 +50,7 @@ export function useShapeTree<T extends TLShape>(
|
|||
page: TLPage<T, TLBinding>,
|
||||
pageState: TLPageState,
|
||||
shapeUtils: TLShapeUtils<T>,
|
||||
isDarkMode: boolean,
|
||||
onChange?: TLCallbacks['onChange']
|
||||
) {
|
||||
const rPreviousCount = React.useRef(0)
|
||||
|
@ -105,7 +106,9 @@ export function useShapeTree<T extends TLShape>(
|
|||
|
||||
shapesToRender
|
||||
.sort((a, b) => a.childIndex - b.childIndex)
|
||||
.forEach((shape) => addToShapeTree(shape, tree, page.shapes, selectedIds, pageState))
|
||||
.forEach((shape) =>
|
||||
addToShapeTree(shape, tree, page.shapes, selectedIds, { ...pageState, isDarkMode })
|
||||
)
|
||||
|
||||
return tree
|
||||
}
|
||||
|
|
|
@ -265,10 +265,13 @@ const tlcss = css`
|
|||
`
|
||||
|
||||
export function useTLTheme(theme?: Partial<TLTheme>) {
|
||||
const [tltheme] = React.useState<TLTheme>(() => ({
|
||||
...defaultTheme,
|
||||
...theme,
|
||||
}))
|
||||
const tltheme = React.useMemo<TLTheme>(
|
||||
() => ({
|
||||
...defaultTheme,
|
||||
...theme,
|
||||
}),
|
||||
[theme]
|
||||
)
|
||||
|
||||
useTheme('tl', tltheme)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>React App</title>
|
||||
<title>tldraw</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
import * as React from 'react'
|
||||
import { DropdownMenuSubMenu, DropdownMenuCheckboxItem } from '~components/shared'
|
||||
import { useTheme, useTLDrawContext } from '~hooks'
|
||||
import { useTLDrawContext } from '~hooks'
|
||||
import type { Data } from '~types'
|
||||
|
||||
const isDebugModeSelector = (s: Data) => s.settings.isDebugMode
|
||||
const isDarkModeSelector = (s: Data) => s.settings.isDarkMode
|
||||
|
||||
export function Preferences() {
|
||||
const { theme, toggle } = useTheme()
|
||||
const { tlstate, useSelector } = useTLDrawContext()
|
||||
|
||||
const isDebugMode = useSelector(isDebugModeSelector)
|
||||
const isDarkMode = theme === 'dark'
|
||||
const isDarkMode = useSelector(isDarkModeSelector)
|
||||
|
||||
const toggleDebugMode = React.useCallback(() => {
|
||||
tlstate.toggleDebugMode()
|
||||
}, [tlstate])
|
||||
|
||||
const toggleDarkMode = React.useCallback(() => {
|
||||
tlstate.toggleDarkMode()
|
||||
}, [tlstate])
|
||||
|
||||
return (
|
||||
<DropdownMenuSubMenu label="Preferences">
|
||||
<DropdownMenuCheckboxItem checked={isDarkMode} onCheckedChange={toggle}>
|
||||
<DropdownMenuCheckboxItem checked={isDarkMode} onCheckedChange={toggleDarkMode}>
|
||||
<span>Dark Mode</span>
|
||||
</DropdownMenuCheckboxItem>
|
||||
<DropdownMenuCheckboxItem checked={isDebugMode} onCheckedChange={toggleDebugMode}>
|
||||
|
|
|
@ -27,6 +27,7 @@ const isSelectedShapeWithHandlesSelector = (s: Data) => {
|
|||
}
|
||||
const pageSelector = (s: Data) => s.document.pages[s.appState.currentPageId]
|
||||
const pageStateSelector = (s: Data) => s.document.pageStates[s.appState.currentPageId]
|
||||
const isDarkModeSelector = (s: Data) => s.settings.isDarkMode
|
||||
|
||||
export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }: TLDrawProps) {
|
||||
const [tlstate] = React.useState(() => new TLDrawState())
|
||||
|
@ -38,6 +39,7 @@ export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }
|
|||
|
||||
const page = context.useSelector(pageSelector)
|
||||
const pageState = context.useSelector(pageStateSelector)
|
||||
const isDarkMode = context.useSelector(isDarkModeSelector)
|
||||
const isSelecting = context.useSelector(isInSelectSelector)
|
||||
const isSelectedHandlesShape = context.useSelector(isSelectedShapeWithHandlesSelector)
|
||||
const isInSession = !!tlstate.session
|
||||
|
@ -65,6 +67,21 @@ export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }
|
|||
onMount?.(tlstate)
|
||||
}, [])
|
||||
|
||||
const theme = React.useMemo(() => {
|
||||
if (isDarkMode) {
|
||||
return {
|
||||
brushFill: 'rgba(180, 180, 180, .05)',
|
||||
brushStroke: 'rgba(180, 180, 180, .25)',
|
||||
selected: 'rgba(38, 150, 255, 1.000)',
|
||||
selectFill: 'rgba(38, 150, 255, 0.05)',
|
||||
background: '#343d45',
|
||||
foreground: '#49555f',
|
||||
}
|
||||
}
|
||||
|
||||
return {}
|
||||
}, [isDarkMode])
|
||||
|
||||
return (
|
||||
<TLDrawContext.Provider value={context}>
|
||||
<IdProvider>
|
||||
|
@ -74,6 +91,8 @@ export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }
|
|||
page={page}
|
||||
pageState={pageState}
|
||||
shapeUtils={tldrawShapeUtils}
|
||||
theme={theme}
|
||||
isDarkMode={isDarkMode}
|
||||
hideBounds={hideBounds}
|
||||
hideHandles={hideHandles}
|
||||
hideIndicators={hideIndicators}
|
||||
|
|
|
@ -148,6 +148,7 @@ const ToolsPanelContainer = styled('div', {
|
|||
maxWidth: '100%',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr auto 1fr',
|
||||
gridTemplateRows: 'auto auto',
|
||||
padding: '0',
|
||||
alignItems: 'flex-end',
|
||||
zIndex: 200,
|
||||
|
|
|
@ -307,8 +307,6 @@ function getDrawStrokePath(shape: DrawShape, isEditing: boolean) {
|
|||
|
||||
const path = Utils.getSvgPathFromStroke(stroke)
|
||||
|
||||
// console.log(path)
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
|
|
|
@ -326,13 +326,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
`settings:toggled_dark_mode`
|
||||
)
|
||||
}
|
||||
/* --------------------- Status --------------------- */
|
||||
// setStatus(status: TLDrawStatus) {
|
||||
// this.status.previous = this.status.current
|
||||
// this.status.current = status
|
||||
// // console.log(this.status.previous, ' -> ', this.status.current)
|
||||
// return this
|
||||
// }
|
||||
|
||||
/* -------------------- App State ------------------- */
|
||||
|
||||
reset = () => {
|
||||
|
@ -1113,7 +1107,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
|
||||
toggleDebugMode = () => {
|
||||
// TODO
|
||||
return this.produce(
|
||||
{
|
||||
settings: {
|
||||
isDebugMode: !this.data.settings.isDebugMode,
|
||||
},
|
||||
},
|
||||
`settings:toggled_debug`
|
||||
)
|
||||
}
|
||||
|
||||
rotate = (delta = Math.PI * -0.5, ids?: string[]) => {
|
||||
|
|
Loading…
Reference in a new issue