reshaped 3.6.0-canary.4 → 3.6.0-canary.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/theming/index.d.ts +3 -3
- package/dist/cjs/cli/theming/index.js +2 -2
- package/dist/cjs/cli/theming/tailwind.d.ts +2 -3
- package/dist/cjs/themes/_generator/definitions/slate.js +1 -1
- package/dist/cjs/themes/_generator/tokens/color/color.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/color/color.transforms.js +29 -7
- package/dist/cjs/themes/_generator/tokens/color/color.types.d.ts +28 -3
- package/dist/cjs/themes/_generator/tokens/color/utilities/a11y.d.ts +20 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/a11y.js +64 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/convert.d.ts +11 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/convert.js +33 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/generateColors.d.ts +4 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/generateColors.js +152 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/generateMetaColors.d.ts +4 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/generateMetaColors.js +68 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/tests/a11y.test.js +38 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/tests/convert.test.d.ts +1 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/tests/convert.test.js +48 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/tests/generateColors.test.d.ts +1 -0
- package/dist/cjs/themes/_generator/tokens/color/utilities/tests/generateColors.test.js +21 -0
- package/dist/{themes/_generator/utilities → cjs/themes/_generator/tokens}/css.d.ts +1 -1
- package/dist/cjs/themes/_generator/tokens/duration/duration.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/duration/duration.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/easing/easing.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/easing/easing.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/font/font.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/font/font.transforms.js +3 -3
- package/dist/cjs/themes/_generator/tokens/fontFamily/fontFamily.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/fontFamily/fontFamily.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/fontWeight/fontWeight.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/fontWeight/fontWeight.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/radius/radius.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/radius/radius.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/shadow/shadow.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/shadow/shadow.transforms.js +4 -4
- package/dist/cjs/themes/_generator/tokens/types.d.ts +19 -17
- package/dist/cjs/themes/_generator/tokens/unit/unit.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/unit/unit.transforms.js +2 -2
- package/dist/cjs/themes/_generator/tokens/unit/utilities/generate.d.ts +5 -0
- package/dist/cjs/themes/_generator/{utilities/generateUnits.js → tokens/unit/utilities/generate.js} +5 -4
- package/dist/cjs/themes/_generator/tokens/viewport/viewport.transforms.d.ts +2 -2
- package/dist/cjs/themes/_generator/tokens/viewport/viewport.transforms.js +2 -2
- package/dist/cjs/themes/_generator/transform.d.ts +3 -2
- package/dist/cjs/themes/_generator/transform.js +39 -11
- package/dist/cjs/themes/_generator/types.d.ts +4 -8
- package/dist/cjs/themes/_generator/utilities/mergeDefinitions.d.ts +1 -3
- package/dist/cjs/themes/_generator/utilities/mergeDefinitions.js +6 -4
- package/dist/cjs/themes/figma/theme.css +1 -1
- package/dist/cjs/themes/fragments/twitter/theme.css +1 -1
- package/dist/cjs/themes/index.d.ts +4 -11
- package/dist/cjs/themes/index.js +2 -5
- package/dist/cjs/themes/reshaped/theme.css +1 -1
- package/dist/cjs/themes/slate/theme.css +1 -1
- package/dist/cjs/types/config.d.ts +11 -7
- package/dist/cli/theming/index.d.ts +3 -3
- package/dist/cli/theming/index.js +2 -2
- package/dist/cli/theming/tailwind.d.ts +2 -3
- package/dist/components/FormControl/FormControl.context.d.ts +1 -1
- package/dist/tests/ThemesPlayground.d.ts +2 -0
- package/dist/tests/ThemesPlayground.js +90 -0
- package/dist/tests/themes.stories.d.ts +16 -0
- package/dist/{themes/_generator/tests → tests}/themes.stories.js +74 -15
- package/dist/themes/_generator/definitions/slate.js +1 -1
- package/dist/themes/_generator/tokens/color/color.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/color/color.transforms.js +29 -7
- package/dist/themes/_generator/tokens/color/color.types.d.ts +28 -3
- package/dist/themes/_generator/tokens/color/utilities/a11y.d.ts +20 -0
- package/dist/themes/_generator/tokens/color/utilities/a11y.js +58 -0
- package/dist/themes/_generator/tokens/color/utilities/convert.d.ts +11 -0
- package/dist/themes/_generator/tokens/color/utilities/convert.js +27 -0
- package/dist/themes/_generator/tokens/color/utilities/generateColors.d.ts +4 -0
- package/dist/themes/_generator/tokens/color/utilities/generateColors.js +150 -0
- package/dist/themes/_generator/tokens/color/utilities/generateMetaColors.d.ts +4 -0
- package/dist/themes/_generator/tokens/color/utilities/generateMetaColors.js +66 -0
- package/dist/{cjs/themes/_generator/utilities → themes/_generator/tokens}/css.d.ts +1 -1
- package/dist/themes/_generator/tokens/duration/duration.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/duration/duration.transforms.js +2 -2
- package/dist/themes/_generator/tokens/easing/easing.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/easing/easing.transforms.js +2 -2
- package/dist/themes/_generator/tokens/font/font.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/font/font.transforms.js +3 -3
- package/dist/themes/_generator/tokens/fontFamily/fontFamily.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/fontFamily/fontFamily.transforms.js +2 -2
- package/dist/themes/_generator/tokens/fontWeight/fontWeight.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/fontWeight/fontWeight.transforms.js +2 -2
- package/dist/themes/_generator/tokens/radius/radius.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/radius/radius.transforms.js +2 -2
- package/dist/themes/_generator/tokens/shadow/shadow.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/shadow/shadow.transforms.js +4 -4
- package/dist/themes/_generator/tokens/types.d.ts +19 -17
- package/dist/themes/_generator/tokens/unit/unit.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/unit/unit.transforms.js +2 -2
- package/dist/themes/_generator/tokens/unit/utilities/generate.d.ts +5 -0
- package/dist/themes/_generator/{utilities/generateUnits.js → tokens/unit/utilities/generate.js} +4 -5
- package/dist/themes/_generator/tokens/viewport/viewport.transforms.d.ts +2 -2
- package/dist/themes/_generator/tokens/viewport/viewport.transforms.js +2 -2
- package/dist/themes/_generator/transform.d.ts +3 -2
- package/dist/themes/_generator/transform.js +39 -11
- package/dist/themes/_generator/types.d.ts +4 -8
- package/dist/themes/_generator/utilities/mergeDefinitions.d.ts +1 -3
- package/dist/themes/_generator/utilities/mergeDefinitions.js +6 -4
- package/dist/themes/figma/theme.css +1 -1
- package/dist/themes/fragments/twitter/theme.css +1 -1
- package/dist/themes/index.d.ts +4 -11
- package/dist/themes/index.js +1 -4
- package/dist/themes/reshaped/theme.css +1 -1
- package/dist/themes/slate/theme.css +1 -1
- package/dist/types/config.d.ts +11 -7
- package/dist/types/global.d.ts +3 -0
- package/package.json +11 -11
- package/dist/cjs/themes/_generator/utilities/color.d.ts +0 -105
- package/dist/cjs/themes/_generator/utilities/color.js +0 -409
- package/dist/cjs/themes/_generator/utilities/generateBackgroundColors.d.ts +0 -4
- package/dist/cjs/themes/_generator/utilities/generateBackgroundColors.js +0 -59
- package/dist/cjs/themes/_generator/utilities/generateColors.d.ts +0 -11
- package/dist/cjs/themes/_generator/utilities/generateColors.js +0 -178
- package/dist/cjs/themes/_generator/utilities/generateUnits.d.ts +0 -4
- package/dist/cjs/themes/_generator/utilities/mergeDeep.d.ts +0 -5
- package/dist/cjs/themes/_generator/utilities/mergeDeep.js +0 -24
- package/dist/cjs/themes/_generator/utilities/resolveTokenReference.d.ts +0 -3
- package/dist/cjs/themes/_generator/utilities/resolveTokenReference.js +0 -18
- package/dist/cjs/themes/_generator/utilities/tests/color.test.js +0 -81
- package/dist/themes/_generator/tests/themes.stories.d.ts +0 -16
- package/dist/themes/_generator/utilities/color.d.ts +0 -105
- package/dist/themes/_generator/utilities/color.js +0 -377
- package/dist/themes/_generator/utilities/generateBackgroundColors.d.ts +0 -4
- package/dist/themes/_generator/utilities/generateBackgroundColors.js +0 -57
- package/dist/themes/_generator/utilities/generateColors.d.ts +0 -11
- package/dist/themes/_generator/utilities/generateColors.js +0 -176
- package/dist/themes/_generator/utilities/generateUnits.d.ts +0 -4
- package/dist/themes/_generator/utilities/mergeDeep.d.ts +0 -5
- package/dist/themes/_generator/utilities/mergeDeep.js +0 -22
- package/dist/themes/_generator/utilities/resolveTokenReference.d.ts +0 -3
- package/dist/themes/_generator/utilities/resolveTokenReference.js +0 -16
- /package/dist/cjs/themes/_generator/{utilities/tests/color.test.d.ts → tokens/color/utilities/tests/a11y.test.d.ts} +0 -0
- /package/dist/cjs/themes/_generator/{utilities → tokens}/css.js +0 -0
- /package/dist/themes/_generator/{utilities → tokens}/css.js +0 -0
@@ -1,14 +1,18 @@
|
|
1
|
-
import type {
|
1
|
+
import type { PassedThemeDefinition } from "../themes/_generator/tokens/types";
|
2
|
+
import type { HexColor, Hue, OklchColor } from "../themes/_generator/tokens/color/color.types";
|
2
3
|
export type ReshapedConfig = {
|
3
|
-
themes?: Record<string,
|
4
|
-
themeFragments?: Record<string,
|
4
|
+
themes?: Record<string, PassedThemeDefinition>;
|
5
|
+
themeFragments?: Record<string, PassedThemeDefinition>;
|
5
6
|
themeOptions?: {
|
6
|
-
generateOnColorsFor?: string[];
|
7
7
|
colorContrastAlgorithm?: "wcag" | "apca";
|
8
|
+
generateOnColorsFor?: string[];
|
8
9
|
onColorValues?: {
|
9
|
-
[key in
|
10
|
-
hexDark:
|
11
|
-
hexLight:
|
10
|
+
[key in Hue]?: {
|
11
|
+
hexDark: HexColor;
|
12
|
+
hexLight: HexColor;
|
13
|
+
} | {
|
14
|
+
oklchDark: OklchColor;
|
15
|
+
oklchLight: OklchColor;
|
12
16
|
};
|
13
17
|
};
|
14
18
|
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type {
|
1
|
+
import type { PassedThemeDefinition } from "../../themes/_generator/tokens/types";
|
2
2
|
import type * as T from "../../themes/_generator/types";
|
3
|
-
export declare const addThemeFragment: (name: string, definition:
|
4
|
-
export declare const addTheme: (name: string, definition:
|
3
|
+
export declare const addThemeFragment: (name: string, definition: PassedThemeDefinition, options: T.CLIOptions) => void;
|
4
|
+
export declare const addTheme: (name: string, definition: PassedThemeDefinition, options: T.CLIOptions) => void;
|
@@ -17,8 +17,8 @@ const transformDefinition = (name, definition, options) => {
|
|
17
17
|
const themeJsonPath = path.resolve(themeFolderPath, "theme.json");
|
18
18
|
fs.mkdirSync(themeFolderPath, { recursive: true });
|
19
19
|
fs.writeFileSync(themePath, code.variables);
|
20
|
-
fs.writeFileSync(themeJsonPath, JSON.stringify(
|
21
|
-
fs.writeFileSync(twPath, transformToTailwind(
|
20
|
+
fs.writeFileSync(themeJsonPath, JSON.stringify(code.theme));
|
21
|
+
fs.writeFileSync(twPath, transformToTailwind(code.theme));
|
22
22
|
if (code.media)
|
23
23
|
fs.writeFileSync(themeMediaPath, code.media);
|
24
24
|
const logOutput = `Compiled ${chalk.bold(name)} theme${isFragment ? " fragment" : ""}`;
|
@@ -1,3 +1,2 @@
|
|
1
|
-
import type {
|
2
|
-
|
3
|
-
export declare const transformToTailwind: (theme?: T.PartialDeep<FullThemeDefinition>) => string;
|
1
|
+
import type { GeneratedThemeDefinition } from "../../themes/_generator/tokens/types";
|
2
|
+
export declare const transformToTailwind: (theme?: GeneratedThemeDefinition) => string;
|
@@ -134,7 +134,7 @@ export declare const useFormControl: () => {
|
|
134
134
|
onBlurCapture?: React.FocusEventHandler<HTMLElement> | undefined;
|
135
135
|
onChange?: React.FormEventHandler<HTMLElement> | undefined;
|
136
136
|
onChangeCapture?: React.FormEventHandler<HTMLElement> | undefined;
|
137
|
-
onBeforeInput?: React.
|
137
|
+
onBeforeInput?: React.InputEventHandler<HTMLElement> | undefined;
|
138
138
|
onBeforeInputCapture?: React.FormEventHandler<HTMLElement> | undefined;
|
139
139
|
onInput?: React.FormEventHandler<HTMLElement> | undefined;
|
140
140
|
onInputCapture?: React.FormEventHandler<HTMLElement> | undefined;
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import View from "../components/View/index.js";
|
3
|
+
import Text from "../components/Text/index.js";
|
4
|
+
import Divider from "../components/Divider/index.js";
|
5
|
+
import Card from "../components/Card/index.js";
|
6
|
+
import Button from "../components/Button/index.js";
|
7
|
+
import Grid from "../components/Grid/index.js";
|
8
|
+
import Avatar from "../components/Avatar/index.js";
|
9
|
+
import Image from "../components/Image/index.js";
|
10
|
+
import IconChevronRight from "../icons/ChevronRight.js";
|
11
|
+
import TextField from "../components/TextField/index.js";
|
12
|
+
import FormControl from "../components/FormControl/index.js";
|
13
|
+
import Link from "../components/Link/index.js";
|
14
|
+
import useToggle from "../hooks/useToggle.js";
|
15
|
+
import Switch from "../components/Switch/index.js";
|
16
|
+
import Badge from "../components/Badge/index.js";
|
17
|
+
import Alert from "../components/Alert/index.js";
|
18
|
+
import IconZap from "../icons/Zap.js";
|
19
|
+
import CheckboxGroup from "../components/CheckboxGroup/index.js";
|
20
|
+
import Checkbox from "../components/Checkbox/index.js";
|
21
|
+
import React from "react";
|
22
|
+
import Table from "../components/Table/index.js";
|
23
|
+
import DropdownMenu from "../components/DropdownMenu/index.js";
|
24
|
+
import IconChevronDown from "../icons/ChevronDown.js";
|
25
|
+
const Color = (props) => {
|
26
|
+
return (_jsx(View, { padding: 2, height: 25, gap: 2, direction: "row", borderRadius: "medium", backgroundColor: props.backgroundColor, borderColor: props.borderColor, attributes: {
|
27
|
+
style: {
|
28
|
+
borderWidth: 4,
|
29
|
+
},
|
30
|
+
}, children: props.children }));
|
31
|
+
};
|
32
|
+
const NeutralContrastTest = () => (_jsxs(View, { gap: 1, children: [_jsxs(View, { direction: "row", gap: 1, children: [_jsx(View, { height: 6, width: 6, backgroundColor: "neutral", borderRadius: "small" }), _jsx(View, { height: 6, width: 6, backgroundColor: "neutral-faded", borderRadius: "small" })] }), _jsxs(View, { direction: "row", gap: 1, children: [_jsx(View, { height: 6, width: 6, backgroundColor: "disabled", borderRadius: "small" }), _jsx(View, { height: 6, width: 6, backgroundColor: "disabled-faded", borderRadius: "small", borderColor: "disabled" })] })] }));
|
33
|
+
const Palette = () => {
|
34
|
+
return (_jsxs(View, { gap: 2, children: [_jsxs(View, { direction: "row", gap: 2, children: [_jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "neutral", borderColor: "neutral", children: _jsx(Text, { weight: "medium", children: "Aa" }) }), _jsx(Color, { backgroundColor: "neutral-faded", borderColor: "neutral-faded", children: _jsx(Text, { weight: "medium", children: "Aa" }) })] }), _jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "primary", borderColor: "primary", children: _jsx(Text, { weight: "medium", children: "Aa" }) }), _jsxs(Color, { backgroundColor: "primary-faded", borderColor: "primary-faded", children: [_jsx(Text, { weight: "medium", color: "primary", children: "Aa" }), _jsx(Text, { weight: "medium", children: "Aa" })] })] }), _jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "critical", borderColor: "critical", children: _jsx(Text, { weight: "medium", children: "Aa" }) }), _jsxs(Color, { backgroundColor: "critical-faded", borderColor: "critical-faded", children: [_jsx(Text, { weight: "medium", color: "critical", children: "Aa" }), _jsx(Text, { weight: "medium", children: "Aa" })] })] }), _jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "positive", borderColor: "positive", children: _jsx(Text, { weight: "medium", children: "Aa" }) }), _jsxs(Color, { backgroundColor: "positive-faded", borderColor: "positive-faded", children: [_jsx(Text, { weight: "medium", color: "positive", children: "Aa" }), _jsx(Text, { weight: "medium", children: "Aa" })] })] }), _jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "warning", borderColor: "warning", children: _jsx(Text, { weight: "medium", children: "Aa" }) }), _jsxs(Color, { backgroundColor: "warning-faded", borderColor: "warning-faded", children: [_jsx(Text, { weight: "medium", color: "warning", children: "Aa" }), _jsx(Text, { weight: "medium", children: "Aa" })] })] }), _jsxs(View, { gap: 2, grow: true, children: [_jsx(Color, { backgroundColor: "disabled", borderColor: "disabled", children: _jsx(Text, { weight: "medium", color: "disabled", children: "Aa" }) }), _jsx(Color, { backgroundColor: "disabled-faded", borderColor: "disabled", children: _jsx(Text, { weight: "medium", color: "disabled", children: "Aa" }) })] })] }), _jsx(Divider, {}), _jsxs(View, { gap: 2, direction: "row", children: [_jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "elevation-base", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Base" }), _jsx(NeutralContrastTest, {})] }) }) }), _jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "elevation-raised", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Raised" }), _jsx(NeutralContrastTest, {})] }) }) }), _jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "elevation-overlay", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Overlay" }), _jsx(NeutralContrastTest, {})] }) }) }), _jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "page", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Page" }), _jsx(NeutralContrastTest, {})] }) }) }), _jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "page-faded", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Page faded" }), _jsx(NeutralContrastTest, {})] }) }) }), _jsx(View.Item, { grow: true, children: _jsx(Color, { backgroundColor: "neutral-faded", borderColor: "neutral-faded", children: _jsxs(View, { gap: 2, children: [_jsx(Text, { weight: "medium", variant: "caption-1", children: "Neutral faded" }), _jsx(NeutralContrastTest, {})] }) }) })] })] }));
|
35
|
+
};
|
36
|
+
const ExampleAnalytics = () => (_jsx(Card, { children: _jsxs(View, { gap: 1, children: [_jsxs(View, { gap: 4, direction: "row", align: "center", children: [_jsx(View, { gap: 1, direction: "row", align: "center", grow: true, children: _jsx(Text, { variant: "body-2", weight: "bold", children: "Audience" }) }), _jsx(Button.Aligner, { children: _jsx(Button, { variant: "ghost", color: "primary", size: "small", endIcon: IconChevronRight, children: "View" }) })] }), _jsx(Text, { variant: "featured-2", color: "positive", children: "+76.28%" }), _jsxs(View, { gap: 2, children: [_jsxs(View, { gap: 3, direction: "row", align: "baseline", children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { color: "neutral-faded", children: "Signed up" }) }), _jsx(Text, { color: "neutral-faded", children: "320 users" }), _jsx(Text, { color: "primary", weight: "medium", children: "81%" })] }), _jsxs(View, { gap: 3, direction: "row", align: "baseline", children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { color: "neutral-faded", children: "Onboarded" }) }), _jsx(Text, { color: "neutral-faded", children: "182 users" }), _jsx(Text, { color: "warning", weight: "medium", children: "62%" })] }), _jsxs(View, { gap: 3, direction: "row", align: "baseline", children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { color: "neutral-faded", children: "Purchased" }) }), _jsx(Text, { color: "neutral-faded", children: "120 users" }), _jsx(Text, { color: "critical", weight: "medium", children: "47%" })] })] })] }) }));
|
37
|
+
const ExampleSocial = () => {
|
38
|
+
return (_jsx(Card, { height: "100%", children: _jsxs(View, { gap: 3, children: [_jsxs(View, { direction: "row", gap: 2, align: "center", children: [_jsx(Avatar, { size: 10, color: "neutral" }), _jsxs(View.Item, { grow: true, children: [_jsx(Text, { weight: "medium", children: "Esther Naomi" }), _jsx(Text, { color: "neutral-faded", variant: "caption-1", children: "31 Jan 2037, 10:28" })] }), _jsx(Badge, { variant: "faded", color: "warning", children: "Archived" })] }), _jsx(Text, { color: "neutral-faded", children: "I have been to 27 countries and only 5 of them call this social network X, while others named it Twitter for some reason. Why is this happening?!" }), _jsxs(View, { direction: "row", gap: 2, children: [_jsx(View, { grow: true, aspectRatio: 1, children: _jsx(Image, { src: "", borderRadius: "medium", fallback: true }) }), _jsx(View, { grow: true, aspectRatio: 1, children: _jsx(Image, { src: "", borderRadius: "medium", fallback: true }) }), _jsx(View, { grow: true, aspectRatio: 1, children: _jsx(Image, { src: "", borderRadius: "medium", fallback: true }) })] })] }) }));
|
39
|
+
};
|
40
|
+
const ExampleLogin = () => {
|
41
|
+
const passwordVisibility = useToggle();
|
42
|
+
return (_jsx(Card, { height: "100%", children: _jsxs(View, { gap: 3, children: [_jsx(Text, { variant: "featured-3", children: "Sign in to your account" }), _jsx(Button, { variant: "outline", fullWidth: true, children: "Sign in with Figma" }), _jsxs(View, { gap: 3, direction: "row", align: "center", children: [_jsx(View.Item, { grow: true, children: _jsx(Divider, {}) }), _jsx(Text, { children: "or" }), _jsx(View.Item, { grow: true, children: _jsx(Divider, {}) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Email" }), _jsx(TextField, { name: "email", placeholder: "hello@reshaped.so" })] }), _jsxs(FormControl, { children: [_jsxs(View, { direction: "row", align: "baseline", children: [_jsx(View.Item, { grow: true, children: _jsx(FormControl.Label, { children: "Password" }) }), _jsx(Text, { variant: "caption-1", weight: "medium", children: _jsx(Link, { variant: "plain", onClick: () => { }, children: "Forgot password?" }) })] }), _jsx(TextField, { name: "password", inputAttributes: { type: passwordVisibility.active ? "text" : "password" } })] }), _jsx(Button, { color: "primary", children: "Sign in" })] }) }));
|
43
|
+
};
|
44
|
+
const ExampleSettings = () => (_jsx(Card, { height: "100%", children: _jsxs(View, { gap: 6, height: "100%", children: [_jsx(Text, { variant: "body-1", weight: "medium", children: "Notification settings" }), _jsxs(View, { gap: 3, grow: true, children: [_jsxs(View, { as: "label", direction: "row", align: "center", gap: 2, children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { weight: "medium", children: "Enable email notifications" }) }), _jsx(Switch, { name: "email" })] }), _jsxs(View, { as: "label", direction: "row", align: "center", gap: 2, children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { weight: "medium", children: "Enable Slack notifications" }) }), _jsx(Switch, { name: "email" })] }), _jsxs(View, { as: "label", direction: "row", align: "center", gap: 2, children: [_jsx(View.Item, { grow: true, children: _jsx(Text, { weight: "medium", children: "Enable paper mail notifications" }) }), _jsx(Switch, { name: "email", defaultChecked: true })] }), _jsx(Text, { variant: "caption-1", color: "neutral-faded", children: "Enable all notifications to unsubscribe from our marketing and promotional materials." }), _jsx(View, { grow: true, justify: "end", children: _jsx(Button, { color: "primary", variant: "faded", children: "Save settings" }) })] })] }) }));
|
45
|
+
const ExampleAlert = () => (_jsx(Alert, { icon: IconZap, color: "primary", title: _jsxs(View, { direction: "row", gap: 2, align: "center", children: ["Auto-approve code reviews with AI", _jsx(Badge, { color: "primary", size: "small", children: "New" })] }), actionsSlot: [
|
46
|
+
_jsx(Button, { children: "Keep using" }, 1),
|
47
|
+
_jsx(Button, { variant: "ghost", color: "critical", children: "Opt-out" }, 2),
|
48
|
+
], children: "Try our new GPT-powered code assistant features and never worry about reviewing other developer's pull requests again. Free for the first 5 pull requests." }));
|
49
|
+
const ExampleCheckboxCard = () => {
|
50
|
+
const [value, setValue] = React.useState(["hobby"]);
|
51
|
+
return (_jsx(CheckboxGroup, { name: "1", value: value, onChange: (args) => {
|
52
|
+
setValue(args.value);
|
53
|
+
}, children: _jsxs(View, { gap: 3, children: [_jsx(Card, { as: "label", selected: value.includes("pro"), children: _jsx(View, { direction: "row", gap: 2, align: "center", children: _jsx(Checkbox, { value: "pro", children: "Figma library" }) }) }), _jsx(Card, { as: "label", selected: value.includes("hobby"), children: _jsxs(View, { direction: "row", gap: 2, align: "center", children: [_jsx(View.Item, { grow: true, children: _jsx(Checkbox, { value: "hobby", children: "React library" }) }), _jsx(Badge, { color: "positive", children: "Free" })] }) })] }) }));
|
54
|
+
};
|
55
|
+
const ExampleTable = () => {
|
56
|
+
const rows = [
|
57
|
+
{
|
58
|
+
name: "File downloaded",
|
59
|
+
id: "rshpd_23jb237dh",
|
60
|
+
time: "Jul 4, 12:36",
|
61
|
+
},
|
62
|
+
{
|
63
|
+
name: "User registered",
|
64
|
+
id: "rshpd_27d223jfh",
|
65
|
+
time: "Jul 4, 12:36",
|
66
|
+
},
|
67
|
+
{
|
68
|
+
name: "New version released",
|
69
|
+
id: "rshpd_sjdniu223nj",
|
70
|
+
time: "Jul 4, 12:35",
|
71
|
+
},
|
72
|
+
];
|
73
|
+
const [value, setValue] = React.useState([rows[1].id]);
|
74
|
+
const allSelected = value.length === rows.length;
|
75
|
+
return (_jsx(Card, { padding: 0, children: _jsxs(Table, { children: [_jsxs(Table.Row, { children: [_jsx(Table.Heading, { width: "auto", children: _jsx(Checkbox, { inputAttributes: { "aria-label": "Select all" }, name: "all", checked: allSelected, indeterminate: !!value.length && value.length < rows.length, onChange: () => {
|
76
|
+
setValue(allSelected ? [] : rows.map((row) => row.id));
|
77
|
+
} }) }), _jsx(Table.Heading, { minWidth: "180px", children: "Event type" }), _jsx(Table.Heading, { children: "Event ID" }), _jsx(Table.Heading, { align: "end", minWidth: "120px", children: "Triggered at" }), _jsx(Table.Heading, {})] }), rows.map((row) => (_jsxs(Table.Row, { highlighted: value.includes(row.id), children: [_jsx(Table.Cell, { children: _jsx(Checkbox, { name: "hey", value: row.id, inputAttributes: { "aria-label": "Select the row" }, checked: value.includes(row.id), onChange: (args) => {
|
78
|
+
setValue((prev) => {
|
79
|
+
if (!args.value)
|
80
|
+
return prev;
|
81
|
+
if (args.checked)
|
82
|
+
return [...prev, args.value];
|
83
|
+
return prev.filter((item) => item !== args.value);
|
84
|
+
});
|
85
|
+
} }) }), _jsx(Table.Cell, { children: row.name }), _jsx(Table.Cell, { children: row.id }), _jsx(Table.Cell, { align: "end", children: row.time }), _jsx(Table.Cell, { width: "auto", children: _jsxs(DropdownMenu, { position: "bottom-end", children: [_jsx(DropdownMenu.Trigger, { children: (attributes) => (_jsx(Button.Aligner, { children: _jsx(Button, { attributes: attributes, icon: IconChevronDown, variant: "ghost", size: "small" }) })) }), _jsxs(DropdownMenu.Content, { children: [_jsxs(DropdownMenu.Section, { children: [_jsx(DropdownMenu.Item, { children: "Trigger event" }), _jsx(DropdownMenu.Item, { children: "Log details" })] }), _jsx(DropdownMenu.Section, { children: _jsx(DropdownMenu.Item, { color: "critical", children: "Remote entry" }) })] })] }) })] }, row.id)))] }) }));
|
86
|
+
};
|
87
|
+
const ThemePlayground = () => {
|
88
|
+
return (_jsxs(Grid, { gap: 4, columns: 12, children: [_jsx(Grid.Item, { colSpan: 12, children: _jsx(Palette, {}) }), _jsx(Grid.Item, { colSpan: 6, children: _jsxs(View, { gap: 4, children: [_jsx(ExampleAnalytics, {}), _jsx(ExampleLogin, {}), _jsx(ExampleAlert, {})] }) }), _jsx(Grid.Item, { colSpan: 6, children: _jsxs(View, { gap: 4, children: [_jsx(ExampleSocial, {}), _jsx(ExampleSettings, {}), _jsx(ExampleCheckboxCard, {})] }) }), _jsx(Grid.Item, { colSpan: 12, children: _jsx(ExampleTable, {}) }), _jsx(Grid.Item, { colSpan: 12, children: _jsxs(View, { gap: 2, padding: 4, backgroundColor: "page-faded", borderRadius: "medium", children: [_jsxs(View, { direction: "row", gap: 2, children: [_jsx(Button, { color: "neutral", onClick: () => { }, children: "Neutral" }), _jsx(Button, { color: "primary", onClick: () => { }, children: "Primary" }), _jsx(Button, { color: "critical", onClick: () => { }, children: "Critical" }), _jsx(Button, { color: "positive", onClick: () => { }, children: "Positive" }), _jsx(Button, { color: "primary", disabled: true, onClick: () => { }, children: "Disabled" }), _jsx(Badge, { color: "warning", children: "Warning" })] }), _jsxs(View, { direction: "row", gap: 2, children: [_jsx(Button, { color: "neutral", variant: "faded", onClick: () => { }, children: "Neutral" }), _jsx(Button, { color: "primary", variant: "faded", onClick: () => { }, children: "Primary" }), _jsx(Button, { color: "critical", variant: "faded", onClick: () => { }, children: "Critical" }), _jsx(Button, { color: "positive", variant: "faded", onClick: () => { }, children: "Positive" }), _jsx(Button, { color: "primary", variant: "faded", disabled: true, onClick: () => { }, children: "Disabled" }), _jsx(Badge, { color: "warning", variant: "faded", children: "Warning" })] }), _jsxs(View, { direction: "row", gap: 2, children: [_jsx(Button, { color: "neutral", variant: "outline", onClick: () => { }, children: "Neutral" }), _jsx(Button, { color: "primary", variant: "outline", onClick: () => { }, children: "Primary" }), _jsx(Button, { color: "critical", variant: "outline", onClick: () => { }, children: "Critical" }), _jsx(Button, { color: "positive", variant: "outline", onClick: () => { }, children: "Positive" }), _jsx(Button, { color: "primary", variant: "outline", disabled: true, onClick: () => { }, children: "Disabled" }), _jsx(Badge, { color: "warning", variant: "outline", children: "Warning" })] })] }) })] }));
|
89
|
+
};
|
90
|
+
export default ThemePlayground;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
declare const _default: {
|
2
|
+
title: string;
|
3
|
+
parameters: {
|
4
|
+
iframe: {
|
5
|
+
url: string;
|
6
|
+
};
|
7
|
+
a11y: {
|
8
|
+
disable: boolean;
|
9
|
+
};
|
10
|
+
};
|
11
|
+
};
|
12
|
+
export default _default;
|
13
|
+
export declare const test: () => import("react").JSX.Element;
|
14
|
+
export declare const base: () => import("react").JSX.Element;
|
15
|
+
export declare const generation: () => import("react").JSX.Element;
|
16
|
+
export declare const onColors: () => import("react").JSX.Element;
|
@@ -1,18 +1,21 @@
|
|
1
|
-
import
|
2
|
-
import { Example } from "
|
3
|
-
import View from "
|
4
|
-
import Button from "
|
5
|
-
import Badge from "
|
6
|
-
import Alert from "
|
7
|
-
import Card from "
|
8
|
-
import Avatar from "
|
9
|
-
import DropdownMenu from "
|
10
|
-
import TextField from "
|
11
|
-
import Theme from "
|
12
|
-
import IconZap from "
|
13
|
-
import Link from "
|
14
|
-
import Text from "
|
15
|
-
import { getThemeCSS, generateThemeColors, baseThemeDefinition } from "
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
2
|
+
import { Example } from "../utilities/storybook/index.js";
|
3
|
+
import View from "../components/View/index.js";
|
4
|
+
import Button from "../components/Button/index.js";
|
5
|
+
import Badge from "../components/Badge/index.js";
|
6
|
+
import Alert from "../components/Alert/index.js";
|
7
|
+
import Card from "../components/Card/index.js";
|
8
|
+
import Avatar from "../components/Avatar/index.js";
|
9
|
+
import DropdownMenu from "../components/DropdownMenu/index.js";
|
10
|
+
import TextField from "../components/TextField/index.js";
|
11
|
+
import Theme, { useTheme } from "../components/Theme/index.js";
|
12
|
+
import IconZap from "../icons/Mic.js";
|
13
|
+
import Link from "../components/Link/index.js";
|
14
|
+
import Text from "../components/Text/index.js";
|
15
|
+
import { getThemeCSS, generateThemeColors, baseThemeDefinition } from "../themes/index.js";
|
16
|
+
import ThemePlayground from "./ThemesPlayground.js";
|
17
|
+
import Actionable from "../components/Actionable/index.js";
|
18
|
+
import Switch from "../components/Switch/index.js";
|
16
19
|
export default {
|
17
20
|
title: "Internal/Themes",
|
18
21
|
parameters: {
|
@@ -23,6 +26,62 @@ export default {
|
|
23
26
|
},
|
24
27
|
},
|
25
28
|
};
|
29
|
+
const colors = [
|
30
|
+
"#2563eb",
|
31
|
+
"#4f39f6",
|
32
|
+
"#4a8200",
|
33
|
+
"#0891b2",
|
34
|
+
"#34d399",
|
35
|
+
"#fe9a00",
|
36
|
+
"#be185d",
|
37
|
+
"#ff2056",
|
38
|
+
"#000000",
|
39
|
+
];
|
40
|
+
export const test = () => {
|
41
|
+
const { colorMode } = useTheme();
|
42
|
+
const [activeColor, setColor] = useState(colors[0]);
|
43
|
+
const [theme, setTheme] = useState("");
|
44
|
+
const [algo, setAlgo] = useState("wcag");
|
45
|
+
useLayoutEffect(() => {
|
46
|
+
setTheme(getThemeCSS("test", {
|
47
|
+
color: generateThemeColors({
|
48
|
+
primary: activeColor === colors[0] ? undefined : activeColor,
|
49
|
+
}),
|
50
|
+
}, {
|
51
|
+
colorContrastAlgorithm: algo,
|
52
|
+
}));
|
53
|
+
}, [activeColor, algo]);
|
54
|
+
return (<>
|
55
|
+
<style>{theme}</style>
|
56
|
+
<Theme name="test">
|
57
|
+
<View gap={4}>
|
58
|
+
<View direction="row" align="center" gap={4}>
|
59
|
+
{colors.map((color) => {
|
60
|
+
const hex = colorMode === "dark" && color === "#000000" ? "#ffffff" : color;
|
61
|
+
return (<Actionable key={color} onClick={() => setColor(color)} borderRadius="inherit">
|
62
|
+
<View width={5} height={5} borderRadius="circular" attributes={{
|
63
|
+
style: {
|
64
|
+
transition: `box-shadow var(--rs-duration-fast) var(--rs-easing-standard)`,
|
65
|
+
background: hex,
|
66
|
+
boxShadow: color === activeColor
|
67
|
+
? `0 0 0 3px var(--rs-color-background-elevation-base), 0 0 0 5px ${hex}`
|
68
|
+
: undefined,
|
69
|
+
},
|
70
|
+
}}/>
|
71
|
+
</Actionable>);
|
72
|
+
})}
|
73
|
+
<View.Item gapBefore="auto">
|
74
|
+
<Switch name="algo" onChange={(args) => setAlgo(args.checked ? "apca" : "wcag")}>
|
75
|
+
Use APCA
|
76
|
+
</Switch>
|
77
|
+
</View.Item>
|
78
|
+
</View>
|
79
|
+
|
80
|
+
<ThemePlayground />
|
81
|
+
</View>
|
82
|
+
</Theme>
|
83
|
+
</>);
|
84
|
+
};
|
26
85
|
const css = getThemeCSS("green", {
|
27
86
|
color: {
|
28
87
|
backgroundPrimary: { hex: "#1abc9c", hexDark: "#00E5C4" },
|
@@ -1,18 +1,40 @@
|
|
1
|
-
const
|
2
|
-
const
|
3
|
-
|
1
|
+
const transformTokenForMode = (args) => {
|
2
|
+
const { hex, oklch } = args;
|
3
|
+
if (oklch) {
|
4
|
+
const components = `${Number(oklch.l.toFixed(4))} ${Number(oklch.c.toFixed(4))} ${Number(oklch.h?.toFixed(4) || 0)}`;
|
5
|
+
const alphaSuffix = oklch?.alpha === undefined ? "" : ` / ${Number(oklch.alpha.toFixed(4))}`;
|
6
|
+
return `oklch(${components}${alphaSuffix})`;
|
7
|
+
}
|
8
|
+
if (hex)
|
9
|
+
return hex;
|
10
|
+
throw new Error(`[Reshaped] ${JSON.stringify(args)} is missing a color value`);
|
11
|
+
};
|
12
|
+
const transformToken = (name, token) => {
|
13
|
+
const { hex, hexDark, oklch, oklchDark } = token;
|
14
|
+
// Apply color to both modes if dark mode is not available
|
15
|
+
const hasDark = !!hexDark || !!oklchDark;
|
16
|
+
const value = transformTokenForMode({ oklch, hex });
|
17
|
+
const darkValue = hasDark ? transformTokenForMode({ oklch: oklchDark, hex: hexDark }) : undefined;
|
18
|
+
const separateModes = hasDark && value !== darkValue;
|
19
|
+
const defaultMode = separateModes ? "light" : undefined;
|
4
20
|
const result = [
|
5
|
-
{
|
21
|
+
{
|
22
|
+
name,
|
23
|
+
tokenType: "color",
|
24
|
+
type: "variable",
|
25
|
+
value,
|
26
|
+
mode: defaultMode,
|
27
|
+
},
|
6
28
|
];
|
7
|
-
if (
|
29
|
+
if (darkValue && separateModes) {
|
8
30
|
result.push({
|
9
31
|
name,
|
10
32
|
tokenType: "color",
|
11
33
|
type: "variable",
|
12
|
-
value:
|
34
|
+
value: darkValue,
|
13
35
|
mode: "dark",
|
14
36
|
});
|
15
37
|
}
|
16
38
|
return result;
|
17
39
|
};
|
18
|
-
export default
|
40
|
+
export default transformToken;
|
@@ -1,7 +1,32 @@
|
|
1
|
+
import type { Oklch } from "culori/fn";
|
2
|
+
export type Hue = "primary" | "positive" | "critical" | "warning" | "neutral" | "brand";
|
1
3
|
export type Name = "foregroundNeutral" | "foregroundNeutralFaded" | "foregroundDisabled" | "foregroundPrimary" | "foregroundCritical" | "foregroundWarning" | "foregroundPositive" | "borderNeutral" | "borderNeutralFaded" | "borderDisabled" | "borderPrimary" | "borderPrimaryFaded" | "borderCritical" | "borderCriticalFaded" | "borderWarning" | "borderWarningFaded" | "borderPositive" | "borderPositiveFaded" | "backgroundNeutral" | "backgroundNeutralFaded" | "backgroundDisabled" | "backgroundDisabledFaded" | "backgroundPrimary" | "backgroundPrimaryFaded" | "backgroundCritical" | "backgroundCriticalFaded" | "backgroundWarning" | "backgroundWarningFaded" | "backgroundPositive" | "backgroundPositiveFaded" | "backgroundPage" | "backgroundPageFaded" | "backgroundElevationBase" | "backgroundElevationRaised" | "backgroundElevationOverlay" | "brand" | "white" | "black";
|
2
4
|
export type GeneratedOnName = "onBackgroundNeutral" | "onBackgroundPrimary" | "onBackgroundPositive" | "onBackgroundWarning" | "onBackgroundCritical";
|
3
5
|
export type GeneratedRGBName = "rgbBackgroundNeutral" | "rgbBackgroundNeutralFaded" | "rgbBackgroundDisabled" | "rgbBackgroundDisabledFaded" | "rgbBackgroundPrimary" | "rgbBackgroundPrimaryFaded" | "rgbBackgroundCritical" | "rgbBackgroundCriticalFaded" | "rgbBackgroundWarning" | "rgbBackgroundWarningFaded" | "rgbBackgroundPositive" | "rgbBackgroundPositiveFaded" | "rgbBackgroundPage" | "rgbBackgroundPageFaded" | "rgbBackgroundElevationBase" | "rgbBackgroundElevationRaised" | "rgbBackgroundElevationOverlay";
|
4
|
-
export type
|
5
|
-
|
6
|
-
|
6
|
+
export type RgbColor = {
|
7
|
+
r: number;
|
8
|
+
g: number;
|
9
|
+
b: number;
|
10
|
+
};
|
11
|
+
export type OklchColor = Omit<Oklch, "mode">;
|
12
|
+
export type HexColor = string;
|
13
|
+
export type ColorValue = HexColor | Token;
|
14
|
+
export type OklchOnlyToken = {
|
15
|
+
oklch: OklchColor;
|
16
|
+
oklchDark?: OklchColor;
|
17
|
+
};
|
18
|
+
export type OklchToken = OklchOnlyToken & {
|
19
|
+
hex?: never;
|
20
|
+
hexDark?: never;
|
21
|
+
};
|
22
|
+
export type HexToken = {
|
23
|
+
hex: HexColor;
|
24
|
+
hexDark?: HexColor;
|
25
|
+
oklch?: never;
|
26
|
+
oklchDark?: never;
|
27
|
+
};
|
28
|
+
export type Token = OklchToken | HexToken;
|
29
|
+
export type InternalToken = {
|
30
|
+
oklch: Oklch;
|
31
|
+
oklchDark?: Oklch;
|
7
32
|
};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { type Oklch } from "culori/fn";
|
2
|
+
export declare const getOnColorWCAG: (args: {
|
3
|
+
bgColor: Oklch;
|
4
|
+
lightColor: Oklch;
|
5
|
+
darkColor: Oklch;
|
6
|
+
}) => Oklch;
|
7
|
+
export declare const getOnColorAPCA: (args: {
|
8
|
+
bgColor: Oklch;
|
9
|
+
lightColor: Oklch;
|
10
|
+
darkColor: Oklch;
|
11
|
+
}) => Oklch;
|
12
|
+
/**
|
13
|
+
* General
|
14
|
+
*/
|
15
|
+
export declare const getOnColor: (args: {
|
16
|
+
bgColor: Oklch;
|
17
|
+
lightColor: Oklch;
|
18
|
+
darkColor: Oklch;
|
19
|
+
algorithm?: "wcag" | "apca";
|
20
|
+
}) => Oklch;
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import { oklchToRgb } from "./convert.js";
|
2
|
+
/**
|
3
|
+
* WCAG
|
4
|
+
*/
|
5
|
+
const RED = 0.2126;
|
6
|
+
const GREEN = 0.7152;
|
7
|
+
const BLUE = 0.0722;
|
8
|
+
const GAMMA = 2.4;
|
9
|
+
function luminanceWCAG(r, g, b) {
|
10
|
+
const a = [r, g, b].map((v) => {
|
11
|
+
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, GAMMA);
|
12
|
+
});
|
13
|
+
return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
|
14
|
+
}
|
15
|
+
function contrastWCAG(rgb1, rgb2) {
|
16
|
+
const lum1 = luminanceWCAG(...rgb1);
|
17
|
+
const lum2 = luminanceWCAG(...rgb2);
|
18
|
+
const brightest = Math.max(lum1, lum2);
|
19
|
+
const darkest = Math.min(lum1, lum2);
|
20
|
+
return (brightest + 0.05) / (darkest + 0.05);
|
21
|
+
}
|
22
|
+
export const getOnColorWCAG = (args) => {
|
23
|
+
const { bgColor, lightColor, darkColor } = args;
|
24
|
+
const bgRgb = oklchToRgb(bgColor);
|
25
|
+
const lightRgb = oklchToRgb(lightColor);
|
26
|
+
return contrastWCAG([bgRgb.r, bgRgb.g, bgRgb.b], [lightRgb.r, lightRgb.g, lightRgb.b]) > 4.5
|
27
|
+
? lightColor
|
28
|
+
: darkColor;
|
29
|
+
};
|
30
|
+
/**
|
31
|
+
* APCA
|
32
|
+
*/
|
33
|
+
function luminanceAPCA(oklch) {
|
34
|
+
const { r, g, b } = oklchToRgb(oklch);
|
35
|
+
return (0.2126 * Math.pow(r / 255, 2.2) +
|
36
|
+
0.7152 * Math.pow(g / 255, 2.2) +
|
37
|
+
0.0722 * Math.pow(b / 255, 2.2));
|
38
|
+
}
|
39
|
+
export const getOnColorAPCA = (args) => {
|
40
|
+
const { bgColor, lightColor, darkColor } = args;
|
41
|
+
const backgroundLuminance = luminanceAPCA(bgColor);
|
42
|
+
const lightLuminance = luminanceAPCA(lightColor);
|
43
|
+
const darkLuminance = luminanceAPCA(darkColor);
|
44
|
+
const contrastWithLight = Math.abs(lightLuminance - backgroundLuminance);
|
45
|
+
const contrastWithDark = Math.abs(darkLuminance - backgroundLuminance);
|
46
|
+
return contrastWithLight > contrastWithDark ? lightColor : darkColor;
|
47
|
+
};
|
48
|
+
/**
|
49
|
+
* General
|
50
|
+
*/
|
51
|
+
export const getOnColor = (args) => {
|
52
|
+
if (args.algorithm === "apca") {
|
53
|
+
return getOnColorAPCA(args);
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
return getOnColorWCAG(args);
|
57
|
+
}
|
58
|
+
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { type Oklch } from "culori/fn";
|
2
|
+
import type * as TColor from "../color.types";
|
3
|
+
export declare const hexToOklch: (hex: string) => Oklch;
|
4
|
+
export declare const oklchToRgb: (oklch: Oklch) => {
|
5
|
+
r: number;
|
6
|
+
g: number;
|
7
|
+
b: number;
|
8
|
+
mode: "rgb";
|
9
|
+
alpha?: number;
|
10
|
+
};
|
11
|
+
export declare const tokenToOklchToken: (token: TColor.Token) => TColor.InternalToken;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { useMode, modeOklch, formatHex, modeRgb } from "culori/fn";
|
2
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
3
|
+
const oklch = useMode(modeOklch);
|
4
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
5
|
+
const rgb = useMode(modeRgb);
|
6
|
+
export const hexToOklch = (hex) => {
|
7
|
+
const result = oklch(formatHex(hex));
|
8
|
+
if (!result)
|
9
|
+
throw new Error(`[Reshaped] Can't convert ${hex} to oklch`);
|
10
|
+
return result;
|
11
|
+
};
|
12
|
+
export const oklchToRgb = (oklch) => {
|
13
|
+
const value = rgb(oklch);
|
14
|
+
return {
|
15
|
+
...value,
|
16
|
+
r: Number(value.r.toFixed(4)),
|
17
|
+
g: Number(value.g.toFixed(4)),
|
18
|
+
b: Number(value.b.toFixed(4)),
|
19
|
+
};
|
20
|
+
};
|
21
|
+
export const tokenToOklchToken = (token) => {
|
22
|
+
const hexDarkFallback = token.hexDark ? hexToOklch(token.hexDark) : undefined;
|
23
|
+
return {
|
24
|
+
oklch: token.oklch ? { ...token.oklch, mode: "oklch" } : hexToOklch(token.hex),
|
25
|
+
oklchDark: token.oklchDark ? { ...token.oklchDark, mode: "oklch" } : hexDarkFallback,
|
26
|
+
};
|
27
|
+
};
|