Skip to content

Commit 4b3c192

Browse files
Juwang110claude
andauthored
MSPCA-32 Add Chakra UI v3 and theme.ts (#15)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a6e91b1 commit 4b3c192

5 files changed

Lines changed: 1279 additions & 13 deletions

File tree

‎apps/frontend/index.html‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77

88
<meta name="viewport" content="width=device-width, initial-scale=1" />
99
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
10+
<link rel="preconnect" href="https://fonts.googleapis.com" />
11+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
12+
<link
13+
rel="stylesheet"
14+
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100..900&display=swap"
15+
/>
1016
<link rel="stylesheet" href="/src/styles.css" />
1117
</head>
1218
<body>

‎apps/frontend/src/main.tsx‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { StrictMode } from 'react';
22
import * as ReactDOM from 'react-dom/client';
33
import { Authenticator } from '@aws-amplify/ui-react';
4+
import '@aws-amplify/ui-react/styles.css';
5+
import { ChakraProvider } from '@chakra-ui/react';
46
import { configureAmplify, isAuthEnabled } from './auth/auth.config';
57
import App from './app';
8+
import { system } from './theme';
69

710
const root = ReactDOM.createRoot(
811
document.getElementById('root') as HTMLElement,
@@ -12,15 +15,17 @@ const root = ReactDOM.createRoot(
1215
configureAmplify();
1316

1417
root.render(
15-
isAuthEnabled() ? (
16-
<Authenticator>
18+
<ChakraProvider value={system}>
19+
{isAuthEnabled() ? (
20+
<Authenticator>
21+
<StrictMode>
22+
<App />
23+
</StrictMode>
24+
</Authenticator>
25+
) : (
1726
<StrictMode>
1827
<App />
1928
</StrictMode>
20-
</Authenticator>
21-
) : (
22-
<StrictMode>
23-
<App />
24-
</StrictMode>
25-
),
29+
)}
30+
</ChakraProvider>,
2631
);

‎apps/frontend/src/theme.ts‎

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import {
2+
createSystem,
3+
defaultConfig,
4+
defineConfig,
5+
defineTextStyles,
6+
} from '@chakra-ui/react';
7+
8+
export const colors = {
9+
black: '#000000',
10+
gray: {
11+
0: '#ffffff',
12+
50: '#fafafa',
13+
100: '#f4f4f5',
14+
200: '#e4e4e7',
15+
300: '#d4d4d8',
16+
400: '#a1a1aa',
17+
500: '#71717a',
18+
600: '#52525b',
19+
700: '#3f3f46',
20+
800: '#27272a',
21+
900: '#18181b',
22+
},
23+
error: {
24+
50: '#fef2f2',
25+
100: '#ef4444',
26+
},
27+
blue: {
28+
primary: '#009cde',
29+
blue2: '#0d5b90',
30+
blue3: '#2c4068',
31+
},
32+
orange: {
33+
orange1: '#dea631',
34+
orange2: '#e9954b',
35+
orange3: '#e17152',
36+
},
37+
green: {
38+
green1: '#88b613',
39+
green2: '#769b3d',
40+
},
41+
teal: {
42+
teal: '#4ba2a6',
43+
},
44+
brown: {
45+
brown: '#5e3638',
46+
},
47+
neutrals: {
48+
black: '#231f20',
49+
black85: '#4d4d4f',
50+
grey: '#858f98',
51+
},
52+
trello: {
53+
noRestrictions: '#174b35',
54+
dogFreeHome: '#87b400',
55+
catFreeHome: '#9f4b00',
56+
activityRestriction: '#5d1f1a',
57+
childFreeHome: '#ae2e24',
58+
petFreeHome: '#813ea5',
59+
requiresMedication: '#1458bc',
60+
},
61+
} as const;
62+
63+
const toColorTokens = (palette: typeof colors) =>
64+
Object.fromEntries(
65+
Object.entries(palette).map(([group, shades]) => [
66+
group,
67+
typeof shades === 'string'
68+
? { value: shades }
69+
: Object.fromEntries(
70+
Object.entries(shades).map(([shade, value]) => [shade, { value }]),
71+
),
72+
]),
73+
);
74+
75+
const textStyle = (
76+
mobile: string,
77+
desktop: string,
78+
lineHeight: string,
79+
font: 'heading' | 'body' = 'heading',
80+
) => ({
81+
value: {
82+
fontFamily: font,
83+
fontSize: { base: mobile, md: desktop },
84+
fontWeight: font === 'heading' ? 'semibold' : 'normal',
85+
lineHeight,
86+
letterSpacing: '0',
87+
},
88+
});
89+
90+
const textStyles = defineTextStyles({
91+
h1: textStyle('36px', '60px', '1.5'),
92+
h2: textStyle('32px', '48px', '1.5'),
93+
h3: textStyle('28px', '36px', '1.5'),
94+
h4: textStyle('24px', '30px', '1.533'),
95+
h5: textStyle('20px', '24px', '1.5'),
96+
h6: textStyle('18px', '20px', '1.5'),
97+
h7: textStyle('16px', '18px', '1.556'),
98+
body: textStyle('14px', '16px', '1.5', 'body'),
99+
'body-small': textStyle('12px', '14px', '1.43', 'body'),
100+
xs: textStyle('10px', '12px', '1rem', 'body'),
101+
'2xs': textStyle('8px', '10px', '0.75rem', 'body'),
102+
});
103+
104+
const config = defineConfig({
105+
theme: {
106+
tokens: {
107+
colors: toColorTokens(colors),
108+
fonts: {
109+
heading: { value: "'Montserrat', sans-serif" },
110+
body: { value: "'Montserrat', sans-serif" },
111+
},
112+
fontWeights: {
113+
thin: { value: '100' },
114+
extralight: { value: '200' },
115+
light: { value: '300' },
116+
normal: { value: '400' },
117+
medium: { value: '500' },
118+
semibold: { value: '600' },
119+
bold: { value: '700' },
120+
extrabold: { value: '800' },
121+
black: { value: '900' },
122+
},
123+
},
124+
semanticTokens: {
125+
colors: {
126+
bg: {
127+
DEFAULT: { value: '{colors.gray.0}' },
128+
subtle: { value: '{colors.gray.50}' },
129+
muted: { value: '{colors.gray.100}' },
130+
emphasized: { value: '{colors.gray.200}' },
131+
inverted: { value: '{colors.black}' },
132+
panel: { value: '{colors.gray.0}' },
133+
error: { value: '{colors.error.50}' },
134+
},
135+
fg: {
136+
DEFAULT: { value: '{colors.black}' },
137+
subtle: { value: '{colors.gray.400}' },
138+
muted: { value: '{colors.gray.600}' },
139+
inverted: { value: '{colors.gray.50}' },
140+
error: { value: '{colors.error.100}' },
141+
},
142+
border: {
143+
DEFAULT: { value: '{colors.gray.200}' },
144+
subtle: { value: '{colors.gray.50}' },
145+
muted: { value: '{colors.gray.100}' },
146+
emphasized: { value: '{colors.gray.300}' },
147+
inverted: { value: '{colors.gray.800}' },
148+
error: { value: '{colors.error.100}' },
149+
},
150+
text: {
151+
fg: { value: '{colors.black}' },
152+
fg_muted: { value: '{colors.gray.600}' },
153+
fg_subtle: { value: '{colors.gray.400}' },
154+
fg_error: { value: '{colors.error.100}' },
155+
},
156+
neutral: {
157+
contrast: { value: '{colors.gray.0}' },
158+
fg: { value: '{colors.gray.800}' },
159+
subtle: { value: '{colors.gray.100}' },
160+
muted: { value: '{colors.gray.200}' },
161+
emphasized: { value: '{colors.gray.300}' },
162+
solid: { value: '{colors.gray.900}' },
163+
focusRing: { value: '{colors.gray.400}' },
164+
},
165+
},
166+
},
167+
textStyles,
168+
},
169+
globalCss: {
170+
body: {
171+
textStyle: 'body',
172+
color: 'fg',
173+
bg: 'bg',
174+
},
175+
h1: { textStyle: 'h1' },
176+
h2: { textStyle: 'h2' },
177+
h3: { textStyle: 'h3' },
178+
h4: { textStyle: 'h4' },
179+
h5: { textStyle: 'h5' },
180+
h6: { textStyle: 'h6' },
181+
'p, li, label': { textStyle: 'body' },
182+
'small, figcaption': { textStyle: 'body-small' },
183+
a: { color: 'blue.primary', textDecoration: 'underline' },
184+
'button, input, textarea, select': { fontFamily: 'body' },
185+
},
186+
});
187+
188+
export const system = createSystem(defaultConfig, config);

‎package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"@aws-sdk/client-cognito-identity-provider": "^3.1058.0",
2424
"@aws-sdk/client-s3": "^3.1073.0",
2525
"@aws-sdk/client-sesv2": "^3.1063.0",
26+
"@chakra-ui/react": "^3.37.0",
27+
"@emotion/react": "^11.14.0",
2628
"@nestjs/cli": "^11.0.24",
2729
"@nestjs/common": "^10.0.2",
2830
"@nestjs/config": "^4.0.4",

0 commit comments

Comments
 (0)