You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-21 23:00:50 +03:00
Cleanup Storybook config and add theme switcher
This commit is contained in:
@@ -15,9 +15,26 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||||
addons: [
|
addons: [
|
||||||
"@storybook/addon-links",
|
// Automatic docs pages
|
||||||
"@storybook/addon-essentials",
|
"@storybook/addon-docs",
|
||||||
"@storybook/addon-interactions",
|
|
||||||
|
// Controls of components props
|
||||||
|
"@storybook/addon-controls",
|
||||||
|
|
||||||
|
// Document components actions
|
||||||
|
"@storybook/addon-actions",
|
||||||
|
|
||||||
|
// Helps measuring elements
|
||||||
|
"@storybook/addon-measure",
|
||||||
|
|
||||||
|
// Helps showing components boundaries
|
||||||
|
"@storybook/addon-outline",
|
||||||
|
|
||||||
|
// Quickly change viewport size
|
||||||
|
"@storybook/addon-viewport",
|
||||||
|
|
||||||
|
// Theme switch toolbar
|
||||||
|
"@storybook/addon-toolbars",
|
||||||
],
|
],
|
||||||
framework: {
|
framework: {
|
||||||
name: "@storybook/react-vite",
|
name: "@storybook/react-vite",
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import "../src/index.css";
|
|
||||||
|
|
||||||
export const parameters = {
|
|
||||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
|
||||||
controls: {
|
|
||||||
matchers: {
|
|
||||||
color: /(background|color)$/i,
|
|
||||||
date: /Date$/,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
58
frontend/.storybook/preview.tsx
Normal file
58
frontend/.storybook/preview.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import "../src/index.css";
|
||||||
|
|
||||||
|
export const parameters = {
|
||||||
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
|
controls: {
|
||||||
|
matchers: {
|
||||||
|
color: /(background|color)$/i,
|
||||||
|
date: /Date$/,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const globalTypes = {
|
||||||
|
theme: {
|
||||||
|
name: "Theme",
|
||||||
|
description: "Global theme for components",
|
||||||
|
defaultValue: "light",
|
||||||
|
toolbar: {
|
||||||
|
title: "Theme",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Light",
|
||||||
|
value: "light",
|
||||||
|
icon: "circle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Dark",
|
||||||
|
value: "dark",
|
||||||
|
icon: "circlehollow",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const ThemeSwitcher = ({ theme }) => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (theme === "dark") {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark");
|
||||||
|
}
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const withThemeProvider = (Story, context) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ThemeSwitcher theme={context.globals.theme} />
|
||||||
|
<Story />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const decorators = [withThemeProvider];
|
||||||
@@ -22,6 +22,22 @@ limitations under the License.
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="/src/index.css" />
|
<link rel="stylesheet" href="/src/index.css" />
|
||||||
<title>matrix-authentication-service</title>
|
<title>matrix-authentication-service</title>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
function handleChange(e) {
|
||||||
|
if (e.matches) {
|
||||||
|
document.documentElement.classList.add("dark")
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query.addListener(handleChange);
|
||||||
|
handleChange(query);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
10719
frontend/package-lock.json
generated
10719
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -25,12 +25,17 @@
|
|||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.18.6",
|
||||||
"@babel/preset-typescript": "^7.18.6",
|
"@babel/preset-typescript": "^7.18.6",
|
||||||
"@graphql-eslint/eslint-plugin": "^3.13.1",
|
"@graphql-eslint/eslint-plugin": "^3.13.1",
|
||||||
|
"@storybook/addon-actions": "^7.0.0-alpha.49",
|
||||||
|
"@storybook/addon-backgrounds": "^7.0.0-alpha.49",
|
||||||
|
"@storybook/addon-controls": "^7.0.0-alpha.49",
|
||||||
|
"@storybook/addon-docs": "^7.0.0-alpha.49",
|
||||||
"@storybook/addon-essentials": "^7.0.0-alpha.49",
|
"@storybook/addon-essentials": "^7.0.0-alpha.49",
|
||||||
"@storybook/addon-interactions": "^7.0.0-alpha.49",
|
"@storybook/addon-measure": "^7.0.0-alpha.49",
|
||||||
"@storybook/addon-links": "^7.0.0-alpha.49",
|
"@storybook/addon-outline": "^7.0.0-alpha.49",
|
||||||
|
"@storybook/addon-toolbars": "^7.0.0-alpha.49",
|
||||||
|
"@storybook/addon-viewport": "^7.0.0-alpha.49",
|
||||||
"@storybook/react": "^7.0.0-alpha.49",
|
"@storybook/react": "^7.0.0-alpha.49",
|
||||||
"@storybook/react-vite": "^7.0.0-alpha.49",
|
"@storybook/react-vite": "^7.0.0-alpha.49",
|
||||||
"@storybook/testing-library": "^0.0.13",
|
|
||||||
"@types/jest": "^29.2.2",
|
"@types/jest": "^29.2.2",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@types/react": "^18.0.25",
|
"@types/react": "^18.0.25",
|
||||||
|
|||||||
54
frontend/src/components/Block.stories.tsx
Normal file
54
frontend/src/components/Block.stories.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import type { Meta, StoryObj } from "@storybook/react";
|
||||||
|
|
||||||
|
import Block from "./Block";
|
||||||
|
import { Title, Subtitle, Body } from "./Typography";
|
||||||
|
|
||||||
|
const meta: Meta<typeof Block> = {
|
||||||
|
title: "UI/Block",
|
||||||
|
component: Block,
|
||||||
|
subcomponents: {
|
||||||
|
Title,
|
||||||
|
Subtitle,
|
||||||
|
Body,
|
||||||
|
} as Record<string, React.ComponentType<any>>,
|
||||||
|
tags: ["docsPage"],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Block>;
|
||||||
|
|
||||||
|
export const Basic: Story = {
|
||||||
|
render: (args) => (
|
||||||
|
<Block {...args}>
|
||||||
|
<Title>Title</Title>
|
||||||
|
<Subtitle>Subtitle</Subtitle>
|
||||||
|
<Body>
|
||||||
|
Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit
|
||||||
|
enim labore culpa sint ad nisi Lorem pariatur mollit ex esse
|
||||||
|
exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit
|
||||||
|
nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor
|
||||||
|
minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure
|
||||||
|
elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor
|
||||||
|
Lorem duis laboris cupidatat officia voluptate. Culpa proident
|
||||||
|
adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod.
|
||||||
|
Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim.
|
||||||
|
Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa
|
||||||
|
et culpa duis.
|
||||||
|
</Body>
|
||||||
|
</Block>
|
||||||
|
),
|
||||||
|
};
|
||||||
27
frontend/src/components/Block.tsx
Normal file
27
frontend/src/components/Block.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Block: React.FC<Props> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<div className="p-4 bg-grey-50 dark:bg-grey-450 dark:text-white rounded">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Block;
|
||||||
@@ -41,7 +41,7 @@ const OAuth2Session: React.FC<Props> = ({ session }) => {
|
|||||||
<div className="p-2 my-1 bg-grey-50 dark:bg-grey-450 dark:text-white rounded">
|
<div className="p-2 my-1 bg-grey-50 dark:bg-grey-450 dark:text-white rounded">
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="body">
|
<Typography variant="body">
|
||||||
Client ID: <Code>{data.scope}</Code>
|
Client ID: <Code>{data.client.clientId}</Code>
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
{data.client.clientName && (
|
{data.client.clientName && (
|
||||||
|
|||||||
@@ -35,24 +35,38 @@ const classMap: Record<Variant, string> = {
|
|||||||
headline: "text-3xl font-semibold",
|
headline: "text-3xl font-semibold",
|
||||||
title: "text-2xl font-semibold",
|
title: "text-2xl font-semibold",
|
||||||
subtitle: "text-lg",
|
subtitle: "text-lg",
|
||||||
body: "text-base",
|
body: "text-base text-justify",
|
||||||
caption: "text-sm",
|
caption: "text-sm",
|
||||||
micro: "text-xs",
|
micro: "text-xs",
|
||||||
};
|
};
|
||||||
|
|
||||||
const Typography: React.FC<Props> = ({ variant, children, bold }) => {
|
const Typography = ({ variant, children, bold }: Props) => {
|
||||||
const element = elementMap[variant];
|
const element = elementMap[variant];
|
||||||
const boldClass = bold ? "font-semibold" : "";
|
const boldClass = bold ? "font-semibold" : "";
|
||||||
const className = `text-black dark:text-white ${boldClass} ${classMap[variant]}`;
|
const className = `text-black dark:text-white ${boldClass} ${classMap[variant]}`;
|
||||||
return createElement(element, { className }, ...Children.toArray(children));
|
return createElement(element, { className }, ...Children.toArray(children));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Bold: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
type SimpleProps = { children: React.ReactNode };
|
||||||
|
|
||||||
|
export const Bold = ({ children }: SimpleProps) => (
|
||||||
<em className="font-semibold">{children}</em>
|
<em className="font-semibold">{children}</em>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Code: React.FC<{ children: React.ReactNode }> = ({ children }) => (
|
export const Code = ({ children }: SimpleProps) => (
|
||||||
<code className="font-mono text-sm">{children}</code>
|
<code className="font-mono text-sm">{children}</code>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const Title = ({ children }: SimpleProps) => (
|
||||||
|
<Typography variant="title" children={children} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Subtitle = ({ children }: SimpleProps) => (
|
||||||
|
<Typography variant="subtitle" children={children} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Body = ({ children }: SimpleProps) => (
|
||||||
|
<Typography variant="body" children={children} />
|
||||||
|
);
|
||||||
|
|
||||||
export default Typography;
|
export default Typography;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
mode: "jit",
|
mode: "jit",
|
||||||
content: ["./src/**/*.tsx", "./index.html"],
|
content: ["./src/**/*.tsx", "./index.html"],
|
||||||
|
darkMode: "class",
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
white: "#FFFFFF",
|
white: "#FFFFFF",
|
||||||
|
|||||||
Reference in New Issue
Block a user