Skip to content

Commit

Permalink
✨ feat: add primary color setting
Browse files Browse the repository at this point in the history
  • Loading branch information
canisminor1990 committed Jun 26, 2023
1 parent 7cdb48d commit 406aba7
Show file tree
Hide file tree
Showing 16 changed files with 488 additions and 307 deletions.
552 changes: 306 additions & 246 deletions javascript/main.js

Large diffs are not rendered by default.

16 changes: 13 additions & 3 deletions src/layouts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { DivProps, ThemeProvider } from '@lobehub/ui';
import { DivProps, ThemeProvider, colors } from '@lobehub/ui';
import { generateColorPalette } from '@lobehub/ui/es/styles/algorithms/generateColorPalette';
import isEqual from 'fast-deep-equal';
import qs from 'query-string';
import { memo, useEffect } from 'react';
import { memo, useCallback, useEffect } from 'react';
import { shallow } from 'zustand/shallow';

import { useIsDarkMode } from '@/hooks/useIsDarkMode';
Expand All @@ -12,6 +14,7 @@ const Layout = memo<DivProps>(({ children }) => {
(st) => ({ onInit: st.onInit, onSetThemeMode: st.onSetThemeMode, themeMode: st.themeMode }),
shallow,
);
const setting = useAppStore((st) => st.setting, isEqual);
const isDarkMode = useIsDarkMode();

useEffect(() => {
Expand All @@ -28,8 +31,15 @@ const Layout = memo<DivProps>(({ children }) => {
}
}, [isDarkMode]);

const genCustomToken = useCallback(() => {
if (!setting.primaryColor) return {};
const scale = colors[setting.primaryColor];

return generateColorPalette({ appearance: themeMode, scale, type: 'Primary' });
}, [setting.primaryColor, themeMode]);

return (
<ThemeProvider themeMode={themeMode}>
<ThemeProvider customToken={genCustomToken} themeMode={themeMode}>
<GlobalStyle />
{children}
</ThemeProvider>
Expand Down
10 changes: 4 additions & 6 deletions src/pages/Content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { useStyles } from './style';
const Content = memo<DivProps>(({ className, ...props }) => {
const mainReference: any = useRef<HTMLElement>();
const setting = useAppStore((st) => st.setting, isEqual);
const { cx, styles } = useStyles({ isPromptResizable: setting.promotTextarea === 'resizable' });
const { cx, styles } = useStyles({
isPrimaryColor: Boolean(setting.primaryColor),
isPromptResizable: setting.promotTextarea === 'resizable',
});
const { mobile } = useResponsive();

useEffect(() => {
Expand All @@ -32,11 +35,6 @@ const Content = memo<DivProps>(({ className, ...props }) => {
className,
)}
ref={mainReference}
style={{
maxWidth: `min( calc(100vw - ${
setting.sidebarWidth + setting.extraNetworkSidebarWidth
}px), 100%)`,
}}
{...props}
>
<div className={styles.background} />
Expand Down
21 changes: 13 additions & 8 deletions src/pages/Content/style.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createStyles } from 'antd-style';
import { rgba } from 'polished';
import { adjustHue, rgba } from 'polished';

const MIN_HEIGHT = 88;
const GALLERY_LIGHT =
Expand All @@ -9,7 +9,7 @@ const GALLERY_DARK =
export const useStyles = createStyles(
(
{ cx, css, token, stylish, isDarkMode },
{ isPromptResizable }: { isPromptResizable: boolean },
{ isPromptResizable, isPrimaryColor }: { isPrimaryColor: boolean; isPromptResizable: boolean },
) => {
const galleryBackground = css`
background: url(${isDarkMode ? GALLERY_DARK : GALLERY_LIGHT}) 0% 0% / 20px !important;
Expand All @@ -19,6 +19,16 @@ export const useStyles = createStyles(
return {
background: cx(
stylish.gradientAnimation,
isPrimaryColor &&
css`
background-image: linear-gradient(
-45deg,
${token.colorPrimary},
${adjustHue(45, token.colorPrimary)},
${token.colorPrimary},
${adjustHue(-45, token.colorPrimary)}
);
`,
css`
pointer-events: none;
Expand All @@ -38,12 +48,7 @@ export const useStyles = createStyles(
container: css`
position: relative;
flex: 1;
max-width: 100%;
div {
position: relative;
box-sizing: border-box;
}
min-width: 0;
.float {
${stylish.blur};
Expand Down
8 changes: 6 additions & 2 deletions src/slots/Loading/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Icon, Logo } from '@lobehub/ui';
import isEqual from 'fast-deep-equal';
import { Loader2 } from 'lucide-react';
import { memo } from 'react';

import { useAppStore } from '@/store';

import { useStyles } from './style';

const Loading = memo(() => {
const { styles } = useStyles();
const setting = useAppStore((st) => st.setting, isEqual);
const { styles } = useStyles(Boolean(setting.primaryColor));

return (
<section className={styles.container}>
<div className={styles.canvas} />
<div className={styles.inner}>
<Logo extra="SD" size={48} type="combine" />
<Icon icon={Loader2} size={{ fontSize: 32 }} spin />
<Icon className={styles.icon} icon={Loader2} size={{ fontSize: 32 }} spin />
</div>
</section>
);
Expand Down
17 changes: 15 additions & 2 deletions src/slots/Loading/style.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { createStyles } from 'antd-style';
import { rgba } from 'polished';
import { adjustHue, rgba } from 'polished';

export const useStyles = createStyles(({ css, stylish, cx, token }) => ({
export const useStyles = createStyles(({ css, stylish, cx, token }, isPrimaryColor?: boolean) => ({
canvas: cx(
stylish.gradientAnimation,
isPrimaryColor &&
css`
background-image: linear-gradient(
-45deg,
${token.colorPrimary},
${adjustHue(45, token.colorPrimary)},
${token.colorPrimary},
${adjustHue(-45, token.colorPrimary)}
);
`,
css`
pointer-events: none;
Expand Down Expand Up @@ -37,6 +47,9 @@ export const useStyles = createStyles(({ css, stylish, cx, token }) => ({
background: ${rgba(token.colorBgLayout, 0.5)};
`,
),
icon: css`
color: ${token.colorPrimary};
`,
inner: css`
display: flex;
flex-direction: column;
Expand Down
46 changes: 38 additions & 8 deletions src/slots/Setting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,47 @@ import isEqual from 'fast-deep-equal';
import { memo, useCallback, useState } from 'react';
import { shallow } from 'zustand/shallow';

import { WebuiSetting, defaultSetting, useAppStore } from '@/store';
import { PrimaryColor, WebuiSetting, defaultSetting, useAppStore } from '@/store';

import { useStyles } from './style';

const { Item } = Form;

const findKey = (
object: { [key in PrimaryColor]: string },
value: string,
): PrimaryColor | undefined => {
const res: { [key: string]: PrimaryColor } = {};
for (const key of Object.keys(object)) {
// @ts-ignore
res[object[key]] = key;
}
return res[value];
};

const Setting = memo(() => {
const setting = useAppStore((st) => st.setting, isEqual);
const [activeColor, setActiveColor] = useState<string | undefined>(setting.primaryColor || '');
const [activeColor, setActiveColor] = useState<PrimaryColor | undefined>(
setting.primaryColor || undefined,
);
const onSetSetting = useAppStore((st) => st.onSetSetting, shallow);
const { styles, theme } = useStyles();

const colors = {
blue: theme.blue,
cyan: theme.cyan,
geekblue: theme.geekblue,
gold: theme.gold,
green: theme.green,
lime: theme.lime,
magenta: theme.magenta,
orange: theme.orange,
purple: theme.purple,
red: theme.red,
volcano: theme.volcano,
yellow: theme.yellow,
};

const onReset = useCallback(() => {
onSetSetting(defaultSetting);
(gradioApp().querySelector('#settings_restart_gradio') as HTMLButtonElement)?.click();
Expand All @@ -29,6 +58,7 @@ const Setting = memo(() => {
[activeColor],
);

// @ts-ignore
return (
<Form
initialValues={setting}
Expand All @@ -39,12 +69,12 @@ const Setting = memo(() => {
style={{ maxWidth: 400 }}
>
<Divider style={{ margin: '4px 0 8px' }} />
<title className={styles.title}>Promot Textarea</title>
<div className={styles.title}>Promot Textarea</div>
<Item className={styles.item} label="Display mode" name="promotTextarea">
<Segmented options={['scroll', 'resizable']} />
</Item>
<Divider style={{ margin: '4px 0 8px' }} />
<title className={styles.title}>Sidebar</title>
<div className={styles.title}>Sidebar</div>
<Item
className={styles.item}
label="Default expand"
Expand All @@ -60,7 +90,7 @@ const Setting = memo(() => {
<InputNumber />
</Item>
<Divider style={{ margin: '4px 0 8px' }} />
<title className={styles.title}>ExtraNetwork Sidebar</title>
<div className={styles.title}>ExtraNetwork Sidebar</div>
<Item
className={styles.item}
label="Enable"
Expand All @@ -87,13 +117,13 @@ const Setting = memo(() => {
<InputNumber />
</Item>
<Divider style={{ margin: '4px 0 8px' }} />
<title className={styles.title}>Theme</title>
<div className={styles.title}>Theme</div>
<Item className={styles.item} label="Use svg icons" name="svgIcon" valuePropName="checked">
<Switch />
</Item>
<Item className={styles.item} label="Primary color">
<Swatches
activeColor={activeColor}
activeColor={activeColor ? colors[activeColor] : undefined}
colors={[
theme.red,
theme.orange,
Expand All @@ -108,7 +138,7 @@ const Setting = memo(() => {
theme.magenta,
theme.volcano,
]}
onSelect={setActiveColor}
onSelect={(c) => setActiveColor(c ? findKey(colors, c) : undefined)}
/>
</Item>
<Divider style={{ margin: '4px 0 16px' }} />
Expand Down
18 changes: 16 additions & 2 deletions src/store/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,27 @@ import { devtools } from 'zustand/middleware';

const SETTING_KEY = 'SD-KITCHEN-SETTING';

export type PrimaryColor =
| 'blue'
| 'cyan'
| 'geekblue'
| 'gold'
| 'green'
| 'lime'
| 'magenta'
| 'orange'
| 'purple'
| 'red'
| 'volcano'
| 'yellow';

export interface WebuiSetting {
enableExtraNetworkSidebar: boolean;
extraNetworkCardSize: number;
extraNetworkFixedMode: 'fixed' | 'float';
extraNetworkSidebarExpand: boolean;
extraNetworkSidebarWidth: number;
primaryColor: string | undefined;
primaryColor: PrimaryColor | undefined;
promotTextarea: 'scroll' | 'resizable';
sidebarExpand: boolean;
sidebarFixedMode: 'fixed' | 'float';
Expand All @@ -23,7 +37,7 @@ export const defaultSetting: WebuiSetting = {
extraNetworkFixedMode: 'fixed',
extraNetworkSidebarExpand: true,
extraNetworkSidebarWidth: 340,
primaryColor: '',
primaryColor: undefined,
promotTextarea: 'scroll',
sidebarExpand: true,
sidebarFixedMode: 'fixed',
Expand Down
5 changes: 5 additions & 0 deletions src/styles/antd-override.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ export default (token: Theme) => css`
background: ${token.colorText} !important;
}
}
.ant-tabs-ink-bar.ant-btn-primary,
.ant-switch-checked {
background: ${token.colorPrimary} !important;
}
`;
2 changes: 1 addition & 1 deletion src/styles/components/button.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Theme, css } from 'antd-style';

export default (token: Theme) => css`
button,
button:not([role='switch'], .ant-btn),
.gradio-button,
.lg {
cursor: pointer;
Expand Down
28 changes: 12 additions & 16 deletions src/styles/components/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import { Theme, css } from 'antd-style';

export default (token: Theme) => {
return css`
.block.gradio-html:has(div.prose) {
display: block;
p {
color: ${token.cyan8};
.gradio-tabitem {
overflow: auto;
}
b {
color: ${token.cyan9};
}
}
.gradio-group,
.gradio-row {
gap: 12px !important;
}
div.gradio-box.block.padded:not(.gradio-accordion) {
Expand Down Expand Up @@ -43,8 +40,7 @@ export default (token: Theme) => {
}
> div:not([id$='_script_container'], .gradio-tabs):has(div),
> fieldset,
> .gradio-row {
> fieldset {
flex-flow: row wrap;
gap: 12px;
Expand All @@ -65,20 +61,20 @@ export default (token: Theme) => {
gap: 12px;
#script_list,
.gradio-group:not(.hidden):has(div) {
> .gradio-group:not(.hidden):has(div) {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
padding: 16px;
background-color: ${token.colorBgContainer};
border: 1px solid ${token.colorBorderSecondary} !important;
border-radius: ${token.borderRadius}px !important;
box-shadow: none;
> div {
padding: 0;
> .gradio-accordion {
padding: 0 !important;
border: none !important;
}
}
Expand All @@ -91,7 +87,7 @@ export default (token: Theme) => {
div.compact,
.wrap {
gap: 8px !important;
gap: 12px !important;
}
#tabs > div {
Expand Down
Loading

0 comments on commit 406aba7

Please sign in to comment.