init
This commit is contained in:
205
docs/steps/step-02.md
Normal file
205
docs/steps/step-02.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# **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'
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user