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 = {
|
module.exports = {
|
||||||
"stories": [
|
stories: [
|
||||||
"../stories/**/*.stories.@(ts|tsx|mdx)"
|
"../stories/**/*.stories.tsx"
|
||||||
],
|
],
|
||||||
"addons": [
|
addons: [
|
||||||
"@storybook/addon-links",
|
|
||||||
"@storybook/addon-essentials",
|
|
||||||
"storybook-dark-mode",
|
"storybook-dark-mode",
|
||||||
"@storybook/addon-a11y"
|
"@storybook/addon-a11y"
|
||||||
],
|
],
|
||||||
"core": {
|
core: {
|
||||||
"builder": "webpack5"
|
builder: "webpack5"
|
||||||
},
|
},
|
||||||
"staticDirs": ["./static"]
|
staticDirs: ["./static"]
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { addons } from '@storybook/addons';
|
import { addons } from '@storybook/addons';
|
||||||
|
|
||||||
addons.setConfig({
|
addons.setConfig({
|
||||||
"selectedPanel": 'storybook/a11y/panel',
|
selectedPanel: 'storybook/a11y/panel',
|
||||||
"showPanel": false,
|
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>
|
<style>
|
||||||
body.sb-show-main.sb-main-padded {
|
body.sb-show-main.sb-main-padded {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -1,116 +1,105 @@
|
|||||||
import { darkTheme, lightTheme } from "./customTheme";
|
import { darkTheme, lightTheme } from "./customTheme";
|
||||||
import { DocsContainer, CanvasContainer } from "./Containers";
|
import { create as createTheme } from "@storybook/theming";
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
"actions": { "argTypesRegex": "^on[A-Z].*" },
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
"controls": {
|
controls: {
|
||||||
"matchers": {
|
matchers: {
|
||||||
"color": /(background|color)$/i,
|
color: /(background|color)$/i,
|
||||||
"date": /Date$/,
|
date: /Date$/,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"backgrounds": { "disable": true },
|
backgrounds: { disable: true },
|
||||||
"darkMode": {
|
darkMode: {
|
||||||
"light": lightTheme,
|
light: createTheme(lightTheme),
|
||||||
"dark": darkTheme,
|
dark: createTheme(darkTheme),
|
||||||
},
|
},
|
||||||
"docs": {
|
controls: {
|
||||||
"container": DocsContainer
|
disable: true,
|
||||||
},
|
},
|
||||||
"controls": {
|
actions: {
|
||||||
"disable": true,
|
disable: true
|
||||||
},
|
},
|
||||||
"actions": {
|
viewport: {
|
||||||
"disable": true
|
viewports: {
|
||||||
},
|
|
||||||
"viewport": {
|
|
||||||
"viewports": {
|
|
||||||
"1440p": {
|
"1440p": {
|
||||||
"name": "1440p",
|
name: "1440p",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "2560px",
|
width: "2560px",
|
||||||
"height": "1440px",
|
height: "1440px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fullHD": {
|
fullHD: {
|
||||||
"name": "Full HD",
|
name: "Full HD",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "1920px",
|
width: "1920px",
|
||||||
"height": "1080px",
|
height: "1080px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"macBookProBig": {
|
macBookProBig: {
|
||||||
"name": "MacBook Pro Big",
|
name: "MacBook Pro Big",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "1024px",
|
width: "1024px",
|
||||||
"height": "640px",
|
height: "640px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"macBookProMedium": {
|
macBookProMedium: {
|
||||||
"name": "MacBook Pro Medium",
|
name: "MacBook Pro Medium",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "1440px",
|
width: "1440px",
|
||||||
"height": "900px",
|
height: "900px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"macBookProSmall": {
|
macBookProSmall: {
|
||||||
"name": "MacBook Pro Small",
|
name: "MacBook Pro Small",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "1680px",
|
width: "1680px",
|
||||||
"height": "1050px",
|
height: "1050px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"pcAgent": {
|
pcAgent: {
|
||||||
"name": "PC Agent",
|
name: "PC Agent",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "960px",
|
width: "960px",
|
||||||
"height": "540px",
|
height: "540px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"iphone12Pro": {
|
iphone12Pro: {
|
||||||
"name": "Iphone 12 pro",
|
name: "Iphone 12 pro",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "390px",
|
width: "390px",
|
||||||
"height": "844px",
|
height: "844px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"iphone5se": {
|
iphone5se: {
|
||||||
"name": "Iphone 5/SE",
|
name: "Iphone 5/SE",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "320px",
|
width: "320px",
|
||||||
"height": "568px",
|
height: "568px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ipadPro": {
|
ipadPro: {
|
||||||
"name": "Ipad pro",
|
name: "Ipad pro",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "1240px",
|
width: "1240px",
|
||||||
"height": "1366px",
|
height: "1366px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Galaxy s9+": {
|
"Galaxy s9+": {
|
||||||
"name": "Galaxy S9+",
|
name: "Galaxy S9+",
|
||||||
"styles": {
|
styles: {
|
||||||
"width": "320px",
|
width: "320px",
|
||||||
"height": "658px",
|
height: "658px",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"options": {
|
options: {
|
||||||
"storySort": (a, b) =>
|
storySort: (a, b) =>
|
||||||
getHardCodedWeight(b[1].kind) - getHardCodedWeight(a[1].kind),
|
getHardCodedWeight(b[1].kind) - getHardCodedWeight(a[1].kind),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const decorators = [
|
|
||||||
(Story) => (
|
|
||||||
<CanvasContainer>
|
|
||||||
<Story />
|
|
||||||
</CanvasContainer>
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
const { getHardCodedWeight } = (() => {
|
const { getHardCodedWeight } = (() => {
|
||||||
|
|
||||||
const orderedPagesPrefix = [
|
const orderedPagesPrefix = [
|
||||||
|
@ -72,14 +72,10 @@
|
|||||||
"@emotion/react": "^11.11.4",
|
"@emotion/react": "^11.11.4",
|
||||||
"@octokit/rest": "^20.1.1",
|
"@octokit/rest": "^20.1.1",
|
||||||
"@storybook/addon-a11y": "^6.5.16",
|
"@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/builder-webpack5": "^6.5.13",
|
||||||
"@storybook/manager-webpack5": "^6.5.13",
|
"@storybook/manager-webpack5": "^6.5.13",
|
||||||
"@storybook/react": "^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/babel__generator": "^7.6.4",
|
||||||
"@types/make-fetch-happen": "^10.0.1",
|
"@types/make-fetch-happen": "^10.0.1",
|
||||||
"@types/minimist": "^1.2.2",
|
"@types/minimist": "^1.2.2",
|
||||||
@ -92,7 +88,6 @@
|
|||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
"chokidar-cli": "^3.0.0",
|
"chokidar-cli": "^3.0.0",
|
||||||
"cli-select": "^1.1.2",
|
"cli-select": "^1.1.2",
|
||||||
"eslint-plugin-storybook": "^0.6.7",
|
|
||||||
"husky": "^4.3.8",
|
"husky": "^4.3.8",
|
||||||
"lint-staged": "^11.0.0",
|
"lint-staged": "^11.0.0",
|
||||||
"magic-string": "^0.30.7",
|
"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 { memo, useState } from "react";
|
||||||
import { useConstCallback } from "powerhooks";
|
import { useConstCallback } from "powerhooks";
|
||||||
import { keyframes } from "tss-react";
|
import { keyframes } from "tss-react";
|
||||||
|
// @ts-expect-error
|
||||||
import keycloakifyLogoHeroMovingPngUrl from "./keycloakify-logo-hero-moving.png";
|
import keycloakifyLogoHeroMovingPngUrl from "./keycloakify-logo-hero-moving.png";
|
||||||
|
// @ts-expect-error
|
||||||
import keycloakifyLogoHeroStillPngUrl from "./keycloakify-logo-hero-still.png";
|
import keycloakifyLogoHeroStillPngUrl from "./keycloakify-logo-hero-still.png";
|
||||||
import { makeStyles } from "./tss";
|
import { tss } from "../tss";
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
style?: React.CSSProperties;
|
className?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
onLoad?: () => void;
|
onLoad?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KeycloakifyRotatingLogo = memo((props: Props) => {
|
export const KeycloakifyRotatingLogo = memo((props: Props) => {
|
||||||
const { id, style, onLoad: onLoadProp } = props;
|
const { id, className, onLoad: onLoadProp } = props;
|
||||||
|
|
||||||
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
||||||
|
|
||||||
@ -22,40 +24,41 @@ export const KeycloakifyRotatingLogo = memo((props: Props) => {
|
|||||||
onLoadProp?.();
|
onLoadProp?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
const { classes } = useStyles({
|
const { cx, classes } = useStyles({
|
||||||
isImageLoaded
|
isImageLoaded
|
||||||
});
|
});
|
||||||
return (
|
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.rotatingImg} onLoad={onLoad} src={keycloakifyLogoHeroMovingPngUrl} alt={"Rotating react logo"} />
|
||||||
<img className={classes.stillImg} src={keycloakifyLogoHeroStillPngUrl} alt={"keyhole"} />
|
<img className={classes.stillImg} src={keycloakifyLogoHeroStillPngUrl} alt={"keyhole"} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const useStyles = makeStyles<{ isImageLoaded: boolean }>({
|
const useStyles = tss
|
||||||
name: { KeycloakifyRotatingLogo }
|
.withParams<{ isImageLoaded: boolean }>()
|
||||||
})((_theme, { isImageLoaded }) => ({
|
.withName({ KeycloakifyRotatingLogo })
|
||||||
root: {
|
.create(({ isImageLoaded }) => ({
|
||||||
position: "relative"
|
root: {
|
||||||
},
|
position: "relative"
|
||||||
rotatingImg: {
|
},
|
||||||
animation: `${keyframes({
|
rotatingImg: {
|
||||||
from: {
|
animation: `${keyframes({
|
||||||
transform: "rotate(0deg)"
|
from: {
|
||||||
},
|
transform: "rotate(0deg)"
|
||||||
to: {
|
},
|
||||||
transform: "rotate(360deg)"
|
to: {
|
||||||
}
|
transform: "rotate(360deg)"
|
||||||
})} infinite 20s linear`,
|
}
|
||||||
width: isImageLoaded ? "100%" : undefined,
|
})} infinite 20s linear`,
|
||||||
height: isImageLoaded ? "auto" : undefined
|
width: isImageLoaded ? "100%" : undefined,
|
||||||
},
|
height: isImageLoaded ? "auto" : undefined
|
||||||
stillImg: {
|
},
|
||||||
position: "absolute",
|
stillImg: {
|
||||||
top: "0",
|
position: "absolute",
|
||||||
left: "0",
|
top: "0",
|
||||||
width: isImageLoaded ? "100%" : undefined,
|
left: "0",
|
||||||
height: isImageLoaded ? "auto" : undefined
|
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