mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: Add theme prop (#3228)
* support appearance when updating scene data * works! * whoops, missed a prop * hide appearance button when prop is not set * cleanup * fix export + rename prop to theme * rename to showThemeBtn, hide via react instead of css * adapt to new state name * add tests and css selector to target the dark mode toggle * updated changelog and readme * fix markdown rendering in readme * pr feedback
This commit is contained in:
parent
1f295955d0
commit
84a1863233
10 changed files with 62 additions and 10 deletions
|
@ -303,9 +303,11 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
viewModeEnabled = false,
|
||||
zenModeEnabled = false,
|
||||
gridModeEnabled = false,
|
||||
theme = defaultAppState.theme,
|
||||
} = props;
|
||||
this.state = {
|
||||
...defaultAppState,
|
||||
theme,
|
||||
isLoading: true,
|
||||
width,
|
||||
height,
|
||||
|
@ -458,6 +460,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
showExitZenModeBtn={
|
||||
typeof this.props?.zenModeEnabled === "undefined" && zenModeEnabled
|
||||
}
|
||||
showThemeBtn={typeof this.props?.theme === "undefined"}
|
||||
libraryReturnUrl={this.props.libraryReturnUrl}
|
||||
/>
|
||||
<div className="excalidraw-textEditorContainer" />
|
||||
|
@ -519,6 +522,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
let viewModeEnabled = actionResult?.appState?.viewModeEnabled || false;
|
||||
let zenModeEnabled = actionResult?.appState?.zenModeEnabled || false;
|
||||
let gridSize = actionResult?.appState?.gridSize || null;
|
||||
let theme = actionResult?.appState?.theme || "light";
|
||||
|
||||
if (typeof this.props.viewModeEnabled !== "undefined") {
|
||||
viewModeEnabled = this.props.viewModeEnabled;
|
||||
|
@ -532,6 +536,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
gridSize = this.props.gridModeEnabled ? GRID_SIZE : null;
|
||||
}
|
||||
|
||||
if (typeof this.props.theme !== "undefined") {
|
||||
theme = this.props.theme;
|
||||
}
|
||||
|
||||
this.setState(
|
||||
(state) => {
|
||||
// using Object.assign instead of spread to fool TS 4.2.2+ into
|
||||
|
@ -547,6 +555,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
viewModeEnabled,
|
||||
zenModeEnabled,
|
||||
gridSize,
|
||||
theme,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
|
@ -882,6 +891,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });
|
||||
}
|
||||
|
||||
if (prevProps.theme !== this.props.theme && this.props.theme) {
|
||||
this.setState({ theme: this.props.theme });
|
||||
}
|
||||
|
||||
if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {
|
||||
this.setState({
|
||||
gridSize: this.props.gridModeEnabled ? GRID_SIZE : null,
|
||||
|
|
|
@ -7,20 +7,24 @@ export const BackgroundPickerAndDarkModeToggle = ({
|
|||
appState,
|
||||
setAppState,
|
||||
actionManager,
|
||||
showThemeBtn,
|
||||
}: {
|
||||
actionManager: ActionManager;
|
||||
appState: AppState;
|
||||
setAppState: React.Component<any, AppState>["setState"];
|
||||
showThemeBtn: boolean;
|
||||
}) => (
|
||||
<div style={{ display: "flex" }}>
|
||||
{actionManager.renderAction("changeViewBackgroundColor")}
|
||||
<div style={{ marginInlineStart: "0.25rem" }}>
|
||||
<DarkModeToggle
|
||||
value={appState.theme}
|
||||
onChange={(theme) => {
|
||||
setAppState({ theme });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{showThemeBtn && (
|
||||
<div style={{ marginInlineStart: "0.25rem" }}>
|
||||
<DarkModeToggle
|
||||
value={appState.theme}
|
||||
onChange={(theme) => {
|
||||
setAppState({ theme });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -20,7 +20,8 @@ export const DarkModeToggle = (props: {
|
|||
|
||||
return (
|
||||
<label
|
||||
className={`ToolIcon ToolIcon_type_floating ToolIcon_size_M`}
|
||||
className="ToolIcon ToolIcon_type_floating ToolIcon_size_M"
|
||||
data-testid="toggle-dark-mode"
|
||||
title={title}
|
||||
>
|
||||
<input
|
||||
|
|
|
@ -53,6 +53,7 @@ interface LayerUIProps {
|
|||
onInsertElements: (elements: readonly NonDeletedExcalidrawElement[]) => void;
|
||||
zenModeEnabled: boolean;
|
||||
showExitZenModeBtn: boolean;
|
||||
showThemeBtn: boolean;
|
||||
toggleZenMode: () => void;
|
||||
langCode: Language["code"];
|
||||
isCollaborating: boolean;
|
||||
|
@ -325,6 +326,7 @@ const LayerUI = ({
|
|||
onInsertElements,
|
||||
zenModeEnabled,
|
||||
showExitZenModeBtn,
|
||||
showThemeBtn,
|
||||
toggleZenMode,
|
||||
isCollaborating,
|
||||
onExportToBackend,
|
||||
|
@ -441,6 +443,7 @@ const LayerUI = ({
|
|||
actionManager={actionManager}
|
||||
appState={appState}
|
||||
setAppState={setAppState}
|
||||
showThemeBtn={showThemeBtn}
|
||||
/>
|
||||
</Stack.Col>
|
||||
</Island>
|
||||
|
@ -671,6 +674,7 @@ const LayerUI = ({
|
|||
isCollaborating={isCollaborating}
|
||||
renderCustomFooter={renderCustomFooter}
|
||||
viewModeEnabled={viewModeEnabled}
|
||||
showThemeBtn={showThemeBtn}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
|
|
@ -30,6 +30,7 @@ type MobileMenuProps = {
|
|||
isCollaborating: boolean;
|
||||
renderCustomFooter?: (isMobile: boolean) => JSX.Element;
|
||||
viewModeEnabled: boolean;
|
||||
showThemeBtn: boolean;
|
||||
};
|
||||
|
||||
export const MobileMenu = ({
|
||||
|
@ -45,6 +46,7 @@ export const MobileMenu = ({
|
|||
isCollaborating,
|
||||
renderCustomFooter,
|
||||
viewModeEnabled,
|
||||
showThemeBtn,
|
||||
}: MobileMenuProps) => {
|
||||
const renderToolbar = () => {
|
||||
return (
|
||||
|
@ -130,6 +132,7 @@ export const MobileMenu = ({
|
|||
actionManager={actionManager}
|
||||
appState={appState}
|
||||
setAppState={setAppState}
|
||||
showThemeBtn={showThemeBtn}
|
||||
/>
|
||||
}
|
||||
</>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue