Rework the storybook
This commit is contained in:
parent
5221fb3479
commit
386a8d7cd7
@ -1,70 +0,0 @@
|
||||
|
||||
import React from "react";
|
||||
import { DocsContainer as BaseContainer } from "@storybook/addon-docs";
|
||||
import { useDarkMode } from "storybook-dark-mode";
|
||||
import { darkTheme, lightTheme } from "./customTheme";
|
||||
import "./static/fonts/WorkSans/font.css";
|
||||
|
||||
export function DocsContainer({ children, context }) {
|
||||
const isStorybookUiDark = useDarkMode();
|
||||
|
||||
const theme = isStorybookUiDark ? darkTheme : lightTheme;
|
||||
|
||||
const backgroundColor = theme.appBg;
|
||||
|
||||
return (
|
||||
<>
|
||||
<style>{`
|
||||
body {
|
||||
padding: 0 !important;
|
||||
background-color: ${backgroundColor};
|
||||
}
|
||||
|
||||
.docs-story {
|
||||
background-color: ${backgroundColor};
|
||||
}
|
||||
[id^=story--] .container {
|
||||
border: 1px dashed #e8e8e8;
|
||||
}
|
||||
|
||||
.docblock-argstable-head th:nth-child(3), .docblock-argstable-body tr > td:nth-child(3) {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
.docblock-argstable-head th:nth-child(3), .docblock-argstable-body tr > td:nth-child(2) p {
|
||||
font-size: 13px;
|
||||
}
|
||||
`}</style>
|
||||
<BaseContainer
|
||||
context={{
|
||||
...context,
|
||||
"storyById": id => {
|
||||
const storyContext = context.storyById(id);
|
||||
return {
|
||||
...storyContext,
|
||||
"parameters": {
|
||||
...storyContext?.parameters,
|
||||
"docs": {
|
||||
...storyContext?.parameters?.docs,
|
||||
"theme": isStorybookUiDark ? darkTheme : lightTheme
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</BaseContainer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function CanvasContainer({ children }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import { create } from "@storybook/theming";
|
||||
|
||||
const brandImage = "logo.png";
|
||||
const brandTitle = "Keycloakify";
|
||||
const brandUrl = "https://github.com/keycloakify/keycloakify";
|
||||
const fontBase = '"Work Sans", sans-serif';
|
||||
const fontCode = "monospace";
|
||||
|
||||
export const darkTheme = create({
|
||||
"base": "dark",
|
||||
"appBg": "#1E1E1E",
|
||||
"appContentBg": "#161616",
|
||||
"barBg": "#161616",
|
||||
"colorSecondary": "#8585F6",
|
||||
"textColor": "#FFFFFF",
|
||||
brandImage,
|
||||
brandTitle,
|
||||
brandUrl,
|
||||
fontBase,
|
||||
fontCode
|
||||
});
|
||||
|
||||
export const lightTheme = create({
|
||||
"base": "light",
|
||||
"appBg": "#F6F6F6",
|
||||
"appContentBg": "#FFFFFF",
|
||||
"barBg": "#FFFFFF",
|
||||
"colorSecondary": "#000091",
|
||||
"textColor": "#212121",
|
||||
brandImage,
|
||||
brandTitle,
|
||||
brandUrl,
|
||||
fontBase,
|
||||
fontCode
|
||||
});
|
33
.storybook/customTheme.ts
Normal file
33
.storybook/customTheme.ts
Normal file
@ -0,0 +1,33 @@
|
||||
const brandImage = "logo.png";
|
||||
const brandTitle = "Keycloakify";
|
||||
const brandUrl = "https://github.com/keycloakify/keycloakify";
|
||||
const fontBase = '"Work Sans", sans-serif';
|
||||
const fontCode = "monospace";
|
||||
|
||||
export const darkTheme = {
|
||||
base: "dark",
|
||||
appBg: "#1E1E1E",
|
||||
appContentBg: "#161616",
|
||||
barBg: "#161616",
|
||||
colorSecondary: "#8585F6",
|
||||
textColor: "#FFFFFF",
|
||||
brandImage,
|
||||
brandTitle,
|
||||
brandUrl,
|
||||
fontBase,
|
||||
fontCode
|
||||
};
|
||||
|
||||
export const lightTheme: typeof darkTheme = {
|
||||
base: "light",
|
||||
appBg: "#F6F6F6",
|
||||
appContentBg: "#FFFFFF",
|
||||
barBg: "#FFFFFF",
|
||||
colorSecondary: "#000091",
|
||||
textColor: "#212121",
|
||||
brandImage,
|
||||
brandTitle,
|
||||
brandUrl,
|
||||
fontBase,
|
||||
fontCode
|
||||
};
|
@ -1,15 +1,13 @@
|
||||
module.exports = {
|
||||
"stories": [
|
||||
"../stories/**/*.stories.@(ts|tsx|mdx)"
|
||||
stories: [
|
||||
"../stories/**/*.stories.tsx"
|
||||
],
|
||||
"addons": [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
addons: [
|
||||
"storybook-dark-mode",
|
||||
"@storybook/addon-a11y"
|
||||
],
|
||||
"core": {
|
||||
"builder": "webpack5"
|
||||
core: {
|
||||
builder: "webpack5"
|
||||
},
|
||||
"staticDirs": ["./static"]
|
||||
staticDirs: ["./static"]
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { addons } from '@storybook/addons';
|
||||
|
||||
addons.setConfig({
|
||||
"selectedPanel": 'storybook/a11y/panel',
|
||||
"showPanel": false,
|
||||
selectedPanel: 'storybook/a11y/panel',
|
||||
showPanel: false
|
||||
});
|
||||
|
@ -1,3 +1,9 @@
|
||||
<link rel="preload" href="/fonts/WorkSans/worksans-bold-webfont.woff2" as="font" crossorigin="anonymous">
|
||||
<link rel="preload" href="/fonts/WorkSans/worksans-medium-webfont.woff2" as="font" crossorigin="anonymous">
|
||||
<link rel="preload" href="/fonts/WorkSans/worksans-regular-webfont.woff2" as="font" crossorigin="anonymous">
|
||||
<link rel="preload" href="/fonts/WorkSans/worksans-semibold-webfont.woff2" as="font" crossorigin="anonymous">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/WorkSans/font.css">
|
||||
|
||||
<style>
|
||||
body.sb-show-main.sb-main-padded {
|
||||
padding: 0;
|
||||
|
@ -1,116 +1,105 @@
|
||||
import { darkTheme, lightTheme } from "./customTheme";
|
||||
import { DocsContainer, CanvasContainer } from "./Containers";
|
||||
import { create as createTheme } from "@storybook/theming";
|
||||
|
||||
export const parameters = {
|
||||
"actions": { "argTypesRegex": "^on[A-Z].*" },
|
||||
"controls": {
|
||||
"matchers": {
|
||||
"color": /(background|color)$/i,
|
||||
"date": /Date$/,
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
"backgrounds": { "disable": true },
|
||||
"darkMode": {
|
||||
"light": lightTheme,
|
||||
"dark": darkTheme,
|
||||
backgrounds: { disable: true },
|
||||
darkMode: {
|
||||
light: createTheme(lightTheme),
|
||||
dark: createTheme(darkTheme),
|
||||
},
|
||||
"docs": {
|
||||
"container": DocsContainer
|
||||
controls: {
|
||||
disable: true,
|
||||
},
|
||||
"controls": {
|
||||
"disable": true,
|
||||
actions: {
|
||||
disable: true
|
||||
},
|
||||
"actions": {
|
||||
"disable": true
|
||||
},
|
||||
"viewport": {
|
||||
"viewports": {
|
||||
viewport: {
|
||||
viewports: {
|
||||
"1440p": {
|
||||
"name": "1440p",
|
||||
"styles": {
|
||||
"width": "2560px",
|
||||
"height": "1440px",
|
||||
name: "1440p",
|
||||
styles: {
|
||||
width: "2560px",
|
||||
height: "1440px",
|
||||
},
|
||||
},
|
||||
"fullHD": {
|
||||
"name": "Full HD",
|
||||
"styles": {
|
||||
"width": "1920px",
|
||||
"height": "1080px",
|
||||
fullHD: {
|
||||
name: "Full HD",
|
||||
styles: {
|
||||
width: "1920px",
|
||||
height: "1080px",
|
||||
},
|
||||
},
|
||||
"macBookProBig": {
|
||||
"name": "MacBook Pro Big",
|
||||
"styles": {
|
||||
"width": "1024px",
|
||||
"height": "640px",
|
||||
macBookProBig: {
|
||||
name: "MacBook Pro Big",
|
||||
styles: {
|
||||
width: "1024px",
|
||||
height: "640px",
|
||||
},
|
||||
},
|
||||
"macBookProMedium": {
|
||||
"name": "MacBook Pro Medium",
|
||||
"styles": {
|
||||
"width": "1440px",
|
||||
"height": "900px",
|
||||
macBookProMedium: {
|
||||
name: "MacBook Pro Medium",
|
||||
styles: {
|
||||
width: "1440px",
|
||||
height: "900px",
|
||||
},
|
||||
},
|
||||
"macBookProSmall": {
|
||||
"name": "MacBook Pro Small",
|
||||
"styles": {
|
||||
"width": "1680px",
|
||||
"height": "1050px",
|
||||
macBookProSmall: {
|
||||
name: "MacBook Pro Small",
|
||||
styles: {
|
||||
width: "1680px",
|
||||
height: "1050px",
|
||||
},
|
||||
},
|
||||
"pcAgent": {
|
||||
"name": "PC Agent",
|
||||
"styles": {
|
||||
"width": "960px",
|
||||
"height": "540px",
|
||||
pcAgent: {
|
||||
name: "PC Agent",
|
||||
styles: {
|
||||
width: "960px",
|
||||
height: "540px",
|
||||
},
|
||||
},
|
||||
"iphone12Pro": {
|
||||
"name": "Iphone 12 pro",
|
||||
"styles": {
|
||||
"width": "390px",
|
||||
"height": "844px",
|
||||
iphone12Pro: {
|
||||
name: "Iphone 12 pro",
|
||||
styles: {
|
||||
width: "390px",
|
||||
height: "844px",
|
||||
},
|
||||
},
|
||||
"iphone5se": {
|
||||
"name": "Iphone 5/SE",
|
||||
"styles": {
|
||||
"width": "320px",
|
||||
"height": "568px",
|
||||
iphone5se: {
|
||||
name: "Iphone 5/SE",
|
||||
styles: {
|
||||
width: "320px",
|
||||
height: "568px",
|
||||
},
|
||||
},
|
||||
"ipadPro": {
|
||||
"name": "Ipad pro",
|
||||
"styles": {
|
||||
"width": "1240px",
|
||||
"height": "1366px",
|
||||
ipadPro: {
|
||||
name: "Ipad pro",
|
||||
styles: {
|
||||
width: "1240px",
|
||||
height: "1366px",
|
||||
},
|
||||
},
|
||||
"Galaxy s9+": {
|
||||
"name": "Galaxy S9+",
|
||||
"styles": {
|
||||
"width": "320px",
|
||||
"height": "658px",
|
||||
name: "Galaxy S9+",
|
||||
styles: {
|
||||
width: "320px",
|
||||
height: "658px",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
"options": {
|
||||
"storySort": (a, b) =>
|
||||
options: {
|
||||
storySort: (a, b) =>
|
||||
getHardCodedWeight(b[1].kind) - getHardCodedWeight(a[1].kind),
|
||||
},
|
||||
};
|
||||
|
||||
export const decorators = [
|
||||
(Story) => (
|
||||
<CanvasContainer>
|
||||
<Story />
|
||||
</CanvasContainer>
|
||||
),
|
||||
];
|
||||
|
||||
const { getHardCodedWeight } = (() => {
|
||||
|
||||
const orderedPagesPrefix = [
|
||||
|
@ -72,14 +72,10 @@
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@octokit/rest": "^20.1.1",
|
||||
"@storybook/addon-a11y": "^6.5.16",
|
||||
"@storybook/addon-actions": "^6.5.13",
|
||||
"@storybook/addon-essentials": "^6.5.13",
|
||||
"@storybook/addon-interactions": "^6.5.13",
|
||||
"@storybook/addon-links": "^6.5.13",
|
||||
"@storybook/builder-webpack5": "^6.5.13",
|
||||
"@storybook/manager-webpack5": "^6.5.13",
|
||||
"@storybook/react": "^6.5.13",
|
||||
"@storybook/testing-library": "^0.0.13",
|
||||
"eslint-plugin-storybook": "^0.6.7",
|
||||
"@types/babel__generator": "^7.6.4",
|
||||
"@types/make-fetch-happen": "^10.0.1",
|
||||
"@types/minimist": "^1.2.2",
|
||||
@ -92,7 +88,6 @@
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"cli-select": "^1.1.2",
|
||||
"eslint-plugin-storybook": "^0.6.7",
|
||||
"husky": "^4.3.8",
|
||||
"lint-staged": "^11.0.0",
|
||||
"magic-string": "^0.30.7",
|
||||
|
@ -1,32 +0,0 @@
|
||||
import { Meta } from "@storybook/addon-docs";
|
||||
import screenshotPngUrl from "./screenshot.png";
|
||||
|
||||
<Meta
|
||||
title="account-spa/index.ftl"
|
||||
parameters={{
|
||||
"viewMode": "docs",
|
||||
"previewTabs": {
|
||||
"canvas": { "hidden": true },
|
||||
"zoom": { "hidden": true },
|
||||
"storybook/background": { "hidden": true },
|
||||
"storybook/viewport": { "hidden": true },
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{ "margin": "0 auto", "maxWidth": "700px", "textAlign": "center" }}>
|
||||
|
||||
<p>
|
||||
|
||||
Keycloakify offers two option for creating an account theme:
|
||||
[Multi Page](https://storybook.keycloakify.dev/?path=/story/account-account-ftl--default) or Single Page (also known as Account v3).
|
||||
Since the account Single Page does not support Storybook, here is a screenshot of it's default look:
|
||||
|
||||
<img width="1508" alt="image" src={screenshotPngUrl} />
|
||||
|
||||
[Learn more](https://docs.keycloakify.dev/account-theme)
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
94
stories/account-spa/index.stories.tsx
Normal file
94
stories/account-spa/index.stories.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { useInsertLinkTags } from "../../dist/tools/useInsertLinkTags";
|
||||
import { tss } from "../tss";
|
||||
// @ts-expect-error
|
||||
import screenshotPngUrl from "./screenshot.png";
|
||||
|
||||
const meta = {
|
||||
title: "Account SPA/index.ftl"
|
||||
} satisfies Meta<any>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const NotInStorybookButSupported: Story = {
|
||||
render: () => <AccountSpa />
|
||||
};
|
||||
|
||||
function AccountSpa() {
|
||||
console.log(window.location.href);
|
||||
|
||||
useInsertLinkTags({
|
||||
componentOrHookName: "Template",
|
||||
hrefs: []
|
||||
});
|
||||
|
||||
const { classes, theme } = useStyles();
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classes.content}>
|
||||
<p>
|
||||
Keycloakify offers two option for creating an account theme:{" "}
|
||||
<a href="https://docs.keycloakify.dev/account-theme#multi-page" target="_blank">
|
||||
Multi Page
|
||||
</a>{" "}
|
||||
or{" "}
|
||||
<a href="https://docs.keycloakify.dev/account-theme#single-page" target="_blank">
|
||||
Single Page
|
||||
</a>
|
||||
. Since the account Single Page does not support Storybook, here is a screenshot of it's default look:
|
||||
<br />
|
||||
<br />
|
||||
<img className={classes.screenshot} alt="image" src={screenshotPngUrl} />
|
||||
<br />
|
||||
<a href="https://docs.keycloakify.dev/account-theme" target="_blank">
|
||||
Learn more
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = tss.withName({ AccountSpa }).create(({ isDark, theme }) => ({
|
||||
root: {
|
||||
height: "100vh",
|
||||
color: isDark ? "white" : "black",
|
||||
backgroundColor: theme.appContentBg,
|
||||
fontFamily: "'Work Sans'",
|
||||
fontSize: "14px",
|
||||
lineHeight: "24px",
|
||||
WebkitFontSmoothing: "antialiased",
|
||||
"& a": {
|
||||
color: theme.colorSecondary,
|
||||
textDecoration: "none",
|
||||
"&:hover": {
|
||||
textDecoration: "underline"
|
||||
}
|
||||
},
|
||||
"& h1": {
|
||||
fontSize: "32px",
|
||||
marginBottom: 35
|
||||
},
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
},
|
||||
content: {
|
||||
maxWidth: 750,
|
||||
textAlign: "center",
|
||||
marginTop: 100
|
||||
},
|
||||
keycloakifyLogoWrapper: {
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
},
|
||||
keycloakifyLogo: {
|
||||
width: 400
|
||||
},
|
||||
screenshot: {
|
||||
maxWidth: "100%"
|
||||
}
|
||||
}));
|
@ -2,18 +2,20 @@ import React from "react";
|
||||
import { memo, useState } from "react";
|
||||
import { useConstCallback } from "powerhooks";
|
||||
import { keyframes } from "tss-react";
|
||||
// @ts-expect-error
|
||||
import keycloakifyLogoHeroMovingPngUrl from "./keycloakify-logo-hero-moving.png";
|
||||
// @ts-expect-error
|
||||
import keycloakifyLogoHeroStillPngUrl from "./keycloakify-logo-hero-still.png";
|
||||
import { makeStyles } from "./tss";
|
||||
import { tss } from "../tss";
|
||||
|
||||
export type Props = {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
id?: string;
|
||||
onLoad?: () => void;
|
||||
};
|
||||
|
||||
export const KeycloakifyRotatingLogo = memo((props: Props) => {
|
||||
const { id, style, onLoad: onLoadProp } = props;
|
||||
const { id, className, onLoad: onLoadProp } = props;
|
||||
|
||||
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
||||
|
||||
@ -22,40 +24,41 @@ export const KeycloakifyRotatingLogo = memo((props: Props) => {
|
||||
onLoadProp?.();
|
||||
});
|
||||
|
||||
const { classes } = useStyles({
|
||||
const { cx, classes } = useStyles({
|
||||
isImageLoaded
|
||||
});
|
||||
return (
|
||||
<div id={id} className={classes.root} style={style}>
|
||||
<div id={id} className={cx(classes.root, className)}>
|
||||
<img className={classes.rotatingImg} onLoad={onLoad} src={keycloakifyLogoHeroMovingPngUrl} alt={"Rotating react logo"} />
|
||||
<img className={classes.stillImg} src={keycloakifyLogoHeroStillPngUrl} alt={"keyhole"} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const useStyles = makeStyles<{ isImageLoaded: boolean }>({
|
||||
name: { KeycloakifyRotatingLogo }
|
||||
})((_theme, { isImageLoaded }) => ({
|
||||
root: {
|
||||
position: "relative"
|
||||
},
|
||||
rotatingImg: {
|
||||
animation: `${keyframes({
|
||||
from: {
|
||||
transform: "rotate(0deg)"
|
||||
},
|
||||
to: {
|
||||
transform: "rotate(360deg)"
|
||||
}
|
||||
})} infinite 20s linear`,
|
||||
width: isImageLoaded ? "100%" : undefined,
|
||||
height: isImageLoaded ? "auto" : undefined
|
||||
},
|
||||
stillImg: {
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: isImageLoaded ? "100%" : undefined,
|
||||
height: isImageLoaded ? "auto" : undefined
|
||||
}
|
||||
}));
|
||||
const useStyles = tss
|
||||
.withParams<{ isImageLoaded: boolean }>()
|
||||
.withName({ KeycloakifyRotatingLogo })
|
||||
.create(({ isImageLoaded }) => ({
|
||||
root: {
|
||||
position: "relative"
|
||||
},
|
||||
rotatingImg: {
|
||||
animation: `${keyframes({
|
||||
from: {
|
||||
transform: "rotate(0deg)"
|
||||
},
|
||||
to: {
|
||||
transform: "rotate(360deg)"
|
||||
}
|
||||
})} infinite 20s linear`,
|
||||
width: isImageLoaded ? "100%" : undefined,
|
||||
height: isImageLoaded ? "auto" : undefined
|
||||
},
|
||||
stillImg: {
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: isImageLoaded ? "100%" : undefined,
|
||||
height: isImageLoaded ? "auto" : undefined
|
||||
}
|
||||
}));
|
||||
|
@ -1,32 +0,0 @@
|
||||
import { Meta } from "@storybook/addon-docs";
|
||||
import { KeycloakifyRotatingLogo } from "./KeycloakifyRotatingLogo";
|
||||
|
||||
<Meta
|
||||
title="Introduction"
|
||||
parameters={{
|
||||
"viewMode": "docs",
|
||||
"previewTabs": {
|
||||
"canvas": { "hidden": true },
|
||||
"zoom": { "hidden": true },
|
||||
"storybook/background": { "hidden": true },
|
||||
"storybook/viewport": { "hidden": true },
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{ "margin": "0 auto", "maxWidth": "700px", "textAlign": "center" }}>
|
||||
<div style={{ "display": "flex", "justifyContent": "center" }}>
|
||||
<KeycloakifyRotatingLogo style={{ "width": 400 }} />
|
||||
</div>
|
||||
<h1><a href="#">Keycloakify </a> Storybook</h1>
|
||||
|
||||
<p>
|
||||
|
||||
This website showcases all the Keycloak user-facing pages of the login and account theme.
|
||||
The storybook serves as a reference to help you determine which pages you would like to personalize.
|
||||
These pages are a direct React adaptation of the [built-in FreeMarker Keycloak pages](https://github.com/keycloak/keycloak/tree/24.0.4/themes/src/main/resources/theme/base).
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
90
stories/intro/intro.stories.tsx
Normal file
90
stories/intro/intro.stories.tsx
Normal file
@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { KeycloakifyRotatingLogo } from "./KeycloakifyRotatingLogo";
|
||||
import { useInsertLinkTags } from "../../dist/tools/useInsertLinkTags";
|
||||
import { useOnFistMount } from "../../dist/tools/useOnFirstMount";
|
||||
import { tss } from "../tss";
|
||||
|
||||
const meta = {
|
||||
title: "Introduction"
|
||||
} satisfies Meta<any>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const WhatIsThisWebsite: Story = {
|
||||
render: () => <Introduction />
|
||||
};
|
||||
|
||||
function Introduction() {
|
||||
console.log(window.location.href);
|
||||
|
||||
useInsertLinkTags({
|
||||
componentOrHookName: "Template",
|
||||
hrefs: []
|
||||
});
|
||||
|
||||
const { classes, theme } = useStyles();
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classes.content}>
|
||||
<div className={classes.keycloakifyLogoWrapper}>
|
||||
<KeycloakifyRotatingLogo className={classes.keycloakifyLogo} />
|
||||
</div>
|
||||
<h1>
|
||||
<a href={theme.brandUrl}>Keycloakify </a> Storybook
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
This website showcases all the Keycloak user-facing pages of the Login and{" "}
|
||||
<a href="https://docs.keycloakify.dev/account-theme#multi-page">Account Multi-Page theme</a>.<br />
|
||||
The storybook serves as a reference to help you determine which pages you would like to personalize.
|
||||
<br />
|
||||
These pages are a direct React adaptation of the{" "}
|
||||
<a href="https://github.com/keycloak/keycloak/tree/24.0.4/themes/src/main/resources/theme/base" target="_blank">
|
||||
built-in FreeMarker Keycloak pages
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = tss.withName({ Introduction }).create(({ isDark, theme }) => ({
|
||||
root: {
|
||||
height: "100vh",
|
||||
color: isDark ? "white" : "black",
|
||||
backgroundColor: theme.appContentBg,
|
||||
fontFamily: "'Work Sans'",
|
||||
fontSize: "14px",
|
||||
lineHeight: "24px",
|
||||
WebkitFontSmoothing: "antialiased",
|
||||
"& a": {
|
||||
color: theme.colorSecondary,
|
||||
textDecoration: "none",
|
||||
"&:hover": {
|
||||
textDecoration: "underline"
|
||||
}
|
||||
},
|
||||
"& h1": {
|
||||
fontSize: "32px",
|
||||
marginBottom: 35
|
||||
},
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
},
|
||||
content: {
|
||||
maxWidth: 750,
|
||||
textAlign: "center"
|
||||
},
|
||||
keycloakifyLogoWrapper: {
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
},
|
||||
keycloakifyLogo: {
|
||||
width: 400
|
||||
}
|
||||
}));
|
@ -1,5 +0,0 @@
|
||||
import { createMakeAndWithStyles } from "tss-react";
|
||||
|
||||
export const { makeStyles, useStyles } = createMakeAndWithStyles({
|
||||
useTheme: () => ({})
|
||||
});
|
13
stories/tss.ts
Normal file
13
stories/tss.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { createTss } from "tss-react";
|
||||
import { useDarkMode } from "storybook-dark-mode";
|
||||
import { darkTheme, lightTheme } from "../.storybook/customTheme";
|
||||
|
||||
function useContext() {
|
||||
const isDark = useDarkMode();
|
||||
|
||||
return { isDark, theme: isDark ? darkTheme : lightTheme };
|
||||
}
|
||||
|
||||
export const { tss } = createTss({
|
||||
useContext
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user