@sit-onyx/storybook-utils 1.0.0-beta.1 → 1.0.0-beta.100

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/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- export * from "./actions";
2
- export * from "./preview";
3
- export * from "./theme";
4
- export * from "./types";
1
+ export * from "./actions.js";
2
+ export * from "./preview.js";
3
+ export * from "./sbType.js";
4
+ export * from "./theme.js";
5
+ export * from "./types.js";
@@ -1,34 +1,24 @@
1
- import bellRing from "@sit-onyx/icons/bell-ring.svg?raw";
2
- import calendar from "@sit-onyx/icons/calendar.svg?raw";
3
- import placeholder from "@sit-onyx/icons/placeholder.svg?raw";
4
- import { describe, expect, test, vi } from "vitest";
5
- import { replaceAll, sourceCodeTransformer } from "./preview";
6
- import * as sourceCodeGenerator from "./source-code-generator";
1
+ import { iconBellRing, iconCalendar, iconPlaceholder } from "@sit-onyx/icons";
2
+ import { describe, expect, test } from "vitest";
3
+ import { replaceAll, sourceCodeTransformer } from "./preview.js";
7
4
 
8
5
  describe("preview.ts", () => {
9
- test("should transform source code and add icon/onyx imports", () => {
10
- // ARRANGE
11
- const generatorSpy = vi.spyOn(sourceCodeGenerator, "generateSourceCode")
12
- .mockReturnValue(`<template>
13
- <OnyxTest icon='${placeholder}' test='${bellRing}' :obj="{foo:'${replaceAll(calendar, '"', "\\'")}'}" />
6
+ test("should transform source code and add icon/onyx imports", async () => {
7
+ // ACT
8
+ const sourceCode = await sourceCodeTransformer(`<template>
9
+ <OnyxTest icon='${iconPlaceholder}' test='${iconBellRing}' :obj="{foo:'${replaceAll(iconCalendar, '"', "\\'")}'}" />
14
10
  <OnyxOtherComponent />
15
11
  <OnyxComp>Test</OnyxComp>
16
12
  </template>`);
17
13
 
18
- // ACT
19
- const sourceCode = sourceCodeTransformer("", { title: "OnyxTest", args: {} });
20
-
21
14
  // ASSERT
22
- expect(generatorSpy).toHaveBeenCalledOnce();
23
15
  expect(sourceCode).toBe(`<script lang="ts" setup>
24
16
  import { OnyxComp, OnyxOtherComponent, OnyxTest } from "sit-onyx";
25
- import bellRing from "@sit-onyx/icons/bell-ring.svg?raw";
26
- import calendar from "@sit-onyx/icons/calendar.svg?raw";
27
- import placeholder from "@sit-onyx/icons/placeholder.svg?raw";
17
+ import { iconBellRing, iconCalendar, iconPlaceholder } from "@sit-onyx/icons";
28
18
  </script>
29
19
 
30
20
  <template>
31
- <OnyxTest :icon="placeholder" :test="bellRing" :obj="{foo:calendar}" />
21
+ <OnyxTest :icon="iconPlaceholder" :test="iconBellRing" :obj="{foo:iconCalendar}" />
32
22
  <OnyxOtherComponent />
33
23
  <OnyxComp>Test</OnyxComp>
34
24
  </template>`);
package/src/preview.ts CHANGED
@@ -1,27 +1,21 @@
1
- import { DOCS_RENDERED } from "@storybook/core-events";
2
- import { addons } from "@storybook/preview-api";
3
- import { type ThemeVars } from "@storybook/theming";
4
- import { type Preview, type StoryContext } from "@storybook/vue3";
1
+ import type { Preview } from "@storybook/vue3-vite";
2
+ import { DARK_MODE_EVENT_NAME } from "@vueless/storybook-dark-mode";
5
3
  import { deepmerge } from "deepmerge-ts";
6
- import { DARK_MODE_EVENT_NAME } from "storybook-dark-mode";
7
-
8
- import { getIconImportName } from "@sit-onyx/icons";
9
- import { requiredGlobalType, withRequired } from "./required";
10
- import { generateSourceCode } from "./source-code-generator";
11
- import { ONYX_BREAKPOINTS, createTheme } from "./theme";
12
-
13
- const themes = {
14
- light: createTheme(),
15
- dark: createTheme({ base: "dark" }),
16
- } as const;
4
+ import { DOCS_RENDERED } from "storybook/internal/core-events";
5
+ import { addons } from "storybook/internal/preview-api";
6
+ import type { ThemeVars } from "storybook/internal/theming";
7
+ import { enhanceEventArgTypes } from "./actions.js";
8
+ import { requiredGlobalType, withRequired } from "./required.js";
9
+ import { ONYX_BREAKPOINTS, createTheme, type BrandDetails } from "./theme.js";
17
10
 
18
11
  /**
19
12
  * Creates a default Storybook preview configuration for 'onyx' with the following features:
20
13
  * - Improved controls (sorting and expanded controls so descriptions etc. are also shown in a single story)
21
14
  * - Improved Vue-specific code highlighting (e.g. using `@` instead of `v-on:`)
22
- * - Setup for dark mode (including docs page). Requires addon `storybook-dark-mode` to be enabled in .storybook/main.ts file
15
+ * - Setup for dark mode (including docs page). Requires addon `@vueless/storybook-dark-mode` to be enabled in .storybook/main.ts file
23
16
  * - Custom Storybook theme using onyx colors (light and dark mode)
24
17
  * - Configure viewports / breakpoints as defined by onyx
18
+ * - Logs Vue emits as Storybook events
25
19
  *
26
20
  * @param overrides Custom preview / overrides, will be deep merged with the default preview.
27
21
  *
@@ -40,8 +34,21 @@ const themes = {
40
34
  * export default preview;
41
35
  * ```
42
36
  */
43
- export const createPreview = <T extends Preview = Preview>(overrides?: T) => {
37
+ export const createPreview = <T extends Preview = Preview>(
38
+ overrides?: T,
39
+ brandDetails?: BrandDetails,
40
+ ) => {
41
+ const themes = {
42
+ light: createTheme("light", brandDetails),
43
+ dark: createTheme("dark", brandDetails),
44
+ } as const;
45
+
44
46
  const defaultPreview = {
47
+ argTypesEnhancers: [enhanceEventArgTypes],
48
+ initialGlobals: {
49
+ ["requiredMode" satisfies keyof typeof requiredGlobalType]: "required",
50
+ backgrounds: { value: "currentTheme" },
51
+ },
45
52
  globalTypes: {
46
53
  ...requiredGlobalType,
47
54
  },
@@ -55,6 +62,7 @@ export const createPreview = <T extends Preview = Preview>(overrides?: T) => {
55
62
  sort: "requiredFirst",
56
63
  // needed to also show props/events descriptions etc. when opening a single story
57
64
  expanded: true,
65
+ exclude: ["ref", "ref_for", "ref_key", "class", "style", "key", "$slots"],
58
66
  },
59
67
  docs: {
60
68
  // see: https://github.com/hipstersmoothie/storybook-dark-mode/issues/127#issuecomment-840701971
@@ -64,11 +72,9 @@ export const createPreview = <T extends Preview = Preview>(overrides?: T) => {
64
72
  if (isDark) {
65
73
  document.body.classList.remove("light");
66
74
  document.body.classList.add("dark");
67
- document.documentElement.style.colorScheme = "dark";
68
75
  } else {
69
76
  document.body.classList.remove("dark");
70
77
  document.body.classList.add("light");
71
- document.documentElement.style.colorScheme = "light";
72
78
  }
73
79
 
74
80
  return isDark ? themes.dark : themes.light;
@@ -90,11 +96,12 @@ export const createPreview = <T extends Preview = Preview>(overrides?: T) => {
90
96
  dark: themes.dark,
91
97
  },
92
98
  backgrounds: {
93
- // backgrounds are not needed because we have configured the darkMode addon/toggle switch
94
- disable: true,
99
+ options: {
100
+ currentTheme: { name: "Dynamic", value: "var(--onyx-color-base-background-tinted)" },
101
+ },
95
102
  },
96
103
  viewport: {
97
- viewports: ONYX_BREAKPOINTS,
104
+ options: ONYX_BREAKPOINTS,
98
105
  },
99
106
  },
100
107
  } satisfies Preview;
@@ -124,52 +131,44 @@ export const createPreview = <T extends Preview = Preview>(overrides?: T) => {
124
131
  *
125
132
  * @see https://storybook.js.org/docs/react/api/doc-block-source
126
133
  */
127
- export const sourceCodeTransformer = (
128
- sourceCode: string,
129
- ctx: Pick<StoryContext, "title" | "component" | "args">,
130
- ): string => {
131
- const RAW_ICONS = import.meta.glob("../node_modules/@sit-onyx/icons/src/assets/*.svg", {
132
- query: "?raw",
133
- import: "default",
134
- eager: true,
135
- });
136
-
137
- /**
138
- * Mapping between icon SVG content (key) and icon name (value).
139
- * Needed to display a labelled dropdown list of all available icons.
140
- */
141
- const ALL_ICONS = Object.entries(RAW_ICONS).reduce<Record<string, string>>(
142
- (obj, [filePath, content]) => {
143
- obj[filePath.split("/").at(-1)!.replace(".svg", "")] = content as string;
144
- return obj;
145
- },
146
- {},
147
- );
134
+ export const sourceCodeTransformer = async (originalSourceCode: string): Promise<string> => {
135
+ const ALL_ICONS = await import("@sit-onyx/icons");
148
136
 
149
- let code = generateSourceCode(ctx);
137
+ let code = originalSourceCode;
150
138
 
151
139
  const additionalImports: string[] = [];
152
140
 
153
141
  // add icon imports to the source code for all used onyx icons
142
+ const usedIcons = new Set<string>();
143
+
154
144
  Object.entries(ALL_ICONS).forEach(([iconName, iconContent]) => {
155
- const importName = getIconImportName(iconName);
156
145
  const singleQuotedIconContent = `'${replaceAll(iconContent, '"', "\\'")}'`;
157
146
  const escapedIconContent = `"${replaceAll(iconContent, '"', '\\"')}"`;
158
147
 
159
148
  if (code.includes(iconContent)) {
160
- code = code.replace(new RegExp(` (\\S+)=['"]${iconContent}['"]`), ` :$1="${importName}"`);
161
- additionalImports.push(`import ${importName} from "@sit-onyx/icons/${iconName}.svg?raw";`);
149
+ usedIcons.add(iconName);
150
+
151
+ code = code.replace(
152
+ new RegExp(` (\\S+)=['"]${escapeRegExp(iconContent)}['"]`),
153
+ ` :$1="${iconName}"`,
154
+ );
162
155
  } else if (code.includes(singleQuotedIconContent)) {
163
156
  // support icons inside objects
164
- code = code.replace(singleQuotedIconContent, importName);
165
- additionalImports.push(`import ${importName} from "@sit-onyx/icons/${iconName}.svg?raw";`);
157
+ usedIcons.add(iconName);
158
+ code = code.replace(singleQuotedIconContent, iconName);
166
159
  } else if (code.includes(escapedIconContent)) {
167
160
  // support icons inside objects
168
- code = code.replace(escapedIconContent, importName);
169
- additionalImports.push(`import ${importName} from "@sit-onyx/icons/${iconName}.svg?raw";`);
161
+ usedIcons.add(iconName);
162
+ code = code.replace(escapedIconContent, iconName);
170
163
  }
171
164
  });
172
165
 
166
+ if (usedIcons.size > 0) {
167
+ additionalImports.push(
168
+ `import { ${Array.from(usedIcons.values()).sort().join(", ")} } from "@sit-onyx/icons";`,
169
+ );
170
+ }
171
+
173
172
  // add imports for all used onyx components
174
173
  // Set is used here to only include unique components if they are used multiple times
175
174
  const usedOnyxComponents = [
@@ -207,3 +206,11 @@ ${code}`;
207
206
  export const replaceAll = (value: string, searchValue: string | RegExp, replaceValue: string) => {
208
207
  return value.replace(new RegExp(searchValue, "gi"), replaceValue);
209
208
  };
209
+
210
+ /**
211
+ * Escapes the given string value to be used in `new RegExp()`.
212
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions#escaping
213
+ */
214
+ export const escapeRegExp = (string: string) => {
215
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
216
+ };
package/src/required.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { type Decorator } from "@storybook/vue3";
1
+ import { type Decorator } from "@storybook/vue3-vite";
2
2
  import { ref, watch } from "vue";
3
- import type { StorybookGlobalType } from "./types";
3
+ import type { StorybookGlobalType } from "./types.js";
4
4
 
5
5
  type RequiredIndicator = "required" | "optional";
6
6
 
@@ -8,7 +8,6 @@ export const requiredGlobalType = {
8
8
  requiredMode: {
9
9
  name: "Required mode",
10
10
  description: "Switch between 'required' and 'optional' indicator",
11
- defaultValue: "required",
12
11
  toolbar: {
13
12
  icon: "flag",
14
13
  items: [
@@ -0,0 +1,38 @@
1
+ import type { SBType } from "storybook/internal/types";
2
+ import { describe, expect, test, vi } from "vitest";
3
+ import { walkTree } from "./sbType.js";
4
+
5
+ describe("walkTree", () => {
6
+ test.each<{ input: SBType; expected: SBType["name"][] }>([
7
+ { input: { name: "array", value: { name: "number" } }, expected: ["array", "number"] },
8
+ { input: { name: "object", value: { a: { name: "number" } } }, expected: ["object", "number"] },
9
+ { input: { name: "enum", value: ["a"] }, expected: ["enum"] },
10
+ {
11
+ input: { name: "intersection", value: [{ name: "number" }] },
12
+ expected: ["intersection", "number"],
13
+ },
14
+ { input: { name: "union", value: [{ name: "number" }] }, expected: ["union", "number"] },
15
+ { input: { name: "other", value: "a" }, expected: ["other"] },
16
+ ])("should execute cb for $input.name correctly", ({ input, expected }) => {
17
+ const spy = vi.fn<(p: SBType) => void>();
18
+ const result = walkTree(input, spy);
19
+
20
+ expect(result).toBeUndefined();
21
+ expect(spy).toHaveBeenCalledTimes(expected.length);
22
+ const nameCalls = spy.mock.calls.map(([{ name }]) => name);
23
+ expect(nameCalls).toMatchObject(expected);
24
+ });
25
+
26
+ test("should return value if there is any returned", () => {
27
+ const target: SBType = { name: "number", raw: "here" };
28
+ const overshoot: SBType = { name: "boolean", raw: "here" };
29
+ const parent: SBType = { name: "intersection", value: [target, overshoot] };
30
+ const returned = 42;
31
+ const spy = vi.fn((p: SBType) => (p.raw === "here" ? returned : undefined));
32
+ const result = walkTree({ name: "union", value: [parent] }, spy);
33
+
34
+ expect(spy).toHaveBeenCalledTimes(3);
35
+ expect(spy).toHaveBeenLastCalledWith(target, parent);
36
+ expect(result).toBe(returned);
37
+ });
38
+ });
package/src/sbType.ts ADDED
@@ -0,0 +1,104 @@
1
+ import type {
2
+ ArgTypesEnhancer,
3
+ InputType,
4
+ SBType,
5
+ StrictInputType,
6
+ } from "storybook/internal/types";
7
+
8
+ /**
9
+ * Call a function `cb` for every type node in the storybook type tree.
10
+ * @param inputType the root type
11
+ * @param cb the function that is called for every type. If any non-nullish value is returned by `cb` the execution is stopped and this value is returned.
12
+ * @param parent optional, the parent type. Is only used as input for the `cb` function and provided when recursing.
13
+ * @returns the first non-nullish value that is returned by `cb`
14
+ */
15
+ export const walkTree = <TValue>(
16
+ inputType: SBType,
17
+ cb: (sb: SBType, parent?: SBType) => TValue,
18
+ parent?: SBType,
19
+ ): TValue | undefined => {
20
+ const shouldReturn = cb(inputType, parent);
21
+ if (shouldReturn) {
22
+ return shouldReturn;
23
+ }
24
+
25
+ if (inputType.name === "union" || inputType.name === "intersection") {
26
+ return inputType.value.reduce<TValue | undefined>(
27
+ (prev, it) => prev ?? walkTree(it, cb, inputType),
28
+ undefined,
29
+ );
30
+ }
31
+ if (inputType.name === "array") {
32
+ return walkTree(inputType.value, cb, inputType);
33
+ }
34
+ if (inputType.name === "object") {
35
+ return Object.values(inputType.value).reduce<TValue | undefined>(
36
+ (prev, it) => prev ?? walkTree(it, cb, inputType),
37
+ undefined,
38
+ );
39
+ }
40
+ };
41
+
42
+ const SB_TYPE_CONTROL_MAP: Partial<Record<SBType["name"], InputType["control"]>> = {
43
+ boolean: { type: "boolean" },
44
+ string: { type: "text" },
45
+ number: { type: "number" },
46
+ };
47
+
48
+ const getFormInjectedParent = (symbol: string, inputType?: StrictInputType) => {
49
+ if (!inputType?.type || inputType.table?.defaultValue?.summary !== symbol) {
50
+ return undefined;
51
+ }
52
+
53
+ return walkTree(inputType.type, (elem, parent) =>
54
+ elem.name === "symbol" || (elem.name === "other" && elem.value === "unique symbol")
55
+ ? parent
56
+ : undefined,
57
+ );
58
+ };
59
+
60
+ /**
61
+ * Can be used to create an `ArgTypesEnhancer` which matches a Symbol that is used as default Prop.
62
+ * When it matches the passed description text will be set.
63
+ *
64
+ * @param symbol description of the symbol that should be matched.
65
+ * @param description the description text that should be shown in Storybook for this prop.
66
+ * @returns An `ArgTypesEnhancer` which can be passed to storybook.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { createSymbolArgTypeEnhancer } from "@sit-onyx/storybook-utils";
71
+ *
72
+ * export const enhanceFormInjectedSymbol = createSymbolArgTypeEnhancer(
73
+ * "FORM_INJECTED_SYMBOL",
74
+ * "If no value (or `undefined`) is provided, `FORM_INJECTED_SYMBOL` is the internal default value for this prop.\n" +
75
+ * "In that case the props value will be derived from it's parent form (if it exists).\n",
76
+ * );
77
+ * ```
78
+ */
79
+ export const createSymbolArgTypeEnhancer = (
80
+ symbol: string,
81
+ description: string,
82
+ ): ArgTypesEnhancer => {
83
+ return (context) => {
84
+ Object.values(context.argTypes)
85
+ .map((argType) => {
86
+ const parent = getFormInjectedParent(symbol, argType);
87
+ return { argType, parent };
88
+ })
89
+ .filter(({ parent }) => parent)
90
+ .forEach(({ argType, parent }) => {
91
+ const firstAvailableControl = walkTree(
92
+ parent || argType.type!,
93
+ (sb) => SB_TYPE_CONTROL_MAP[sb.name],
94
+ );
95
+
96
+ if (firstAvailableControl && argType.table?.defaultValue) {
97
+ argType.control = firstAvailableControl;
98
+ argType.table.defaultValue.detail = description;
99
+ }
100
+ });
101
+
102
+ return context.argTypes;
103
+ };
104
+ };
package/src/style.css ADDED
@@ -0,0 +1,161 @@
1
+ .onyx-disclaimer {
2
+ border-radius: 0.5rem;
3
+ padding: 1rem;
4
+ line-height: var(--onyx-font-line-height-md);
5
+ margin: 1rem 0;
6
+
7
+ /* same color as VitePress var(--vp-c-tip-soft) */
8
+ background-color: color-mix(in srgb, var(--onyx-color-base-info-400) 25%, transparent);
9
+ }
10
+
11
+ .onyx-disclaimer__title {
12
+ font-weight: var(--onyx-font-weight-semibold);
13
+ margin-bottom: 0.5rem;
14
+ }
15
+
16
+ .onyx-disclaimer p {
17
+ margin: 0;
18
+ }
19
+
20
+ /* the Storybook table of content headline is always black so we need to manually set it for the dark mode */
21
+ #storybook-docs .sbdocs-wrapper > aside > nav > h2 {
22
+ /* same as Storybook color "textMuted" inside ./theme.ts */
23
+ color: var(--onyx-color-text-icons-neutral-medium);
24
+ }
25
+
26
+ /* To prevent bg flashing when changing between elements in darkmode */
27
+ .sb-preparing-story,
28
+ .sb-preparing-docs {
29
+ background-color: transparent;
30
+ }
31
+ /* removed placeholder for the same reason */
32
+ .sb-previewBlock,
33
+ .sb-argstableBlock {
34
+ display: none;
35
+ }
36
+
37
+ /*
38
+ Copy of ../sit-onyx/src/styles/variables/themes/onyx.css
39
+ TODO: Find a way to automate this
40
+ */
41
+ :where(:root),
42
+ .onyx-theme-default {
43
+ --onyx-color-neutral-steel-100: #fafbfc;
44
+ --onyx-color-neutral-steel-200: #e3eaf0;
45
+ --onyx-color-neutral-steel-300: #c9d6e0;
46
+ --onyx-color-neutral-steel-400: #9db3c4;
47
+ --onyx-color-neutral-steel-500: #7392aa;
48
+ --onyx-color-neutral-steel-600: #506e84;
49
+ --onyx-color-neutral-steel-700: #3e596e;
50
+ --onyx-color-neutral-steel-800: #31495c;
51
+ --onyx-color-neutral-steel-900: #22384a;
52
+ --onyx-color-neutral-steel-1000: #11212d;
53
+ --onyx-color-neutral-steel-1100: #081723;
54
+ --onyx-color-neutral-steel-1200: #000e19;
55
+ --onyx-color-themed-primary-100: #e8fcfc;
56
+ --onyx-color-themed-primary-200: #bbeaed;
57
+ --onyx-color-themed-primary-300: #79dde2;
58
+ --onyx-color-themed-primary-400: #3dd0d8;
59
+ --onyx-color-themed-primary-500: #00c3cd;
60
+ --onyx-color-themed-primary-600: #00adb5;
61
+ --onyx-color-themed-primary-700: #00969d;
62
+ --onyx-color-themed-primary-800: #008085;
63
+ --onyx-color-themed-primary-900: #00696e;
64
+ --onyx-color-themed-primary-1000: #005356;
65
+ --onyx-color-themed-primary-1100: #003c3e;
66
+ --onyx-color-themed-primary-1200: #002626;
67
+ --onyx-color-themed-secondary-100: var(--onyx-color-themed-primary-100);
68
+ --onyx-color-themed-secondary-200: var(--onyx-color-themed-primary-200);
69
+ --onyx-color-themed-secondary-300: var(--onyx-color-themed-primary-300);
70
+ --onyx-color-themed-secondary-400: var(--onyx-color-themed-primary-400);
71
+ --onyx-color-themed-secondary-500: var(--onyx-color-themed-primary-500);
72
+ --onyx-color-themed-secondary-600: var(--onyx-color-themed-primary-600);
73
+ --onyx-color-themed-secondary-700: var(--onyx-color-themed-primary-700);
74
+ --onyx-color-themed-secondary-800: var(--onyx-color-themed-primary-800);
75
+ --onyx-color-themed-secondary-900: var(--onyx-color-themed-primary-900);
76
+ --onyx-color-themed-secondary-1000: var(--onyx-color-themed-primary-1000);
77
+ --onyx-color-themed-secondary-1100: var(--onyx-color-themed-primary-1100);
78
+ --onyx-color-themed-secondary-1200: var(--onyx-color-themed-primary-1200);
79
+ --onyx-color-universal-grayscale-black: #000000;
80
+ --onyx-color-universal-grayscale-white: #ffffff;
81
+ --onyx-color-universal-green-100: #ecf8f2;
82
+ --onyx-color-universal-green-200: #c6e4d5;
83
+ --onyx-color-universal-green-300: #98d1b3;
84
+ --onyx-color-universal-green-400: #6ebe94;
85
+ --onyx-color-universal-green-500: #44aa75;
86
+ --onyx-color-universal-green-600: #3b9b69;
87
+ --onyx-color-universal-green-700: #328c5e;
88
+ --onyx-color-universal-green-800: #297d52;
89
+ --onyx-color-universal-green-900: #216d46;
90
+ --onyx-color-universal-green-1000: #185e3a;
91
+ --onyx-color-universal-green-1100: #064023;
92
+ --onyx-color-universal-green-1200: #064023;
93
+ --onyx-color-universal-orange-100: #faf6f2;
94
+ --onyx-color-universal-orange-200: #f8e7d8;
95
+ --onyx-color-universal-orange-300: #f6d1b1;
96
+ --onyx-color-universal-orange-400: #f4b57e;
97
+ --onyx-color-universal-orange-500: #f2994a;
98
+ --onyx-color-universal-orange-600: #d98841;
99
+ --onyx-color-universal-orange-700: #bf7737;
100
+ --onyx-color-universal-orange-800: #a6662e;
101
+ --onyx-color-universal-orange-900: #8c5625;
102
+ --onyx-color-universal-orange-1000: #73451c;
103
+ --onyx-color-universal-orange-1100: #593412;
104
+ --onyx-color-universal-orange-1200: #402309;
105
+ --onyx-color-universal-purple-100: #f4f1f8;
106
+ --onyx-color-universal-purple-200: #dbcfea;
107
+ --onyx-color-universal-purple-300: #c2addc;
108
+ --onyx-color-universal-purple-400: #a98ace;
109
+ --onyx-color-universal-purple-500: #9068c0;
110
+ --onyx-color-universal-purple-600: #805aae;
111
+ --onyx-color-universal-purple-700: #704c9b;
112
+ --onyx-color-universal-purple-800: #603e89;
113
+ --onyx-color-universal-purple-900: #513077;
114
+ --onyx-color-universal-purple-1000: #412265;
115
+ --onyx-color-universal-purple-1100: #311452;
116
+ --onyx-color-universal-purple-1200: #210640;
117
+ --onyx-color-universal-quantitatives-100: #005795;
118
+ --onyx-color-universal-quantitatives-200: #ff8a25;
119
+ --onyx-color-universal-quantitatives-300: #e51718;
120
+ --onyx-color-universal-quantitatives-400: #36b16b;
121
+ --onyx-color-universal-quantitatives-500: #56d8fc;
122
+ --onyx-color-universal-quantitatives-600: #ff9990;
123
+ --onyx-color-universal-quantitatives-700: #ff3fd1;
124
+ --onyx-color-universal-quantitatives-800: #3c6475;
125
+ --onyx-color-universal-quantitatives-900: #c4bc81;
126
+ --onyx-color-universal-quantitatives-1000: #c3143f;
127
+ --onyx-color-universal-quantitatives-1100: #a09dfa;
128
+ --onyx-color-universal-quantitatives-1200: #00bcc6;
129
+ --onyx-color-universal-red-100: #fbefee;
130
+ --onyx-color-universal-red-200: #f1d2d1;
131
+ --onyx-color-universal-red-300: #e6a7a5;
132
+ --onyx-color-universal-red-400: #dc716e;
133
+ --onyx-color-universal-red-500: #d1332f;
134
+ --onyx-color-universal-red-600: #bc2d2a;
135
+ --onyx-color-universal-red-700: #a82824;
136
+ --onyx-color-universal-red-800: #93221f;
137
+ --onyx-color-universal-red-900: #7e1d19;
138
+ --onyx-color-universal-red-1000: #691714;
139
+ --onyx-color-universal-red-1100: #400c09;
140
+ --onyx-color-universal-red-1200: #400c09;
141
+ --onyx-number-radius-100: 0.125rem;
142
+ --onyx-number-radius-200: 0.25rem;
143
+ --onyx-number-radius-300: 0.5rem;
144
+ --onyx-number-radius-400: 1rem;
145
+ --onyx-number-radius-500: 2rem;
146
+ --onyx-number-radius-600: 62.5rem;
147
+ --onyx-number-spacing-0: 0rem;
148
+ --onyx-number-spacing-100: 0.125rem;
149
+ --onyx-number-spacing-200: 0.25rem;
150
+ --onyx-number-spacing-250: 0.375rem;
151
+ --onyx-number-spacing-300: 0.5rem;
152
+ --onyx-number-spacing-325: 0.625rem;
153
+ --onyx-number-spacing-350: 0.75rem;
154
+ --onyx-number-spacing-400: 1rem;
155
+ --onyx-number-spacing-500: 1.5rem;
156
+ --onyx-number-spacing-600: 2rem;
157
+ --onyx-number-spacing-700: 3rem;
158
+ --onyx-number-spacing-800: 4rem;
159
+ --onyx-number-spacing-900: 6rem;
160
+ --onyx-number-spacing-950: 8rem;
161
+ }