✨(demo) new demo
This new demo aims to take advantage of all the new Cunningham's components. The old demo was kind of a draft, this new one gives a better overview of what Cunningham is capable of.
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
import { Configuration } from "@openfun/cunningham-react";
|
||||
|
||||
const config: Configuration = {
|
||||
themes: {
|
||||
default: {
|
||||
components: {
|
||||
button: {
|
||||
"border-radius": "30px",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
const defaultConfig: Configuration = { themes: {} };
|
||||
|
||||
export default defaultConfig;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@faker-js/faker": "8.3.1",
|
||||
"@openfun/cunningham-react": "*",
|
||||
"@openfun/cunningham-tokens": "*",
|
||||
"@openfun/typescript-configs": "*",
|
||||
|
||||
BIN
apps/demo/public/pattern_dark.png
Normal file
BIN
apps/demo/public/pattern_dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
apps/demo/public/pattern_default.png
Normal file
BIN
apps/demo/public/pattern_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -1,62 +1,69 @@
|
||||
import {
|
||||
Button,
|
||||
CunninghamProvider,
|
||||
Pagination,
|
||||
Select,
|
||||
SUPPORTED_LOCALES,
|
||||
Switch,
|
||||
usePagination,
|
||||
} from "@openfun/cunningham-react";
|
||||
import React, { useState } from "react";
|
||||
import { tokens } from "./cunningham-tokens";
|
||||
import { Button, CunninghamProvider } from "@openfun/cunningham-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Create } from "./Create";
|
||||
import { Home } from "./Home";
|
||||
|
||||
enum Theme {
|
||||
DEFAULT = "default",
|
||||
DARK = "dark",
|
||||
}
|
||||
|
||||
const THEMES: Theme[] = [Theme.DEFAULT, Theme.DARK];
|
||||
export enum Page {
|
||||
HOME,
|
||||
CREATE,
|
||||
}
|
||||
|
||||
export interface PageProps {
|
||||
changePage: (page: Page) => void;
|
||||
}
|
||||
|
||||
const preferredScheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
.matches
|
||||
? Theme.DARK
|
||||
: Theme.DEFAULT;
|
||||
|
||||
export const App = () => {
|
||||
const pagination = usePagination({ defaultPage: 50, defaultPagesCount: 100 });
|
||||
const [locale, setLocale] = useState("en-US");
|
||||
const [theme, setTheme] = useState<Theme>(Theme.DEFAULT);
|
||||
const [locale] = useState("en-US");
|
||||
const [theme, setTheme] = useState<Theme>(preferredScheme);
|
||||
const [page, setPage] = useState<Page>(Page.HOME);
|
||||
const handleThemeChange = (event: MediaQueryListEvent) =>
|
||||
setTheme(event.matches ? Theme.DARK : Theme.DEFAULT);
|
||||
|
||||
useEffect(() => {
|
||||
const query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
query.addEventListener("change", handleThemeChange);
|
||||
|
||||
return () => {
|
||||
query.removeEventListener("change", handleThemeChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<CunninghamProvider currentLocale={locale} theme={theme}>
|
||||
<div className="center">
|
||||
<h1 className="clr-greyscale-900">Cunningham Demo.</h1>
|
||||
|
||||
<div className="mb-s">
|
||||
<Select
|
||||
label="Locale"
|
||||
options={SUPPORTED_LOCALES.map((v) => ({
|
||||
label: v,
|
||||
}))}
|
||||
clearable={false}
|
||||
value={locale}
|
||||
onChange={(e) => setLocale(e.target.value as string)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Select
|
||||
label="Theme"
|
||||
options={THEMES.map((v) => ({
|
||||
label: v,
|
||||
}))}
|
||||
clearable={false}
|
||||
value={THEMES[0]}
|
||||
onChange={(e) => setTheme(e.target.value as Theme)}
|
||||
<div className="container">
|
||||
<img
|
||||
className="pattern"
|
||||
src={
|
||||
theme === Theme.DARK ? "pattern_dark.png" : "pattern_default.png"
|
||||
}
|
||||
alt="Background pattern"
|
||||
/>
|
||||
{page === Page.HOME && <Home changePage={(p) => setPage(p)} />}
|
||||
{page === Page.CREATE && <Create changePage={(p) => setPage(p)} />}
|
||||
</div>
|
||||
|
||||
<div className="p-s">
|
||||
<Switch defaultChecked={true} label="Switch" />
|
||||
</div>
|
||||
<Button>World best button.</Button>
|
||||
<h3 className="clr-greyscale-900">
|
||||
Primary-500 color is{" "}
|
||||
{tokens.themes[theme].theme.colors["primary-500"]}
|
||||
</h3>
|
||||
<Pagination {...pagination} />
|
||||
<div className="theme-switch">
|
||||
<Button
|
||||
color="tertiary"
|
||||
icon={
|
||||
<span className="material-icons">
|
||||
{theme === Theme.DARK ? "light_mode" : "dark_mode"}
|
||||
</span>
|
||||
}
|
||||
onClick={() => {
|
||||
setTheme(theme === Theme.DARK ? Theme.DEFAULT : Theme.DARK);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</CunninghamProvider>
|
||||
);
|
||||
|
||||
168
apps/demo/src/Character.ts
Normal file
168
apps/demo/src/Character.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
export interface Character {
|
||||
id: string;
|
||||
name: string;
|
||||
gender: "male" | "female" | "other";
|
||||
birthDate: Date;
|
||||
firstAppearanceDate: Date;
|
||||
lastAppearanceDate: Date;
|
||||
isGuest: boolean;
|
||||
}
|
||||
|
||||
export const randomDates = () => {
|
||||
return {
|
||||
birthDate: faker.date.between({
|
||||
from: "1950-01-01T00:00:00.000Z",
|
||||
to: "1970-01-01T00:00:00.000Z",
|
||||
}),
|
||||
firstAppearanceDate: faker.date.between({
|
||||
from: "1974-01-01T00:00:00.000Z",
|
||||
to: "1984-01-01T00:00:00.000Z",
|
||||
}),
|
||||
lastAppearanceDate: faker.date.past(),
|
||||
};
|
||||
};
|
||||
|
||||
export const database: Character[] = [
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Richie Cunningham",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Joanie Cunningham",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Arthur Fonzarelli",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Marion Cunningham",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Ralph Malph",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Howard Cunningham",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Marsha Simms",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Warren Berlinger",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Al Molinaro",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Verna LaVerne",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Arnold Takahashi",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Linda Purl",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Crystal Bernard",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Heather O'Rourke",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Scott Bernstein",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Ed Peck",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Beatrice Colen",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Dody Goodman",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Linda Dano",
|
||||
gender: "female",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
{
|
||||
id: faker.string.uuid(),
|
||||
name: "Gavan O'Herlihy",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
},
|
||||
];
|
||||
132
apps/demo/src/Create.tsx
Normal file
132
apps/demo/src/Create.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Alert,
|
||||
AlertType,
|
||||
Button,
|
||||
Checkbox,
|
||||
DatePicker,
|
||||
DateRangePicker,
|
||||
FileUploader,
|
||||
Input,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Select,
|
||||
Switch,
|
||||
TextArea,
|
||||
ToastType,
|
||||
useToastProvider,
|
||||
} from "@openfun/cunningham-react";
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { Character, database, randomDates } from "./Character";
|
||||
import { Page, PageProps } from "./App";
|
||||
|
||||
export const Create = ({ changePage }: PageProps) => {
|
||||
const { toast } = useToastProvider();
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
|
||||
const submit = () => {
|
||||
const character: Character = {
|
||||
id: faker.string.uuid(),
|
||||
name: inputRef.current?.value || "",
|
||||
gender: "male",
|
||||
isGuest: false,
|
||||
...randomDates(),
|
||||
};
|
||||
database.unshift(character);
|
||||
|
||||
changePage(Page.HOME);
|
||||
toast("Character created successfully", ToastType.SUCCESS);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="page__create clr-greyscale-900">
|
||||
<h1>Add a character</h1>
|
||||
<div className="card">
|
||||
<h3 className="fw-bold fs-h3">General Information</h3>
|
||||
<Alert type={AlertType.INFO}>
|
||||
You are about to add a new character to the collection
|
||||
</Alert>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
label="Name"
|
||||
text="Enter first and last name"
|
||||
fullWidth={true}
|
||||
/>
|
||||
<Select
|
||||
label="Gender"
|
||||
fullWidth={true}
|
||||
options={[
|
||||
{
|
||||
label: "Male",
|
||||
},
|
||||
{
|
||||
label: "Female",
|
||||
},
|
||||
{
|
||||
label: "Other",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<DatePicker label="Birth Date" fullWidth={true} />
|
||||
<DateRangePicker
|
||||
startLabel="First appearance"
|
||||
endLabel="Last appearance"
|
||||
fullWidth={true}
|
||||
/>
|
||||
<Checkbox label="This character is a guest" />
|
||||
</div>
|
||||
<div className="card mt-l">
|
||||
<h3 className="fw-bold fs-h3">Bio</h3>
|
||||
<Alert type={AlertType.WARNING}>
|
||||
Please be exhaustive, every detail counts!
|
||||
</Alert>
|
||||
<TextArea
|
||||
label="Biography"
|
||||
text="Enter a detailed biography"
|
||||
fullWidth={true}
|
||||
rows={8}
|
||||
/>
|
||||
<RadioGroup>
|
||||
<Radio
|
||||
label="Appeared between 0 and 5 times"
|
||||
name="occurences"
|
||||
value="A"
|
||||
/>
|
||||
<Radio
|
||||
label="Appeared between 6 and 10 times"
|
||||
name="occurences"
|
||||
value="B"
|
||||
/>
|
||||
<Radio
|
||||
label="Appeared between 10 and 20 times"
|
||||
name="occurences"
|
||||
value="C"
|
||||
/>
|
||||
<Radio
|
||||
label="Appeared between 20+ times"
|
||||
name="occurences"
|
||||
value="D"
|
||||
/>
|
||||
</RadioGroup>
|
||||
<Switch label="Make this character public" />
|
||||
|
||||
<div>
|
||||
<h4>Add pictures</h4>
|
||||
|
||||
<div className="mt-s">
|
||||
<FileUploader
|
||||
fullWidth={true}
|
||||
text="JPG, PNG or GIF - Max file size 2MB"
|
||||
multiple={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-l">
|
||||
<Button fullWidth={true} onClick={() => submit()}>
|
||||
Add character
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
141
apps/demo/src/Home.tsx
Normal file
141
apps/demo/src/Home.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
DataGrid,
|
||||
SortModel,
|
||||
ToastType,
|
||||
usePagination,
|
||||
useToastProvider,
|
||||
} from "@openfun/cunningham-react";
|
||||
import { Page, PageProps } from "./App";
|
||||
import { database } from "./Character";
|
||||
|
||||
export const Home = ({ changePage }: PageProps) => {
|
||||
const { toast } = useToastProvider();
|
||||
const [rowSelection, setRowSelection] = useState({});
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const pagination = usePagination({ defaultPage: 1 });
|
||||
const [sortModel, setSortModel] = useState<SortModel>([
|
||||
{
|
||||
field: "lastName",
|
||||
sort: "desc",
|
||||
},
|
||||
]);
|
||||
const [rows, setRows] = useState<typeof database>([]);
|
||||
const [refresh, setRefresh] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
// Sort database. On your side this is supposed to be done on the server.
|
||||
const sortKey = sortModel.length > 0 ? sortModel[0].field : "id";
|
||||
const sortPolarity =
|
||||
sortModel.length > 0 && sortModel[0].sort === "asc" ? 1 : -1;
|
||||
const sortedDatabase = [...database].sort((a: any, b: any) => {
|
||||
if (a[sortKey] < b[sortKey]) return -sortPolarity;
|
||||
if (a[sortKey] > b[sortKey]) return sortPolarity;
|
||||
return 0;
|
||||
});
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
// Set the pagination length.
|
||||
pagination.setPagesCount(
|
||||
Math.ceil(sortedDatabase.length / pagination.pageSize),
|
||||
);
|
||||
// Select the rows to display on the current page.
|
||||
setRows(
|
||||
sortedDatabase.slice(
|
||||
(pagination.page - 1) * pagination.pageSize,
|
||||
pagination.page * pagination.pageSize,
|
||||
),
|
||||
);
|
||||
setIsLoading(false);
|
||||
}, [pagination.page, sortModel, refresh]);
|
||||
|
||||
return (
|
||||
<div className="page__home">
|
||||
<div className="page__home__title">
|
||||
<h1 className="clr-greyscale-900">
|
||||
{/* eslint-disable-next-line react/no-unescaped-entities */}
|
||||
🍿Cunningham's <span className="clr-primary-400">Cast</span>
|
||||
</h1>
|
||||
<p className="clr-greyscale-600 fs-m fw-regular">
|
||||
Happy Days is an American television sitcom that aired first-run from
|
||||
January 15, 1974, to September 24, 1984, on ABC-TV
|
||||
<br /> with a total of 255 half-hour episodes spanning over eleven
|
||||
seasons. <br />
|
||||
<br />
|
||||
Created by Garry Marshall, the series presented an idealized vision of
|
||||
life in the mid-1950s to mid-1960s Midwestern United States.
|
||||
</p>
|
||||
<Button
|
||||
color="primary"
|
||||
icon={<span className="material-icons">movie</span>}
|
||||
onClick={() => changePage(Page.CREATE)}
|
||||
>
|
||||
Add character
|
||||
</Button>
|
||||
</div>
|
||||
<div className="card">
|
||||
<DataGrid
|
||||
columns={[
|
||||
{
|
||||
field: "name",
|
||||
headerName: "Name",
|
||||
},
|
||||
{
|
||||
field: "gender",
|
||||
headerName: "Gender",
|
||||
},
|
||||
{
|
||||
id: "birthDate",
|
||||
headerName: "Birth Date",
|
||||
renderCell: (params) => {
|
||||
return params.row.birthDate.toLocaleDateString();
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "firstAppearanceDate",
|
||||
headerName: "First Appearance",
|
||||
renderCell: (params) => {
|
||||
return params.row.firstAppearanceDate.toLocaleDateString();
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "isGuest",
|
||||
headerName: "Is Guest",
|
||||
renderCell: (params) => {
|
||||
return params.row.isGuest ? "yes" : "no";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
renderCell: (params) => (
|
||||
<Button
|
||||
color="tertiary-text"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const index = database.findIndex(
|
||||
(character) => character.id === params.row.id,
|
||||
);
|
||||
database.splice(index, 1);
|
||||
setRefresh(refresh + 1);
|
||||
toast("Character deleted successfully", ToastType.WARNING);
|
||||
}}
|
||||
icon={<span className="material-icons">delete</span>}
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
rows={rows}
|
||||
pagination={pagination}
|
||||
sortModel={sortModel}
|
||||
onSortModelChange={setSortModel}
|
||||
isLoading={isLoading}
|
||||
enableRowSelection={true}
|
||||
rowSelection={rowSelection}
|
||||
onRowSelectionChange={setRowSelection}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -106,7 +106,12 @@
|
||||
--c--theme--transitions--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
|
||||
--c--theme--transitions--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||
--c--theme--transitions--duration: 250ms;
|
||||
--c--components--button--border-radius: 30px;
|
||||
--c--theme--breakpoints--xs: 0;
|
||||
--c--theme--breakpoints--sm: 576px;
|
||||
--c--theme--breakpoints--md: 768px;
|
||||
--c--theme--breakpoints--lg: 992px;
|
||||
--c--theme--breakpoints--xl: 1200px;
|
||||
--c--theme--breakpoints--xxl: 1400px;
|
||||
}
|
||||
.cunningham-theme--dark{
|
||||
--c--theme--colors--greyscale-100: #182536;
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const tokens = {"themes":{"default":{"theme":{"colors":{"secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","greyscale-000":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000","primary-text":"#FFFFFF","success-text":"#FFFFFF","warning-text":"#FFFFFF","danger-text":"#FFFFFF"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":200,"light":300,"regular":400,"medium":500,"bold":600,"extrabold":700,"black":800},"families":{"base":"\"Roboto Flex Variable\", sans-serif","accent":"\"Roboto Flex Variable\", sans-serif"},"letterSpacings":{"h1":"normal","h2":"normal","h3":"normal","h4":"normal","h5":"1px","h6":"normal","l":"normal","m":"normal","s":"normal"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"button":{"border-radius":"30px"}}},"dark":{"theme":{"colors":{"greyscale-100":"#182536","greyscale-200":"#303C4B","greyscale-300":"#555F6B","greyscale-400":"#79818A","greyscale-500":"#9EA3AA","greyscale-600":"#C2C6CA","greyscale-700":"#E7E8EA","greyscale-800":"#F3F4F4","greyscale-900":"#FAFAFB","greyscale-000":"#0C1A2B","primary-100":"#3B4C62","primary-200":"#4D6481","primary-300":"#6381A6","primary-400":"#7FA5D5","primary-500":"#8CB5EA","primary-600":"#A3C4EE","primary-700":"#C3D8F4","primary-800":"#DDE9F8","primary-900":"#F4F8FD","success-100":"#EEF8D7","success-200":"#D9F1B2","success-300":"#BDE985","success-400":"#A0E25D","success-500":"#76D628","success-600":"#5BB520","success-700":"#43941A","success-800":"#307414","success-900":"#225D10","warning-100":"#F7F3D5","warning-200":"#F0E5AA","warning-300":"#E8D680","warning-400":"#E3C95F","warning-500":"#D9B32B","warning-600":"#BD9721","warning-700":"#9D7B1C","warning-800":"#7E6016","warning-900":"#684D12","danger-100":"#F8D0D0","danger-200":"#F09898","danger-300":"#F09898","danger-400":"#ED8585","danger-500":"#E96666","danger-600":"#DD6666","danger-700":"#C36666","danger-800":"#AE6666","danger-900":"#9D6666"}}}}};
|
||||
export const tokens = {"themes":{"default":{"theme":{"colors":{"secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","greyscale-000":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000","primary-text":"#FFFFFF","success-text":"#FFFFFF","warning-text":"#FFFFFF","danger-text":"#FFFFFF"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":200,"light":300,"regular":400,"medium":500,"bold":600,"extrabold":700,"black":800},"families":{"base":"\"Roboto Flex Variable\", sans-serif","accent":"\"Roboto Flex Variable\", sans-serif"},"letterSpacings":{"h1":"normal","h2":"normal","h3":"normal","h4":"normal","h5":"1px","h6":"normal","l":"normal","m":"normal","s":"normal"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"},"breakpoints":{"xs":0,"sm":"576px","md":"768px","lg":"992px","xl":"1200px","xxl":"1400px"}}},"dark":{"theme":{"colors":{"greyscale-100":"#182536","greyscale-200":"#303C4B","greyscale-300":"#555F6B","greyscale-400":"#79818A","greyscale-500":"#9EA3AA","greyscale-600":"#C2C6CA","greyscale-700":"#E7E8EA","greyscale-800":"#F3F4F4","greyscale-900":"#FAFAFB","greyscale-000":"#0C1A2B","primary-100":"#3B4C62","primary-200":"#4D6481","primary-300":"#6381A6","primary-400":"#7FA5D5","primary-500":"#8CB5EA","primary-600":"#A3C4EE","primary-700":"#C3D8F4","primary-800":"#DDE9F8","primary-900":"#F4F8FD","success-100":"#EEF8D7","success-200":"#D9F1B2","success-300":"#BDE985","success-400":"#A0E25D","success-500":"#76D628","success-600":"#5BB520","success-700":"#43941A","success-800":"#307414","success-900":"#225D10","warning-100":"#F7F3D5","warning-200":"#F0E5AA","warning-300":"#E8D680","warning-400":"#E3C95F","warning-500":"#D9B32B","warning-600":"#BD9721","warning-700":"#9D7B1C","warning-800":"#7E6016","warning-900":"#684D12","danger-100":"#F8D0D0","danger-200":"#F09898","danger-300":"#F09898","danger-400":"#ED8585","danger-500":"#E96666","danger-600":"#DD6666","danger-700":"#C36666","danger-800":"#AE6666","danger-900":"#9D6666"}}}}};
|
||||
|
||||
@@ -3,28 +3,95 @@
|
||||
@use "@openfun/cunningham-react/style";
|
||||
@use "cunningham-tokens";
|
||||
|
||||
:root {
|
||||
font-family: Roboto, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3rem;
|
||||
background-color: var(--c--theme--colors--greyscale-000);
|
||||
|
||||
// Reset
|
||||
h1 {
|
||||
font-family: var(--c--theme--font--families--accent);
|
||||
font-size: 4rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 2rem;
|
||||
background-color: var(--c--theme--colors--greyscale-100);
|
||||
border-radius: 1rem;
|
||||
// App
|
||||
html {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 5rem;
|
||||
background: linear-gradient(153deg, var(--c--theme--colors--greyscale-100) 0%, var(--c--theme--colors--greyscale-000) 100%);
|
||||
}
|
||||
|
||||
h1, h3 {
|
||||
margin-bottom: 40px;
|
||||
.pattern {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: -200px;
|
||||
left: -290px;
|
||||
transform: rotate(335deg);
|
||||
}
|
||||
|
||||
.theme-switch {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
top: 0.75rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: var(--c--theme--colors--greyscale-000);
|
||||
padding: 2rem;
|
||||
border-radius: 4px;
|
||||
border: 1px var(--c--theme--colors--greyscale-300) solid;
|
||||
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
|
||||
}
|
||||
|
||||
.cunningham-theme--dark {
|
||||
.card {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: auto;
|
||||
position: relative;
|
||||
|
||||
width: 1100px;
|
||||
@media (max-width: 1200px) {
|
||||
width: calc(100% - 2rem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Home
|
||||
.page__home {
|
||||
&__title {
|
||||
gap: 1.5rem;
|
||||
margin: 4rem 0;
|
||||
|
||||
h1 {
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
.page__create {
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin: 4rem 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
|
||||
h3, h4 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user