206 lines
5.0 KiB
Markdown
206 lines
5.0 KiB
Markdown
# **File: COMMIT\_02\_THEME.md**
|
|
|
|
## **Commit 2: Global UI & Theme Setup**
|
|
|
|
### **Objective**
|
|
|
|
Integrate the Mantine UI library and configure the global grayscale, minimalist theme. This addresses the "stunningly-beautiful" and "minimal, grayscale" requirements.
|
|
|
|
### **Implementation Specification**
|
|
|
|
**1\. Create postcss.config.mjs**
|
|
|
|
Create a file at /postcss.config.mjs to enable Mantine's PostCSS features:
|
|
|
|
JavaScript
|
|
|
|
/\*\* @type {import('postcss-load-config').Config} \*/
|
|
const config \= {
|
|
plugins: {
|
|
'postcss-preset-mantine': {},
|
|
'postcss-simple-vars': {
|
|
variables: {
|
|
'mantine-breakpoint-xs': '36em',
|
|
'mantine-breakpoint-sm': '48em',
|
|
'mantine-breakpoint-md': '62em',
|
|
'mantine-breakpoint-lg': '75em',
|
|
'mantine-breakpoint-xl': '88em',
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
export default config;
|
|
|
|
**2\. Create app/theme.ts**
|
|
|
|
Create a file at /app/theme.ts to define the app's aesthetic:
|
|
|
|
TypeScript
|
|
|
|
'use client';
|
|
|
|
import { createTheme, MantineColorsTuple } from '@mantine/core';
|
|
|
|
// Define a rich 10-shade grayscale palette
|
|
const ponderGray: MantineColorsTuple \=;
|
|
|
|
export const theme \= createTheme({
|
|
primaryColor: 'gray',
|
|
// Use our custom gray palette
|
|
colors: {
|
|
gray: ponderGray,
|
|
},
|
|
// Set default dark mode and grayscale for the "minimalist" look
|
|
defaultRadius: 'md',
|
|
fontFamily: 'Inter, sans-serif',
|
|
// Enforce dark mode
|
|
forceColorscheme: 'dark',
|
|
|
|
// Set default component props for a consistent look
|
|
components: {
|
|
Button: {
|
|
defaultProps: {
|
|
variant: 'filled',
|
|
color: 'gray',
|
|
radius: 'xl',
|
|
},
|
|
},
|
|
Paper: {
|
|
defaultProps: {
|
|
shadow: 'xs',
|
|
p: 'md',
|
|
radius: 'md',
|
|
withBorder: true,
|
|
},
|
|
styles: {
|
|
root: {
|
|
backgroundColor: '\#212529', // gray
|
|
borderColor: '\#495057', // gray
|
|
},
|
|
},
|
|
},
|
|
TextInput: {
|
|
defaultProps: {
|
|
variant: 'filled',
|
|
radius: 'xl',
|
|
},
|
|
},
|
|
Textarea: {
|
|
defaultProps: {
|
|
variant: 'filled',
|
|
radius: 'lg',
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
**3\. Update app/globals.css**
|
|
|
|
Update /app/globals.css to import Mantine's core styles:
|
|
|
|
CSS
|
|
|
|
@import '@mantine/core/styles.css';
|
|
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: \#181a1d; /\* Our darkest gray \*/
|
|
color: \#e9ecef; /\* Our lightest gray \*/
|
|
}
|
|
|
|
**4\. Update Root Layout (app/layout.tsx)**
|
|
|
|
Update /app/layout.tsx to apply the MantineProvider:
|
|
|
|
TypeScript
|
|
|
|
import type { Metadata } from "next";
|
|
import { Inter } from "next/font/google";
|
|
import "./globals.css";
|
|
import { MantineProvider, ColorSchemeScript } from "@mantine/core";
|
|
import { theme } from "./theme";
|
|
|
|
const inter \= Inter({ subsets: \["latin"\] });
|
|
|
|
export const metadata: Metadata \= {
|
|
title: "Ponderants",
|
|
description: "Your AI Thought Partner",
|
|
};
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly\<{
|
|
children: React.ReactNode;
|
|
}\>) {
|
|
return (
|
|
\<html lang="en"\>
|
|
\<head\>
|
|
{/\* Enforce dark scheme as per our theme \*/}
|
|
\<ColorSchemeScript forceColorscheme="dark" /\>
|
|
\</head\>
|
|
\<body className={inter.className}\>
|
|
\<MantineProvider theme={theme} forceColorscheme="dark"\>
|
|
{children}
|
|
\</MantineProvider\>
|
|
\</body\>
|
|
\</html\>
|
|
);
|
|
}
|
|
|
|
**5\. Update Homepage (app/page.tsx)**
|
|
|
|
Update /app/page.tsx to use Mantine components, confirming the theme is applied:
|
|
|
|
TypeScript
|
|
|
|
import { Stack, Title, Paper, Button, Center } from '@mantine/core';
|
|
|
|
export default function Home() {
|
|
return (
|
|
\<Center h="100vh"\>
|
|
\<Paper w={400} p="xl"\>
|
|
\<Stack align="center"\>
|
|
\<Title order={1}\>Ponderants\</Title\>
|
|
\<Button\>Test Button\</Button\>
|
|
\</Stack\>
|
|
\</Paper\>
|
|
\</Center\>
|
|
);
|
|
}
|
|
|
|
### **Test Specification**
|
|
|
|
**1\. Create Test File (tests/magnitude/02-theme.mag.ts)**
|
|
|
|
Create a file at /tests/magnitude/02-theme.mag.ts:
|
|
|
|
TypeScript
|
|
|
|
import { test } from 'magnitude-test';
|
|
|
|
test('Mantine theme is applied correctly', async (agent) \=\> {
|
|
// Act: Navigate to the homepage
|
|
await agent.act('Navigate to the homepage');
|
|
|
|
// Check: Verify the Mantine components are rendered
|
|
await agent.check('The text "Ponderants" is visible as a title');
|
|
await agent.check('A "Test Button" is visible on the screen');
|
|
|
|
// Check: Verify the theme is applied.
|
|
// We check that the button has the specific visual properties
|
|
// defined in our theme (gray color, xl radius).
|
|
await agent.check(
|
|
'The "Test Button" has a gray background, indicating the theme\\'s primaryColor is active'
|
|
);
|
|
await agent.check(
|
|
'The "Test Button" has rounded corners, indicating the theme\\'s defaultRadius is active'
|
|
);
|
|
|
|
// Check: Verify the Paper component is rendered with its themed styles
|
|
await agent.check(
|
|
'The page content is inside a "Paper" component with a border'
|
|
);
|
|
});
|