|
| 1 | +/* eslint-disable react/jsx-no-bind */ |
1 | 2 | import * as React from 'react';
|
2 | 3 | import { makeStyles } from '@griffel/react';
|
3 | 4 | import { ColorTokensList } from './ColorTokensList';
|
4 |
| -import { Caption1 } from '@fluentui/react-components'; |
5 |
| -import { Brands, BrandVariants, teamsLightTheme, Theme } from '@fluentui/react-theme'; |
| 5 | +import { Button, Caption1 } from '@fluentui/react-components'; |
| 6 | +import { Brands, BrandVariants, teamsLightTheme } from '@fluentui/react-theme'; |
6 | 7 | import { OverridableTokenBrandColors } from './OverridableTokenBrandColors';
|
7 | 8 | import { brandTeams } from '../../utils/brandColors';
|
8 |
| - |
9 | 9 | import type { DispatchTheme } from '../../useThemeDesignerReducer';
|
| 10 | +import { themeNames } from '../../utils/themeList'; |
10 | 11 |
|
11 | 12 | export interface ColorTokensProps {
|
12 | 13 | className?: string;
|
13 |
| - isDark: boolean; |
14 | 14 | brand: BrandVariants;
|
15 |
| - dispatchState: React.Dispatch<DispatchTheme>; |
| 15 | + themeLabel: string; |
| 16 | + dispatchAppState: React.Dispatch<DispatchTheme>; |
16 | 17 | }
|
17 | 18 |
|
| 19 | +export type ColorOverrideBrands = Record<string, Brands>; |
| 20 | + |
| 21 | +export type ColorOverrides = Record<string, ColorOverrideBrands>; |
| 22 | + |
| 23 | +export type DispatchColorOverrides = { |
| 24 | + type: string; |
| 25 | + colorToken?: string; |
| 26 | + newValue?: Brands; |
| 27 | +}; |
| 28 | + |
| 29 | +const getCurrentOverride = (themeLabel: string, colorOverride: ColorOverrides) => { |
| 30 | + return colorOverride[themeLabel]; |
| 31 | +}; |
| 32 | + |
| 33 | +const initialColorOverride: ColorOverrides = Object.fromEntries(themeNames.map(currTheme => [currTheme, {}])); |
| 34 | + |
18 | 35 | const useStyles = makeStyles({
|
19 | 36 | root: {},
|
20 | 37 | row: {
|
21 | 38 | display: 'grid',
|
22 |
| - gridTemplateColumns: '1fr 1fr 1fr', |
| 39 | + gridTemplateColumns: '1fr 1fr 1fr .5fr', |
23 | 40 | alignItems: 'center',
|
24 | 41 | },
|
25 | 42 | });
|
26 | 43 |
|
27 |
| -const brandColors: Record<string, Brands> = OverridableTokenBrandColors(teamsLightTheme, brandTeams); |
| 44 | +const brandColors: ColorOverrideBrands = OverridableTokenBrandColors(teamsLightTheme, brandTeams); |
28 | 45 |
|
29 | 46 | export const ColorTokens: React.FunctionComponent<ColorTokensProps> = props => {
|
30 | 47 | const styles = useStyles();
|
31 | 48 |
|
32 |
| - const { brand, dispatchState } = props; |
33 |
| - |
34 |
| - const [overrideList, setOverrideList] = React.useState<Partial<Theme>>({}); |
| 49 | + const { brand, themeLabel, dispatchAppState } = props; |
35 | 50 |
|
36 | 51 | const colorOverrideReducer: (
|
37 |
| - state: Record<string, Brands>, |
38 |
| - action: { colorToken: string; newValue: Brands }, |
39 |
| - ) => Record<string, Brands> = (state, action) => { |
40 |
| - const overrides = { ...state, [action.colorToken]: action.newValue }; |
41 |
| - setOverrideList({ ...overrideList, [action.colorToken]: brand[action.newValue] }); |
42 |
| - dispatchState({ type: 'Overrides', overrides: overrideList }); |
43 |
| - return overrides; |
| 52 | + state: ColorOverrides, |
| 53 | + action: { type: string; colorToken?: string; newValue?: Brands }, |
| 54 | + ) => ColorOverrides = (state, action) => { |
| 55 | + switch (action.type) { |
| 56 | + case 'Add Override': |
| 57 | + if (!action.colorToken || !action.newValue) { |
| 58 | + return state; |
| 59 | + } |
| 60 | + return { |
| 61 | + ...state, |
| 62 | + [themeLabel]: { ...state[themeLabel], [action.colorToken]: action.newValue }, |
| 63 | + }; |
| 64 | + case 'Reset Overrides': |
| 65 | + return { ...state, [themeLabel]: {} }; |
| 66 | + case 'Reset Custom Overrides': |
| 67 | + return { ...state, customLight: {}, customDark: {} }; |
| 68 | + default: |
| 69 | + return state; |
| 70 | + } |
| 71 | + }; |
| 72 | + |
| 73 | + const [colorOverride, dispatchColorOverride] = React.useReducer(colorOverrideReducer, initialColorOverride); |
| 74 | + |
| 75 | + const onNewOverride = (color: string, newColor: Brands) => { |
| 76 | + dispatchAppState({ type: 'Override', overrides: { [color]: brand[newColor] } }); |
| 77 | + dispatchColorOverride({ type: 'Add Override', colorToken: color, newValue: newColor }); |
44 | 78 | };
|
45 | 79 |
|
46 |
| - const [colorOverrides, dispatchColorOverrides] = React.useReducer(colorOverrideReducer, {}); |
| 80 | + const handleResetClick = () => { |
| 81 | + dispatchAppState({ type: 'Override' }); |
| 82 | + dispatchColorOverride({ type: 'Reset Overrides' }); |
| 83 | + }; |
47 | 84 |
|
48 | 85 | return (
|
49 | 86 | <div className={props.className}>
|
50 | 87 | <div className={styles.row}>
|
51 | 88 | <Caption1>Color tokens</Caption1>
|
52 | 89 | <Caption1>Assigned values</Caption1>
|
53 | 90 | <Caption1>Usage examples</Caption1>
|
| 91 | + <Button size="small" onClick={handleResetClick}> |
| 92 | + Reset Customizations |
| 93 | + </Button> |
54 | 94 | </div>
|
55 | 95 | <ColorTokensList
|
56 | 96 | brand={brand}
|
57 | 97 | brandColors={brandColors}
|
58 |
| - colorOverrides={colorOverrides} |
59 |
| - dispatchColorOverrides={dispatchColorOverrides} |
| 98 | + colorOverride={getCurrentOverride(themeLabel, colorOverride)} |
| 99 | + onNewOverride={onNewOverride} |
60 | 100 | />
|
61 | 101 | </div>
|
62 | 102 | );
|
|
0 commit comments