Rework the storybook

This commit is contained in:
Joseph Garrone
2024-07-29 05:12:31 +02:00
parent 5221fb3479
commit 386a8d7cd7
16 changed files with 367 additions and 1219 deletions

View File

@ -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>

View 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%"
}
}));

View File

@ -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
}
}));

View File

@ -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>

View 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
}
}));

View File

@ -1,5 +0,0 @@
import { createMakeAndWithStyles } from "tss-react";
export const { makeStyles, useStyles } = createMakeAndWithStyles({
useTheme: () => ({})
});

13
stories/tss.ts Normal file
View 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
});