Skip to content

Commit b556d46

Browse files
committed
feat(theme-generator): restructure components, and optimize utils for improved maintainability
1 parent 6ac11b3 commit b556d46

File tree

11 files changed

+147
-149
lines changed

11 files changed

+147
-149
lines changed

packages/storybook/src/components/themeGenerator/ThemeGenerator.tsx

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Splitter } from '@ark-ui/react/splitter';
22
import React, { type JSX, useEffect, useState } from 'react';
33
import classNames from 'classnames';
4-
import * as ODSReact from '@ovhcloud/ods-react';
4+
import { Button, BUTTON_COLOR, BUTTON_VARIANT, Icon, ICON_NAME, Switch, type SwitchValueChangeDetail, SwitchItem } from '@ovhcloud/ods-react';
55
import { ORIENTATION, OrientationSwitch } from '../sandbox/actions/OrientationSwitch';
66
import styles from './themeGenerator.module.css';
77
import { ThemeGeneratorTreeView } from './themeGeneratorTreeView/ThemeGeneratorTreeView';
88
import { ThemeGeneratorPreview } from './themeGeneratorPreview/ThemeGeneratorPreview';
9-
import { parseCssVariables } from './useThemeGenerator';
10-
import { ThemeGeneratorModal } from './themeGeneratorModal/ThemeGeneratorModal';
11-
import { ThemeGeneratorJSON } from './themeGeneratorJSON/ThemeGeneratorJSON';
9+
import { parseCssVariables } from './themeVariableUtils';
10+
import { ThemeGeneratorSwitchThemeModal } from './themeGeneratorSwitchThemeModal/ThemeGeneratorSwitchThemeModal';
11+
import { ThemeGeneratorJSONModal } from './themeGeneratorJSON/ThemeGeneratorJSONModal';
1212

