diff --git a/packages/odyssey-storybook/.storybook/components/ThemeTable.tsx b/packages/odyssey-storybook/.storybook/components/ThemeTable.tsx new file mode 100644 index 0000000000..08192b2e34 --- /dev/null +++ b/packages/odyssey-storybook/.storybook/components/ThemeTable.tsx @@ -0,0 +1,78 @@ +/*! + * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved. + * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (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. + */ + +/* eslint-disable import/no-extraneous-dependencies */ +import React from "react"; +import type { Theme, ThemeReducer } from "@okta/odyssey-react-theme"; +import { tokens } from "@okta/odyssey-react-theme/dist/ThemeProvider/context"; +import type { ThemeKey } from "@okta/odyssey-react-theme/dist/ThemeProvider/context"; +import { Table, Text } from "@okta/odyssey-react"; +/* eslint-enable import/no-extraneous-dependencies */ +import type { ReactNode } from "react"; + +type ThemeTableProps = { + componentThemeReducer: ThemeReducer; +}; + +const ThemeTable = ({ componentThemeReducer }: ThemeTableProps): ReactNode => { + const remappedTokens: { [key: string]: string } = {}; + for (const [k] of Object.entries(tokens)) { + remappedTokens[k] = k; + } + const componentVariables = componentThemeReducer( + remappedTokens as unknown as Theme + ); + + function getTokenValue(tokenName: string | number): string | number | null { + let tokenValue = null; + let p: ThemeKey; + for (p in tokens) { + if (p === tokenName) { + tokenValue = tokens[p]; + } + } + return tokenValue; + } + + return ( + + + + Variable Name + Token Value + + + + + {Object.keys(componentVariables).map((variable) => ( + + + {variable} + + + {componentVariables[variable]} + + + + {getTokenValue(componentVariables[variable]) + ? `(${getTokenValue(componentVariables[variable])})` + : ""} + + + + ))} + +
+ ); +}; + +export { ThemeTable }; diff --git a/packages/odyssey-storybook/.storybook/components/TokenTables.tsx b/packages/odyssey-storybook/.storybook/components/TokenTables.tsx new file mode 100644 index 0000000000..1e002260d9 --- /dev/null +++ b/packages/odyssey-storybook/.storybook/components/TokenTables.tsx @@ -0,0 +1,240 @@ +/*! + * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved. + * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (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. + */ + +/* eslint-disable import/no-extraneous-dependencies */ +import React, { useState, useEffect } from "react"; +import * as Tokens from "@okta/odyssey-design-tokens"; +import { Table, Text } from "@okta/odyssey-react"; +/* eslint-enable import/no-extraneous-dependencies */ +import type { ReactNode } from "react"; + +type FontWeight = 400 | 600; + +type Token = { + name: string; + value: string | number; +}; + +type TableData = { + name: string; + values: Array; +}; + +type TokenName = keyof typeof Tokens; + +const TokenTables = (): ReactNode => { + const [tables, setTables] = useState>([]); + + useEffect(() => { + const tokenKeys = Object.keys(Tokens); + const tempTables: Array = []; + let currentType: string; + let currentValues: Array; + tokenKeys.forEach((tokenName) => { + const parts = tokenName.match(/[A-Z][a-z]+/g); + if (!parts) return; + + let tokenType = parts[0]; + if (parts[0] === "Color") { + tokenType = `${parts[1]} ${parts[0]}s`; + } + + if (tokenType !== currentType) { + currentValues = []; + tempTables.push({ name: tokenType, values: currentValues }); + currentType = tokenType; + } + + currentValues.push({ + name: tokenName, + value: Tokens[tokenName as TokenName], + }); + }); + + tempTables + .find((table) => table.name === "Palette Colors") + ?.values.sort((a: Token, b: Token) => { + const nameA = a.name.toUpperCase(); + const nameB = b.name.toUpperCase(); + if (nameA < nameB) { + return -1; + } + if (nameA > nameB) { + return 1; + } + return 0; + }); + + setTables(tempTables); + }, [setTables]); + + const renderBorder = (token: Token) => ( + + ); + + const renderColor = (val: string | number) => ( + + ); + + const renderColorText = (val: string | number) => ( + + Aa + + ); + + const renderSpace = (val: string | number) => ( + + ); + + const renderFont = (token: Token) => ( + + Waltz, bad nymph, for quick jigs vex! + + ); + + const renderFocus = (val: string | number) => ( + + ); + + const renderShadow = (val: string | number) => ( + + ); + + function getDisplayedValue(tableName: string, val: string | number) { + if (!tableName.includes("Colors") || tableName === "Palette Colors") { + return val; + } + const tokenValue = tables + .find((table) => table.name === "Palette Colors") + ?.values.find((value) => value.value === val) ?? { name: "" }; + return tokenValue.name; + } + + return ( + <> + {tables.map((table) => ( + + + + Token Name + Example + Value + + + + {table.values.map((token: Token) => ( + + + {token.name} + + + {token.name.includes("Border") && + !token.name.includes("ColorBorder") && + renderBorder(token)} + {token.name.includes("Color") && + !token.name.includes("ColorText") && + renderColor(token.value)} + {token.name.includes("ColorText") && + renderColorText(token.value)} + {token.name.includes("Space") && renderSpace(token.value)} + {token.name.includes("Font") && renderFont(token)} + {token.name.includes("Focus") && + !token.name.includes("ColorFocus") && + renderFocus(token.value)} + {token.name.includes("Shadow") && renderShadow(token.value)} + + + + {getDisplayedValue(table.name, token.value)} + + + + ))} + +
+ ))} + + ); +}; + +export { TokenTables }; diff --git a/packages/odyssey-storybook/src/components/Banner/Banner.mdx b/packages/odyssey-storybook/src/components/Banner/Banner.mdx index bc88739cb5..c4be4952b3 100644 --- a/packages/odyssey-storybook/src/components/Banner/Banner.mdx +++ b/packages/odyssey-storybook/src/components/Banner/Banner.mdx @@ -1,4 +1,6 @@ import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"; +import { theme } from "@okta/odyssey-react/dist/components/Banner/Banner.theme"; +import { ThemeTable } from "../../../.storybook/components/ThemeTable"; # Banner @@ -20,7 +22,9 @@ They are best used to indicate global states or errors that effect an entire pro Use Info Banners to surface neutral information or broad announcements to users. - + + + ### Danger @@ -28,7 +32,9 @@ Use Danger Banners to inform users that a system-wide error has occurred. You ma Include guidance to make sure users know what steps to take to address the error or avoid the threat. - + + + ### Caution @@ -36,7 +42,9 @@ Use Caution Banners to inform users of tasks or processes that may need their at When using the Caution variant, ensure the user does not need more context than you can give in the space available. - + + + ## Usage @@ -68,10 +76,12 @@ Banners support dismissal for messages that do not persist or only require a one Banner content should be succinct and direct. When including an action, be sure the link text clearly indicates where it leads. -## Arguments +## Props + + ## References
diff --git a/packages/odyssey-storybook/src/components/Box/Box.mdx b/packages/odyssey-storybook/src/components/Box/Box.mdx index cd9d70aed8..6208f1549a 100644 --- a/packages/odyssey-storybook/src/components/Box/Box.mdx +++ b/packages/odyssey-storybook/src/components/Box/Box.mdx @@ -1,4 +1,6 @@ import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"; +import { theme } from "@okta/odyssey-react/dist/components/Box/Box.theme"; +import { ThemeTable } from "../../../.storybook/components/ThemeTable"; # Box @@ -20,6 +22,8 @@ A simple `
-## Arguments +## Props + + diff --git a/packages/odyssey-storybook/src/components/Tooltip/Tooltip.mdx b/packages/odyssey-storybook/src/components/Tooltip/Tooltip.mdx index bb3cca4a80..8d333ade0d 100644 --- a/packages/odyssey-storybook/src/components/Tooltip/Tooltip.mdx +++ b/packages/odyssey-storybook/src/components/Tooltip/Tooltip.mdx @@ -1,4 +1,6 @@ import { Canvas, Story, ArgsTable } from "@storybook/addon-docs"; +import { theme } from "@okta/odyssey-react/dist/components/Tooltip/Tooltip.theme"; +import { ThemeTable } from "../../../.storybook/components/ThemeTable"; # Tooltip @@ -65,7 +67,9 @@ When positioning a Tooltip, ensure: - Placement doesn't interfere with the object of interest or relevant information. - The Tooltip is always visible when activated, not cropped or off-page. - + + + ## Content @@ -106,6 +110,8 @@ Consider fallback alternatives on a case-by-case basis. When possible, provide inline text that becomes visible on touchscreen devices. Otherwise, a fixed-position fallback is provided for mobile devices. -## Arguments +## Props + + diff --git a/packages/odyssey-storybook/src/guidelines/Color.stories.mdx b/packages/odyssey-storybook/src/guidelines/Color.mdx similarity index 100% rename from packages/odyssey-storybook/src/guidelines/Color.stories.mdx rename to packages/odyssey-storybook/src/guidelines/Color.mdx diff --git a/packages/odyssey-storybook/src/guidelines/Tokens.stories.mdx b/packages/odyssey-storybook/src/guidelines/Tokens.stories.mdx index a6903b1925..5976bb56b3 100644 --- a/packages/odyssey-storybook/src/guidelines/Tokens.stories.mdx +++ b/packages/odyssey-storybook/src/guidelines/Tokens.stories.mdx @@ -1,4 +1,5 @@ import { Meta } from "@storybook/addon-docs/blocks"; +import { TokenTables } from "../../.storybook/components/TokenTables"; @@ -6,243 +7,4 @@ import { Meta } from "@storybook/addon-docs/blocks"; Design Tokens abstract Base elements into names that are commonly understood. They are then used together to build components. -
-
Semantic Colors
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token NameExampleValue
-
- $color-primary-light -
-
- - Blue 300
- $color-primary-base - - - Blue 500
- $color-primary-dark - - - Blue 900
- $color-danger-light - - - Red 300
- $color-danger-base - - - Red 500
- $color-danger-dark - - - Red 900
-
- -
-
Focus Ring
- - - - - - - - - - - - - - - - - - - - -
Token NameExampleValue
- $focus-ring-primary - - - Blue 300
- $focus-ring-danger - - - Red 300
-
- -
-
Type
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token NameExampleValue
- $text-body - - Aa - Gray 900
- $text-danger - - Aa - Red 500
- $text-heading - - Aa - Gray 900
- $text-sub - - Aa - Gray 600
-
- -
-
Spacing
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token NameExampleValuePixels
- $spacing-xl - -
-
- - - -
- $spacing-l - -
-
- - - -
- $spacing-m - -
-
- - - -
- $spacing-s - -
-
- - - -
- $spacing-xs - -
-
- - - -
-
+ diff --git a/packages/odyssey-storybook/src/guidelines/Typography.stories.mdx b/packages/odyssey-storybook/src/guidelines/Typography.mdx similarity index 100% rename from packages/odyssey-storybook/src/guidelines/Typography.stories.mdx rename to packages/odyssey-storybook/src/guidelines/Typography.mdx