1313
const ThemeGenerator = (): JSX.Element => {
1414
const [isFullscreen, setIsFullscreen] = useState(false);
@@ -28,8 +28,7 @@ const ThemeGenerator = (): JSX.Element => {
2828
}
2929

3030
try {
31-
console.log('Selected theme:', selectedTheme);
32-
31+
3332
// Fetch the CSS file from the static directory
3433
// Path: /themes/{themeName}/index.css (exposed via staticDirs in main.ts)
3534
const response = await fetch(`/themes/${selectedTheme}/index.css`);
@@ -42,7 +41,6 @@ const ThemeGenerator = (): JSX.Element => {
4241

4342
// Parse CSS variables
4443
const variables = parseCssVariables(cssContent);
45-
console.log('Parsed variables:', Object.keys(variables).length, 'variables found');
4644
setEditedVariables(variables);
4745
setIsCustomTheme(false);
4846
} catch (error) {
@@ -77,15 +75,15 @@ const ThemeGenerator = (): JSX.Element => {
7775
)}>
7876
<div className={ styles['theme-generator__menu'] }>
7977
<div className={styles['theme-generator__menu__left']}>
80-
<ODSReact.Button
81-
variant={ ODSReact.BUTTON_VARIANT.ghost }
78+
<Button
79+
variant={ BUTTON_VARIANT.ghost }
8280
onClick={ () => setIsJsonOpen(true) }>
83-
<ODSReact.Icon name={ODSReact.ICON_NAME.chevronLeftUnderscore} />
81+
<Icon name={ ICON_NAME.chevronLeftUnderscore } />
8482
JSON
85-
</ODSReact.Button>
86-
<ODSReact.Switch
83+
</Button>
84+
<Switch
8785
value={selectedTheme}
88-
onValueChange={(details: { value: string }) => {
86+
onValueChange={(details: SwitchValueChangeDetail) => {
8987
const next = details.value;
9088
const isLeavingCustom = isCustomTheme && next !== 'custom';
9189

@@ -98,27 +96,27 @@ const ThemeGenerator = (): JSX.Element => {
9896
setSelectedTheme(next);
9997
}}
10098
>
101-
<ODSReact.SwitchItem value="default">
99+
<SwitchItem value="default">
102100
Default
103-
</ODSReact.SwitchItem>
104-
<ODSReact.SwitchItem value="developer">
101+
</SwitchItem>
102+
<SwitchItem value="developer">
105103
Developer
106-
</ODSReact.SwitchItem>
107-
<ODSReact.SwitchItem value="custom">
104+
</SwitchItem>
105+
<SwitchItem value="custom">
108106
Custom
109-
</ODSReact.SwitchItem>
110-
</ODSReact.Switch>
107+
</SwitchItem>
108+
</Switch>
111109
</div>
112110
<div className={styles['theme-generator__menu__right']}>
113111
<OrientationSwitch
114112
onChange={ (value) => setOrientation(value) }
115113
orientation={ orientation } />
116114

117-
<ODSReact.Button
115+
<Button
118116
onClick={ onToggleFullscreen }
119-
variant={ ODSReact.BUTTON_VARIANT.ghost }>
120-
<ODSReact.Icon name={ isFullscreen ? ODSReact.ICON_NAME.shrink : ODSReact.ICON_NAME.resize } />
121-
</ODSReact.Button>
117+
variant={ BUTTON_VARIANT.ghost }>
118+
<Icon name={ isFullscreen ? ICON_NAME.shrink : ICON_NAME.resize } />
119+
</Button>
122120
</div>
123121
</div>
124122
<Splitter.Root
@@ -135,13 +133,13 @@ const ThemeGenerator = (): JSX.Element => {
135133
asChild
136134
aria-label="Resize"
137135
id="tree-view:preview">
138-
<ODSReact.Button
136+
<Button
139137
className={ classNames(
140138
styles['theme-generator__container__resize'],
141139
{ [styles['theme-generator__container__resize--horizontal']]: orientation === ORIENTATION.horizontal },
142140
{ [styles['theme-generator__container__resize--vertical']]: orientation === ORIENTATION.vertical },
143141
)}
144-
color={ ODSReact.BUTTON_COLOR.neutral } />
142+
color={ BUTTON_COLOR.neutral } />
145143
</Splitter.ResizeTrigger>
146144

147145
<Splitter.Panel id="preview">
@@ -151,7 +149,7 @@ const ThemeGenerator = (): JSX.Element => {
151149
</Splitter.Panel>
152150
</Splitter.Root>
153151

154-
<ThemeGeneratorModal
152+
<ThemeGeneratorSwitchThemeModal
155153
open={ isConfirmOpen }
156154
targetTheme={ pendingTheme }
157155
onConfirm={() => {
@@ -167,7 +165,7 @@ const ThemeGenerator = (): JSX.Element => {
167165
}}
168166
/>
169167

170-
<ThemeGeneratorJSON
168+
<ThemeGeneratorJSONModal
171169
open={ isJsonOpen }
172170
variables={ editedVariables }
173171
onClose={ () => setIsJsonOpen(false) }

packages/storybook/src/components/themeGenerator/ThemeGeneratorTreeView/ThemeGeneratorTreeView.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import { Spinner, Text, TreeView, TreeViewNode, TreeViewNodes } from '@ovhcloud/ods-react';
1+
import { Spinner, Text, TreeView, TreeViewNode, TreeViewNodes, SPINNER_SIZE, TEXT_PRESET } from '@ovhcloud/ods-react';
22
import React, { useMemo } from 'react';
3-
import { categorizeCssVariables } from '../useThemeGenerator';
3+
import { categorizeCssVariables } from '../themeVariableUtils';
44
import styles from './themeGeneratorTreeView.module.css';
5-
import { SPINNER_SIZE } from '../../../../../ods-react/src/components/spinner/src/constants/spinner-size';
6-
import { TEXT_PRESET } from '../../../../../ods-react/src/components/text/src/constants/text-preset';
7-
85
interface TreeItem {
96
id: string;
107
name: string;
@@ -62,18 +59,18 @@ const ThemeGeneratorTreeView = ({ variables, onVariableChange }: ThemeGeneratorT
6259
<TreeView
6360
className={styles['theme-generator-tree-view']}
6461
items={items}
65-
onValueChange={() => {}}>
62+
>
6663
<TreeViewNodes>
6764
{items.map((item) => (
6865
<TreeViewNode key={item.id} item={item}>
6966
{({ item, isBranch }: { item: TreeItem; isBranch: boolean }) => (
7067
<div className={styles['theme-generator-tree-view__item']}>
71-
<Text className={styles['theme-generator-tree-view__name']}>
68+
<Text className={styles['theme-generator-tree-view__item__name']}>
7269
{item.name}
7370
</Text>
7471
{!isBranch && item.value && (
7572
<input
76-
className={styles['theme-generator-tree-view__color-input']}
73+
className={styles['theme-generator-tree-view__item__color-input']}
7774
type="color"
7875
onClick={(e) => {
7976
e.stopPropagation();
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
.theme-generator-tree-view {
2+
padding: 1rem;
23
height: 100%;
34
overflow: auto;
4-
padding: 1rem;
55
}
66

77
.theme-generator-tree-view__item {
88
display: flex;
9+
gap: 0.5rem;
910
align-items: center;
1011
justify-content: space-between;
11-
gap: 0.5rem;
1212
width: 100%;
1313
}
1414

15-
.theme-generator-tree-view__name {
16-
color: var(--ods-color-text);
15+
.theme-generator-tree-view__item__name {
1716
flex: 1;
17+
color: var(--ods-color-text);
1818
}
1919

20-
.theme-generator-tree-view__color-input {
21-
cursor: pointer;
22-
height: 26px;
23-
width: 24px;
24-
padding: 0;
20+
.theme-generator-tree-view__item__color-input {
2521
border: none;
2622
background-color: transparent;
27-
}
23+
cursor: pointer;
24+
padding: 0;
25+
width: 24px;
26+
height: 26px;
27+
}

packages/storybook/src/components/themeGenerator/themeGeneratorJSON/ThemeGeneratorJSON.tsx renamed to packages/storybook/src/components/themeGenerator/themeGeneratorJSON/ThemeGeneratorJSONModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useEffect, useMemo, useState, type JSX } from 'react';
22
import { Button, BUTTON_VARIANT, Modal, ModalBody, ModalContent, Text, TEXT_PRESET } from '@ovhcloud/ods-react';
3-
import styles from './themeGeneratorJSON.module.css';
3+
import styles from './themeGeneratorJSONModal.module.css';
44

55
interface ThemeGeneratorJSONProps {
66
open: boolean;
@@ -9,7 +9,7 @@ interface ThemeGeneratorJSONProps {
99
onReplace: (nextVariables: Record<string, string>) => void;
1010
}
1111

12-
const ThemeGeneratorJSON = ({ open, variables, onClose, onReplace }: ThemeGeneratorJSONProps): JSX.Element => {
12+
const ThemeGeneratorJSONModal = ({ open, variables, onClose, onReplace }: ThemeGeneratorJSONProps): JSX.Element => {
1313
const initialText = useMemo(() => JSON.stringify(variables, null, 2), [variables]);
1414
const [textValue, setTextValue] = useState(initialText);
1515
const [error, setError] = useState<string | null>(null);
@@ -81,6 +81,6 @@ const ThemeGeneratorJSON = ({ open, variables, onClose, onReplace }: ThemeGenera
8181
);
8282
};
8383

84-
export { ThemeGeneratorJSON };
84+
export { ThemeGeneratorJSONModal };
8585

8686

File renamed without changes.

packages/storybook/src/components/themeGenerator/themeGeneratorModal/ThemeGeneratorModal.tsx renamed to packages/storybook/src/components/themeGenerator/themeGeneratorSwitchThemeModal/ThemeGeneratorSwitchThemeModal.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@ import {
88
ModalContent,
99
} from '@ovhcloud/ods-react';
1010
import { Text, TEXT_PRESET } from '@ovhcloud/ods-react';
11-
import styles from './themeGeneratorModal.module.css';
11+
import styles from './themeGeneratorSwitchThemeModal.module.css';
1212

13-
interface ThemeGeneratorModalProps {
13+
interface ThemeGeneratorSwitchThemeModalProps {
1414
open: boolean;
1515
targetTheme?: string | null;
1616
onConfirm: () => void;
1717
onCancel: () => void;
1818
}
1919

20-
const ThemeGeneratorModal = ({
20+
const ThemeGeneratorSwitchThemeModal = ({
2121
open,
2222
targetTheme,
2323
onConfirm,
2424
onCancel,
25-
}: ThemeGeneratorModalProps): JSX.Element => {
25+
}: ThemeGeneratorSwitchThemeModalProps): JSX.Element => {
2626
function onOpenChange({ open }: { open: boolean }) {
2727
if (!open) {
2828
onCancel();
@@ -45,7 +45,7 @@ const ThemeGeneratorModal = ({
4545
You have unsaved customizations. Switching to { targetLabel || 'another theme' } will discard them.
4646
</Text>
4747

48-
<div className={ styles.actions }>
48+
<div className={ styles['theme-generator-switch-theme-modal__actions'] }>
4949
<Button onClick={ onConfirm } color={ BUTTON_COLOR.critical }>
5050
Switch to { targetLabel || 'theme' }
5151
</Button>
@@ -60,6 +60,6 @@ const ThemeGeneratorModal = ({
6060
);
6161
};
6262

63-
export { ThemeGeneratorModal };
63+
export { ThemeGeneratorSwitchThemeModal };
6464

6565

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
.actions {
1+
.theme-generator-switch-theme-modal__actions {
22
display: flex;
3-
margin-top: 16px;
43
gap: 8px;
54
justify-content: end;
5+
margin-top: 16px;
66
}
77

88

packages/storybook/src/components/themeGenerator/themeGeneratorTreeView/ThemeGeneratorTreeView.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import { Spinner, Text, TreeView, TreeViewNode, TreeViewNodes } from '@ovhcloud/ods-react';
1+
import { Spinner, Text, TreeView, TreeViewNode, TreeViewNodes, SPINNER_SIZE, TEXT_PRESET } from '@ovhcloud/ods-react';
22
import React, { useMemo } from 'react';
3-
import { categorizeCssVariables } from '../useThemeGenerator';
3+
import { categorizeCssVariables } from '../themeVariableUtils';
44
import styles from './themeGeneratorTreeView.module.css';
5-
import { SPINNER_SIZE } from '../../../../../ods-react/src/components/spinner/src/constants/spinner-size';
6-
import { TEXT_PRESET } from '../../../../../ods-react/src/components/text/src/constants/text-preset';
7-
85
interface TreeItem {
96
id: string;
107
name: string;
@@ -62,18 +59,18 @@ const ThemeGeneratorTreeView = ({ variables, onVariableChange }: ThemeGeneratorT
6259
<TreeView
6360
className={styles['theme-generator-tree-view']}
6461
items={items}
65-
onValueChange={() => {}}>
62+
>
6663
<TreeViewNodes>
6764
{items.map((item) => (
6865
<TreeViewNode key={item.id} item={item}>
6966
{({ item, isBranch }: { item: TreeItem; isBranch: boolean }) => (
7067
<div className={styles['theme-generator-tree-view__item']}>
71-
<Text className={styles['theme-generator-tree-view__name']}>
68+
<Text className={styles['theme-generator-tree-view__item__name']}>
7269
{item.name}
7370
</Text>
7471
{!isBranch && item.value && (
7572
<input
76-
className={styles['theme-generator-tree-view__color-input']}
73+
className={styles['theme-generator-tree-view__item__color-input']}
7774
type="color"
7875
onClick={(e) => {
7976
e.stopPropagation();
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
.theme-generator-tree-view {
2+
padding: 1rem;
23
height: 100%;
34
overflow: auto;
4-
padding: 1rem;
55
}
66

77
.theme-generator-tree-view__item {
88
display: flex;
9+
gap: 0.5rem;
910
align-items: center;
1011
justify-content: space-between;
11-
gap: 0.5rem;
1212
width: 100%;
1313
}
1414

15-
.theme-generator-tree-view__name {
16-
color: var(--ods-color-text);
15+
.theme-generator-tree-view__item__name {
1716
flex: 1;
17+
color: var(--ods-color-text);
1818
}
1919

20-
.theme-generator-tree-view__color-input {
21-
cursor: pointer;
22-
height: 26px;
23-
width: 24px;
24-
padding: 0;
20+
.theme-generator-tree-view__item__color-input {
2521
border: none;
2622
background-color: transparent;
27-
}
23+
cursor: pointer;
24+
padding: 0;
25+
width: 24px;
26+
height: 26px;
27+
}

0 commit comments

Comments
 (0)