diff --git a/.github/workflows/wac/utils/listPackagesWithJestTests.ts b/.github/workflows/wac/utils/listPackagesWithJestTests.ts index 6ec12ccb331..c106d79a431 100644 --- a/.github/workflows/wac/utils/listPackagesWithJestTests.ts +++ b/.github/workflows/wac/utils/listPackagesWithJestTests.ts @@ -266,6 +266,13 @@ const CUSTOM_HANDLERS: Record Array> = { } ]; }, + "admin-ui": () => { + return [ + { + cmd: "packages/admin-ui" + } + ]; + }, migrations: () => { return [ { diff --git a/.gitignore b/.gitignore index 1cc0254c336..fe6ab61fd50 100644 --- a/.gitignore +++ b/.gitignore @@ -47,8 +47,7 @@ schema.graphql .pnp.* lerna.json .stormTests - -# TODO remove after moving traffic splitting config to WPC -gateway.*.json - +*storybook.log +.normalizedFigmaExport.json +.normalizedPrimitivesFigmaExport.json packages/tasks/tpl/* diff --git a/.prettierignore b/.prettierignore index 9e095ed2163..d30d1abb9f3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,6 +9,7 @@ .webiny/** packages/ui/src/RichTextEditor/editorjs/** packages/cli-plugin-deploy-pulumi/src/commands/newWatch/handler/mqtt.js +packages/admin-ui/scripts/importFromFigma/exports/Alias tokens.json packages/cli-plugin-scaffold-ci/src/githubActions/files/workflows/ lerna.json coverage/** diff --git a/apps/admin/src/App.scss b/apps/admin/src/App.scss index 54439b54975..4deec2d55a1 100644 --- a/apps/admin/src/App.scss +++ b/apps/admin/src/App.scss @@ -1,16 +1,2 @@ -// Webiny theme variables -// $webiny-theme-light-primary: #fa5723; -// $webiny-theme-light-secondary: #00ccb0; -// $webiny-theme-light-background: #f2f2f2; -// $webiny-theme-light-surface: #fff; -// $webiny-theme-light-on-primary: #ffffff; -// $webiny-theme-light-on-secondary: #ffffff; -// $webiny-theme-light-on-surface: #000000; -// $webiny-theme-light-on-background: rgba(212, 212, 212, 0.5); -// $webiny-theme-light-text-primary-on-background: rgba(0, 0, 0, 0.87); -// $webiny-theme-light-text-secondary-on-background: rgba(0, 0, 0, 0.54); -// $webiny-theme-light-text-hint-on-dark: rgba(255, 255, 255, 0.5); -// $webiny-theme-typography-font-family: "Source Sans Pro"; - // Import main styles @import "~@webiny/app-serverless-cms/styles.scss"; diff --git a/apps/api/graphql/src/index.ts b/apps/api/graphql/src/index.ts index 33b5483bc5c..bf8db7d48bc 100644 --- a/apps/api/graphql/src/index.ts +++ b/apps/api/graphql/src/index.ts @@ -107,7 +107,9 @@ export const handler = createHandler({ createApwPageBuilderContext({ storageOperations: createApwSaStorageOperations({ documentClient }) }), - createAco(), + createAco({ + documentClient + }), createAcoPageBuilderContext(), createAcoHcmsContext(), createHcmsTasks(), diff --git a/apps/core/dynamoToElastic/src/index.ts b/apps/core/dynamoToElastic/src/index.ts index f03e43ec6f3..d73b3276068 100644 --- a/apps/core/dynamoToElastic/src/index.ts +++ b/apps/core/dynamoToElastic/src/index.ts @@ -1,6 +1,5 @@ import { createHandler } from "@webiny/handler-aws/raw"; import elasticsearchClientContextPlugin from "@webiny/api-elasticsearch"; -import elasticsearchDataGzipCompression from "@webiny/api-elasticsearch/plugins/GzipCompression"; import { createEventHandler as createDynamoDBEventHandler } from "@webiny/api-dynamodb-to-elasticsearch"; export const handler = createHandler({ @@ -8,7 +7,6 @@ export const handler = createHandler({ elasticsearchClientContextPlugin({ endpoint: `https://${process.env.ELASTIC_SEARCH_ENDPOINT}` }), - elasticsearchDataGzipCompression(), createDynamoDBEventHandler() ] }); diff --git a/package.json b/package.json index d2caae2481f..c443c839e65 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@babel/preset-react": "^7.26.3", "@babel/preset-typescript": "^7.26.0", "@babel/register": "^7.25.9", - "@babel/runtime": "7.26.7", + "@babel/runtime": "7.26.10", "@babel/template": "^7.25.9", "@babel/traverse": "7.26.7", "@babel/types": "7.26.7", @@ -171,6 +171,7 @@ "webiny-versions": "node ./scripts/webinyVersions.js", "trigger-release": "node ./scripts/release/triggerRelease.js", "dispatch-github-event": "node ./scripts/dispatchGitHubEvent.js", + "link-workspaces": "node ./scripts/linkWorkspaces.js", "lint-staged": "lint-staged", "postinstall": "yarn node ./scripts/linkWorkspaces.js", "prepublishOnly": "node scripts/prepublishOnly", @@ -194,7 +195,10 @@ "system:verify": "yarn eslint && yarn prettier:check && yarn adio && yarn check-ts-configs && yarn webiny verify-dependencies", "system:build": "yarn && yarn ghawac build && yarn webiny sync-dependencies && yarn build", "wby": "./node_modules/.bin/wby", - "webiny-ui-build-storybook": "cd packages/ui && cross-env OUT=../../netlify-static yarn build-storybook" + "webiny-admin-storybook": "cd packages/admin-ui && yarn storybook", + "webiny-admin-storybook-docs": "cd packages/admin-ui && yarn storybook-docs", + "webiny-admin-build-storybook": "cd packages/admin-ui && cross-env OUT=../../netlify-static yarn build-storybook", + "webiny-admin-import-from-figma": "node packages/admin-ui/scripts/importFromFigma.js" }, "husky": { "hooks": { @@ -246,7 +250,7 @@ ] }, "resolutions": { - "@babel/runtime": "^7.26.0", + "@babel/runtime": "7.26.10", "systeminformation": "^5.23.18", "@emotion/react": "11.10.8", "@octokit/rest": "^20.0.2", diff --git a/packages/app-admin-rmwc/.babelrc.js b/packages/admin-ui/.babelrc.js similarity index 100% rename from packages/app-admin-rmwc/.babelrc.js rename to packages/admin-ui/.babelrc.js diff --git a/packages/admin-ui/.storybook/main.ts b/packages/admin-ui/.storybook/main.ts new file mode 100644 index 00000000000..8090aabb88e --- /dev/null +++ b/packages/admin-ui/.storybook/main.ts @@ -0,0 +1,118 @@ +import type { StorybookConfig } from "@storybook/react-webpack5"; +import path from "path"; +import tailwindcss from "tailwindcss"; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value: string): any { + return path.dirname(require.resolve(path.join(value, "package.json"))); +} + +const config: StorybookConfig = { + stories: [ + "../docs/stories/**/*.mdx", + "../src/**/*.mdx", + "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)" + ], + staticDirs: ["../assets"], + addons: [ + getAbsolutePath("@storybook/addon-a11y"), + { + name: "@storybook/addon-essentials", + options: { + controls: true, + code: true + } + } + ], + framework: { + name: getAbsolutePath("@storybook/react-webpack5"), + options: {} + }, + core: { + disableTelemetry: true, + disableWhatsNewNotifications: true + }, + webpackFinal: async config => { + config.resolve = config.resolve || {}; + config.resolve.alias = { + ...config.resolve.alias, + "~": path.resolve(__dirname, "../src") + }; + + // Add custom style handling + config.module?.rules?.push({ + test: /\.s[ac]ss$/i, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 1 + } + }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: [ + tailwindcss({ + config: path.join(__dirname, "../tailwind.config.js") + }) + ] + } + } + }, + { + loader: "sass-loader", + options: { implementation: require.resolve("sass") } + } + ] + }); + + // Add SVG handling + const svgRule = config.module?.rules?.find(rule => { + const test = (rule as { test: RegExp }).test; + return test ? test.test(".svg") : false; + }) as { [key: string]: any }; + + if (svgRule) { + svgRule.exclude = /\.svg$/; + } + + config.module?.rules?.push({ + test: /\.svg$/i, + use: [ + { + loader: "@svgr/webpack", + options: { + svgoConfig: { + plugins: [ + { + name: "preset-default", + params: { + overrides: { + removeViewBox: false + } + } + } + ] + } + } + }, + { + loader: "file-loader", + options: { + name: "[name].[hash].[ext]" + } + } + ] + }); + + return config; + } +}; + +export default config; diff --git a/packages/admin-ui/.storybook/preview.ts b/packages/admin-ui/.storybook/preview.ts new file mode 100644 index 00000000000..0dd3314486b --- /dev/null +++ b/packages/admin-ui/.storybook/preview.ts @@ -0,0 +1,12 @@ +import type { Preview } from "@storybook/react"; + +import "../src/theme.scss"; + +const preview: Preview = { + parameters: { + layout: "centered", + docs: { toc: { headingSelector: "h2, h3, h4" } } + } +}; + +export default preview; diff --git a/packages/admin-ui/DEVELOPMENT.md b/packages/admin-ui/DEVELOPMENT.md new file mode 100644 index 00000000000..a73b4ce749b --- /dev/null +++ b/packages/admin-ui/DEVELOPMENT.md @@ -0,0 +1,31 @@ +# Overview +This document covers different aspects of the development process for the `@webiny/admin-ui` package. + +## Tailwind CSS +Webiny's Admin app uses Tailwind CSS for styling. + +### Tailwind Configuration +Tailwind CSS is configured as usual, via the [`tailwind.config.js`](./tailwind.config.js) file. Among other things, this file defines the default Webiny theme, which is based on Webiny's design system. More on this in the next section. + +### Default Theme +One of the main things we define via the [`tailwind.config.js`](./tailwind.config.js) file is the default theme, which is based on Webiny's design system, and which can be found in this [Figma file](https://www.figma.com/file/f0QUDWX37Kt5X53eltTRiT/Webiny-Design-System?type=design&node-id=127-26352&mode=design&t=nhoOU7NamjWvImoW-0). + +But, do note that all the default theme-values are not actually defined in the `tailwind.config.js` file, but rather in the `tailwind.config.theme.js` file, which is a file that is generated from a Figma export (more on this in the next section). + +### Figma To Code +Since manually transferring values from the mentioned Figma file into code has shown to be a very cumbersome process, we've created a script that basically takes a Figma export and generates all the necessary Tailwind CSS configuration. + +When we say "Figma export", we basically mean exports of (1) Primitives and (2) Alias tokens, which are created by this [Export/Import Variables](https://www.figma.com/community/plugin/1256972111705530093/export-import-variables) plugin. + +The exports need to be downloaded and place into the `packages/admin-ui/scripts/importFromFigma/exports` folder. Ultimately, we should end up with the following two: + +1. `packages/admin-ui/scripts/importFromFigma/exports/Alias tokens.json` +2. `packages/admin-ui/scripts/importFromFigma/exports/Primitives.json` + +Finally, from project root, we run the following script: + +```bash +yarn webiny-admin-import-from-figma +``` + +First, the script will regenerate the `tailwind.config.theme.js` file, which will contain all the necessary Tailwind CSS configuration. Second, it will also regenerate the `src/styles.scss` file, which contains actual values for CSS variables that are referenced in the `tailwind.config.theme.js` file. diff --git a/packages/app-admin-rmwc/LICENSE b/packages/admin-ui/LICENSE similarity index 100% rename from packages/app-admin-rmwc/LICENSE rename to packages/admin-ui/LICENSE diff --git a/packages/admin-ui/README.md b/packages/admin-ui/README.md new file mode 100644 index 00000000000..ffaaf1585dc --- /dev/null +++ b/packages/admin-ui/README.md @@ -0,0 +1,6 @@ +# `@webiny/admin-ui` + +This package contains React components and styles for Webiny's Admin app. + +> [!NOTE] +> This package is included in every Webiny project by default, and it's not meant to be used as a standalone package. diff --git a/packages/admin-ui/assets/images/design-system-cover.png b/packages/admin-ui/assets/images/design-system-cover.png new file mode 100644 index 00000000000..6c2f960effc Binary files /dev/null and b/packages/admin-ui/assets/images/design-system-cover.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/examples.png b/packages/admin-ui/assets/images/storybook/alert/examples.png new file mode 100644 index 00000000000..f7259812a34 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/examples.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/floating-element.png b/packages/admin-ui/assets/images/storybook/alert/floating-element.png new file mode 100644 index 00000000000..8a8f3551cfc Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/floating-element.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/full-width-banner.png b/packages/admin-ui/assets/images/storybook/alert/full-width-banner.png new file mode 100644 index 00000000000..ae41f487a9b Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/full-width-banner.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/nested-element.png b/packages/admin-ui/assets/images/storybook/alert/nested-element.png new file mode 100644 index 00000000000..1fac4b70c96 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/nested-element.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/options.png b/packages/admin-ui/assets/images/storybook/alert/options.png new file mode 100644 index 00000000000..d3d9198aabf Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/options.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/style.png b/packages/admin-ui/assets/images/storybook/alert/style.png new file mode 100644 index 00000000000..10327613dba Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/style.png differ diff --git a/packages/admin-ui/assets/images/storybook/alert/type.png b/packages/admin-ui/assets/images/storybook/alert/type.png new file mode 100644 index 00000000000..be7772ce88c Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/alert/type.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/field-size.png b/packages/admin-ui/assets/images/storybook/autocomplete/field-size.png new file mode 100644 index 00000000000..eec94755717 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/field-size.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/input-anatomy.png b/packages/admin-ui/assets/images/storybook/autocomplete/input-anatomy.png new file mode 100644 index 00000000000..3a208243219 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/input-anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/label-anatomy.png b/packages/admin-ui/assets/images/storybook/autocomplete/label-anatomy.png new file mode 100644 index 00000000000..f329582e155 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/label-anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/label-options.png b/packages/admin-ui/assets/images/storybook/autocomplete/label-options.png new file mode 100644 index 00000000000..aea0aad98a2 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/label-options.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/label-properties.png b/packages/admin-ui/assets/images/storybook/autocomplete/label-properties.png new file mode 100644 index 00000000000..284f4feb077 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/label-properties.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/option.png b/packages/admin-ui/assets/images/storybook/autocomplete/option.png new file mode 100644 index 00000000000..ac8361e84a5 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/option.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/states-and-styles.png b/packages/admin-ui/assets/images/storybook/autocomplete/states-and-styles.png new file mode 100644 index 00000000000..db05b38ed52 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/states-and-styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/style.png b/packages/admin-ui/assets/images/storybook/autocomplete/style.png new file mode 100644 index 00000000000..69a41e160d7 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/style.png differ diff --git a/packages/admin-ui/assets/images/storybook/autocomplete/used-in-forms.png b/packages/admin-ui/assets/images/storybook/autocomplete/used-in-forms.png new file mode 100644 index 00000000000..2a636abfe76 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/autocomplete/used-in-forms.png differ diff --git a/packages/admin-ui/assets/images/storybook/avatar/header.png b/packages/admin-ui/assets/images/storybook/avatar/header.png new file mode 100644 index 00000000000..9ea02477dd2 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/avatar/header.png differ diff --git a/packages/admin-ui/assets/images/storybook/avatar/size.png b/packages/admin-ui/assets/images/storybook/avatar/size.png new file mode 100644 index 00000000000..b22e36d712b Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/avatar/size.png differ diff --git a/packages/admin-ui/assets/images/storybook/avatar/style.png b/packages/admin-ui/assets/images/storybook/avatar/style.png new file mode 100644 index 00000000000..9ca1141f8f8 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/avatar/style.png differ diff --git a/packages/admin-ui/assets/images/storybook/avatar/table.png b/packages/admin-ui/assets/images/storybook/avatar/table.png new file mode 100644 index 00000000000..4af80bebda9 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/avatar/table.png differ diff --git a/packages/admin-ui/assets/images/storybook/avatar/type.png b/packages/admin-ui/assets/images/storybook/avatar/type.png new file mode 100644 index 00000000000..5faa684b4bb Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/avatar/type.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/button-group.png b/packages/admin-ui/assets/images/storybook/button/button-group.png new file mode 100644 index 00000000000..3cf8fdaa38f Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/button-group.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/contruction.png b/packages/admin-ui/assets/images/storybook/button/contruction.png new file mode 100644 index 00000000000..00d29cc0324 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/contruction.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/icon-usage.png b/packages/admin-ui/assets/images/storybook/button/icon-usage.png new file mode 100644 index 00000000000..d991420489f Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/icon-usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/options.png b/packages/admin-ui/assets/images/storybook/button/options.png new file mode 100644 index 00000000000..b520db65f96 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/options.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/primary-button-usage.png b/packages/admin-ui/assets/images/storybook/button/primary-button-usage.png new file mode 100644 index 00000000000..cf2b92f4b3a Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/primary-button-usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/size-icon-only.png b/packages/admin-ui/assets/images/storybook/button/size-icon-only.png new file mode 100644 index 00000000000..714f8f4ca12 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/size-icon-only.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/size.png b/packages/admin-ui/assets/images/storybook/button/size.png new file mode 100644 index 00000000000..3bfa15b20d1 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/size.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/states.png b/packages/admin-ui/assets/images/storybook/button/states.png new file mode 100644 index 00000000000..877d850d60c Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/states.png differ diff --git a/packages/admin-ui/assets/images/storybook/button/type.png b/packages/admin-ui/assets/images/storybook/button/type.png new file mode 100644 index 00000000000..98b1e908c00 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/button/type.png differ diff --git a/packages/admin-ui/assets/images/storybook/card/construction.png b/packages/admin-ui/assets/images/storybook/card/construction.png new file mode 100644 index 00000000000..2a4a78493fd Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/card/construction.png differ diff --git a/packages/admin-ui/assets/images/storybook/card/elevation.png b/packages/admin-ui/assets/images/storybook/card/elevation.png new file mode 100644 index 00000000000..e2b6ea8fe39 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/card/elevation.png differ diff --git a/packages/admin-ui/assets/images/storybook/card/padding.png b/packages/admin-ui/assets/images/storybook/card/padding.png new file mode 100644 index 00000000000..dd9e491decf Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/card/padding.png differ diff --git a/packages/admin-ui/assets/images/storybook/card/radius.png b/packages/admin-ui/assets/images/storybook/card/radius.png new file mode 100644 index 00000000000..c496289f232 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/card/radius.png differ diff --git a/packages/admin-ui/assets/images/storybook/card/stacked.png b/packages/admin-ui/assets/images/storybook/card/stacked.png new file mode 100644 index 00000000000..517b30569a0 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/card/stacked.png differ diff --git a/packages/admin-ui/assets/images/storybook/checkbox-group/general.png b/packages/admin-ui/assets/images/storybook/checkbox-group/general.png new file mode 100644 index 00000000000..079df4de469 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/checkbox-group/general.png differ diff --git a/packages/admin-ui/assets/images/storybook/checkbox/checkbox-input-options.png b/packages/admin-ui/assets/images/storybook/checkbox/checkbox-input-options.png new file mode 100644 index 00000000000..90fdfa923cf Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/checkbox/checkbox-input-options.png differ diff --git a/packages/admin-ui/assets/images/storybook/checkbox/general.png b/packages/admin-ui/assets/images/storybook/checkbox/general.png new file mode 100644 index 00000000000..079df4de469 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/checkbox/general.png differ diff --git a/packages/admin-ui/assets/images/storybook/checkbox/states.png b/packages/admin-ui/assets/images/storybook/checkbox/states.png new file mode 100644 index 00000000000..c756f30b185 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/checkbox/states.png differ diff --git a/packages/admin-ui/assets/images/storybook/checkbox/text-overflow.png b/packages/admin-ui/assets/images/storybook/checkbox/text-overflow.png new file mode 100644 index 00000000000..16a43ce5d7e Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/checkbox/text-overflow.png differ diff --git a/packages/admin-ui/assets/images/storybook/dialog/anatomy.png b/packages/admin-ui/assets/images/storybook/dialog/anatomy.png new file mode 100644 index 00000000000..298fc189c50 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/dialog/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/dialog/overlay-and-positioning.png b/packages/admin-ui/assets/images/storybook/dialog/overlay-and-positioning.png new file mode 100644 index 00000000000..89e6a8d2f38 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/dialog/overlay-and-positioning.png differ diff --git a/packages/admin-ui/assets/images/storybook/dialog/usage.png b/packages/admin-ui/assets/images/storybook/dialog/usage.png new file mode 100644 index 00000000000..d19a2210d78 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/dialog/usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/drawer/anatomy.png b/packages/admin-ui/assets/images/storybook/drawer/anatomy.png new file mode 100644 index 00000000000..8855503100e Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/drawer/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/drawer/dividers.png b/packages/admin-ui/assets/images/storybook/drawer/dividers.png new file mode 100644 index 00000000000..e295c4ef3fe Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/drawer/dividers.png differ diff --git a/packages/admin-ui/assets/images/storybook/drawer/header.png b/packages/admin-ui/assets/images/storybook/drawer/header.png new file mode 100644 index 00000000000..d117a0c1400 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/drawer/header.png differ diff --git a/packages/admin-ui/assets/images/storybook/drawer/positioning.png b/packages/admin-ui/assets/images/storybook/drawer/positioning.png new file mode 100644 index 00000000000..0f9c98f7e13 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/drawer/positioning.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/breakpoints.png b/packages/admin-ui/assets/images/storybook/grid/breakpoints.png new file mode 100644 index 00000000000..1e860281501 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/breakpoints.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/column-offsets.png b/packages/admin-ui/assets/images/storybook/grid/column-offsets.png new file mode 100644 index 00000000000..773f38b9183 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/column-offsets.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/column-spans.png b/packages/admin-ui/assets/images/storybook/grid/column-spans.png new file mode 100644 index 00000000000..4258b5baa7e Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/column-spans.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/fixed-dashboard.png b/packages/admin-ui/assets/images/storybook/grid/fixed-dashboard.png new file mode 100644 index 00000000000..70f36c35855 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/fixed-dashboard.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/fixed.png b/packages/admin-ui/assets/images/storybook/grid/fixed.png new file mode 100644 index 00000000000..73e8f87a762 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/fixed.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/fluid-dashboard.png b/packages/admin-ui/assets/images/storybook/grid/fluid-dashboard.png new file mode 100644 index 00000000000..bcdc5cc93ee Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/fluid-dashboard.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/fluid.png b/packages/admin-ui/assets/images/storybook/grid/fluid.png new file mode 100644 index 00000000000..eb92a242c11 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/fluid.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-comfortable.png b/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-comfortable.png new file mode 100644 index 00000000000..05552bd2bab Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-comfortable.png differ diff --git a/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-spacious.png b/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-spacious.png new file mode 100644 index 00000000000..7261808e45f Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/grid/grid-gutter-size-spacious.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/anatomy.png b/packages/admin-ui/assets/images/storybook/input/anatomy.png new file mode 100644 index 00000000000..6f77adc3788 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/field-size.png b/packages/admin-ui/assets/images/storybook/input/field-size.png new file mode 100644 index 00000000000..07ba7e57706 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/field-size.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/label-anatomy.png b/packages/admin-ui/assets/images/storybook/input/label-anatomy.png new file mode 100644 index 00000000000..d4a13499c95 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/label-anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/label-options.png b/packages/admin-ui/assets/images/storybook/input/label-options.png new file mode 100644 index 00000000000..4b9ccfd09be Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/label-options.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/label-properties.png b/packages/admin-ui/assets/images/storybook/input/label-properties.png new file mode 100644 index 00000000000..08f8dfaa87c Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/label-properties.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/states-and-styles.png b/packages/admin-ui/assets/images/storybook/input/states-and-styles.png new file mode 100644 index 00000000000..c85e5318ac5 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/states-and-styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/styles.png b/packages/admin-ui/assets/images/storybook/input/styles.png new file mode 100644 index 00000000000..b5273deb00a Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/input/used-in-forms.png b/packages/admin-ui/assets/images/storybook/input/used-in-forms.png new file mode 100644 index 00000000000..00a851b9eba Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/input/used-in-forms.png differ diff --git a/packages/admin-ui/assets/images/storybook/link/primary.png b/packages/admin-ui/assets/images/storybook/link/primary.png new file mode 100644 index 00000000000..7c0fc2dacf8 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/link/primary.png differ diff --git a/packages/admin-ui/assets/images/storybook/link/secondary.png b/packages/admin-ui/assets/images/storybook/link/secondary.png new file mode 100644 index 00000000000..45241e7ea0f Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/link/secondary.png differ diff --git a/packages/admin-ui/assets/images/storybook/link/sizing.png b/packages/admin-ui/assets/images/storybook/link/sizing.png new file mode 100644 index 00000000000..032c65e59b1 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/link/sizing.png differ diff --git a/packages/admin-ui/assets/images/storybook/link/states.png b/packages/admin-ui/assets/images/storybook/link/states.png new file mode 100644 index 00000000000..c4d7d6aa9cc Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/link/states.png differ diff --git a/packages/admin-ui/assets/images/storybook/link/usage.png b/packages/admin-ui/assets/images/storybook/link/usage.png new file mode 100644 index 00000000000..03331a3083b Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/link/usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/background-overlay.png b/packages/admin-ui/assets/images/storybook/loader/background-overlay.png new file mode 100644 index 00000000000..e1fe6d06ca9 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/background-overlay.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/construction.png b/packages/admin-ui/assets/images/storybook/loader/construction.png new file mode 100644 index 00000000000..f45ec1de2bb Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/construction.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/size.png b/packages/admin-ui/assets/images/storybook/loader/size.png new file mode 100644 index 00000000000..c53e4d9bfae Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/size.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/style.png b/packages/admin-ui/assets/images/storybook/loader/style.png new file mode 100644 index 00000000000..821e6dd1936 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/style.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/type.png b/packages/admin-ui/assets/images/storybook/loader/type.png new file mode 100644 index 00000000000..57eb1ea488c Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/type.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/usage-1.png b/packages/admin-ui/assets/images/storybook/loader/usage-1.png new file mode 100644 index 00000000000..cb474cfc5e8 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/usage-1.png differ diff --git a/packages/admin-ui/assets/images/storybook/loader/usage-2.png b/packages/admin-ui/assets/images/storybook/loader/usage-2.png new file mode 100644 index 00000000000..6e005db8116 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/loader/usage-2.png differ diff --git a/packages/admin-ui/assets/images/storybook/radio-group/anatomy.png b/packages/admin-ui/assets/images/storybook/radio-group/anatomy.png new file mode 100644 index 00000000000..c41104ead42 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/radio-group/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/radio-group/options.png b/packages/admin-ui/assets/images/storybook/radio-group/options.png new file mode 100644 index 00000000000..dfa594fea5d Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/radio-group/options.png differ diff --git a/packages/admin-ui/assets/images/storybook/radio-group/states.png b/packages/admin-ui/assets/images/storybook/radio-group/states.png new file mode 100644 index 00000000000..275b8d4b9ea Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/radio-group/states.png differ diff --git a/packages/admin-ui/assets/images/storybook/radio-group/text-overflow.png b/packages/admin-ui/assets/images/storybook/radio-group/text-overflow.png new file mode 100644 index 00000000000..1c783dd9cba Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/radio-group/text-overflow.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/anatomy.png b/packages/admin-ui/assets/images/storybook/select/anatomy.png new file mode 100644 index 00000000000..1021e08266a Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/label-anatomy.png b/packages/admin-ui/assets/images/storybook/select/label-anatomy.png new file mode 100644 index 00000000000..bd1777e07e4 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/label-anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/label-options.png b/packages/admin-ui/assets/images/storybook/select/label-options.png new file mode 100644 index 00000000000..4872dd4fe14 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/label-options.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/label-properties.png b/packages/admin-ui/assets/images/storybook/select/label-properties.png new file mode 100644 index 00000000000..a7d79d73329 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/label-properties.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/options.png b/packages/admin-ui/assets/images/storybook/select/options.png new file mode 100644 index 00000000000..4752e02a33d Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/options.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/states-and-styles.png b/packages/admin-ui/assets/images/storybook/select/states-and-styles.png new file mode 100644 index 00000000000..6d773452150 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/states-and-styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/styles.png b/packages/admin-ui/assets/images/storybook/select/styles.png new file mode 100644 index 00000000000..56e7a701f32 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/select/used-in-forms.png b/packages/admin-ui/assets/images/storybook/select/used-in-forms.png new file mode 100644 index 00000000000..6c15662cc02 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/select/used-in-forms.png differ diff --git a/packages/admin-ui/assets/images/storybook/tabs/construction.png b/packages/admin-ui/assets/images/storybook/tabs/construction.png new file mode 100644 index 00000000000..c0ebe9a2d34 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tabs/construction.png differ diff --git a/packages/admin-ui/assets/images/storybook/tabs/size-and-states.png b/packages/admin-ui/assets/images/storybook/tabs/size-and-states.png new file mode 100644 index 00000000000..dd5897d5b59 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tabs/size-and-states.png differ diff --git a/packages/admin-ui/assets/images/storybook/tabs/tab-group.png b/packages/admin-ui/assets/images/storybook/tabs/tab-group.png new file mode 100644 index 00000000000..ddc54cd68bc Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tabs/tab-group.png differ diff --git a/packages/admin-ui/assets/images/storybook/tabs/usage.png b/packages/admin-ui/assets/images/storybook/tabs/usage.png new file mode 100644 index 00000000000..faca6f0328e Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tabs/usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/tag/construction.png b/packages/admin-ui/assets/images/storybook/tag/construction.png new file mode 100644 index 00000000000..6d0e1d602de Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tag/construction.png differ diff --git a/packages/admin-ui/assets/images/storybook/tag/states.png b/packages/admin-ui/assets/images/storybook/tag/states.png new file mode 100644 index 00000000000..eba452dceca Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tag/states.png differ diff --git a/packages/admin-ui/assets/images/storybook/tag/style.png b/packages/admin-ui/assets/images/storybook/tag/style.png new file mode 100644 index 00000000000..29458b4fd85 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tag/style.png differ diff --git a/packages/admin-ui/assets/images/storybook/tag/usage.png b/packages/admin-ui/assets/images/storybook/tag/usage.png new file mode 100644 index 00000000000..26c61187df0 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/tag/usage.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/anatomy.png b/packages/admin-ui/assets/images/storybook/textarea/anatomy.png new file mode 100644 index 00000000000..a6252083dfb Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/field-size.png b/packages/admin-ui/assets/images/storybook/textarea/field-size.png new file mode 100644 index 00000000000..31b944f8175 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/field-size.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/label-anatomy.png b/packages/admin-ui/assets/images/storybook/textarea/label-anatomy.png new file mode 100644 index 00000000000..5756e04df55 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/label-anatomy.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/label-options.png b/packages/admin-ui/assets/images/storybook/textarea/label-options.png new file mode 100644 index 00000000000..272f3aa6d70 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/label-options.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/label-properties.png b/packages/admin-ui/assets/images/storybook/textarea/label-properties.png new file mode 100644 index 00000000000..f583300c06c Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/label-properties.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/states-and-styles.png b/packages/admin-ui/assets/images/storybook/textarea/states-and-styles.png new file mode 100644 index 00000000000..20a1a2761a0 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/states-and-styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/styles.png b/packages/admin-ui/assets/images/storybook/textarea/styles.png new file mode 100644 index 00000000000..9a0c28871e0 Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/styles.png differ diff --git a/packages/admin-ui/assets/images/storybook/textarea/used-in-forms.png b/packages/admin-ui/assets/images/storybook/textarea/used-in-forms.png new file mode 100644 index 00000000000..acce6fcb69a Binary files /dev/null and b/packages/admin-ui/assets/images/storybook/textarea/used-in-forms.png differ diff --git a/packages/admin-ui/assets/images/wby-logo.png b/packages/admin-ui/assets/images/wby-logo.png new file mode 100644 index 00000000000..ee207a1d70d Binary files /dev/null and b/packages/admin-ui/assets/images/wby-logo.png differ diff --git a/packages/admin-ui/docs/stories/00-getting-started/welcome.mdx b/packages/admin-ui/docs/stories/00-getting-started/welcome.mdx new file mode 100644 index 00000000000..c8aa67f4d91 --- /dev/null +++ b/packages/admin-ui/docs/stories/00-getting-started/welcome.mdx @@ -0,0 +1,39 @@ +import { Meta } from '@storybook/blocks'; + + + + + +![Webiny Design System cover](/images/design-system-cover.png) + +# Welcome + +Welcome to the Webiny Design System, your go-to resource for creating consistent, user-friendly, and innovative interfaces across all Webiny applications. + +The Webiny Design System is a collection of UI components, guidelines, and best practices that help you build interfaces that are not only visually appealing but also highly functional and accessible. Whether you're a developer, designer, or product manager, this system provides the tools and resources you need to create exceptional user experiences. + +## What You'll Find Here + +In this documentation, you'll find the following: + +1. **Components**: A comprehensive list of UI components, each with its own documentation, usage examples, and code snippets. You'll learn how to use these components to build your interfaces, as well as how to customize them to fit your specific needs. + +2. **Guidelines**: A set of design and development guidelines that help you create consistent and accessible interfaces. These guidelines cover topics such as color, layout, and accessibility. + +3. **Best Practices**: A collection of best practices for building interfaces that are not only visually appealing but also highly functional and accessible. These best practices cover topics such as form design, button usage, and error handling. + +## How to Use This Documentation + +To get started, we recommend that you explore the different components and their documentation. Each component has its own page with usage examples, code snippets, and additional resources. + +If you're looking for something specific, you can use the search bar at the top of the page to find what you're looking for. + +## Feedback and Contributions + +We welcome feedback and contributions to the Webiny Design System. If you have questions, suggestions, or bug reports, feel free to reach out on our 👉 [community Slack](https://www.webiny.com/slack) or open an issue on our [GitHub repository](https://github.com/webiny/webiny-js). diff --git a/packages/admin-ui/jest.setup.js b/packages/admin-ui/jest.setup.js new file mode 100644 index 00000000000..cc5ac2bb64f --- /dev/null +++ b/packages/admin-ui/jest.setup.js @@ -0,0 +1,5 @@ +const base = require("../../jest.config.base"); + +module.exports = { + ...base({ path: __dirname }) +}; diff --git a/packages/admin-ui/package.json b/packages/admin-ui/package.json new file mode 100644 index 00000000000..5604ff18b5e --- /dev/null +++ b/packages/admin-ui/package.json @@ -0,0 +1,98 @@ +{ + "name": "@webiny/admin-ui", + "version": "0.0.0", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/webiny/webiny-js.git" + }, + "description": "The UI component library for Webiny's Admin app.", + "license": "MIT", + "dependencies": { + "@editorjs/editorjs": "2.26.5", + "@fortawesome/fontawesome-svg-core": "^1.3.0", + "@fortawesome/react-fontawesome": "^0.1.17", + "@radix-ui/react-accessible-icon": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-tooltip": "^1.1.8", + "@tanstack/react-table": "^8.20.6", + "@webiny/icons": "0.0.0", + "@webiny/react-composition": "0.0.0", + "@webiny/react-router": "0.0.0", + "@webiny/utils": "0.0.0", + "ace-builds": "^1.37.1", + "bytes": "^3.1.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "cmdk": "^1.0.4", + "lodash": "^4.17.21", + "mobx": "^6.9.0", + "react": "18.2.0", + "react-ace": "^13.0.0", + "react-color": "^2.19.3", + "react-custom-scrollbars": "^4.2.1", + "react-virtualized": "^9.22.5", + "sonner": "^2.0.1", + "tailwind-merge": "^2.4.0", + "tailwindcss": "^3.4.6", + "tailwindcss-animate": "^1.0.7", + "timeago-react": "^3.0.6" + }, + "devDependencies": { + "@fortawesome/free-solid-svg-icons": "^6.0.0", + "@storybook/addon-a11y": "7.6.20", + "@storybook/addon-essentials": "7.6.20", + "@storybook/react": "7.6.20", + "@storybook/react-webpack5": "7.6.20", + "@storybook/theming": "7.6.20", + "@svgr/webpack": "^6.1.1", + "@types/react": "18.2.79", + "@types/react-color": "^2.17.11", + "@types/react-custom-scrollbars": "^4.0.10", + "@types/react-virtualized": "^9.22.0", + "@webiny/cli": "0.0.0", + "@webiny/project-utils": "0.0.0", + "chalk": "^4.1.2", + "css-loader": "^6.10.0", + "file-loader": "6.2.0", + "postcss-loader": "^6.2.1", + "prettier": "^2.8.8", + "rimraf": "^6.0.1", + "sass": "1.44.0", + "storybook": "7.6.20", + "tailwindcss": "^3.4.6", + "typescript": "5.3.3" + }, + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "scripts": { + "build": "yarn webiny run build", + "watch": "yarn webiny run watch", + "storybook": "storybook dev -p 6006", + "storybook-docs": "storybook dev --docs -p 6007", + "build-storybook": "storybook build --docs" + }, + "adio": { + "ignore": { + "dependencies": [ + "react-dom" + ] + } + } +} diff --git a/packages/admin-ui/scripts/importFromFigma.js b/packages/admin-ui/scripts/importFromFigma.js new file mode 100644 index 00000000000..7725dfc7f47 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma.js @@ -0,0 +1,65 @@ +const fs = require("fs"); +const { green } = require("chalk"); +const path = require("path"); +const { normalizeFigmaExport } = require("./importFromFigma/normalizeFigmaExport"); +const { + normalizePrimitivesFigmaExport +} = require("./importFromFigma/normalizePrimitivesFigmaExport"); +const { createTailwindConfigTheme } = require("./importFromFigma/createTailwindConfigTheme"); +const { createThemeScss } = require("./importFromFigma/createThemeScss"); +const { formatCode } = require("./importFromFigma/formatCode"); + +const saveFileAndFormat = async (filePath, content) => { + fs.writeFileSync(filePath, content); + await formatCode(filePath); +}; + +(async () => { + const normalizedFigmaExport = normalizeFigmaExport(); + const normalizedPrimitivesFigmaExport = normalizePrimitivesFigmaExport(); + const tailwindConfigTheme = createTailwindConfigTheme(normalizedFigmaExport); + const stylesScss = createThemeScss(normalizedFigmaExport, normalizedPrimitivesFigmaExport); + + const paths = { + cwd: process.cwd(), + normalizedFigmaExport: path.join(__dirname, "../.normalizedFigmaExport.json"), + normalizedPrimitivesFigmaExport: path.join( + __dirname, + "../.normalizedPrimitivesFigmaExport.json" + ), + createTailwindConfigTheme: path.join(__dirname, "../tailwind.config.theme.js"), + stylesScss: path.join(__dirname, "../src/theme.scss") + }; + + console.log("Storing..."); + console.log( + `‣ normalized Figma export (${green( + path.relative(paths.cwd, paths.normalizedFigmaExport) + )}).` + ); + console.log( + `‣ Tailwind config theme (${green( + path.relative(paths.cwd, paths.createTailwindConfigTheme) + )}).` + ); + console.log(`‣ styles.scss (${green(path.relative(paths.cwd, paths.stylesScss))}).`); + + await saveFileAndFormat( + paths.normalizedFigmaExport, + JSON.stringify(normalizedFigmaExport, null, 2) + ); + + await saveFileAndFormat( + paths.normalizedPrimitivesFigmaExport, + JSON.stringify(normalizedPrimitivesFigmaExport, null, 2) + ); + + await saveFileAndFormat( + paths.createTailwindConfigTheme, + `module.exports = ${JSON.stringify(tailwindConfigTheme, null, 2)};` + ); + + await saveFileAndFormat(paths.stylesScss, stylesScss); + + console.log("Done."); +})(); diff --git a/packages/admin-ui/scripts/importFromFigma/createTailwindConfigTheme.js b/packages/admin-ui/scripts/importFromFigma/createTailwindConfigTheme.js new file mode 100644 index 00000000000..9405f80423b --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/createTailwindConfigTheme.js @@ -0,0 +1,249 @@ +const { DEFAULTS } = require("./defaults"); + +// We don't need tokens that end with `-a{one or two numbers}` because they are used for +// alpha colors. We don't need these because we can use the /alpha function in Tailwind CSS. +const isColorWithAlpha = variantName => { + return variantName.match(/^.*-a\d{1,2}$/); +}; + +const createTailwindConfigTheme = normalizedFigmaExport => { + return { + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + "collapsible-down": "collapsible-down 0.2s ease-out", + "collapsible-up": "collapsible-up 0.2s ease-out", + "skeleton-pulse": "skeleton-pulse 1400ms ease-in-out infinite" + }, + backgroundColor: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "backgroundColor") { + if (isColorWithAlpha(variantName)) { + return acc; + } + + const [, color, variant] = variantName.match("(.*?)-(.*)"); + + if (!acc[color]) { + acc[color] = { + DEFAULT: `hsl(var(--bg-${color}-default))` + }; + } + + acc[color][variant] = `hsl(var(--bg-${variantName}))`; + } + return acc; + }, + { ...DEFAULTS.COLORS } + ), + borderColor: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "borderColor") { + const [color, ...variantParts] = variantName.split("-"); + const variantKey = variantParts.join("-") || "DEFAULT"; + + if (!acc[color]) { + acc[color] = { + DEFAULT: `hsl(var(--border-${color}-default))` + }; + } + + acc[color][variantKey] = `hsl(var(--border-${variantName}))`; + } + return acc; + }, + { ...DEFAULTS.COLORS } + ), + borderRadius: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "borderRadius") { + acc[variantName] = `var(--radius-${variantName})`; + } + return acc; + }, {}), + borderWidth: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "borderWidth") { + acc[variantName] = `var(--border-width-${variantName})`; + } + return acc; + }, {}), + fill: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "fill") { + if (isColorWithAlpha(variantName)) { + return acc; + } + const [color, variant] = variantName.split("-"); + if (!acc[color]) { + acc[color] = { + DEFAULT: `hsl(var(--fill-${color}))` + }; + } + + // `variant || color` was needed because we have some colors that don't have variants. + // Like, `destructive` only has `destructive` variant. No `muted`, `strong`, etc. + acc[color][variant || color] = `hsl(var(--fill-${variantName}))`; + } + return acc; + }, + { ...DEFAULTS.COLORS } + ), + fontSize: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "textFont") { + if (!variantName.startsWith("font-size-")) { + return acc; + } + + const size = variantName.replace("font-size-", ""); + acc[size] = [ + `var(--text-${size})`, + { + lineHeight: `var(--text-${size}-leading)`, + letterSpacing: `var(--text-${size}-tracking)` + } + ]; + + return acc; + } + + return acc; + }, + // On top of what will be imported from Figma, we also add the default heading sizes. + [1, 2, 3, 4, 5, 6].reduce((acc, lvl) => { + acc[`h${lvl}`] = [ + `var(--text-h${lvl})`, + { + lineHeight: `var(--text-h${lvl}-leading)`, + letterSpacing: `var(--text-h${lvl}-tracking)`, + fontWeight: `var(--text-h${lvl}-weight)` + } + ]; + return acc; + }, {}) + ), + fontWeight: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "textFont") { + if (!variantName.startsWith("font-weight-")) { + return acc; + } + + const weight = variantName.replace("font-weight-", ""); + acc[weight] = `var(--font-weight-${weight})`; + + return acc; + } + + return acc; + }, {}), + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" } + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" } + }, + "collapsible-down": { + from: { height: "0" }, + to: { height: "var(--radix-collapsible-content-height)" } + }, + "collapsible-up": { + from: { height: "var(--radix-collapsible-content-height)" }, + to: { height: "0" } + }, + "skeleton-pulse": { + "0%, 100%": { backgroundColor: "hsl(var(--bg-neutral-dimmed))" }, + "50%": { backgroundColor: "hsl(var(--bg-neutral-muted))" } + } + }, + margin: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "margin") { + acc[variantName] = `var(--margin-${variantName})`; + } + return acc; + }, {}), + padding: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "padding") { + acc[variantName] = `var(--padding-${variantName})`; + } + return acc; + }, {}), + ringColor: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "ringColor") { + if (isColorWithAlpha(variantName)) { + return acc; + } + + const [color, variant] = variantName.split("-"); + if (!acc[color]) { + acc[color] = { + DEFAULT: `hsl(var(--ring-${color}-default))` + }; + } + + acc[color][variant] = `hsl(var(--ring-${variantName}))`; + } + return acc; + }, + { ...DEFAULTS.COLORS } + ), + ringWidth: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "ringWidth") { + acc[variantName] = `var(--ring-width-${variantName})`; + } + return acc; + }, {}), + shadow: normalizedFigmaExport.reduce((acc, { type, variantName }) => { + if (type === "shadow") { + acc[variantName] = `var(--shadow-${variantName})`; + } + return acc; + }, {}), + spacing: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "spacing") { + acc[variantName] = `var(--spacing-${variantName})`; + } + return acc; + }, + { + // Custom sidebar-related variables. + "sidebar-collapsed": "var(--spacing-sidebar-collapsed)", + "sidebar-expanded": "var(--spacing-sidebar-expanded)", + // Custom main content-related variables. + "main-content": "var(--spacing-main-content)" + } + ), + textColor: normalizedFigmaExport.reduce( + (acc, { type, variantName }) => { + if (type === "textColor") { + if (isColorWithAlpha(variantName)) { + return acc; + } + + const [color, ...variantParts] = variantName.split("-"); + const variant = variantParts.join("-"); + if (!acc[color]) { + acc[color] = { + DEFAULT: `hsl(var(--text-${color}-default))` + }; + } + + acc[color][variant] = `hsl(var(--text-${variantName}))`; + } + return acc; + }, + { ...DEFAULTS.COLORS } + ), + zIndex: { + 5: 5, + 15: 15, + 25: 25, + 35: 35, + 45: 45 + } + }; +}; +module.exports = { createTailwindConfigTheme }; diff --git a/packages/admin-ui/scripts/importFromFigma/createThemeScss.js b/packages/admin-ui/scripts/importFromFigma/createThemeScss.js new file mode 100644 index 00000000000..2597fc2d9d7 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/createThemeScss.js @@ -0,0 +1,331 @@ +const fs = require("fs"); + +// We don't need tokens that end with `-a{one or two numbers}` because they are used for +// alpha colors. We don't need these because we can use the /alpha function in Tailwind CSS. +const isColorWithAlpha = variantName => { + return variantName.match(/^.*-a\d{1,2}$/); +}; + +const createThemeScss = (normalizedFigmaExport, normalizedPrimitivesFigmaExport) => { + // Generate `theme.scss` file. + let stylesScss = fs.readFileSync(__dirname + "/templates/theme.scss.txt", "utf8"); + + // 0. Colors + { + let currentBgColorGroup = null; + const bgColors = normalizedPrimitivesFigmaExport + .filter(item => item.type === "colors") + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVar = `--color-${variable.variantName}: ${variable.hsla.h} ${variable.hsla.s}% ${variable.hsla.l}%;`; + + if (!currentBgColorGroup) { + currentBgColorGroup = colorGroup; + return cssVar; + } + + if (!currentBgColorGroup || currentBgColorGroup !== colorGroup) { + currentBgColorGroup = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat() + .reverse(); + + stylesScss = stylesScss.replace("{COLORS}", bgColors.join("\n")); + } + + // 1. Background color. + { + let currentBgColorGroup = null; + const bgColors = normalizedFigmaExport + .filter(item => item.type === "backgroundColor") + .filter(variable => !isColorWithAlpha(variable.variantName)) + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVarName = variable.aliasName.replace("colors/colors-", "color-"); + const cssVar = `--bg-${variable.variantName}: var(--${cssVarName});`; + + if (!currentBgColorGroup) { + currentBgColorGroup = colorGroup; + return cssVar; + } + + if (!currentBgColorGroup || currentBgColorGroup !== colorGroup) { + currentBgColorGroup = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat(); + + stylesScss = stylesScss.replace("{BACKGROUND_COLOR}", bgColors.join("\n")); + } + + // 2. Border color. + { + let currentBorderColor = null; + const borderColors = normalizedFigmaExport + .filter(item => item.type === "borderColor") + .filter(variable => !isColorWithAlpha(variable.variantName)) + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVarName = variable.aliasName.replace("colors/colors-", "color-"); + const cssVar = `--border-${variable.variantName}: var(--${cssVarName});`; + + if (!currentBorderColor) { + currentBorderColor = colorGroup; + return cssVar; + } + + if (!currentBorderColor || currentBorderColor !== colorGroup) { + currentBorderColor = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat(); + + stylesScss = stylesScss.replace("{BORDER_COLOR}", borderColors.join("\n")); + } + + // 3. Border radius. + { + const borderRadius = normalizedFigmaExport + .filter(item => item.type === "borderRadius") + .map(variable => { + return `--radius-${variable.variantName}: ${variable.resolvedValue}px;`; + }); + + stylesScss = stylesScss.replace("{BORDER_RADIUS}", borderRadius.join("\n")); + } + + // 4. Border width. + { + const borderWidth = normalizedFigmaExport + .filter(item => item.type === "borderWidth") + .map( + variable => `--border-width-${variable.variantName}: ${variable.resolvedValue}px;` + ); + + stylesScss = stylesScss.replace("{BORDER_WIDTH}", borderWidth.join("\n")); + } + + // 5. Fill. + { + let currentFillColorGroup = null; + const fillColors = normalizedFigmaExport + .filter(item => item.type === "fill") + .filter(variable => !isColorWithAlpha(variable.variantName)) + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVarName = variable.aliasName.replace("colors/colors-", "color-"); + const cssVar = `--fill-${variable.variantName}: var(--${cssVarName});`; + + if (!currentFillColorGroup) { + currentFillColorGroup = colorGroup; + return cssVar; + } + + if (!currentFillColorGroup || currentFillColorGroup !== colorGroup) { + currentFillColorGroup = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat(); + + stylesScss = stylesScss.replace("{FILL}", fillColors.join("\n")); + } + + // 6. Font. + { + // Font is not in Figma, we're manually setting the values here. + stylesScss = stylesScss.replace("{FONT}", `--font-sans: 'Inter', sans-serif;`); + } + + // 6. Font weight. + { + const weight = normalizedFigmaExport + .filter(item => item.type === "textFont" && item.variantName.startsWith("font-weight-")) + .map(variable => `--${variable.variantName}: ${variable.resolvedValue};`); + + stylesScss = stylesScss.replace("{FONT_WEIGHT}", weight.join("\n")); + } + + // 7. Margin. + { + const margin = normalizedFigmaExport + .filter(item => item.type === "margin") + .map(variable => `--margin-${variable.variantName}: ${variable.resolvedValue}px;`); + + stylesScss = stylesScss.replace("{MARGIN}", margin.join("\n")); + } + + // 8. Padding. + { + const padding = normalizedFigmaExport + .filter(item => item.type === "padding") + .map(variable => `--padding-${variable.variantName}: ${variable.resolvedValue}px;`); + + stylesScss = stylesScss.replace("{PADDING}", padding.join("\n")); + } + + // 9. Ring color. + { + let currentRingColorGroup = null; + const ringColors = normalizedFigmaExport + .filter(item => item.type === "ringColor") + .filter(variable => !isColorWithAlpha(variable.variantName)) + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVarName = variable.aliasName.replace("colors/colors-", "color-"); + const cssVar = `--ring-${variable.variantName}: var(--${cssVarName});`; + + if (!currentRingColorGroup) { + currentRingColorGroup = colorGroup; + return cssVar; + } + + if (!currentRingColorGroup || currentRingColorGroup !== colorGroup) { + currentRingColorGroup = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat(); + + stylesScss = stylesScss.replace("{RING_COLOR}", ringColors.join("\n")); + } + + // 10. Ring width. + { + const ringWidth = normalizedFigmaExport + .filter(item => item.type === "ringWidth") + .map(variable => `--ring-width-${variable.variantName}: ${variable.resolvedValue}px;`); + + stylesScss = stylesScss.replace("{RING_WIDTH}", ringWidth.join("\n")); + } + + // 11. Shadow. + { + const shadow = normalizedFigmaExport + .filter(item => item.type === "shadow") + .map(variable => `--shadow-${variable.variantName}: ${variable.resolvedValue}px;`); + + stylesScss = stylesScss.replace("{SHADOW}", shadow.join("\n")); + } + + // 12. Spacing. + { + const spacing = normalizedFigmaExport + .filter(item => item.type === "spacing") + .map(variable => `--spacing-${variable.variantName}: ${variable.resolvedValue}px;`) + + // Custom sidebar-related variables. + .concat( + `--spacing-sidebar-collapsed: 44px;`, + `--spacing-sidebar-expanded: 256px;`, + `--spacing-main-content: calc(100vh - 45px);` + ); + + stylesScss = stylesScss.replace("{SPACING}", spacing.join("\n")); + } + + // 13. Text color. + { + let currentTextColor = null; + const textColors = normalizedFigmaExport + .filter(item => item.type === "textColor") + .filter(variable => !isColorWithAlpha(variable.variantName)) + .map(variable => { + const [colorGroup] = variable.variantName.split("-"); + const cssVarName = variable.aliasName.replace("colors/colors-", "color-"); + const cssVar = `--text-${variable.variantName}: var(--${cssVarName});`; + + if (!currentTextColor) { + currentTextColor = colorGroup; + return cssVar; + } + + if (!currentTextColor || currentTextColor !== colorGroup) { + currentTextColor = colorGroup; + return ["", cssVar]; + } + return cssVar; + }) + .flat(); + + stylesScss = stylesScss.replace("{TEXT_COLOR}", textColors.join("\n")); + } + + // 14. Text size. + { + const textSize = normalizedFigmaExport + .filter(item => item.type === "textFont" && item.variantName.startsWith("font-size-")) + .sort((a, b) => a.resolvedValue - b.resolvedValue) + .reduce( + (acc, { variantName, resolvedValue }) => { + const size = variantName.replace("font-size-", ""); + const { resolvedValue: lineHeight } = normalizedFigmaExport.find(item => { + return item.variantName === `line-height-${size}`; + }); + + return [ + ...acc, + [ + `--text-${size}: ${resolvedValue}px;`, + `--text-${size}-leading: ${lineHeight}px;`, + `--text-${size}-tracking: initial;`, + `--text-${size}-weight: normal;` + ] + ]; + }, + [ + [ + `--text-h1: var(--text-4xl);`, + `--text-h1-leading: var(--text-4xl-leading);`, + `--text-h1-tracking: var(--text-4xl-tracking);`, + `--text-h1-weight: var(--font-weight-semibold);` + ], + [ + `--text-h2: var(--text-3xl);`, + `--text-h2-leading: var(--text-3xl-leading);`, + `--text-h2-tracking: var(--text-3xl-tracking);`, + `--text-h2-weight: var(--font-weight-semibold);` + ], + [ + `--text-h3: var(--text-xxl);`, + `--text-h3-leading: var(--text-xxl-leading);`, + `--text-h3-tracking: var(--text-xxl-tracking);`, + `--text-h3-weight: var(--font-weight-semibold);` + ], + [ + `--text-h4: var(--text-xl);`, + `--text-h4-leading: var(--text-xl-leading);`, + `--text-h4-tracking: initial;`, + `--text-h4-weight: var(--font-weight-semibold);` + ], + [ + `--text-h5: var(--text-lg);`, + `--text-h5-leading: var(--text-lg-leading);`, + `--text-h5-tracking: initial;`, + `--text-h5-weight: var(--font-weight-semibold);` + ], + [ + `--text-h6: var(--text-md);`, + `--text-h6-leading: var(--text-md-leading);`, + `--text-h6-tracking: initial;`, + `--text-h6-weight: var(--font-weight-semibold);` + ] + ] + ); + + stylesScss = stylesScss.replace("{TEXT_SIZE}", textSize.flat().join("\n")); + } + + return stylesScss; +}; + +module.exports = { createThemeScss }; diff --git a/packages/admin-ui/scripts/importFromFigma/defaults.js b/packages/admin-ui/scripts/importFromFigma/defaults.js new file mode 100644 index 00000000000..13c9bb8f7c5 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/defaults.js @@ -0,0 +1,8 @@ +const DEFAULTS = { + COLORS: { + transparent: "transparent", + white: "white" + } +}; + +module.exports = { DEFAULTS }; diff --git a/packages/admin-ui/scripts/importFromFigma/exports/Alias tokens.json b/packages/admin-ui/scripts/importFromFigma/exports/Alias tokens.json new file mode 100644 index 00000000000..70af99e039a --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/exports/Alias tokens.json @@ -0,0 +1 @@ +{"id":"VariableCollectionId:37:6","name":"Alias tokens","modes":{"37:2":"Mode 1"},"variableIds":["VariableID:39:112","VariableID:1970:8527","VariableID:1970:8529","VariableID:1970:8528","VariableID:1141:3695","VariableID:39:113","VariableID:62:2199","VariableID:1141:3698","VariableID:39:116","VariableID:39:117","VariableID:39:114","VariableID:39:115","VariableID:2665:9916","VariableID:1970:9130","VariableID:1970:9131","VariableID:39:118","VariableID:39:119","VariableID:1141:4555","VariableID:39:120","VariableID:841:778","VariableID:841:783","VariableID:39:121","VariableID:39:122","VariableID:1141:4556","VariableID:39:123","VariableID:841:779","VariableID:841:784","VariableID:835:90","VariableID:835:91","VariableID:1141:4557","VariableID:835:92","VariableID:841:780","VariableID:841:785","VariableID:52:22","VariableID:1522:9133","VariableID:1849:9683","VariableID:1658:621","VariableID:1658:638","VariableID:1522:9134","VariableID:1522:9135","VariableID:1522:9136","VariableID:1522:9137","VariableID:1522:9138","VariableID:1522:9139","VariableID:1522:9140","VariableID:1522:9141","VariableID:1522:9142","VariableID:1522:9143","VariableID:1522:9144","VariableID:1522:9145","VariableID:1522:9146","VariableID:52:23","VariableID:851:2608","VariableID:52:24","VariableID:891:81144","VariableID:2629:7631","VariableID:52:25","VariableID:52:28","VariableID:52:29","VariableID:52:30","VariableID:52:31","VariableID:52:32","VariableID:529:17319","VariableID:1335:7762","VariableID:183:122214","VariableID:1335:7763","VariableID:1335:7764","VariableID:1152:342","VariableID:849:906","VariableID:183:122215","VariableID:4661:15434","VariableID:183:122216","VariableID:183:122217","VariableID:1798:12878","VariableID:183:122218","VariableID:1141:6772","VariableID:183:122219","VariableID:849:783","VariableID:2237:20498","VariableID:849:784","VariableID:2237:20499","VariableID:1639:554","VariableID:52:18","VariableID:81:1904","VariableID:81:1905","VariableID:52:19","VariableID:2369:76482","VariableID:79:37","VariableID:79:38","VariableID:79:39","VariableID:79:40","VariableID:79:235","VariableID:79:239","VariableID:80:242","VariableID:80:243","VariableID:80:244","VariableID:80:245","VariableID:59:8","VariableID:59:9","VariableID:1141:4558","VariableID:59:10","VariableID:841:781","VariableID:841:786","VariableID:59:11","VariableID:59:12","VariableID:1141:4559","VariableID:59:13","VariableID:841:782","VariableID:841:787","VariableID:1148:687","VariableID:79:7","VariableID:1699:9362","VariableID:1148:690","VariableID:1148:689","VariableID:528:17123","VariableID:1516:33864","VariableID:528:17124","VariableID:1516:33861","VariableID:1516:33862","VariableID:528:17125","VariableID:1516:33863","VariableID:528:17126","VariableID:528:17127","VariableID:528:17128","VariableID:1148:688","VariableID:79:8","VariableID:1699:9360","VariableID:1699:9361","VariableID:79:12","VariableID:1699:9359","VariableID:79:236","VariableID:79:237","VariableID:79:238","VariableID:1849:9055","VariableID:1516:33865","VariableID:1516:15576","VariableID:107:716","VariableID:1516:33674","VariableID:1751:787","VariableID:1751:786","VariableID:528:17129","VariableID:1751:788","VariableID:528:17130","VariableID:1751:789","VariableID:1751:790","VariableID:528:17131","VariableID:1751:791","VariableID:528:17132","VariableID:528:17133","VariableID:528:17134","VariableID:107:713","VariableID:1516:33668","VariableID:1516:33671","VariableID:79:232","VariableID:1516:33672","VariableID:79:233","VariableID:79:234","VariableID:203:4497","VariableID:95:1557","VariableID:849:780","VariableID:2675:20392","VariableID:95:1558","VariableID:846:3890","VariableID:95:1559","VariableID:1227:19184","VariableID:1227:21660","VariableID:1227:21661","VariableID:95:1560","VariableID:2675:17230","VariableID:1639:2","VariableID:1639:3","VariableID:1639:540","VariableID:1639:547","VariableID:1639:548","VariableID:1639:549","VariableID:1639:551","VariableID:1639:552","VariableID:1639:553","VariableID:1751:924","VariableID:1751:925"],"variables":[{"id":"VariableID:39:112","name":"backgroundColor/backgroundColor-neutral-dark","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:57"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":1},"alias":"VariableID:39:57","aliasName":"colors/colors-neutral-900"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:113","name":"backgroundColor/backgroundColor-neutral-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:52"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7438521981239319,"g":0.7645292282104492,"b":0.7989909052848816,"a":1},"alias":"VariableID:39:52","aliasName":"colors/colors-neutral-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:114","name":"backgroundColor/backgroundColor-neutral-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:118:19505"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.9843137264251709,"b":0.9843137264251709,"a":1},"alias":"VariableID:118:19505","aliasName":"colors/colors-neutral-50"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:115","name":"backgroundColor/backgroundColor-neutral-base","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:823:2"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":1},"alias":"VariableID:823:2","aliasName":"colors/colors-neutral-0"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:116","name":"backgroundColor/backgroundColor-neutral-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:50"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9411764740943909,"g":0.9450980424880981,"b":0.9529411792755127,"a":1},"alias":"VariableID:39:50","aliasName":"colors/colors-neutral-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:117","name":"backgroundColor/backgroundColor-neutral-light","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:49"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9686274528503418,"g":0.9725490212440491,"b":0.9764705896377563,"a":1},"alias":"VariableID:39:49","aliasName":"colors/colors-neutral-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:118","name":"backgroundColor/backgroundColor-primary-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:17"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.34117648005485535,"b":0.13725490868091583,"a":1},"alias":"VariableID:38:17","aliasName":"colors/colors-primary-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:119","name":"backgroundColor/backgroundColor-primary-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:15"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9882352948188782,"g":0.6666666865348816,"b":0.5686274766921997,"a":1},"alias":"VariableID:38:15","aliasName":"colors/colors-primary-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:120","name":"backgroundColor/backgroundColor-primary-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:4"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9529722929000854,"b":0.9474395513534546,"a":1},"alias":"VariableID:37:4","aliasName":"colors/colors-primary-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:121","name":"backgroundColor/backgroundColor-secondary-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:122","name":"backgroundColor/backgroundColor-secondary-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:25"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.43921568989753723,"g":0.8588235378265381,"b":0.7803921699523926,"a":1},"alias":"VariableID:38:25","aliasName":"colors/colors-success-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:39:123","name":"backgroundColor/backgroundColor-secondary-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:23"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8705882430076599,"g":0.9647058844566345,"b":0.9490196108818054,"a":1},"alias":"VariableID:38:23","aliasName":"colors/colors-success-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:18","name":"borderRadius/borderRadius-xs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:133"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:39:133","aliasName":"radius/dimensions-border-radius-2"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:19","name":"borderRadius/borderRadius-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:134"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:39:134","aliasName":"radius/dimensions-border-radius-4"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:22","name":"textColor/textColor-neutral-primary","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:57"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":1},"alias":"VariableID:39:57","aliasName":"colors/colors-neutral-900"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:23","name":"textColor/textColor-neutral-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:55"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.34716352820396423,"g":0.38350826501846313,"b":0.42792969942092896,"a":1},"alias":"VariableID:39:55","aliasName":"colors/colors-neutral-700"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:24","name":"textColor/textColor-neutral-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:52"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7438521981239319,"g":0.7645292282104492,"b":0.7989909052848816,"a":1},"alias":"VariableID:39:52","aliasName":"colors/colors-neutral-400"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:25","name":"textColor/textColor-neutral-light","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:823:2"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":1},"alias":"VariableID:823:2","aliasName":"colors/colors-neutral-0"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:28","name":"textColor/textColor-accent-primary","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:17"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.34117648005485535,"b":0.13725490868091583,"a":1},"alias":"VariableID:38:17","aliasName":"colors/colors-primary-500"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:29","name":"textColor/textColor-accent-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:15"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9882352948188782,"g":0.6666666865348816,"b":0.5686274766921997,"a":1},"alias":"VariableID:38:15","aliasName":"colors/colors-primary-300"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:30","name":"textColor/textColor-accent-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:4"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9529722929000854,"b":0.9474395513534546,"a":1},"alias":"VariableID:37:4","aliasName":"colors/colors-primary-100"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:31","name":"textColor/textColor-success-primary","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:52:32","name":"textColor/textColor-success-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:25"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.43921568989753723,"g":0.8588235378265381,"b":0.7803921699523926,"a":1},"alias":"VariableID:38:25","aliasName":"colors/colors-success-400"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:8","name":"backgroundColor/backgroundColor-destructive-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:44"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8313725590705872,"g":0.1411764770746231,"b":0.1411764770746231,"a":1},"alias":"VariableID:38:44","aliasName":"colors/colors-destructive-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:9","name":"backgroundColor/backgroundColor-destructive-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:43"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8745098114013672,"g":0.3803921639919281,"b":0.3803921639919281,"a":1},"alias":"VariableID:38:43","aliasName":"colors/colors-destructive-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:10","name":"backgroundColor/backgroundColor-destructive-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:40"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9372549057006836,"b":0.9372549057006836,"a":1},"alias":"VariableID:38:40","aliasName":"colors/colors-destructive-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:11","name":"backgroundColor/backgroundColor-warning-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:35"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9843137264251709,"g":0.8117647171020508,"b":0.29019609093666077,"a":1},"alias":"VariableID:38:35","aliasName":"colors/colors-warning-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:12","name":"backgroundColor/backgroundColor-warning-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:33"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9882352948188782,"g":0.8745098114013672,"b":0.529411792755127,"a":1},"alias":"VariableID:38:33","aliasName":"colors/colors-warning-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:59:13","name":"backgroundColor/backgroundColor-warning-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:31"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9803921580314636,"b":0.929411768913269,"a":1},"alias":"VariableID:38:31","aliasName":"colors/colors-warning-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:62:2199","name":"backgroundColor/backgroundColor-neutral-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:51"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8909133672714233,"g":0.898869514465332,"b":0.9227376580238342,"a":1},"alias":"VariableID:39:51","aliasName":"colors/colors-neutral-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:7","name":"dimension/dimension-xs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4487"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:203:4487","aliasName":"space/dimensions-fixed-4"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:8","name":"dimension/dimension-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4488"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":"VariableID:203:4488","aliasName":"space/dimensions-fixed-8"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:12","name":"dimension/dimension-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4492"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:203:4492","aliasName":"space/dimensions-fixed-16"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:37","name":"borderRadius/borderRadius-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:135"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":"VariableID:39:135","aliasName":"radius/dimensions-border-radius-8"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:38","name":"borderRadius/borderRadius-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:136"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:39:136","aliasName":"radius/dimensions-border-radius-16"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:39","name":"borderRadius/borderRadius-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:137"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:39:137","aliasName":"radius/dimensions-border-radius-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:40","name":"borderRadius/borderRadius-3Xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:52:21"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":36,"alias":"VariableID:52:21","aliasName":"radius/dimensions-border-radius-36"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:232","name":"padding/padding-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4492"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:203:4492","aliasName":"space/dimensions-fixed-16"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:233","name":"padding/padding-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4493"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:203:4493","aliasName":"space/dimensions-fixed-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:234","name":"padding/padding-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4494"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":32,"alias":"VariableID:203:4494","aliasName":"space/dimensions-fixed-32"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:235","name":"shadow/shadow-flat","description":"","type":"FLOAT","valuesByMode":{"37:2":0},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:236","name":"dimension/dimension-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4493"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:203:4493","aliasName":"space/dimensions-fixed-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:237","name":"dimension/dimension-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4494"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":32,"alias":"VariableID:203:4494","aliasName":"space/dimensions-fixed-32"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:238","name":"dimension/dimension-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1849:9057"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":40,"alias":"VariableID:1849:9057","aliasName":"space/dimensions-fixed-40"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:79:239","name":"shadow/shadow-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":4},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:80:242","name":"shadow/shadow-md","description":"","type":"FLOAT","valuesByMode":{"37:2":8},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:80:243","name":"shadow/shadow-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":16},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:80:244","name":"shadow/shadow-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":24},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:80:245","name":"shadow/shadow-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":48},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":null}},"scopes":["EFFECT_FLOAT"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:81:1904","name":"borderWidth/borderWidth-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:59:20"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":1,"alias":"VariableID:59:20","aliasName":"borderWidth/dimensions-border-width-1"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:81:1905","name":"borderWidth/borderWidth-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:59:21"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:59:21","aliasName":"borderWidth/dimensions-border-width-2"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:95:1557","name":"fill/fill-neutral-dark","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:56"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.1882352977991104,"g":0.2078431397676468,"b":0.23529411852359772,"a":1},"alias":"VariableID:39:56","aliasName":"colors/colors-neutral-800"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:95:1558","name":"fill/fill-neutral-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:53"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.6138784885406494,"g":0.6435658931732178,"b":0.689746081829071,"a":1},"alias":"VariableID:39:53","aliasName":"colors/colors-neutral-500"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:95:1559","name":"fill/fill-accent-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:17"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.34117648005485535,"b":0.13725490868091583,"a":1},"alias":"VariableID:38:17","aliasName":"colors/colors-primary-500"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:95:1560","name":"fill/fill-neutral-base","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:823:2"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":1},"alias":"VariableID:823:2","aliasName":"colors/colors-neutral-0"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:107:713","name":"padding/padding-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4488"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":"VariableID:203:4488","aliasName":"space/dimensions-fixed-8"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:107:716","name":"padding/padding-xs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4487"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:203:4487","aliasName":"space/dimensions-fixed-4"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122214","name":"borderColor/borderColor-neutral-black","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:57"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":1},"alias":"VariableID:39:57","aliasName":"colors/colors-neutral-900"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122215","name":"borderColor/borderColor-neutral-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:52"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7438521981239319,"g":0.7645292282104492,"b":0.7989909052848816,"a":1},"alias":"VariableID:39:52","aliasName":"colors/colors-neutral-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122216","name":"borderColor/borderColor-neutral-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:50"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9411764740943909,"g":0.9450980424880981,"b":0.9529411792755127,"a":1},"alias":"VariableID:39:50","aliasName":"colors/colors-neutral-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122217","name":"borderColor/borderColor-neutral-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:49"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9686274528503418,"g":0.9725490212440491,"b":0.9764705896377563,"a":1},"alias":"VariableID:39:49","aliasName":"colors/colors-neutral-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122218","name":"borderColor/borderColor-accent-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:17"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.34117648005485535,"b":0.13725490868091583,"a":1},"alias":"VariableID:38:17","aliasName":"colors/colors-primary-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:183:122219","name":"borderColor/borderColor-accent-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:4"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9529722929000854,"b":0.9474395513534546,"a":1},"alias":"VariableID:37:4","aliasName":"colors/colors-primary-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:203:4497","name":"padding/padding-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4495"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":"VariableID:203:4495","aliasName":"space/dimensions-fixed-48"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17123","name":"spacing/spacing-xs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4487"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:203:4487","aliasName":"space/dimensions-fixed-4"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17124","name":"spacing/spacing-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4488"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":"VariableID:203:4488","aliasName":"space/dimensions-fixed-8"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17125","name":"spacing/spacing-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4492"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:203:4492","aliasName":"space/dimensions-fixed-16"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17126","name":"spacing/spacing-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4493"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:203:4493","aliasName":"space/dimensions-fixed-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17127","name":"spacing/spacing-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4494"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":32,"alias":"VariableID:203:4494","aliasName":"space/dimensions-fixed-32"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17128","name":"spacing/spacing-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4495"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":"VariableID:203:4495","aliasName":"space/dimensions-fixed-48"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17129","name":"margin/margin-xs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4487"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:203:4487","aliasName":"space/dimensions-fixed-4"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17130","name":"margin/margin-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4488"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":8,"alias":"VariableID:203:4488","aliasName":"space/dimensions-fixed-8"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17131","name":"margin/margin-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4492"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:203:4492","aliasName":"space/dimensions-fixed-16"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17132","name":"margin/margin-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4493"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:203:4493","aliasName":"space/dimensions-fixed-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17133","name":"margin/margin-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4494"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":32,"alias":"VariableID:203:4494","aliasName":"space/dimensions-fixed-32"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:528:17134","name":"margin/margin-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4495"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":"VariableID:203:4495","aliasName":"space/dimensions-fixed-48"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:529:17319","name":"textColor/textColor-success-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:23"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8705882430076599,"g":0.9647058844566345,"b":0.9490196108818054,"a":1},"alias":"VariableID:38:23","aliasName":"colors/colors-success-200"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:835:90","name":"backgroundColor/backgroundColor-success-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:835:91","name":"backgroundColor/backgroundColor-success-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:25"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.43921568989753723,"g":0.8588235378265381,"b":0.7803921699523926,"a":1},"alias":"VariableID:38:25","aliasName":"colors/colors-success-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:835:92","name":"backgroundColor/backgroundColor-success-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:23"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8705882430076599,"g":0.9647058844566345,"b":0.9490196108818054,"a":1},"alias":"VariableID:38:23","aliasName":"colors/colors-success-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:778","name":"backgroundColor/backgroundColor-primary-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:19"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7764706015586853,"g":0.20000000298023224,"b":0.0235294122248888,"a":1},"alias":"VariableID:38:19","aliasName":"colors/colors-primary-700"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:779","name":"backgroundColor/backgroundColor-secondary-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:28"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.572549045085907,"b":0.4313725531101227,"a":1},"alias":"VariableID:38:28","aliasName":"colors/colors-success-700"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:780","name":"backgroundColor/backgroundColor-success-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:824:7484"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.572549045085907,"b":0.4313725531101227,"a":1},"alias":"VariableID:824:7484","aliasName":"colors/colors-secondary-700"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:781","name":"backgroundColor/backgroundColor-destructive-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:45"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.6745098233222961,"g":0.09019608050584793,"b":0.0941176488995552,"a":1},"alias":"VariableID:38:45","aliasName":"colors/colors-destructive-600"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:782","name":"backgroundColor/backgroundColor-warning-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:37"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7450980544090271,"g":0.5568627715110779,"b":0,"a":1},"alias":"VariableID:38:37","aliasName":"colors/colors-warning-700"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:783","name":"backgroundColor/backgroundColor-primary-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:21"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.5098039507865906,"g":0.12156862765550613,"b":0,"a":1},"alias":"VariableID:38:21","aliasName":"colors/colors-primary-900"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:784","name":"backgroundColor/backgroundColor-secondary-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:30"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.29019609093666077,"b":0.1921568661928177,"a":1},"alias":"VariableID:38:30","aliasName":"colors/colors-success-900"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:785","name":"backgroundColor/backgroundColor-success-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:824:7486"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.29019609093666077,"b":0.1921568661928177,"a":1},"alias":"VariableID:824:7486","aliasName":"colors/colors-secondary-900"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:786","name":"backgroundColor/backgroundColor-destructive-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:47"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.3960784375667572,"g":0.03529411926865578,"b":0.03529411926865578,"a":1},"alias":"VariableID:38:47","aliasName":"colors/colors-destructive-800"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:841:787","name":"backgroundColor/backgroundColor-warning-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:38"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.4274509847164154,"g":0.32156863808631897,"b":0.003921568859368563,"a":1},"alias":"VariableID:38:38","aliasName":"colors/colors-warning-800"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:846:3890","name":"fill/fill-neutral-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:52"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7438521981239319,"g":0.7645292282104492,"b":0.7989909052848816,"a":1},"alias":"VariableID:39:52","aliasName":"colors/colors-neutral-400"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:849:780","name":"fill/fill-neutral-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:55"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.34716352820396423,"g":0.38350826501846313,"b":0.42792969942092896,"a":1},"alias":"VariableID:39:55","aliasName":"colors/colors-neutral-700"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:849:783","name":"borderColor/borderColor-destructive-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:44"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8313725590705872,"g":0.1411764770746231,"b":0.1411764770746231,"a":1},"alias":"VariableID:38:44","aliasName":"colors/colors-destructive-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:849:784","name":"borderColor/borderColor-success-default","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:849:906","name":"borderColor/borderColor-neutral-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:53"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.6138784885406494,"g":0.6435658931732178,"b":0.689746081829071,"a":1},"alias":"VariableID:39:53","aliasName":"colors/colors-neutral-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:851:2608","name":"textColor/textColor-neutral-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:53"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.6138784885406494,"g":0.6435658931732178,"b":0.689746081829071,"a":1},"alias":"VariableID:39:53","aliasName":"colors/colors-neutral-500"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:891:81144","name":"textColor/textColor-neutral-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:52"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.7438521981239319,"g":0.7645292282104492,"b":0.7989909052848816,"a":1},"alias":"VariableID:39:52","aliasName":"colors/colors-neutral-400"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:3695","name":"backgroundColor/backgroundColor-neutral-xstrong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:55"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.34716352820396423,"g":0.38350826501846313,"b":0.42792969942092896,"a":1},"alias":"VariableID:39:55","aliasName":"colors/colors-neutral-700"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:3698","name":"backgroundColor/backgroundColor-neutral-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:50"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9411764740943909,"g":0.9450980424880981,"b":0.9529411792755127,"a":1},"alias":"VariableID:39:50","aliasName":"colors/colors-neutral-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:4555","name":"backgroundColor/backgroundColor-primary-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:15"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9882352948188782,"g":0.6666666865348816,"b":0.5686274766921997,"a":1},"alias":"VariableID:38:15","aliasName":"colors/colors-primary-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:4556","name":"backgroundColor/backgroundColor-secondary-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:25"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.43921568989753723,"g":0.8588235378265381,"b":0.7803921699523926,"a":1},"alias":"VariableID:38:25","aliasName":"colors/colors-success-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:4557","name":"backgroundColor/backgroundColor-success-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:24"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.6745098233222961,"g":0.9137254953384399,"b":0.8666666746139526,"a":1},"alias":"VariableID:38:24","aliasName":"colors/colors-success-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:4558","name":"backgroundColor/backgroundColor-destructive-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:42"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9607843160629272,"g":0.5803921818733215,"b":0.572549045085907,"a":1},"alias":"VariableID:38:42","aliasName":"colors/colors-destructive-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:4559","name":"backgroundColor/backgroundColor-warning-disabled","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:32"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9960784316062927,"g":0.9333333373069763,"b":0.7529411911964417,"a":1},"alias":"VariableID:38:32","aliasName":"colors/colors-warning-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1141:6772","name":"borderColor/borderColor-accent-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:9"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9921568632125854,"g":0.800000011920929,"b":0.7372549176216125,"a":1},"alias":"VariableID:37:9","aliasName":"colors/colors-primary-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1148:687","name":"dimension/dimension-xxs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4489"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:203:4489","aliasName":"space/dimensions-fixed-2"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1148:688","name":"spacing/spacing-3xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4496"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":64,"alias":"VariableID:203:4496","aliasName":"space/dimensions-fixed-64"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1148:689","name":"spacing/spacing-xxs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4489"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:203:4489","aliasName":"space/dimensions-fixed-2"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1148:690","name":"spacing/spacing-none","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1148:691"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":"VariableID:1148:691","aliasName":"space/dimensions-fixed-0"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1152:342","name":"borderColor/borderColor-neutral-dark","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:54"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.4613589644432068,"g":0.5014801025390625,"b":0.5576497316360474,"a":1},"alias":"VariableID:39:54","aliasName":"colors/colors-neutral-600"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1227:19184","name":"fill/fill-success","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1227:21660","name":"fill/fill-warning","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:35"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9843137264251709,"g":0.8117647171020508,"b":0.29019609093666077,"a":1},"alias":"VariableID:38:35","aliasName":"colors/colors-warning-500"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1227:21661","name":"fill/fill-destructive","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:44"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8313725590705872,"g":0.1411764770746231,"b":0.1411764770746231,"a":1},"alias":"VariableID:38:44","aliasName":"colors/colors-destructive-500"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1335:7762","name":"textColor/textColor-destructive-primary","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:44"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8313725590705872,"g":0.1411764770746231,"b":0.1411764770746231,"a":1},"alias":"VariableID:38:44","aliasName":"colors/colors-destructive-500"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1335:7763","name":"textColor/textColor-destructive-muted","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:42"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9607843160629272,"g":0.5803921818733215,"b":0.572549045085907,"a":1},"alias":"VariableID:38:42","aliasName":"colors/colors-destructive-300"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1335:7764","name":"textColor/textColor-destructive-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:40"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9372549057006836,"b":0.9372549057006836,"a":1},"alias":"VariableID:38:40","aliasName":"colors/colors-destructive-100"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:15576","name":"padding/padding-xxs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4489"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:203:4489","aliasName":"space/dimensions-fixed-2"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33668","name":"padding/padding-sm-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33669"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":10,"alias":"VariableID:1516:33669","aliasName":"space/dimensions-fixed-10"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33671","name":"padding/padding-sm-extra","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5688"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":12,"alias":"VariableID:203:5688","aliasName":"space/dimensions-fixed-12"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33672","name":"padding/padding-md-extra","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5689"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:203:5689","aliasName":"space/dimensions-fixed-20"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33674","name":"padding/padding-xs-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33670"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":6,"alias":"VariableID:1516:33670","aliasName":"space/dimensions-fixed-6"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33861","name":"spacing/spacing-sm-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33669"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":10,"alias":"VariableID:1516:33669","aliasName":"space/dimensions-fixed-10"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33862","name":"spacing/spacing-sm-extra","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5688"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":12,"alias":"VariableID:203:5688","aliasName":"space/dimensions-fixed-12"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33863","name":"spacing/spacing-md-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5689"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:203:5689","aliasName":"space/dimensions-fixed-20"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33864","name":"spacing/spacing-xs-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33670"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":6,"alias":"VariableID:1516:33670","aliasName":"space/dimensions-fixed-6"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1516:33865","name":"padding/padding-none","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1148:691"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":"VariableID:1148:691","aliasName":"space/dimensions-fixed-0"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9133","name":"textFont/text-font-size-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:529:17323"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":12,"alias":"VariableID:529:17323","aliasName":"fontSize/font-size-text-12"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9134","name":"textFont/text-font-size-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:529:17324"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":14,"alias":"VariableID:529:17324","aliasName":"fontSize/font-size-text-14"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9135","name":"textFont/text-font-size-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:529:17325"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:529:17325","aliasName":"fontSize/font-size-text-16"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9136","name":"textFont/text-font-size-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:529:17327"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:529:17327","aliasName":"fontSize/font-size-text-20"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9137","name":"textFont/text-font-size-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9148"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":30,"alias":"VariableID:1522:9148","aliasName":"fontSize/font-size-text-30"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9138","name":"textFont/text-font-size-3xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9149"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":36,"alias":"VariableID:1522:9149","aliasName":"fontSize/font-size-text-36"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9139","name":"textFont/text-font-size-4xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9150"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":"VariableID:1522:9150","aliasName":"fontSize/font-size-text-48"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9140","name":"textFont/text-line-height-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9155"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":16,"alias":"VariableID:1522:9155","aliasName":"lineHeight/line-height-text-16"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9141","name":"textFont/text-line-height-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9157"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:1522:9157","aliasName":"lineHeight/line-height-text-20"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9142","name":"textFont/text-line-height-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9158"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":24,"alias":"VariableID:1522:9158","aliasName":"lineHeight/line-height-text-24"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9143","name":"textFont/text-line-height-xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9160"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":32,"alias":"VariableID:1522:9160","aliasName":"lineHeight/line-height-text-32"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9144","name":"textFont/text-line-height-xxl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9161"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":38,"alias":"VariableID:1522:9161","aliasName":"lineHeight/line-height-text-38"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9145","name":"textFont/text-line-height-3xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9162"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":44,"alias":"VariableID:1522:9162","aliasName":"lineHeight/line-height-text-44"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1522:9146","name":"textFont/text-line-height-4xl","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1522:9163"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":60,"alias":"VariableID:1522:9163","aliasName":"lineHeight/line-height-text-60"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:2","name":"ringWidth/ringWidth-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1639:537"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":1,"alias":"VariableID:1639:537","aliasName":"ringWidth/dimensions-ring-width-1"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:3","name":"ringWidth/ringWidth-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1639:538"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:1639:538","aliasName":"ringWidth/dimensions-ring-width-2"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:540","name":"ringWidth/ringWidth-lg","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1639:539"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":4,"alias":"VariableID:1639:539","aliasName":"ringWidth/dimensions-ring-width-4"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:547","name":"ringColor/ringColor-primary-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:17"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9803921580314636,"g":0.34117648005485535,"b":0.13725490868091583,"a":1},"alias":"VariableID:38:17","aliasName":"colors/colors-primary-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:548","name":"ringColor/ringColor-primary-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:9"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9921568632125854,"g":0.800000011920929,"b":0.7372549176216125,"a":1},"alias":"VariableID:37:9","aliasName":"colors/colors-primary-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:549","name":"ringColor/ringColor-primary-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:37:4"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9529722929000854,"b":0.9474395513534546,"a":1},"alias":"VariableID:37:4","aliasName":"colors/colors-primary-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:551","name":"ringColor/ringColor-success-strong","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:26"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0,"g":0.7490196228027344,"b":0.6196078658103943,"a":1},"alias":"VariableID:38:26","aliasName":"colors/colors-success-500"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:552","name":"ringColor/ringColor-success-dimmed","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:23"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8705882430076599,"g":0.9647058844566345,"b":0.9490196108818054,"a":1},"alias":"VariableID:38:23","aliasName":"colors/colors-success-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:553","name":"ringColor/ringColor-success-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:22"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.9411764740943909,"g":0.9803921580314636,"b":0.9725490212440491,"a":1},"alias":"VariableID:38:22","aliasName":"colors/colors-success-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1639:554","name":"borderWidth/borderWidth-none","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:529:17331"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":"VariableID:529:17331","aliasName":"borderWidth/dimensions-border-width-0"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1658:621","name":"textLetterspacing/text-letter-spacing-sm","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1658:637"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":-1,"alias":"VariableID:1658:637","aliasName":"fontSpacing/font-letter-spacing-1"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1658:638","name":"textLetterspacing/text-letter-spacing-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1658:610"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":-2,"alias":"VariableID:1658:610","aliasName":"fontSpacing/font-letter-spacing-2"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1699:9359","name":"dimension/dimension-md-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5689"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:203:5689","aliasName":"space/dimensions-fixed-20"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1699:9360","name":"dimension/dimension-sm-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33669"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":10,"alias":"VariableID:1516:33669","aliasName":"space/dimensions-fixed-10"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1699:9361","name":"dimension/dimension-sm-extra","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5688"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":12,"alias":"VariableID:203:5688","aliasName":"space/dimensions-fixed-12"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1699:9362","name":"dimension/dimension-xs-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33670"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":6,"alias":"VariableID:1516:33670","aliasName":"space/dimensions-fixed-6"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:786","name":"margin/margin-xxs","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4489"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":2,"alias":"VariableID:203:4489","aliasName":"space/dimensions-fixed-2"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:787","name":"margin/margin-none","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1148:691"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":"VariableID:1148:691","aliasName":"space/dimensions-fixed-0"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:788","name":"margin/margin-xs-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33670"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":6,"alias":"VariableID:1516:33670","aliasName":"space/dimensions-fixed-6"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:789","name":"margin/margin-sm-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1516:33669"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":10,"alias":"VariableID:1516:33669","aliasName":"space/dimensions-fixed-10"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:790","name":"margin/margin-sm-extra","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5688"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":12,"alias":"VariableID:203:5688","aliasName":"space/dimensions-fixed-12"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:791","name":"margin/margin-md-plus","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:5689"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":20,"alias":"VariableID:203:5689","aliasName":"space/dimensions-fixed-20"}},"scopes":["WIDTH_HEIGHT","GAP"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:924","name":"textFont/text-font-weight-regular","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1751:921"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":400,"alias":"VariableID:1751:921","aliasName":"fontWeight/font-weight-400"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1751:925","name":"textFont/text-font-weight-semibold","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1751:922"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":600,"alias":"VariableID:1751:922","aliasName":"fontWeight/font-weight-600"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1798:12878","name":"borderColor/borderColor-neutral-base","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:823:2"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":1},"alias":"VariableID:823:2","aliasName":"colors/colors-neutral-0"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1849:9055","name":"dimension/dimension-3XL","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:203:4495"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":48,"alias":"VariableID:203:4495","aliasName":"space/dimensions-fixed-48"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1849:9683","name":"textLetterspacing/text-letter-spacing-none","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1849:9684"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":0,"alias":"VariableID:1849:9684","aliasName":"fontSpacing/font-letter-spacing-none"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1970:8527","name":"backgroundColor/backgroundColor-neutral-dark-a50","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8513"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":0.5},"alias":"VariableID:1970:8513","aliasName":"colors/colors-neutral-900-a50"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1970:8528","name":"backgroundColor/backgroundColor-neutral-dark-a5","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8517"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":0.05000000074505806},"alias":"VariableID:1970:8517","aliasName":"colors/colors-neutral-900-a5"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1970:8529","name":"backgroundColor/backgroundColor-neutral-dark-a10","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8516"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":0.10000000149011612},"alias":"VariableID:1970:8516","aliasName":"colors/colors-neutral-900-a10"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1970:9130","name":"backgroundColor/backgroundColor-neutral-base-a30","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8521"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":0.30000001192092896},"alias":"VariableID:1970:8521","aliasName":"colors/colors-neutral-0-a30"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:1970:9131","name":"backgroundColor/backgroundColor-neutral-base-a20","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8522"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":0.20000000298023224},"alias":"VariableID:1970:8522","aliasName":"colors/colors-neutral-0-a20"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2237:20498","name":"borderColor/borderColor-destructive-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:40"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":0.9372549057006836,"b":0.9372549057006836,"a":1},"alias":"VariableID:38:40","aliasName":"colors/colors-destructive-100"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2237:20499","name":"borderColor/borderColor-success-subtle","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:38:23"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8705882430076599,"g":0.9647058844566345,"b":0.9490196108818054,"a":1},"alias":"VariableID:38:23","aliasName":"colors/colors-success-200"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2369:76482","name":"borderRadius/borderRadius-md","description":"","type":"FLOAT","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:2110:16027"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":6,"alias":"VariableID:2110:16027","aliasName":"radius/dimensions-border-radius-6"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2629:7631","name":"textColor/textColor-neutral-light-a50","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8520"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":0.5},"alias":"VariableID:1970:8520","aliasName":"colors/colors-neutral-0-a50"}},"scopes":["TEXT_FILL"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2665:9916","name":"backgroundColor/backgroundColor-neutral-base-a80","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8518"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":0.800000011920929},"alias":"VariableID:1970:8518","aliasName":"colors/colors-neutral-0-a80"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2675:17230","name":"fill/fill-neutral-base-a50","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8520"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":1,"g":1,"b":1,"a":0.5},"alias":"VariableID:1970:8520","aliasName":"colors/colors-neutral-0-a50"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:2675:20392","name":"fill/fill-neutral-xstrong-a30","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:1970:8514"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.09803921729326248,"g":0.10980392247438431,"b":0.125490203499794,"a":0.30000001192092896},"alias":"VariableID:1970:8514","aliasName":"colors/colors-neutral-900-a30"}},"scopes":["FRAME_FILL","SHAPE_FILL","STROKE_COLOR"],"hiddenFromPublishing":false,"codeSyntax":{}},{"id":"VariableID:4661:15434","name":"borderColor/borderColor-neutral-dimmed-darker","description":"","type":"COLOR","valuesByMode":{"37:2":{"type":"VARIABLE_ALIAS","id":"VariableID:39:51"}},"resolvedValuesByMode":{"37:2":{"resolvedValue":{"r":0.8909133672714233,"g":0.898869514465332,"b":0.9227376580238342,"a":1},"alias":"VariableID:39:51","aliasName":"colors/colors-neutral-300"}},"scopes":["ALL_SCOPES"],"hiddenFromPublishing":false,"codeSyntax":{}}]} \ No newline at end of file diff --git a/packages/admin-ui/scripts/importFromFigma/exports/Primitives.json b/packages/admin-ui/scripts/importFromFigma/exports/Primitives.json new file mode 100644 index 00000000000..8d9f03eb903 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/exports/Primitives.json @@ -0,0 +1,2464 @@ +{ + "id": "VariableCollectionId:37:3", + "name": ".Primitives", + "modes": { "37:0": "Light" }, + "variableIds": [ + "VariableID:37:4", + "VariableID:37:9", + "VariableID:38:15", + "VariableID:38:16", + "VariableID:38:17", + "VariableID:38:18", + "VariableID:38:19", + "VariableID:38:20", + "VariableID:38:21", + "VariableID:824:7478", + "VariableID:824:7479", + "VariableID:824:7480", + "VariableID:824:7481", + "VariableID:824:7482", + "VariableID:824:7483", + "VariableID:824:7484", + "VariableID:824:7485", + "VariableID:824:7486", + "VariableID:38:22", + "VariableID:38:23", + "VariableID:38:24", + "VariableID:38:25", + "VariableID:38:26", + "VariableID:38:27", + "VariableID:38:28", + "VariableID:38:29", + "VariableID:38:30", + "VariableID:38:31", + "VariableID:38:32", + "VariableID:38:33", + "VariableID:38:34", + "VariableID:38:35", + "VariableID:38:36", + "VariableID:38:37", + "VariableID:38:38", + "VariableID:38:39", + "VariableID:38:40", + "VariableID:38:41", + "VariableID:38:42", + "VariableID:38:43", + "VariableID:38:44", + "VariableID:38:45", + "VariableID:38:46", + "VariableID:823:2", + "VariableID:38:47", + "VariableID:2665:9917", + "VariableID:1970:8518", + "VariableID:1970:8519", + "VariableID:1970:8520", + "VariableID:2629:7632", + "VariableID:1970:8521", + "VariableID:1970:8522", + "VariableID:1970:8523", + "VariableID:1970:8524", + "VariableID:38:48", + "VariableID:118:19505", + "VariableID:39:49", + "VariableID:39:50", + "VariableID:39:51", + "VariableID:39:52", + "VariableID:39:53", + "VariableID:39:54", + "VariableID:39:55", + "VariableID:39:56", + "VariableID:39:57", + "VariableID:1970:8513", + "VariableID:1970:8514", + "VariableID:1970:8515", + "VariableID:1970:8516", + "VariableID:1970:8517", + "VariableID:39:133", + "VariableID:39:134", + "VariableID:2110:16027", + "VariableID:39:135", + "VariableID:39:136", + "VariableID:39:137", + "VariableID:52:21", + "VariableID:529:17331", + "VariableID:1148:691", + "VariableID:203:4491", + "VariableID:59:20", + "VariableID:59:21", + "VariableID:203:4489", + "VariableID:529:17332", + "VariableID:203:4487", + "VariableID:1516:33670", + "VariableID:203:4488", + "VariableID:1516:33669", + "VariableID:203:5688", + "VariableID:1516:33673", + "VariableID:203:4492", + "VariableID:1798:15360", + "VariableID:203:5689", + "VariableID:203:4493", + "VariableID:203:4494", + "VariableID:1849:9057", + "VariableID:203:4495", + "VariableID:203:4496", + "VariableID:529:17322", + "VariableID:1849:9684", + "VariableID:1658:637", + "VariableID:1658:610", + "VariableID:529:17323", + "VariableID:529:17324", + "VariableID:529:17325", + "VariableID:529:17326", + "VariableID:529:17327", + "VariableID:529:17328", + "VariableID:1522:9148", + "VariableID:529:17330", + "VariableID:1522:9149", + "VariableID:1522:9150", + "VariableID:1522:9152", + "VariableID:1522:9153", + "VariableID:1522:9154", + "VariableID:1522:9155", + "VariableID:1522:9156", + "VariableID:1522:9157", + "VariableID:1522:9193", + "VariableID:1522:9158", + "VariableID:1522:9159", + "VariableID:1522:9160", + "VariableID:1522:9161", + "VariableID:1522:9162", + "VariableID:1522:9163", + "VariableID:1639:536", + "VariableID:1639:537", + "VariableID:1639:538", + "VariableID:1639:539", + "VariableID:1751:920", + "VariableID:1751:921", + "VariableID:1751:922", + "VariableID:1751:923" + ], + "variables": [ + { + "id": "VariableID:37:4", + "name": "colors/colors-primary-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 1, "g": 0.9529722929000854, "b": 0.9474395513534546, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 0.9529722929000854, "b": 0.9474395513534546, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:37:9", + "name": "colors/colors-primary-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.9921568632125854, "g": 0.800000011920929, "b": 0.7372549176216125, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9921568632125854, + "g": 0.800000011920929, + "b": 0.7372549176216125, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:15", + "name": "colors/colors-primary-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9882352948188782, + "g": 0.6666666865348816, + "b": 0.5686274766921997, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9882352948188782, + "g": 0.6666666865348816, + "b": 0.5686274766921997, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:16", + "name": "colors/colors-primary-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 1, "g": 0.45098039507865906, "b": 0.2705882489681244, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 0.45098039507865906, "b": 0.2705882489681244, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:17", + "name": "colors/colors-primary-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9803921580314636, + "g": 0.34117648005485535, + "b": 0.13725490868091583, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9803921580314636, + "g": 0.34117648005485535, + "b": 0.13725490868091583, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:18", + "name": "colors/colors-primary-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.8784313797950745, + "g": 0.27843138575553894, + "b": 0.09019608050584793, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8784313797950745, + "g": 0.27843138575553894, + "b": 0.09019608050584793, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:19", + "name": "colors/colors-primary-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.7764706015586853, + "g": 0.20000000298023224, + "b": 0.0235294122248888, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.7764706015586853, + "g": 0.20000000298023224, + "b": 0.0235294122248888, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:20", + "name": "colors/colors-primary-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.6431372761726379, "g": 0.14901961386203766, "b": 0, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0.6431372761726379, "g": 0.14901961386203766, "b": 0, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:21", + "name": "colors/colors-primary-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.5098039507865906, "g": 0.12156862765550613, "b": 0, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0.5098039507865906, "g": 0.12156862765550613, "b": 0, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:22", + "name": "colors/colors-success-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9411764740943909, + "g": 0.9803921580314636, + "b": 0.9725490212440491, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9411764740943909, + "g": 0.9803921580314636, + "b": 0.9725490212440491, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:23", + "name": "colors/colors-success-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.8705882430076599, + "g": 0.9647058844566345, + "b": 0.9490196108818054, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8705882430076599, + "g": 0.9647058844566345, + "b": 0.9490196108818054, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:24", + "name": "colors/colors-success-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.6745098233222961, + "g": 0.9137254953384399, + "b": 0.8666666746139526, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.6745098233222961, + "g": 0.9137254953384399, + "b": 0.8666666746139526, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:25", + "name": "colors/colors-success-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.43921568989753723, + "g": 0.8588235378265381, + "b": 0.7803921699523926, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.43921568989753723, + "g": 0.8588235378265381, + "b": 0.7803921699523926, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:26", + "name": "colors/colors-success-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.7490196228027344, "b": 0.6196078658103943, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.7490196228027344, "b": 0.6196078658103943, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:27", + "name": "colors/colors-success-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.6941176652908325, "b": 0.5529412031173706, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.6941176652908325, "b": 0.5529412031173706, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:28", + "name": "colors/colors-success-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.572549045085907, "b": 0.4313725531101227, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.572549045085907, "b": 0.4313725531101227, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:29", + "name": "colors/colors-success-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.3921568691730499, "b": 0.25882354378700256, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.3921568691730499, "b": 0.25882354378700256, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:30", + "name": "colors/colors-success-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.29019609093666077, "b": 0.1921568661928177, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.29019609093666077, "b": 0.1921568661928177, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:31", + "name": "colors/colors-warning-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 1, "g": 0.9803921580314636, "b": 0.929411768913269, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 0.9803921580314636, "b": 0.929411768913269, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:32", + "name": "colors/colors-warning-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9960784316062927, + "g": 0.9333333373069763, + "b": 0.7529411911964417, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9960784316062927, + "g": 0.9333333373069763, + "b": 0.7529411911964417, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:33", + "name": "colors/colors-warning-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.9882352948188782, "g": 0.8745098114013672, "b": 0.529411792755127, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9882352948188782, + "g": 0.8745098114013672, + "b": 0.529411792755127, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:34", + "name": "colors/colors-warning-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9843137264251709, + "g": 0.8117647171020508, + "b": 0.29019609093666077, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9843137264251709, + "g": 0.8117647171020508, + "b": 0.29019609093666077, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:35", + "name": "colors/colors-warning-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9843137264251709, + "g": 0.8117647171020508, + "b": 0.29019609093666077, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9843137264251709, + "g": 0.8117647171020508, + "b": 0.29019609093666077, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:36", + "name": "colors/colors-warning-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.8509804010391235, "g": 0.6352941393852234, "b": 0, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0.8509804010391235, "g": 0.6352941393852234, "b": 0, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:37", + "name": "colors/colors-warning-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.7450980544090271, "g": 0.5568627715110779, "b": 0, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0.7450980544090271, "g": 0.5568627715110779, "b": 0, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:38", + "name": "colors/colors-warning-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.4274509847164154, + "g": 0.32156863808631897, + "b": 0.003921568859368563, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.4274509847164154, + "g": 0.32156863808631897, + "b": 0.003921568859368563, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:39", + "name": "colors/colors-warning-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.22745098173618317, + "g": 0.1725490242242813, + "b": 0.003921568859368563, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.22745098173618317, + "g": 0.1725490242242813, + "b": 0.003921568859368563, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:40", + "name": "colors/colors-destructive-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 1, "g": 0.9372549057006836, "b": 0.9372549057006836, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 0.9372549057006836, "b": 0.9372549057006836, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:41", + "name": "colors/colors-destructive-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9960784316062927, + "g": 0.7882353067398071, + "b": 0.7882353067398071, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9960784316062927, + "g": 0.7882353067398071, + "b": 0.7882353067398071, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:42", + "name": "colors/colors-destructive-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.9607843160629272, "g": 0.5803921818733215, "b": 0.572549045085907, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9607843160629272, + "g": 0.5803921818733215, + "b": 0.572549045085907, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:43", + "name": "colors/colors-destructive-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.8745098114013672, + "g": 0.3803921639919281, + "b": 0.3803921639919281, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8745098114013672, + "g": 0.3803921639919281, + "b": 0.3803921639919281, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:44", + "name": "colors/colors-destructive-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.8313725590705872, + "g": 0.1411764770746231, + "b": 0.1411764770746231, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8313725590705872, + "g": 0.1411764770746231, + "b": 0.1411764770746231, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:45", + "name": "colors/colors-destructive-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.6745098233222961, + "g": 0.09019608050584793, + "b": 0.0941176488995552, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.6745098233222961, + "g": 0.09019608050584793, + "b": 0.0941176488995552, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:46", + "name": "colors/colors-destructive-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.49803921580314636, + "g": 0.0784313753247261, + "b": 0.08627451211214066, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.49803921580314636, + "g": 0.0784313753247261, + "b": 0.08627451211214066, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:38:47", + "name": "colors/colors-destructive-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.3960784375667572, + "g": 0.03529411926865578, + "b": 0.03529411926865578, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.3960784375667572, + "g": 0.03529411926865578, + "b": 0.03529411926865578, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": { "WEB": "base-color/Destructive/colors-destructive-800" } + }, + { + "id": "VariableID:38:48", + "name": "colors/colors-destructive-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.30980393290519714, + "g": 0.0313725508749485, + "b": 0.03529411926865578, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.30980393290519714, + "g": 0.0313725508749485, + "b": 0.03529411926865578, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:49", + "name": "colors/colors-neutral-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9686274528503418, + "g": 0.9725490212440491, + "b": 0.9764705896377563, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9686274528503418, + "g": 0.9725490212440491, + "b": 0.9764705896377563, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:50", + "name": "colors/colors-neutral-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9411764740943909, + "g": 0.9450980424880981, + "b": 0.9529411792755127, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9411764740943909, + "g": 0.9450980424880981, + "b": 0.9529411792755127, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:51", + "name": "colors/colors-neutral-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.8909133672714233, "g": 0.898869514465332, "b": 0.9227376580238342, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8909133672714233, + "g": 0.898869514465332, + "b": 0.9227376580238342, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:52", + "name": "colors/colors-neutral-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.7438521981239319, + "g": 0.7645292282104492, + "b": 0.7989909052848816, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.7438521981239319, + "g": 0.7645292282104492, + "b": 0.7989909052848816, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:53", + "name": "colors/colors-neutral-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0.6138784885406494, "g": 0.6435658931732178, "b": 0.689746081829071, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.6138784885406494, + "g": 0.6435658931732178, + "b": 0.689746081829071, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:54", + "name": "colors/colors-neutral-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.4613589644432068, + "g": 0.5014801025390625, + "b": 0.5576497316360474, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.4613589644432068, + "g": 0.5014801025390625, + "b": 0.5576497316360474, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:55", + "name": "colors/colors-neutral-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.34716352820396423, + "g": 0.38350826501846313, + "b": 0.42792969942092896, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.34716352820396423, + "g": 0.38350826501846313, + "b": 0.42792969942092896, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:56", + "name": "colors/colors-neutral-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.1882352977991104, + "g": 0.2078431397676468, + "b": 0.23529411852359772, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.1882352977991104, + "g": 0.2078431397676468, + "b": 0.23529411852359772, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:57", + "name": "colors/colors-neutral-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:133", + "name": "radius/dimensions-border-radius-2", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 2 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 2, "alias": null } }, + "scopes": ["WIDTH_HEIGHT"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:134", + "name": "radius/dimensions-border-radius-4", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 4 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 4, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:135", + "name": "radius/dimensions-border-radius-8", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 8 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 8, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:136", + "name": "radius/dimensions-border-radius-16", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 16 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 16, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:39:137", + "name": "radius/dimensions-border-radius-24", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 24 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 24, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:52:21", + "name": "radius/dimensions-border-radius-36", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 36 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 36, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:59:20", + "name": "borderWidth/dimensions-border-width-1", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 1 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 1, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:59:21", + "name": "borderWidth/dimensions-border-width-2", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 2 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 2, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:118:19505", + "name": "colors/colors-neutral-50", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9803921580314636, + "g": 0.9843137264251709, + "b": 0.9843137264251709, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9803921580314636, + "g": 0.9843137264251709, + "b": 0.9843137264251709, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4487", + "name": "space/dimensions-fixed-4", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 4 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 4, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4488", + "name": "space/dimensions-fixed-8", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 8 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 8, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4489", + "name": "space/dimensions-fixed-2", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 2 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 2, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4491", + "name": "space/dimensions-fixed-1", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 1 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 1, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4492", + "name": "space/dimensions-fixed-16", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 16 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 16, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4493", + "name": "space/dimensions-fixed-24", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 24 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 24, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4494", + "name": "space/dimensions-fixed-32", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 32 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 32, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4495", + "name": "space/dimensions-fixed-48", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 48 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 48, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:4496", + "name": "space/dimensions-fixed-64", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 64 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 64, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:5688", + "name": "space/dimensions-fixed-12", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 12 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 12, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:203:5689", + "name": "space/dimensions-fixed-20", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 20 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 20, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17322", + "name": "fontSize/font-size-text-10", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 10 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 10, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17323", + "name": "fontSize/font-size-text-12", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 12 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 12, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17324", + "name": "fontSize/font-size-text-14", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 14 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 14, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17325", + "name": "fontSize/font-size-text-16", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 16 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 16, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17326", + "name": "fontSize/font-size-text-18", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 18 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 18, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17327", + "name": "fontSize/font-size-text-20", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 20 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 20, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17328", + "name": "fontSize/font-size-text-24", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 24 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 24, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17330", + "name": "fontSize/font-size-text-32", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 32 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 32, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17331", + "name": "borderWidth/dimensions-border-width-0", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 0 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 0, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:529:17332", + "name": "borderWidth/dimensions-border-width-4", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 4 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 4, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:823:2", + "name": "colors/colors-neutral-0", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 1 } }, + "resolvedValuesByMode": { + "37:0": { "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 1 }, "alias": null } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7478", + "name": "colors/colors-secondary-100", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.9411764740943909, + "g": 0.9803921580314636, + "b": 0.9725490212440491, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.9411764740943909, + "g": 0.9803921580314636, + "b": 0.9725490212440491, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7479", + "name": "colors/colors-secondary-200", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.8705882430076599, + "g": 0.9647058844566345, + "b": 0.9490196108818054, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.8705882430076599, + "g": 0.9647058844566345, + "b": 0.9490196108818054, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7480", + "name": "colors/colors-secondary-300", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.6745098233222961, + "g": 0.9137254953384399, + "b": 0.8666666746139526, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.6745098233222961, + "g": 0.9137254953384399, + "b": 0.8666666746139526, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7481", + "name": "colors/colors-secondary-400", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.43921568989753723, + "g": 0.8588235378265381, + "b": 0.7803921699523926, + "a": 1 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.43921568989753723, + "g": 0.8588235378265381, + "b": 0.7803921699523926, + "a": 1 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7482", + "name": "colors/colors-secondary-500", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.7490196228027344, "b": 0.6196078658103943, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.7490196228027344, "b": 0.6196078658103943, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7483", + "name": "colors/colors-secondary-600", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.6941176652908325, "b": 0.5529412031173706, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.6941176652908325, "b": 0.5529412031173706, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7484", + "name": "colors/colors-secondary-700", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.572549045085907, "b": 0.4313725531101227, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.572549045085907, "b": 0.4313725531101227, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7485", + "name": "colors/colors-secondary-800", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.3921568691730499, "b": 0.25882354378700256, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.3921568691730499, "b": 0.25882354378700256, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:824:7486", + "name": "colors/colors-secondary-900", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { "r": 0, "g": 0.29019609093666077, "b": 0.1921568661928177, "a": 1 } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 0, "g": 0.29019609093666077, "b": 0.1921568661928177, "a": 1 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1148:691", + "name": "space/dimensions-fixed-0", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 0 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 0, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1516:33669", + "name": "space/dimensions-fixed-10", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 10 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 10, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1516:33670", + "name": "space/dimensions-fixed-6", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 6 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 6, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1516:33673", + "name": "space/dimensions-fixed-14", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 14 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 14, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9148", + "name": "fontSize/font-size-text-30", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 30 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 30, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9149", + "name": "fontSize/font-size-text-36", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 36 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 36, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9150", + "name": "fontSize/font-size-text-48", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 48 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 48, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9152", + "name": "lineHeight/line-height-text-10", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 10 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 10, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9153", + "name": "lineHeight/line-height-text-12", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 12 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 12, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9154", + "name": "lineHeight/line-height-text-14", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 14 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 14, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9155", + "name": "lineHeight/line-height-text-16", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 16 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 16, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9156", + "name": "lineHeight/line-height-text-18", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 18 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 18, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9157", + "name": "lineHeight/line-height-text-20", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 20 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 20, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9158", + "name": "lineHeight/line-height-text-24", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 24 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 24, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9159", + "name": "lineHeight/line-height-text-30", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 30 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 30, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9160", + "name": "lineHeight/line-height-text-32", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 32 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 32, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9161", + "name": "lineHeight/line-height-text-38", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 38 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 38, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9162", + "name": "lineHeight/line-height-text-44", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 44 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 44, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9163", + "name": "lineHeight/line-height-text-60", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 60 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 60, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1522:9193", + "name": "lineHeight/line-height-text-22", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 22 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 22, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1639:536", + "name": "ringWidth/dimensions-ring-width-0", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 0 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 0, "alias": null } }, + "scopes": ["WIDTH_HEIGHT"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1639:537", + "name": "ringWidth/dimensions-ring-width-1", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 1 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 1, "alias": null } }, + "scopes": ["WIDTH_HEIGHT"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1639:538", + "name": "ringWidth/dimensions-ring-width-2", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 2 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 2, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1639:539", + "name": "ringWidth/dimensions-ring-width-4", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 4 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 4, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1658:610", + "name": "fontSpacing/font-letter-spacing-2", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": -2 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": -2, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1658:637", + "name": "fontSpacing/font-letter-spacing-1", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": -1 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": -1, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1751:920", + "name": "fontWeight/font-weight-100", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 100 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 100, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1751:921", + "name": "fontWeight/font-weight-400", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 400 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 400, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1751:922", + "name": "fontWeight/font-weight-600", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 600 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 600, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1751:923", + "name": "fontWeight/font-weight-700", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 700 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 700, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1798:15360", + "name": "space/dimensions-fixed-18", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 18 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 18, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1849:9057", + "name": "space/dimensions-fixed-40", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 40 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 40, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1849:9684", + "name": "fontSpacing/font-letter-spacing-none", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 0 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 0, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8513", + "name": "colors/colors-neutral-900-a50", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.5 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.5 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8514", + "name": "colors/colors-neutral-900-a30", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.30000001192092896 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.30000001192092896 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8515", + "name": "colors/colors-neutral-900-a20", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.20000000298023224 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.20000000298023224 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8516", + "name": "colors/colors-neutral-900-a10", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.10000000149011612 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.10000000149011612 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8517", + "name": "colors/colors-neutral-900-a5", + "description": "", + "type": "COLOR", + "valuesByMode": { + "37:0": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.05000000074505806 + } + }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { + "r": 0.09803921729326248, + "g": 0.10980392247438431, + "b": 0.125490203499794, + "a": 0.05000000074505806 + }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8518", + "name": "colors/colors-neutral-0-a80", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.800000011920929 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.800000011920929 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8519", + "name": "colors/colors-neutral-0-a70", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.699999988079071 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.699999988079071 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8520", + "name": "colors/colors-neutral-0-a50", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.5 } }, + "resolvedValuesByMode": { + "37:0": { "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.5 }, "alias": null } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8521", + "name": "colors/colors-neutral-0-a30", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.30000001192092896 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.30000001192092896 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8522", + "name": "colors/colors-neutral-0-a20", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.20000000298023224 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.20000000298023224 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8523", + "name": "colors/colors-neutral-0-a10", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.10000000149011612 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.10000000149011612 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:1970:8524", + "name": "colors/colors-neutral-0-a5", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.05000000074505806 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.05000000074505806 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:2110:16027", + "name": "radius/dimensions-border-radius-6", + "description": "", + "type": "FLOAT", + "valuesByMode": { "37:0": 6 }, + "resolvedValuesByMode": { "37:0": { "resolvedValue": 6, "alias": null } }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:2629:7632", + "name": "colors/colors-neutral-0-a40", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.4000000059604645 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.4000000059604645 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + }, + { + "id": "VariableID:2665:9917", + "name": "colors/colors-neutral-0-a95", + "description": "", + "type": "COLOR", + "valuesByMode": { "37:0": { "r": 1, "g": 1, "b": 1, "a": 0.949999988079071 } }, + "resolvedValuesByMode": { + "37:0": { + "resolvedValue": { "r": 1, "g": 1, "b": 1, "a": 0.949999988079071 }, + "alias": null + } + }, + "scopes": ["ALL_SCOPES"], + "hiddenFromPublishing": false, + "codeSyntax": {} + } + ] +} diff --git a/packages/admin-ui/scripts/importFromFigma/figmaRgbaToHsla.js b/packages/admin-ui/scripts/importFromFigma/figmaRgbaToHsla.js new file mode 100644 index 00000000000..d6ab4b73331 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/figmaRgbaToHsla.js @@ -0,0 +1,53 @@ +function rgbToHsl(r, g, b) { + // Convert RGB values (0-255 range) to the range of 0-1 + r /= 255; + g /= 255; + b /= 255; + + const maxVal = Math.max(r, g, b); + const minVal = Math.min(r, g, b); + const delta = maxVal - minVal; + + let h = 0, + s = 0, + l = (maxVal + minVal) / 2; + + if (delta !== 0) { + s = delta / (1 - Math.abs(2 * l - 1)); + + if (maxVal === r) { + h = ((g - b) / delta) % 6; + } else if (maxVal === g) { + h = (b - r) / delta + 2; + } else { + h = (r - g) / delta + 4; + } + + h = Math.round(h * 60); // Convert to degrees + if (h < 0) { + h += 360; + } + } + + s = +(s * 100).toFixed(1); + l = +(l * 100).toFixed(1); + + return { h, s, l }; +} + +function figmaRgbaToHsla(figmaColor) { + const { r, g, b, a } = figmaColor; + + // Convert normalized RGBA to standard RGB (0-255) + const red = Math.round(r * 255); + const green = Math.round(g * 255); + const blue = Math.round(b * 255); + + // Get the HSL values + const { h, s, l } = rgbToHsl(red, green, blue); + + // Return the HSLA value + return { h, s, l, a }; +} + +module.exports = { figmaRgbaToHsla }; diff --git a/packages/admin-ui/scripts/importFromFigma/formatCode.js b/packages/admin-ui/scripts/importFromFigma/formatCode.js new file mode 100644 index 00000000000..3b851aaf12c --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/formatCode.js @@ -0,0 +1,14 @@ +const fs = require("fs"); +const prettier = require("prettier"); + +const formatCode = async filePath => { + const options = await prettier.resolveConfig(filePath); + const fileContentRaw = fs.readFileSync(filePath).toString("utf8"); + const fileContentFormatted = prettier.format(fileContentRaw, { + ...options, + filepath: filePath + }); + fs.writeFileSync(filePath, fileContentFormatted); +}; + +module.exports = { formatCode }; diff --git a/packages/admin-ui/scripts/importFromFigma/normalizeFigmaExport.js b/packages/admin-ui/scripts/importFromFigma/normalizeFigmaExport.js new file mode 100644 index 00000000000..546b3240269 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/normalizeFigmaExport.js @@ -0,0 +1,71 @@ +const aliasTokensExport = require("./exports/Alias tokens.json"); +const { figmaRgbaToHsla } = require("./figmaRgbaToHsla"); + +const VARIABLE_TYPES = [ + "backgroundColor", + "borderColor", + "borderRadius", + "borderWidth", + "fill", + "margin", + "padding", + "ringColor", + "ringWidth", + "shadow", + "spacing", + "textColor", + "textFont" +]; + +const IGNORED_VARIABLE_TYPES = ["dimension", "textLetterspacing"]; + +const isIgnoredVariableType = variableName => { + for (const type of IGNORED_VARIABLE_TYPES) { + if (variableName.startsWith(type + "/")) { + return true; + } + } + + return false; +}; + +const getVariableType = variableName => { + for (const type of VARIABLE_TYPES) { + if (variableName.startsWith(type + "/")) { + return type; + } + } + + throw new Error(`Unknown variable type for variable "${variableName}".`); +}; + +const normalizeFigmaExport = () => { + return aliasTokensExport.variables + .map(variable => { + const { aliasName, resolvedValue } = variable.resolvedValuesByMode["37:2"]; + + const [, variantName] = variable.name.match(/[a-zA-Z]*?\/[a-zA-Z]*?-(.*)/); + + if (isIgnoredVariableType(variable.name)) { + return null; + } + + const type = getVariableType(variable.name); + + return { + type, + name: variable.name, + aliasName, + hsla: figmaRgbaToHsla(resolvedValue), + variantName, + resolvedValue + }; + }) + .filter(Boolean) + .sort((variable1, variable2) => { + // Order by variable.name, from A to Z. + return variable1.name.localeCompare(variable2.name); + }); +}; + +module.exports = { normalizeFigmaExport }; diff --git a/packages/admin-ui/scripts/importFromFigma/normalizePrimitivesFigmaExport.js b/packages/admin-ui/scripts/importFromFigma/normalizePrimitivesFigmaExport.js new file mode 100644 index 00000000000..d7e6804d8cb --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/normalizePrimitivesFigmaExport.js @@ -0,0 +1,64 @@ +const primitiveTokensExport = require("./exports/Primitives.json"); +const { figmaRgbaToHsla } = require("./figmaRgbaToHsla"); + +const INCLUDED_VARIABLE_TYPES = ["colors"]; + +// We don't need tokens that end with `-a{one or two numbers}` because they are used for +// alpha colors. We don't need these because we can use the /alpha function in Tailwind CSS. +const isColorWithAlpha = variantName => { + return variantName.match(/^.*-a\d{1,2}$/); +}; + +const isIncludedVariableType = variableName => { + for (const type of INCLUDED_VARIABLE_TYPES) { + if (variableName.startsWith(type + "/")) { + return true; + } + } + + return false; +}; + +const getVariableType = variableName => { + for (const type of INCLUDED_VARIABLE_TYPES) { + if (variableName.startsWith(type + "/")) { + return type; + } + } + + throw new Error(`Unknown variable type for variable "${variableName}".`); +}; + +const normalizePrimitivesFigmaExport = () => { + return primitiveTokensExport.variables + .map(variable => { + const resolvedValue = variable.valuesByMode["37:0"]; + + const [, variantName] = variable.name.match(/[a-zA-Z]*?\/[a-zA-Z]*?-(.*)/); + + if (!isIncludedVariableType(variable.name)) { + return null; + } + + const type = getVariableType(variable.name); + + if (isColorWithAlpha(variantName)) { + return null; + } + + return { + type, + name: variable.name, + hsla: figmaRgbaToHsla(resolvedValue), + variantName, + resolvedValue + }; + }) + .filter(Boolean) + .sort((variable1, variable2) => { + // Order by variable.name, from A to Z. + return variable1.name.localeCompare(variable2.name); + }); +}; + +module.exports = { normalizePrimitivesFigmaExport }; diff --git a/packages/admin-ui/scripts/importFromFigma/templates/theme.scss.txt b/packages/admin-ui/scripts/importFromFigma/templates/theme.scss.txt new file mode 100644 index 00000000000..27c24265b54 --- /dev/null +++ b/packages/admin-ui/scripts/importFromFigma/templates/theme.scss.txt @@ -0,0 +1,79 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap"); + +@layer base { + :root { + // Colors. + {COLORS} + + // Background colors. + {BACKGROUND_COLOR} + + // Border color. + {BORDER_COLOR} + + // Border radius. + {BORDER_RADIUS} + + // Border width. + {BORDER_WIDTH} + + // Fill. + {FILL} + + // Font. + {FONT} + + // Font weight. + {FONT_WEIGHT} + + // Margin. + {MARGIN} + + // Padding. + {PADDING} + + // Ring color. + {RING_COLOR} + + // Ring width. + {RING_WIDTH} + + // Shadow. + {SHADOW} + + // Spacing. + {SPACING} + + // Text color. + {TEXT_COLOR} + + // Text size. + {TEXT_SIZE} + } +} + +@layer base { + body { + // Styles all text that was not rendered via the Text component. + @apply wby-font-sans wby-antialiased wby-text-md wby-text-neutral-primary; + } + + a { + // Styles all links that were not rendered via the Link component. + @apply wby-text-accent-primary hover:wby-underline focus-visible:wby-outline-none focus-visible:wby-ring-lg focus-visible:wby-ring-primary-dimmed wby-rounded-xs; + } + + b, + strong { + @apply wby-font-semibold; + } + + i, + em { + @apply wby-italic; + } +} diff --git a/packages/admin-ui/src/Accordion/Accordion.mdx b/packages/admin-ui/src/Accordion/Accordion.mdx new file mode 100644 index 00000000000..9b9ad507d38 --- /dev/null +++ b/packages/admin-ui/src/Accordion/Accordion.mdx @@ -0,0 +1,509 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; + +import * as AccordionStories from './Accordion.stories'; + + + +# Accordion + +The Accordion component is a vertically stacked set of interactive headings that each reveal an associated section of content. It allows users to show and hide sections of related content on a page, helping to reduce page length and organize complex content. + +## Usage + + { + return ( + + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } + > + This is the content for the first accordion item. It can contain any React elements. + + + + This is the content for the second accordion item. It's open by default. + + + + This content won't be visible because the item is disabled. + + + ); +}; + +export default AccordionExample; + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Accordion/Accordion.tsx', + '_blank' + ); + }, + } + ]} +/> + + + +```tsx +import React from "react"; +import { Accordion } from "@webiny/admin-ui"; +import { ReactComponent as WarningIcon } from "@webiny/icons/insert_chart.svg"; +import { ReactComponent as EditIcon } from "@webiny/icons/edit.svg"; +import { ReactComponent as TrashIcon } from "@webiny/icons/delete.svg"; + +const AccordionExample = () => { + return ( + + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } + > + This is the content for the first accordion item. It can contain any React elements. + + + + This is the content for the second accordion item. It's open by default. + + + + This content won't be visible because the item is disabled. + + + ); +}; + +export default AccordionExample; +``` + +## Examples + +### Default + + { + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. Etiam venenatis, odio + sed consectetur consectetur, quam quam blandit ante, semper maximus lorem est vel dolor. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. Etiam venenatis, odio + sed consectetur consectetur, quam quam blandit ante, semper maximus lorem est vel dolor. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. Etiam venenatis, odio + sed consectetur consectetur, quam quam blandit ante, semper maximus lorem est vel dolor. + + + ); +}; + +export default DefaultAccordionExample; +` } } /> + +### With Descriptions + + { + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default WithDescriptionsExample; +` } } /> + +### With Icon + + { + return ( + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default WithIconExample; +` } } /> + +### With Actions + + { + return ( + + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } /> + } /> + + } + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } /> + } /> + + } + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default WithActionsExample; +` } } /> + +### With Handle + + { + return ( + + } label={"Warning icon"} />} + handle={} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default WithHandleExample; +` } } /> + +### Non-Interactive Item + + { + return ( + + + This content won't be accessible because the item is not interactive. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default NonInteractiveExample; +` } } /> + +### Default Open Item + + { + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + This item is open by default. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Sed elit sem, pretium sit amet convallis nec, consequat non nulla. + + + ); +}; + +export default DefaultOpenExample; +` } } /> + +### Disabled Item + + { + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + This content won't be accessible because the item is disabled. + + + This item is disabled but open by default. Users cannot toggle it. + + + ); +}; + +export default DisabledItemExample; +` } } /> + +### Container Variant + + { + return ( + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default ContainerVariantExample; +` } } /> + +### Light Background + + { + return ( + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default LightBackgroundExample; +` } } /> + +### Container Variant with Light Background + + { + return ( + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + } label={"Warning icon"} />} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. + + + ); +}; + +export default ContainerLightExample; +` } } /> diff --git a/packages/admin-ui/src/Accordion/Accordion.stories.tsx b/packages/admin-ui/src/Accordion/Accordion.stories.tsx new file mode 100644 index 00000000000..c45a0099de3 --- /dev/null +++ b/packages/admin-ui/src/Accordion/Accordion.stories.tsx @@ -0,0 +1,401 @@ +import React, { useState } from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import { Accordion, type AccordionItemProps as BaseAccordionItemProps } from "./Accordion"; + +import { ReactComponent as WarningIcon } from "@webiny/icons/insert_chart.svg"; +import { ReactComponent as ArrowUp } from "@webiny/icons/arrow_upward.svg"; +import { ReactComponent as ArrowDown } from "@webiny/icons/arrow_downward.svg"; +import { ReactComponent as EditIcon } from "@webiny/icons/edit.svg"; +import { ReactComponent as TrashIcon } from "@webiny/icons/delete.svg"; +import { Button } from "~/Button"; + +const meta: Meta = { + title: "Components/Accordion", + component: Accordion, + argTypes: {}, + decorators: [ + Story => ( +
+ +
+ ) + ], + render: args => { + return ; + } +}; + +export default meta; + +type Story = StoryObj; + +interface AccordionItemProps extends Omit { + index: number; +} + +const AccordionItem = (props: AccordionItemProps) => { + return ( + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed elit sem, pretium sit amet + convallis nec, consequat non nulla. Nunc sit amet sagittis tellus. Etiam venenatis, odio + sed consectetur consectetur, quam quam blandit ante, semper maximus lorem est vel dolor. + Praesent ac neque rutrum, elementum turpis et, vulputate enim. In ex lorem, + + ); +}; + +export const Default: Story = { + args: { + children: ( + <> + + + + + ) + } +}; + +export const WithDescriptions: Story = { + ...Default, + args: { + children: ( + <> + + + + + ) + }, + argTypes: {} +}; + +export const WithIcon: Story = { + ...Default, + args: { + children: ( + <> + } label={"Warning icon"} />} + /> + } label={"Warning icon"} />} + /> + + ) + } +}; + +export const WithActionsIcon: Story = { + ...Default, + args: { + children: ( + <> + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } /> + } /> + + } + /> + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } /> + } /> + + } + /> + + ) + } +}; + +export const WithHandleIcon: Story = { + ...Default, + args: { + children: ( + <> + } label={"Warning icon"} />} + handle={} + /> + } + /> + + ) + } +}; + +export const WithNotInteractiveItem: Story = { + ...Default, + args: { + children: ( + <> + + + + + ) + } +}; + +export const WithDefaultOpenedItem: Story = { + ...Default, + args: { + children: ( + <> + + + + ) + } +}; + +export const WithDisabledItem: Story = { + ...Default, + args: { + children: ( + <> + + + + + ) + } +}; + +export const WithControlledOpenedItem: Story = { + ...Default, + render: args => { + const [openFirstItem, setOpenFirstItem] = useState(); + const [openSecondItem, setOpenSecondItem] = useState(); + const [openThirdItem, setOpenThirdItem] = useState(); + + return ( + <> + + + + + +
+
+ + ); + } +}; + +export const ContainerVariant: Story = { + ...Default, + args: { + variant: "container", + children: ( + <> + } label={"Warning icon"} />} + /> + } label={"Warning icon"} />} + /> + + ) + } +}; + +export const LightBackground: Story = { + ...Default, + decorators: [ + Story => ( +
+ +
+ ) + ], + args: { + background: "light", + children: ( + <> + } label={"Warning icon"} />} + /> + } label={"Warning icon"} />} + /> + + ) + } +}; + +export const ContainerVariantWithLightBackground: Story = { + ...Default, + decorators: [ + Story => ( +
+ +
+ ) + ], + args: { + variant: "container", + background: "light", + children: ( + <> + } label={"Warning icon"} />} + /> + } label={"Warning icon"} />} + /> + + ) + } +}; + +// Add a Documentation story +export const Documentation: Story = { + render: args => { + return ; + }, + args: { + variant: "underline", + background: "base", + children: ( + <> + } label={"Warning icon"} />} + actions={ + <> + } /> + } /> + + } + > + This is the content for the first accordion item. It can contain any React + elements. + + + + This is the content for the second accordion item. It's open by default. + + + + This content won't be visible because the item is disabled. + + + ) + }, + argTypes: { + variant: { + control: "select", + options: ["underline", "container"], + description: "The visual style of the accordion" + }, + background: { + control: "select", + options: ["base", "light", "transparent"], + description: "The background color of the accordion" + }, + children: { + description: + "The content of the accordion. Please refer to the example code for details.", + control: "none" + } + } +}; diff --git a/packages/admin-ui/src/Accordion/Accordion.tsx b/packages/admin-ui/src/Accordion/Accordion.tsx new file mode 100644 index 00000000000..e87b94b53e2 --- /dev/null +++ b/packages/admin-ui/src/Accordion/Accordion.tsx @@ -0,0 +1,43 @@ +import React from "react"; +import { makeDecoratable, withStaticProps, cva, type VariantProps, cn } from "~/utils"; +import { AccordionRoot } from "./components/AccordionRoot"; +import { AccordionItem, type AccordionItemProps } from "./components/AccordionItem"; + +const accordionVariants = cva("wby-group wby-w-full", { + variants: { + variant: { + container: "wby-accordion-variant-container wby-gap-xs wby-flex wby-flex-col", + underline: "wby-accordion-variant-underline " + }, + background: { + base: "wby-accordion-background-base", + light: "wby-accordion-background-light", + transparent: "wby-accordion-background-transparent" + } + }, + defaultVariants: { + variant: "underline", + background: "base" + } +}); + +type AccordionProps = React.ComponentPropsWithoutRef & + VariantProps & { + children: React.ReactNode; + }; + +const AccordionBase = ({ children, variant, background, className, ...props }: AccordionProps) => { + return ( +
+ {children} +
+ ); +}; + +const DecoratableAccordion = makeDecoratable("Accordion", AccordionBase); + +const Accordion = withStaticProps(DecoratableAccordion, { + Item: AccordionItem +}); + +export { Accordion, type AccordionProps, type AccordionItemProps }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionContent.tsx b/packages/admin-ui/src/Accordion/components/AccordionContent.tsx new file mode 100644 index 00000000000..a8ce2077c2c --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionContent.tsx @@ -0,0 +1,49 @@ +import * as React from "react"; +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; +import { cva, type VariantProps, cn } from "~/utils"; + +const accordionContentVariants = cva( + [ + "wby-overflow-hidden wby-text-md", + "wby-transition-all data-[state=closed]:wby-animate-collapsible-up data-[state=open]:wby-animate-collapsible-down" + ], + { + // Using pixel values here because of non-existing design tokens. + variants: { + withIcon: { + true: "wby-pl-9" + }, + withHandle: { + true: "wby-pl-5" + } + }, + compoundVariants: [ + { + withIcon: true, + withHandle: true, + className: "wby-pl-14" + } + ], + defaultVariants: { + withIcon: false, + withHandle: false + } + } +); + +export interface AccordionContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const AccordionContent = ({ children, withIcon, withHandle, ...props }: AccordionContentProps) => { + return ( + +
{children}
+
+ ); +}; + +export { AccordionContent }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionItem.tsx b/packages/admin-ui/src/Accordion/components/AccordionItem.tsx new file mode 100644 index 00000000000..c0e3516c6ef --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionItem.tsx @@ -0,0 +1,82 @@ +import * as React from "react"; +import { cn, makeDecoratable, withStaticProps } from "~/utils"; +import { AccordionTrigger } from "./AccordionTrigger"; +import { AccordionContent } from "./AccordionContent"; +import { AccordionItemIcon } from "./AccordionItemIcon"; +import { AccordionItemAction } from "./AccordionItemAction"; +import { AccordionItemHandle } from "./AccordionItemHandle"; +import { AccordionRoot, type AccordionRootProps } from "~/Accordion/components/AccordionRoot"; + +interface AccordionItemProps extends Omit { + title: React.ReactNode; + description?: React.ReactNode; + icon?: React.ReactNode; + handle?: React.ReactNode; + interactive?: boolean; + actions?: React.ReactNode; + children: React.ReactNode; +} + +const AccordionItemBase = (props: AccordionItemProps) => { + const { itemProps, triggerProps, contentProps } = React.useMemo(() => { + const { + // Item props. + className, + defaultOpen, + disabled, + interactive, + onOpenChange, + open, + + // Content props. + children, + + // Trigger props. + ...triggerProps + } = props; + + return { + itemProps: { + className, + defaultOpen, + disabled, + onOpenChange, + open + }, + triggerProps: { + ...triggerProps, + interactive + }, + contentProps: { children, withIcon: !!props.icon, withHandle: !!props.handle } + }; + }, [props]); + + return ( + + + + + ); +}; + +const DecoratableAccordionItem = makeDecoratable("AccordionItem", AccordionItemBase); + +const AccordionItem = withStaticProps(DecoratableAccordionItem, { + Icon: AccordionItemIcon, + Action: AccordionItemAction, + Handle: AccordionItemHandle +}); + +export { AccordionItem, type AccordionItemProps }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionItemAction.tsx b/packages/admin-ui/src/Accordion/components/AccordionItemAction.tsx new file mode 100644 index 00000000000..65c32315478 --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionItemAction.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; +import { makeDecoratable, withStaticProps } from "~/utils"; +import { IconButton, IconButtonProps as IconButtonProps } from "~/Button"; +import { AccordionItemSeparator } from "./AccordionItemSeparator"; + +type AccordionItemActionProps = IconButtonProps; + +const AccordionItemActionBase = ({ onClick, ...props }: AccordionItemActionProps) => { + // We need to stop the event propagation to prevent the accordion from opening/closing when the action is clicked. + const onClickCallback = React.useCallback( + (e: React.MouseEvent) => { + e.stopPropagation(); + + if (onClick) { + onClick(e); + } + }, + [onClick] + ); + + return ; +}; + +const DecoratableAccordionItemAction = makeDecoratable( + "AccordionItemAction", + AccordionItemActionBase +); + +const AccordionItemAction = withStaticProps(DecoratableAccordionItemAction, { + Separator: AccordionItemSeparator +}); + +export { AccordionItemAction, type AccordionItemActionProps }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionItemHandle.tsx b/packages/admin-ui/src/Accordion/components/AccordionItemHandle.tsx new file mode 100644 index 00000000000..f5d9f99e5ff --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionItemHandle.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { ReactComponent as DragHandleIcon } from "@webiny/icons/drag_indicator.svg"; +import { makeDecoratable } from "~/utils"; +import { Icon, IconProps as IconProps } from "~/Icon"; + +interface AccordionItemHandleProps extends Omit { + icon?: React.ReactElement; + label?: string; +} + +const AccordionItemHandleBase = ({ onClick, ...props }: AccordionItemHandleProps) => { + // We need to stop the event propagation to prevent the accordion from opening/closing when the handle is clicked. + const onClickCallback = React.useCallback( + (e: React.MouseEvent) => { + e.stopPropagation(); + + if (onClick) { + onClick(e); + } + }, + [onClick] + ); + + return ( + } + label={"Drag handle"} + {...props} + onClick={onClickCallback} + /> + ); +}; + +const AccordionItemHandle = makeDecoratable("AccordionItemHandle", AccordionItemHandleBase); + +export { AccordionItemHandle, type AccordionItemHandleProps }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionItemIcon.tsx b/packages/admin-ui/src/Accordion/components/AccordionItemIcon.tsx new file mode 100644 index 00000000000..aa2b8b78044 --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionItemIcon.tsx @@ -0,0 +1,11 @@ +import * as React from "react"; +import { makeDecoratable } from "~/utils"; +import { Icon as IconComponent, IconProps as IconComponentProps } from "~/Icon"; + +type AccordionItemIconProps = IconComponentProps; + +const AccordionItemIconBase = (props: AccordionItemIconProps) => { + return ; +}; + +export const AccordionItemIcon = makeDecoratable("AccordionItemIcon", AccordionItemIconBase); diff --git a/packages/admin-ui/src/Accordion/components/AccordionItemSeparator.tsx b/packages/admin-ui/src/Accordion/components/AccordionItemSeparator.tsx new file mode 100644 index 00000000000..d2df80dee16 --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionItemSeparator.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; +import { makeDecoratable } from "~/utils"; +import { Separator, type SeparatorProps } from "~/Separator"; + +type AccordionItemSeparatorProps = SeparatorProps; + +const AccordionItemSeparatorBase = (props: AccordionItemSeparatorProps) => { + return ; +}; + +export const AccordionItemSeparator = makeDecoratable( + "AccordionItemSeparator", + AccordionItemSeparatorBase +); diff --git a/packages/admin-ui/src/Accordion/components/AccordionRoot.tsx b/packages/admin-ui/src/Accordion/components/AccordionRoot.tsx new file mode 100644 index 00000000000..502c366fd4c --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionRoot.tsx @@ -0,0 +1,7 @@ +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; + +type AccordionRootProps = CollapsiblePrimitive.CollapsibleProps; + +const AccordionRoot = CollapsiblePrimitive.Root; + +export { AccordionRoot, type AccordionRootProps }; diff --git a/packages/admin-ui/src/Accordion/components/AccordionTrigger.tsx b/packages/admin-ui/src/Accordion/components/AccordionTrigger.tsx new file mode 100644 index 00000000000..87a7c812848 --- /dev/null +++ b/packages/admin-ui/src/Accordion/components/AccordionTrigger.tsx @@ -0,0 +1,94 @@ +import * as React from "react"; +import { ReactComponent as KeyboardArrowDownIcon } from "@webiny/icons/keyboard_arrow_down.svg"; +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; +import { cn } from "~/utils"; +import { type AccordionItemProps } from "./AccordionItem"; +import { AccordionItemAction } from "./AccordionItemAction"; +import { Icon } from "~/Icon"; + +type AccordionTriggerProps = Pick< + AccordionItemProps, + "title" | "description" | "icon" | "handle" | "interactive" | "actions" +>; + +const AccordionTrigger = ({ + title, + description, + actions, + icon, + handle, + interactive = true +}: AccordionTriggerProps) => { + // The following three attributes are required for the trigger to act as a button. + // We can't use the default button element here because the content of the trigger + // can also contain one or more buttons. + const divAsButtonProps = React.useMemo>(() => { + return { + role: "button", + tabIndex: interactive ? 0 : -1, // Disable keyboard interaction if not interactive + onKeyDown: e => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + e.currentTarget.click(); + } + } + }; + }, [interactive]); + + return ( + !interactive && e.preventDefault()} // Prevent clicking if not interactive + > +
+ {handle} +
+ {icon &&
{icon}
} +
+
+ {title} +
+
{description}
+
+
+ {actions} + + {/* No need to show the separator if there are no actions and the item is not interactive. */} + {actions && interactive && } + + {interactive && ( + } + /> + )} +
+
+
+
+ ); +}; + +export { AccordionTrigger }; diff --git a/packages/admin-ui/src/Accordion/index.ts b/packages/admin-ui/src/Accordion/index.ts new file mode 100644 index 00000000000..16e0243c2a0 --- /dev/null +++ b/packages/admin-ui/src/Accordion/index.ts @@ -0,0 +1 @@ +export * from "./Accordion"; diff --git a/packages/admin-ui/src/Alert/Alert.mdx b/packages/admin-ui/src/Alert/Alert.mdx new file mode 100644 index 00000000000..f89a900d230 --- /dev/null +++ b/packages/admin-ui/src/Alert/Alert.mdx @@ -0,0 +1,192 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; + +import * as AlertStories from './Alert.stories'; + + + +# Alert + +Alert component is an element used to display important messages to users, such as notifications, warnings, errors, or success confirmations. Its purpose is to bring attention to users by providing feedback on user actions or system states, ensuring users are informed about critical information. Alerts are relevant for guiding user behaviour, preventing errors, and improving user experience by delivering timely feedback and enhancing the communication between the user and the system. + +## Usage + + { + return ( + + <> + This type of notification is suitable for general usage where there’s no need for + accent. And this thing here is a short link. + + + ); +}; + +export default AlertExample; + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Alert/Alert.tsx', + '_blank' + ); + }, + } + ]} +/> + + + +```tsx +import React from "react"; + +import { Alert } from "@webiny/admin-ui"; + +const AlertExample = () => { + return ( + + <> + This type of notification is suitable for general usage where there’s no need for + accent. And this thing here is a short link. + + + ); +}; + +export default AlertExample; +``` + +## Examples + +### Info + + + <> + This type of notification is suitable for general usage where there’s no need for + accent. And this thing here is a short link. + + +` } } +/> + +### Success + + + <> + This is a success alert, used when something occurred successfully. And{" "} + this thing here is a short link. + + +` } } +/> + + +### Warning + + + <> + This is a warning alert, used when something of strong relevance needs to be + communicated. And this thing here is a short link. + + +` } } +/> + +### Danger + + + <> + This is a danger alert, used when something critical needs to be communicated. And{" "} + this thing here is a short link. + + +` } } +/> + +### With Close Button + + alert("Close button clicked.")}> + <> + An alert that can be closed. + + +` } } +/> + +### With Action + + alert("Close button clicked.")} + actions={( + alert("Custom action button clicked.")} /> + )}> + <> + An alert that can be closed and also has action button. + + +` } } +/> + +## Anatomy + +### Options +Options + +### Style +Style + +### Type +Type + +### Examples +Examples + +## Usage + +### Full width banner +Full width banner + + +### Floating element +Floating element + +### Nested element +Nested element \ No newline at end of file diff --git a/packages/admin-ui/src/Alert/Alert.stories.tsx b/packages/admin-ui/src/Alert/Alert.stories.tsx new file mode 100644 index 00000000000..501fd671b38 --- /dev/null +++ b/packages/admin-ui/src/Alert/Alert.stories.tsx @@ -0,0 +1,211 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Alert } from "./Alert"; +import React from "react"; + +const meta: Meta = { + title: "Components/Alert", + component: Alert, + argTypes: {}, + decorators: [ + Story => ( +
+ +
+ ) + ] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + showCloseButton: true, + children: "This is an alert. Play around with different properties to see how it looks." + }, + argTypes: { + type: { + control: "select", + options: ["info", "success", "warning", "danger"] + }, + variant: { + control: "select", + options: ["strong", "subtle"] + } + } +}; + +export const Info: Story = { + args: { + ...Default.args, + type: "info", + children: ( + <> + This type of notification is suitable for general usage where there’s no need for + accent. And this thing here is a short link. + + ) + } +}; + +export const InfoStrong: Story = { + name: "Info (strong)", + args: { + ...Info.args, + variant: "strong", + children: ( + <> + This type of notification is suitable for general usage where there is a need for + strong accent. And this thing here is a short link. + + ) + } +}; + +export const Success: Story = { + args: { + ...Default.args, + type: "success", + children: ( + <> + This is a success alert, used when something occurred successfully. And{" "} + this thing here is a short link. + + ) + } +}; + +export const SuccessStrong: Story = { + name: "Success (strong)", + args: { + ...Success.args, + variant: "strong", + children: ( + <> + This is a success alert, used when something occurred successfully and needs to be + prominent. And this thing here is a short link. + + ) + } +}; + +export const Warning: Story = { + args: { + ...Default.args, + children: ( + <> + This is a warning alert, used when something of strong relevance needs to be + communicated. And this thing here is a short link. + + ), + type: "warning" + } +}; + +export const WarningStrong: Story = { + name: "Warning (strong)", + args: { + ...Warning.args, + children: ( + <> + This is a warning alert, used when something of strong relevance needs to be + prominently communicated. And this thing here is a short link. + + ), + variant: "strong" + } +}; + +export const Danger: Story = { + args: { + ...Default.args, + children: ( + <> + This is a danger alert, used when something critical needs to be communicated. And{" "} + this thing here is a short link. + + ), + type: "danger" + } +}; + +export const DangerStrong: Story = { + name: "Danger (strong)", + args: { + ...Danger.args, + children: ( + <> + This is a danger alert, used when something critical needs to be prominently + communicated. And this thing here is a short link. + + ), + variant: "strong" + } +}; + +export const WithCloseButton: Story = { + name: "With close button", + args: { + ...Default.args, + children: <>An alert that can be closed., + showCloseButton: true, + onClose: () => alert("Close button clicked.") + } +}; + +export const WithAction: Story = { + name: "With action", + args: { + ...WithCloseButton.args, + children: <>An alert that can be closed and also has action button., + showCloseButton: true, + actions: ( + alert("Custom action button clicked.")} /> + ) + } +}; + +export const Documentation: Story = { + args: { + type: "info", + variant: "subtle", + showCloseButton: false, + children: ( + <> + This type of notification is suitable for general usage where there’s no need for + accent. And this thing here is a short link. + + ), + onClose: () => {}, + actions: undefined + }, + argTypes: { + type: { + description: "Type", + control: "select", + options: ["info", "success", "warning", "danger"], + defaultValue: "info" + }, + variant: { + description: "Variant", + control: "select", + options: ["subtle", "strong"], + defaultValue: "subtle" + }, + showCloseButton: { + description: + "Show close button, please refer to the 'With Close Button' example below for details.", + control: "boolean", + defaultValue: false + }, + onClose: { + description: "Please refer to the 'With Close Button' example below for details.", + control: "none" + }, + actions: { + description: "Please refer to the 'With Action' example below for details.", + control: "none" + } + } +}; diff --git a/packages/admin-ui/src/Alert/Alert.tsx b/packages/admin-ui/src/Alert/Alert.tsx new file mode 100644 index 00000000000..eabf76ed0aa --- /dev/null +++ b/packages/admin-ui/src/Alert/Alert.tsx @@ -0,0 +1,181 @@ +import * as React from "react"; +import { cva, type VariantProps, cn, makeDecoratable, withStaticProps } from "~/utils"; +import { Button, type ButtonProps, IconButton } from "~/Button"; +import { ReactComponent as InfoIcon } from "@webiny/icons/info.svg"; +import { ReactComponent as WarningIcon } from "@webiny/icons/warning_amber.svg"; +import { ReactComponent as SuccessIcon } from "@webiny/icons/check_circle.svg"; +import { ReactComponent as XIcon } from "@webiny/icons/close.svg"; +import { Icon } from "~/Icon"; + +const VARIANT_ICON_MAP = { + info: InfoIcon, + success: SuccessIcon, + warning: InfoIcon, + danger: WarningIcon +}; + +const variants = { + type: { info: "", success: "", warning: "", danger: "" }, + variant: { strong: "", subtle: "" } +}; + +const DEFAULT_TYPE = "info"; +const DEFAULT_VARIANT = "subtle"; + +const defaultVariants = { + type: DEFAULT_TYPE, + variant: DEFAULT_VARIANT +} as const; + +const alertVariants = cva( + "wby-flex wby-gap-sm-plus wby-items-start wby-w-full wby-rounded-lg wby-text-md wby-py-sm-extra wby-pl-md wby-pr-sm-plus [&_a]:wby-font-semibold [&_a]:wby-underline", + { + variants, + defaultVariants, + compoundVariants: [ + { + type: "info", + variant: "strong", + className: + "wby-bg-neutral-dark wby-text-neutral-light [&_a]:!wby-text-neutral-light" + }, + { + type: "info", + variant: "subtle", + className: + "wby-bg-neutral-dimmed wby-text-neutral-primary [&_a]:!wby-text-neutral-primary" + }, + { + type: "success", + variant: "strong", + className: + "wby-bg-secondary-default wby-text-neutral-light [&_a]:!wby-text-neutral-light" + }, + { + type: "success", + variant: "subtle", + className: + "wby-bg-success-subtle wby-text-neutral-primary [&_a]:!wby-text-neutral-primary" + }, + { + type: "warning", + variant: "strong", + className: + "wby-bg-warning-default wby-text-neutral-primary [&_a]:!wby-text-neutral-primary" + }, + { + type: "warning", + variant: "subtle", + className: + "wby-bg-warning-subtle wby-text-neutral-primary [&_a]:!wby-text-neutral-primary" + }, + { + type: "danger", + variant: "strong", + className: + "wby-bg-destructive-default wby-text-neutral-light [&_a]:!wby-text-neutral-light" + }, + { + type: "danger", + variant: "subtle", + className: + "wby-bg-destructive-subtle wby-text-neutral-primary [&_a]:!wby-text-neutral-primary" + } + ] + } +); + +const alertIconVariants = cva("wby-size-md", { + variants, + defaultVariants, + compoundVariants: [ + { type: "info", variant: "strong", className: "wby-fill-neutral-base" }, + { type: "info", variant: "subtle", className: "wby-fill-neutral-xstrong" }, + { type: "success", variant: "strong", className: "wby-fill-neutral-base" }, + { type: "success", variant: "subtle", className: "wby-fill-success" }, + { type: "warning", variant: "strong", className: "wby-fill-neutral-xstrong" }, + { type: "warning", variant: "subtle", className: "wby-fill-warning" }, + { type: "danger", variant: "strong", className: "wby-fill-neutral-base" }, + { type: "danger", variant: "subtle", className: "wby-fill-destructive" } + ] +}); + +const closeButtonVariants = (props: Parameters[0] = {}) => { + const { type = DEFAULT_TYPE, variant = DEFAULT_VARIANT } = props; + if (variant === "subtle") { + return "ghost"; + } + + if (type === "warning") { + return "ghost"; + } + + return "ghost-negative"; +}; + +export interface AlertProps + extends React.HTMLAttributes, + VariantProps { + showCloseButton?: boolean; + onClose?: () => void; + actions?: React.ReactElement; +} + +const AlertContext = React.createContext>({}); + +const AlertActionBase = (props: ButtonProps) => { + const { variant: alertVariant } = React.useContext(AlertContext); + return ( + + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Button/Button.tsx', + '_blank' + ); + }, + } + ]} +/> + + + +```jsx +import { Button } from '@webiny/admin-ui'; + + +``` + +## Examples + +### Primary + + + +` } } +/> + + +### Secondary + + + +` } } +/> + +### Tertiary + + + +` } } +/> + +### Ghost + + + +` } } +/> + +### Ghost Negative + + + +` } } +/> + +### With Icon + +} iconPosition="start"> +` } } +/> + + +### As Child +The Button component can be used as a wrapper for other elements, allowing flexible composition. This is particularly useful when integrating custom text elements, or any other components inside a button. + + + Button + + +` } } +/> + +### Icon Only Button +import * as IconButtonStories from './IconButton.stories'; + +**We have a dedicated `IconButton` component for the Icon-only button. Please check the code below for more details.** + +#### Usage + +```jsx +import { IconButton } from '@webiny/admin-ui'; +``` + +```jsx +import { ReactComponent as AddIcon } from "@webiny/icons/add.svg" +} size={"md"}/> +``` + +} size={"md"}/> + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Button/Button.tsx', + '_blank' + ); + }, + } + ]} +/> + +#### Props + + + +## Anatomy + +### Construction +Construction + +### Options +Options + +### Variants +Variants + +### Size +Regular buttons come in four different sizes: small, medium, large, and xl. The medium size is the default and most frequently used option. Use the other sizes sparingly; they should be used to create a hierarchy of importance within the page. + +Size + +**Icon-only button** come in six different sizes to accommodate for various component needs. + +Size - Icon Only + + +### States +States + +## Usage + +### Icon Usage +An icon should only be used in a button when it's benefitial and when it has a meaningful association with the label. + +Icon Usage + +### Use primary buttons sparingly +Use primary buttons as the desired action for users. Competing primary buttons may leave the user unsure of next steps in their user journey. As a rule of thumb limit primary buttons to 1 in contained UIs and 3 in full page UIs. + +Primary Button Usage + +### Button Group +When used in groups, buttons should support only maximum of two type variants, with an exception of third variant being ghost extension button (eg. ellipsis). Avoid using random type and icon options within the button groups. Avoid using different sizes within the same group. + +Button Group \ No newline at end of file diff --git a/packages/admin-ui/src/Button/Button.stories.tsx b/packages/admin-ui/src/Button/Button.stories.tsx new file mode 100644 index 00000000000..40837c692f4 --- /dev/null +++ b/packages/admin-ui/src/Button/Button.stories.tsx @@ -0,0 +1,163 @@ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import { ReactComponent as PencilIcon } from "@webiny/icons/edit.svg"; +import { Button } from "./Button"; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta: Meta = { + title: "Components/Button", + component: Button, + argTypes: { + variant: { + description: "Type", + control: "select", + options: ["primary", "secondary", "tertiary", "ghost", "ghost-negative"], + defaultValue: "primary" + }, + size: { + description: "Size", + control: "select", + options: ["sm", "md", "lg", "xl"], + defaultValue: "md" + }, + text: { + description: "Label", + control: "text", + defaultValue: "Button" + }, + disabled: { + control: "boolean", + defaultValue: false + }, + icon: { + description: "Please refer to the 'With Icon' button example below for details.", + control: "none" + }, + iconPosition: { + description: "Please refer to the 'With Icon' button example below for details.", + control: "select", + defaultValue: "start", + options: ["start", "end"] + }, + asChild: { + description: "Please refer to the 'As Child' button example below for details.", + control: "none" + }, + // Note: after upgrading to Storybook 8.X, use `fn`from `@storybook/test` to spy on the onClick argument. + onClick: { action: "onClick" } + } +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + variant: "primary", + text: "Button" + } +}; + +export const Secondary: Story = { + args: { + ...Primary.args, + variant: "secondary" + } +}; + +export const Tertiary: Story = { + args: { + ...Primary.args, + variant: "tertiary" + } +}; + +export const Ghost: Story = { + args: { + ...Primary.args, + variant: "ghost" + } +}; + +export const GhostNegative: Story = { + decorators: [ + (Story: any) => ( +
+ +
+ ) + ], + args: { + ...Primary.args, + variant: "ghost-negative" + } +}; + +export const Small: Story = { + args: { + ...Primary.args, + size: "sm" + } +}; + +export const Medium: Story = { + args: { + ...Primary.args, + size: "md" + } +}; + +export const Large: Story = { + args: { + ...Primary.args, + size: "lg" + } +}; + +export const ExtraLarge: Story = { + args: { + ...Primary.args, + size: "xl" + } +}; + +export const WithIcon: Story = { + args: { + ...Primary.args, + icon: + } +}; + +export const WithIconPositionEnd: Story = { + args: { + ...Primary.args, + icon: , + iconPosition: "end" + } +}; + +export const WithAsChild: Story = { + args: { + ...Primary.args, + asChild: true, + text: Button + } +}; + +/* The Documentation story is created for the Docs page. + * The description column for the `iconPosition` and `icon` props displays + * an extra dash (-), and the formatting breaks unless defined in the story. + * Hence, this Documentation story was created. + */ + +export const Documentation: Story = { + args: { + variant: "primary", + text: "Button", + size: "md", + disabled: false, + icon: "", + iconPosition: "start", + asChild: false + } +}; diff --git a/packages/admin-ui/src/Button/Button.tsx b/packages/admin-ui/src/Button/Button.tsx new file mode 100644 index 00000000000..44a8e9d9f97 --- /dev/null +++ b/packages/admin-ui/src/Button/Button.tsx @@ -0,0 +1,229 @@ +import React, { useMemo } from "react"; +import { Slot, Slottable } from "@radix-ui/react-slot"; +import { cn, cva, type VariantProps, makeDecoratable } from "~/utils"; + +const buttonWrapperVariants = cva("wby-inline-block", { + variants: { + disabled: { + true: "wby-cursor-not-allowed", + false: "wby-cursor-pointer" + } + } +}); + +const buttonVariants = cva( + [ + "wby-border-transparent wby-rounded wby-font-sans wby-inline-flex wby-items-center wby-justify-center wby-whitespace-nowrap wby-ring-offset-background wby-transition-colors !wby-no-underline", + "aria-disabled:wby-pointer-events-none", + "focus-visible:wby-outline-none focus-visible:wby-border-accent-default" + ], + { + variants: { + variant: { + primary: [ + "wby-bg-primary wby-text-neutral-light wby-fill-neutral-base", + "hover:wby-bg-primary-strong", + "active:wby-bg-primary-xstrong", + "aria-disabled:wby-bg-primary-disabled", + "focus-visible:wby-ring-lg focus-visible:wby-ring-primary-dimmed" + ], + secondary: [ + "wby-bg-neutral-dimmed wby-text-neutral-strong wby-fill-neutral-xstrong", + "hover:wby-bg-neutral-muted", + "active:wby-bg-neutral-strong", + "aria-disabled:wby-bg-neutral-disabled aria-disabled:wby-text-neutral-disabled aria-disabled:wby-fill-neutral-strong", + "focus-visible:wby-ring-lg focus-visible:wby-ring-primary-dimmed" + ], + tertiary: [ + "wby-bg-neutral-base wby-text-neutral-strong wby-border-neutral-muted wby-fill-neutral-xstrong", + "hover:wby-bg-neutral-light", + "active:wby-bg-neutral-muted", + "aria-disabled:wby-bg-neutral-disabled aria-disabled:wby-border-neutral-dimmed aria-disabled:wby-text-neutral-disabled aria-disabled:wby-fill-neutral-strong", + "focus-visible:wby-ring-lg focus-visible:wby-ring-primary-dimmed" + ], + ghost: [ + "wby-text-neutral-strong wby-fill-neutral-xstrong", + "hover:wby-bg-neutral-dimmed", + "active:wby-bg-neutral-muted", + "aria-disabled:wby-text-neutral-disabled aria-disabled:wby-fill-neutral-strong" + ], + "ghost-negative": [ + "wby-text-neutral-light wby-fill-neutral-base", + "hover:wby-bg-neutral-base/20", + "active:wby-bg-neutral-base/30", + "aria-disabled:wby-text-neutral-disabled aria-disabled:wby-fill-neutral-base/50", + "focus-visible:!wby-border-neutral-base" + ] + }, + size: { + sm: [ + "wby-text-sm wby-border-sm wby-rounded-sm [&>svg]:wby-size-md", + "wby-py-[calc(theme(padding.xs)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.sm)-theme(borderWidth.sm))]" + ], + md: [ + "wby-text-md wby-border-sm wby-rounded-md [&>svg]:wby-size-md", + "wby-py-[calc(theme(padding.xs-plus)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.sm-extra)-theme(borderWidth.sm))]" + ], + lg: [ + "wby-text-md wby-border-sm wby-rounded-md [&>svg]:wby-size-md-plus", + "wby-py-[calc(theme(padding.sm-plus)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.md)-theme(borderWidth.sm))]" + ], + xl: [ + "wby-text-lg wby-font-semibold wby-border-lg wby-rounded-md [&>svg]:wby-size-lg", + "wby-py-[calc(theme(padding.md-plus)-theme(borderWidth.md))] wby-px-[calc(theme(padding.md)-theme(borderWidth.md))]" + ] + }, + contentLayout: { + text: "", + icon: "", + "text-icon-start": "", + "text-icon-end": "" + } + }, + compoundVariants: [ + { + size: "xl", + variant: "ghost", + className: "focus-visible:wby-border-md" + }, + { + size: "sm", + contentLayout: "icon", + className: "wby-p-[calc(theme(padding.xs)-theme(borderWidth.sm))]" + }, + { + size: "sm", + contentLayout: "text-icon-start", + className: + "wby-pl-[calc(theme(padding.xs)-theme(borderWidth.sm))] [&>svg]:wby-mr-xs" + }, + { + size: "sm", + contentLayout: "text-icon-end", + className: + "wby-pr-[calc(theme(padding.xs)-theme(borderWidth.sm))] [&>svg]:wby-ml-xs" + }, + { + size: "md", + contentLayout: "icon", + className: "wby-p-[calc(theme(padding.sm)-theme(borderWidth.sm))]" + }, + { + size: "md", + contentLayout: "text-icon-start", + className: + "wby-pl-[calc(theme(padding.xs-plus)-theme(borderWidth.sm))] [&>svg]:wby-mr-xs" + }, + { + size: "md", + contentLayout: "text-icon-end", + className: + "wby-pr-[calc(theme(padding.xs-plus)-theme(borderWidth.sm))] [&>svg]:wby-ml-xs" + }, + { + size: "lg", + contentLayout: "icon", + className: "wby-p-[calc(theme(padding.sm-plus)-theme(borderWidth.sm))]" + }, + { + size: "lg", + contentLayout: "text-icon-start", + className: + "wby-pl-[calc(theme(padding.sm-extra)-theme(borderWidth.sm))] [&>svg]:wby-mr-xs-plus" + }, + { + size: "lg", + contentLayout: "text-icon-end", + className: + "wby-pr-[calc(theme(padding.sm-extra)-theme(borderWidth.sm))] [&>svg]:wby-ml-xs-plus" + }, + { + size: "xl", + contentLayout: "icon", + className: "wby-p-[calc(theme(padding.md)-theme(borderWidth.md))]" + }, + { + size: "xl", + contentLayout: "text-icon-start", + className: + "wby-pl-[calc(theme(padding.sm-extra)-theme(borderWidth.md))] [&>svg]:wby-mr-sm" + }, + { + size: "xl", + contentLayout: "text-icon-end", + className: + "wby-pr-[calc(theme(padding.sm-extra)-theme(borderWidth.md))] [&>svg]:wby-ml-sm" + } + ], + defaultVariants: { + variant: "primary", + size: "md" + } + } +); + +interface ButtonProps + extends Omit, "children">, + VariantProps { + text?: React.ReactNode; + + icon?: React.ReactNode; + + iconPosition?: "start" | "end"; + + asChild?: boolean; + + containerClassName?: string; +} + +type ContentLayout = "text" | "icon" | "text-icon-start" | "text-icon-end"; + +const ButtonBase = ({ + className, + variant, + size, + asChild = false, + text, + icon, + iconPosition = "start", + disabled, + containerClassName, + ...rest +}: ButtonProps) => { + const Comp = asChild ? Slot : "button"; + + const contentLayout = useMemo(() => { + if (!text) { + return "icon"; + } + + if (!icon) { + return "text"; + } + + return `text-icon-${iconPosition}` as ContentLayout; + }, [text, icon, iconPosition]); + + const cssClasses = cn( + buttonVariants({ + variant, + size, + contentLayout + }), + className + ); + + return ( + + + {iconPosition !== "end" && icon} + {text} + {iconPosition === "end" && icon} + + + ); +}; + +const Button = makeDecoratable("Button", ButtonBase); + +export { Button, type ButtonProps, buttonVariants }; diff --git a/packages/admin-ui/src/Button/CopyButton.tsx b/packages/admin-ui/src/Button/CopyButton.tsx new file mode 100644 index 00000000000..92c19afd971 --- /dev/null +++ b/packages/admin-ui/src/Button/CopyButton.tsx @@ -0,0 +1,33 @@ +import React, { useCallback } from "react"; +import { ReactComponent as CopyToClipboardIcon } from "@webiny/icons/content_copy.svg"; +import { ButtonProps, Button } from "./Button"; +import { makeDecoratable } from "../utils"; + +interface CopyButtonProps extends ButtonProps { + /** + * Value to copy to clipboard. + */ + value: string; + + /** + * Callback function that is executed after the value is copied to the clipboard. + */ + onCopy?: () => void; +} + +const CopyButtonBase = (props: CopyButtonProps) => { + const { value, onCopy, ...rest } = props; + + const copyToClipboard = useCallback(() => { + navigator.clipboard.writeText(value); + if (typeof onCopy === "function") { + onCopy(); + } + }, [value]); + + return + + e.stopPropagation()} // Wheel event should not propagate to the parent: this fixes scrolling issues when the IconPicker is placed inside a Dialog. + > + + + + + ); +}; + +export { IconPickerPrimitive, type IconPickerPrimitiveProps }; diff --git a/packages/admin-ui/src/IconPicker/primitives/components/IconPickerGrid.tsx b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerGrid.tsx new file mode 100644 index 00000000000..a377d7b7608 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerGrid.tsx @@ -0,0 +1,89 @@ +import React, { useCallback } from "react"; +import { Grid, GridCellProps } from "react-virtualized"; +import { Text } from "~/Text"; +import { cn } from "~/utils"; +import { IconPickerFontAwesome, IconPickerIconFormatter } from "../../domains"; +import { IconPickerIcon } from "./IconPickerIcon"; + +const COLUMN_COUNT = 5; +const GRID_WIDTH = 424; +const GRID_HEIGHT = 270; +const COLUMN_WIDTH = 80; +const ROW_HEIGHT = 80; + +interface IconPickerGridProps { + icons: IconPickerFontAwesome[]; + iconsLength: number; + onIconSelect: (value: string) => void; +} + +const IconPickerGrid = (props: IconPickerGridProps) => { + const renderCell = useCallback(() => { + return function renderCell({ + columnIndex, + key, + rowIndex, + style + }: GridCellProps): React.ReactNode { + const item = props.icons[rowIndex * COLUMN_COUNT + columnIndex]; + if (!item) { + return null; + } + + return ( +
{ + if (props.onIconSelect) { + props.onIconSelect(IconPickerIconFormatter.formatStringValue(item)); + } + }} + > + + + {item.name} + +
+ ); + }; + }, [props.icons]); + + return ( +
+ {props.iconsLength === 0 ? ( +
+ {"No results found."} +
+ ) : ( + + )} +
+ ); +}; + +export { IconPickerGrid, type IconPickerGridProps }; diff --git a/packages/admin-ui/src/IconPicker/primitives/components/IconPickerIcon.tsx b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerIcon.tsx new file mode 100644 index 00000000000..b5e8a549e35 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerIcon.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { IconName, IconPrefix } from "@fortawesome/fontawesome-svg-core"; + +interface IconPickerIconProps extends React.HTMLAttributes { + name: IconName; + prefix: IconPrefix; +} + +const IconPickerIcon = ({ name, prefix, ...props }: IconPickerIconProps) => { + return ( +
+ +
+ ); +}; + +export { IconPickerIcon, type IconPickerIconProps }; diff --git a/packages/admin-ui/src/IconPicker/primitives/components/IconPickerInput.tsx b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerInput.tsx new file mode 100644 index 00000000000..c8ff0c5a802 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerInput.tsx @@ -0,0 +1,44 @@ +import React, { useCallback } from "react"; +import { ReactComponent as SearchIcon } from "@webiny/icons/search.svg"; +import { Input } from "~/Input"; +import { Icon } from "~/Icon"; +import { DelayedOnChange, OnChangeCallable } from "~/DelayedOnChange"; +import { cn } from "~/utils"; + +interface IconPickerInputProps { + value: string; + onChange: (value: string) => void; + inputRef: React.RefObject; +} + +const IconPickerInput = (props: IconPickerInputProps) => { + const onInputChange = useCallback( + (value, cb) => { + props.onChange(value); + if (cb) { + cb(value); + } + }, + [props.onChange] + ); + + return ( + + {({ value, onChange }) => ( +
+ } label={"Search icons"} />} + /> +
+ )} +
+ ); +}; + +export { IconPickerInput, type IconPickerInputProps }; diff --git a/packages/admin-ui/src/IconPicker/primitives/components/IconPickerTrigger.tsx b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerTrigger.tsx new file mode 100644 index 00000000000..0df951dabef --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/components/IconPickerTrigger.tsx @@ -0,0 +1,47 @@ +import React, { useMemo } from "react"; +import { ReactComponent as ChevronDown } from "@webiny/icons/keyboard_arrow_down.svg"; +import { Icon as IconComponent } from "~/Icon"; +import { cn, cva, type VariantProps } from "~/utils"; +import { IconPickerIcon as IconPickerIconComponent } from "./IconPickerIcon"; +import { IconPickerIcon, IconPickerIconFormatter } from "../../domains"; + +const iconPickerTriggerVariants = cva("wby-flex wby-items-center", { + variants: { + size: { + md: "wby-gap-xs", + lg: "wby-gap-xs", + xl: "wby-gap-sm" + } + }, + defaultVariants: { + size: "lg" + } +}); + +interface IconPickerTriggerProps extends VariantProps { + value?: string; +} + +const IconPickerTrigger = ({ value, size }: IconPickerTriggerProps) => { + const icon = useMemo(() => { + const icon = IconPickerIcon.createFromString(value); + return IconPickerIconFormatter.formatFontAwesome(icon); + }, [value]); + + return ( +
+
+ } + label={`Selected icon`} + /> +
+
+ } label={"Open list"} /> +
+
+ ); +}; + +export { IconPickerTrigger, type IconPickerTriggerProps }; diff --git a/packages/admin-ui/src/IconPicker/primitives/components/index.ts b/packages/admin-ui/src/IconPicker/primitives/components/index.ts new file mode 100644 index 00000000000..8879ccfc718 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/components/index.ts @@ -0,0 +1,4 @@ +export * from "./IconPickerGrid"; +export * from "./IconPickerIcon"; +export * from "./IconPickerInput"; +export * from "./IconPickerTrigger"; diff --git a/packages/admin-ui/src/IconPicker/primitives/index.ts b/packages/admin-ui/src/IconPicker/primitives/index.ts new file mode 100644 index 00000000000..3a7cc475366 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/index.ts @@ -0,0 +1 @@ +export * from "./IconPickerPrimitive"; diff --git a/packages/admin-ui/src/IconPicker/primitives/presenters/IconPickerPresenter.ts b/packages/admin-ui/src/IconPicker/primitives/presenters/IconPickerPresenter.ts new file mode 100644 index 00000000000..e257df5eb37 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/presenters/IconPickerPresenter.ts @@ -0,0 +1,75 @@ +import { makeAutoObservable } from "mobx"; +import { + IconPickerIcon, + IconPickerIconDto, + IconPickerFontAwesome, + IconPickerIconFormatter, + ListCache +} from "../../domains"; + +interface IconPickerParams { + icons: IconPickerIconDto[]; + onChange?: (value: string) => void; +} + +interface IIconPickerPresenter { + vm: { + open: boolean; + icons: IconPickerFontAwesome[]; + iconsLength: number; + searchQuery: string; + }; + init: (params: IconPickerParams) => void; + setListOpenState: (open: boolean) => void; + searchIcon: (value: string) => void; + setSelectedIcon: (icon: string) => void; +} + +class IconPickerPresenter implements IIconPickerPresenter { + private open = false; + private icons = new ListCache(); + private searchQuery = ""; + private params?: IconPickerParams = undefined; + + constructor() { + makeAutoObservable(this); + } + + public init = (params: IconPickerParams) => { + this.params = params; + this.icons.clear(); + this.icons.addItems(params.icons.map(icon => IconPickerIcon.create(icon))); + }; + + get vm() { + return { + open: this.open, + searchQuery: this.searchQuery, + icons: this.getIcons().map(icon => IconPickerIconFormatter.formatFontAwesome(icon)), + iconsLength: this.getIcons().length || 0 + }; + } + + public setListOpenState = (open: boolean) => { + this.open = open; + }; + + public searchIcon = (value: string) => { + this.searchQuery = value; + }; + + public setSelectedIcon = (icon: string) => { + this.setListOpenState(false); + this.params?.onChange?.(icon); + }; + + private getIcons = () => { + if (this.searchQuery) { + return this.icons.getItems(icon => icon.name.includes(this.searchQuery)); + } + + return this.icons.getItems(); + }; +} + +export { IconPickerPresenter, type IIconPickerPresenter, type IconPickerParams }; diff --git a/packages/admin-ui/src/IconPicker/primitives/presenters/index.ts b/packages/admin-ui/src/IconPicker/primitives/presenters/index.ts new file mode 100644 index 00000000000..d564f818dc8 --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/presenters/index.ts @@ -0,0 +1 @@ +export * from "./IconPickerPresenter"; diff --git a/packages/admin-ui/src/IconPicker/primitives/useIconPicker.ts b/packages/admin-ui/src/IconPicker/primitives/useIconPicker.ts new file mode 100644 index 00000000000..580df9529ec --- /dev/null +++ b/packages/admin-ui/src/IconPicker/primitives/useIconPicker.ts @@ -0,0 +1,37 @@ +import { useEffect, useMemo, useState } from "react"; +import { autorun } from "mobx"; +import { IconPickerParams, IconPickerPresenter } from "./presenters"; +import { IconPickerPrimitiveProps } from "./IconPickerPrimitive"; + +export const useIconPicker = (props: IconPickerPrimitiveProps) => { + const params: IconPickerParams = useMemo( + () => ({ + icons: props.icons, + onChange: props.onChange + }), + [props.icons, props.onChange] + ); + + const presenter = useMemo(() => { + return new IconPickerPresenter(); + }, []); + + const [vm, setVm] = useState(presenter.vm); + + useEffect(() => { + presenter.init(params); + }, [params, presenter]); + + useEffect(() => { + return autorun(() => { + setVm(presenter.vm); + }); + }, [presenter]); + + return { + vm, + setListOpenState: presenter.setListOpenState, + searchIcon: presenter.searchIcon, + setSelectedIcon: presenter.setSelectedIcon + }; +}; diff --git a/packages/ui/src/Image/Image.tsx b/packages/admin-ui/src/Image/Image.tsx similarity index 83% rename from packages/ui/src/Image/Image.tsx rename to packages/admin-ui/src/Image/Image.tsx index 0527ddc5d06..28928f763e1 100644 --- a/packages/ui/src/Image/Image.tsx +++ b/packages/admin-ui/src/Image/Image.tsx @@ -1,12 +1,12 @@ import React from "react"; // Accepts all props that a normal element would accept. -interface Props +interface ImageProps extends React.DetailedHTMLProps, HTMLImageElement> { [key: string]: any; } -const Image = ({ ...rest }: Props) => { +const Image = ({ ...rest }: ImageProps) => { const finalProps = { ...rest }; const srcSet = finalProps.srcSet; if (srcSet && typeof srcSet === "object") { @@ -18,4 +18,4 @@ const Image = ({ ...rest }: Props) => { return ; }; -export { Image }; +export { Image, type ImageProps }; diff --git a/packages/admin-ui/src/Image/index.ts b/packages/admin-ui/src/Image/index.ts new file mode 100644 index 00000000000..321f81e82aa --- /dev/null +++ b/packages/admin-ui/src/Image/index.ts @@ -0,0 +1 @@ +export * from "./Image"; diff --git a/packages/admin-ui/src/Input/Input.mdx b/packages/admin-ui/src/Input/Input.mdx new file mode 100644 index 00000000000..9c03bdfbbad --- /dev/null +++ b/packages/admin-ui/src/Input/Input.mdx @@ -0,0 +1,178 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; + +import * as InputStories from './Input.stories'; + + + +# Input + +The Input component is a form control that allows users to enter and edit text. It supports various types of input (text, number, email, etc.), can be customized with icons, and includes built-in validation support. + +## Usage + + { + const [value, setValue] = useState(""); + const [validation, setValidation] = useState({ isValid: true, message: "" }); + + const handleValidation = () => { + if (!value.trim()) { + setValidation({ isValid: false, message: "This field is required" }); + } else if (value.trim().length < 3) { + setValidation({ isValid: false, message: "Must be at least 3 characters long" }); + } else { + setValidation({ isValid: true, message: "" }); + } + }; + + return ( +
+ setValue(newValue)} + onBlur={handleValidation} + onEnter={handleValidation} + /> +
+ ); +}; + +export default InputExample; + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Input/Input.tsx', + '_blank' + ); + }, + } + ]} +/> + + + +```jsx +import React, { useState } from "react"; + +import { Input } from "@webiny/admin-ui"; + +const InputExample = () => { + const [value, setValue] = useState(""); + const [validation, setValidation] = useState({ isValid: true, message: "" }); + + const handleValidation = () => { + if (!value.trim()) { + setValidation({ isValid: false, message: "This field is required" }); + } else if (value.trim().length < 3) { + setValidation({ isValid: false, message: "Must be at least 3 characters long" }); + } else { + setValidation({ isValid: true, message: "" }); + } + }; + + return ( +
+ setValue(newValue)} + onBlur={handleValidation} + onEnter={handleValidation} + /> +
+ ); +}; + +export default InputExample; +``` + +## Examples + +### With Validate Function +The Input component supports validation using the validation prop, as shown in the example above. +For more complex or reusable validation scenarios, you can use the validate prop, which accepts a custom validation function. +Try entering **exists@** in the input box to see it in action, and click on **Show code** to view the validation function. + + { + const [value, setValue] = useState(""); + const [validation, setValidation] = useState({ isValid: true, message: undefined }); + + const validate = async () => { + // Simulate API call delay + await new Promise(resolve => setTimeout(resolve, 500)); + + // Example validation: check if email already exists + if (value.includes("exists@")) { + setValidation({ isValid: false, message: "This email is already registered" }); + } else { + setValidation({ isValid: true, message: undefined }); + } + }; + + return ( + setValue(newValue)} + validate={validate} + validation={validation} + /> + ); +};` } } +/> + +## Anatomy + +### Input Anatomy +Input Anatomy + +### Styles +Styles + +### Field Size +Field Size + +### States and Styles +States and Styles + +### Label Anatomy +Label Anatomy + +### Label Properties +Label Properties + +### Label Options +Label Options + +## Usage + +### Used in forms +Used in forms diff --git a/packages/admin-ui/src/Input/Input.stories.tsx b/packages/admin-ui/src/Input/Input.stories.tsx new file mode 100644 index 00000000000..3ee6358bed9 --- /dev/null +++ b/packages/admin-ui/src/Input/Input.stories.tsx @@ -0,0 +1,289 @@ +import React, { useState } from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import { Input } from "~/Input"; + +const meta: Meta = { + title: "Components/Form/Input", + component: Input, + argTypes: { + onChange: { action: "onChange" }, + type: { + control: "select", + options: [ + "text", + "number", + "email", + "password", + "tel", + "url", + "search", + "date", + "datetime-local", + "month", + "week", + "time", + "color", + "file", + "checkbox", + "radio", + "range", + "hidden", + "button", + "submit", + "reset", + "image" + ], + defaultValue: "text" + }, + disabled: { + control: "boolean", + defaultValue: false + } + }, + parameters: { + layout: "padded" + } +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const WithLabel: Story = { + args: { + label: "Any field label" + } +}; + +export const WithLabelRequired: Story = { + args: { + label: "Any field label", + required: true + } +}; + +export const WithDescription: Story = { + args: { + description: "Provide the required information for processing your request." + } +}; + +export const WithNotes: Story = { + args: { + note: "Note: Ensure your selection or input is accurate before proceeding." + } +}; + +export const WithErrors: Story = { + args: { + validation: { + isValid: false, + message: "This field is required." + } + } +}; + +export const Disabled: Story = { + args: { + label: "Any field label", + disabled: true + } +}; + +export const WithValidateFunction: Story = { + render: args => { + const [value, setValue] = useState(""); + const [validation, setValidation] = useState({ isValid: true, message: undefined }); + + const validate = async () => { + // Simulate API call delay + await new Promise(resolve => setTimeout(resolve, 500)); + + // Example validation: check if email already exists + if (value.includes("exists@")) { + setValidation({ isValid: false, message: "This email is already registered" }); + } else { + setValidation({ isValid: true, message: undefined }); + } + }; + + return ( + setValue(newValue)} + validate={validate} + validation={validation} + /> + ); + } +}; + +export const FullExample: Story = { + args: { + ...Default.args, + label: "Any field label", + required: true, + description: "Provide the required information for processing your request.", + note: "Note: Ensure your selection or input is accurate before proceeding.", + validation: { + isValid: false, + message: "This field is required." + } + } +}; + +export const Documentation: Story = { + render: args => { + const [value, setValue] = useState(""); + const [validation, setValidation] = useState({ isValid: true, message: "" }); + + const handleValidation = () => { + if (args.required && !value.trim()) { + setValidation({ isValid: false, message: "This field is required" }); + } else if (args.minLength && value.trim().length < args.minLength) { + setValidation({ + isValid: false, + message: `Must be at least ${args.minLength} characters long` + }); + } else { + setValidation({ isValid: true, message: "" }); + } + }; + + return ( + setValue(newValue)} + validation={validation} + onBlur={handleValidation} + onEnter={handleValidation} + /> + ); + }, + args: { + type: "text", + size: "lg", + variant: "primary", + label: "Full Name", + description: "Enter your full name as it appears on your ID", + note: "This will be used for official documentation", + placeholder: "Enter your full name", + required: true, + disabled: false, + startIcon: undefined, + endIcon: undefined, + minLength: 3, + maxLength: undefined, + onChange: undefined, + onBlur: undefined, + onEnter: undefined, + validation: undefined, + validate: undefined + }, + argTypes: { + type: { + description: "HTML input type attribute", + control: "select", + options: [ + "text", + "number", + "email", + "password", + "tel", + "url", + "search", + "date", + "datetime-local", + "month", + "week", + "time", + "color", + "file" + ], + defaultValue: "text" + }, + size: { + description: "Input field size", + control: "select", + options: ["md", "lg", "xl"], + defaultValue: "lg" + }, + variant: { + description: "Input field style variant", + control: "select", + options: ["primary", "secondary", "ghost"], + defaultValue: "primary" + }, + label: { + description: "Label text displayed above the input", + control: "text" + }, + description: { + description: "Helper text displayed below the label", + control: "text" + }, + note: { + description: "Additional note displayed below the input", + control: "text" + }, + placeholder: { + description: "Placeholder text shown when input is empty", + control: "text" + }, + required: { + description: "Makes the input field required", + control: "boolean", + defaultValue: true + }, + disabled: { + description: "Disables the input field", + control: "boolean", + defaultValue: false + }, + startIcon: { + description: "Icon displayed at the start of the input", + control: "none" + }, + endIcon: { + description: "Icon displayed at the end of the input", + control: "none" + }, + minLength: { + description: "Minimum number of characters required", + control: "number", + defaultValue: 3 + }, + maxLength: { + description: + "Maximum number of characters allowed. To apply this maxLength, update the code similarly to how it's done for minLength. Refer to the minLength example above for guidance.", + control: "number" + }, + validation: { + description: + "Validation state and error message. Please refer to the example code for details on usage.", + control: "none" + }, + validate: { + description: "Custom validation function", + control: "none" + }, + onChange: { + description: "Callback function when input value changes", + control: "none" + }, + onBlur: { + description: "Callback function when input loses focus", + control: "none" + }, + onEnter: { + description: "Callback function when Enter key is pressed", + control: "none" + } + } // Removed forwardEventOnChange and inputRef +}; diff --git a/packages/admin-ui/src/Input/Input.tsx b/packages/admin-ui/src/Input/Input.tsx new file mode 100644 index 00000000000..7f705cbcbee --- /dev/null +++ b/packages/admin-ui/src/Input/Input.tsx @@ -0,0 +1,62 @@ +import React, { useCallback, useMemo } from "react"; +import { makeDecoratable } from "~/utils"; +import { InputPrimitive, type InputPrimitiveProps } from "./InputPrimitive"; +import { + FormComponentDescription, + FormComponentErrorMessage, + FormComponentLabel, + FormComponentNote, + type FormComponentProps +} from "~/FormComponent"; + +type InputProps = InputPrimitiveProps & FormComponentProps; + +const DecoratableInput = ({ + label, + description, + note, + required, + disabled, + validation, + validate, + onBlur: originalOnBlur, + ...props +}: InputProps) => { + const { isValid: validationIsValid, message: validationMessage } = validation || {}; + const invalid = useMemo(() => validationIsValid === false, [validationIsValid]); + + const onBlur = useCallback( + async (e: React.FocusEvent) => { + if (validate) { + // Since we are accessing event in an async operation, we need to persist it. + // See https://reactjs.org/docs/events.html#event-pooling. + e.persist(); + await validate(); + } + originalOnBlur && originalOnBlur(e); + }, + [validate, originalOnBlur] + ); + + return ( +
+ + + + + +
+ ); +}; +const Input = makeDecoratable("Input", DecoratableInput); + +export { Input, type InputProps }; diff --git a/packages/admin-ui/src/Input/InputPrimitive.stories.tsx b/packages/admin-ui/src/Input/InputPrimitive.stories.tsx new file mode 100644 index 00000000000..d7f5ae67924 --- /dev/null +++ b/packages/admin-ui/src/Input/InputPrimitive.stories.tsx @@ -0,0 +1,166 @@ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import { ReactComponent as NotificationsIcon } from "@webiny/icons/notifications.svg"; +import { ReactComponent as CalendarIcon } from "@webiny/icons/calendar_month.svg"; + +import { InputPrimitive } from "./InputPrimitive"; +import { Icon } from "~/Icon"; + +const meta: Meta = { + title: "Components/Form Primitives/Input", + component: InputPrimitive, + argTypes: { + onChange: { action: "onChange" }, + onEnter: { action: "onEnter" }, + onKeyDown: { action: "onKeyDown" }, + type: { + control: "select", + options: [ + "text", + "number", + "email", + "password", + "tel", + "url", + "search", + "date", + "datetime-local", + "month", + "week", + "time", + "color", + "file", + "checkbox", + "radio", + "range", + "hidden", + "button", + "submit", + "reset", + "image" + ], + defaultValue: "text" + } + }, + parameters: { + layout: "padded" + } +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const MediumSize: Story = { + args: { + placeholder: "Custom placeholder", + size: "md" + } +}; + +export const LargeSize: Story = { + args: { + placeholder: "Custom placeholder", + size: "lg" + } +}; + +export const ExtraLargeSize: Story = { + args: { + placeholder: "Custom placeholder", + size: "xl" + } +}; + +export const WithStartIcon: Story = { + args: { + placeholder: "Custom placeholder", + startIcon: } /> + } +}; + +export const WithEndIcon: Story = { + args: { + placeholder: "Custom placeholder", + endIcon: } /> + } +}; + +export const WithStartAndEndIcons: Story = { + args: { + placeholder: "Custom placeholder", + startIcon: } />, + endIcon: } /> + } +}; + +export const PrimaryVariant: Story = { + args: { + variant: "primary", + placeholder: "Custom placeholder" + } +}; + +export const PrimaryVariantDisabled: Story = { + args: { + ...PrimaryVariant.args, + disabled: true + } +}; + +export const PrimaryVariantInvalid: Story = { + args: { + ...PrimaryVariant.args, + invalid: true + } +}; + +export const SecondaryVariant: Story = { + args: { + variant: "secondary", + placeholder: "Custom placeholder" + } +}; + +export const SecondaryVariantDisabled: Story = { + args: { + ...SecondaryVariant.args, + disabled: true + } +}; + +export const SecondaryVariantInvalid: Story = { + args: { + ...SecondaryVariant.args, + invalid: true + } +}; + +export const GhostVariant: Story = { + args: { + variant: "ghost", + placeholder: "Custom placeholder" + } +}; + +export const GhostVariantDisabled: Story = { + args: { + ...GhostVariant.args, + disabled: true + } +}; + +export const GhostVariantInvalid: Story = { + args: { + ...GhostVariant.args, + invalid: true + } +}; + +export const WithForwardEventOnChange: Story = { + args: { + ...Default.args, + forwardEventOnChange: true + } +}; diff --git a/packages/admin-ui/src/Input/InputPrimitive.tsx b/packages/admin-ui/src/Input/InputPrimitive.tsx new file mode 100644 index 00000000000..05afc068d61 --- /dev/null +++ b/packages/admin-ui/src/Input/InputPrimitive.tsx @@ -0,0 +1,342 @@ +import * as React from "react"; +import { Icon as BaseIcon } from "~/Icon"; +import { cn, cva, type VariantProps, makeDecoratable } from "~/utils"; + +/** + * Icon + */ +const inputIconVariants = cva("wby-absolute wby-fill-neutral-xstrong", { + variants: { + // Define dummy variants to be used in combination with `compoundVariants` below. + inputSize: { + md: "wby-top-sm", + lg: "wby-top-sm-extra", + xl: "wby-top-md" + }, + position: { + start: "", + end: "" + }, + disabled: { + true: "wby-fill-neutral-disabled" + } + }, + defaultVariants: { + inputSize: "lg", + position: "start" + }, + compoundVariants: [ + // The icon position is `absolute` and is adjusted horizontally across its parent using left and right. + { + inputSize: "md", + position: "start", + class: "wby-left-[calc(theme(spacing.sm-plus)-theme(borderWidth.sm))]" + }, + { + inputSize: "md", + position: "end", + class: "wby-right-[calc(theme(spacing.sm-plus)-theme(borderWidth.sm))]" + }, + { + inputSize: "lg", + position: "start", + class: "wby-left-[calc(theme(spacing.sm-plus)-theme(borderWidth.sm))]" + }, + { + inputSize: "lg", + position: "end", + class: "wby-right-[calc(theme(spacing.sm-plus)-theme(borderWidth.sm))]" + }, + { + inputSize: "xl", + position: "start", + class: "wby-left-[calc(theme(spacing.md)-theme(borderWidth.sm))]" + }, + { + inputSize: "xl", + position: "end", + class: "wby-right-[calc(theme(spacing.md)-theme(borderWidth.sm))]" + } + ] +}); + +interface InputIconProps + extends React.HTMLAttributes, + VariantProps { + icon: React.ReactElement; +} + +const InputIcon = ({ icon, disabled, position, inputSize, className }: InputIconProps) => { + return ( +
+ {React.cloneElement(icon, { + ...icon.props, + size: inputSize === "xl" ? "lg" : "sm" // Map icon size based on the input size. + })} +
+ ); +}; + +/** + * Input + * + * We support both `disabled` and `data-disabled` as well as `focused` and `data-focused` variants + * because these variants can be used by both input and div elements. The last one is used by `MultiAutocomplete` component, + * where the `inputVariants` is used to style a div that wraps multiple elements (input, Tags, icons, etc.) + */ +const inputVariants = cva( + [ + "wby-w-full wby-border-sm wby-text-md wby-peer", + "focus-visible:wby-outline-none", + "disabled:wby-cursor-not-allowed data-[disabled=true]:wby-cursor-not-allowed", + "file:wby-bg-transparent file:wby-border-none file:wby-text-sm file:wby-font-semibold" + ], + { + variants: { + size: { + md: [ + "wby-rounded-md", + "wby-py-[calc(theme(padding.xs-plus)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.sm-extra)-theme(borderWidth.sm))]" + ], + lg: [ + "wby-rounded-md", + "wby-py-[calc(theme(padding.sm-plus)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.sm-extra)-theme(borderWidth.sm))]" + ], + xl: [ + "wby-rounded-lg wby-leading-6", + "wby-py-[calc(theme(padding.md)-theme(borderWidth.sm))] wby-px-[calc(theme(padding.md)-theme(borderWidth.sm))]" + ] + }, + variant: { + primary: [ + "wby-bg-neutral-base wby-border-neutral-muted wby-text-neutral-strong placeholder:wby-text-neutral-dimmed", + "hover:wby-border-neutral-strong", + "focus:wby-border-neutral-black", + "data-[focused=true]:wby-border-neutral-black", + "disabled:wby-bg-neutral-disabled disabled:wby-border-neutral-dimmed disabled:wby-text-neutral-disabled disabled:placeholder:wby-text-neutral-disabled", + "data-[disabled=true]:wby-bg-neutral-disabled data-[disabled=true]:wby-border-neutral-dimmed data-[disabled=true]:wby-text-neutral-disabled data-[disabled=true]:placeholder:wby-text-neutral-disabled" + ], + secondary: [ + "wby-bg-neutral-light wby-border-neutral-subtle wby-text-neutral-strong placeholder:wby-text-neutral-dimmed", + "hover:wby-bg-neutral-dimmed", + "focus:wby-bg-neutral-base focus:wby-border-neutral-black", + "data-[focused=true]:wby-bg-neutral-base data-[focused=true]:wby-border-neutral-black", + "disabled:wby-bg-neutral-disabled disabled:wby-text-neutral-disabled disabled:placeholder:wby-text-neutral-disabled", + "data-[disabled=true]:wby-bg-neutral-disabled data-[disabled=true]:wby-text-neutral-disabled data-[disabled=true]:placeholder:wby-text-neutral-disabled" + ], + ghost: [ + "wby-bg-transparent wby-border-transparent wby-text-neutral-strong placeholder:wby-text-neutral-dimmed", + "hover:wby-bg-neutral-dark/5", + "focus:wby-bg-neutral-dark/5", + "data-[focused=true]:wby-bg-neutral-dark/5", + "disabled:wby-bg-transparent disabled:wby-text-neutral-disabled disabled:placeholder:wby-text-neutral-disabled", + "data-[disabled=true]:wby-bg-transparent data-[disabled=true]:wby-text-neutral-disabled data-[disabled=true]:placeholder:wby-text-neutral-disabled" + ] + }, + iconPosition: { + start: "wby-pl-[calc(theme(padding.xl)-theme(borderWidth.sm))]", + end: "wby-pr-[calc(theme(padding.xl)-theme(borderWidth.sm))]", + both: [ + "wby-pl-[calc(theme(padding.xl)-theme(borderWidth.sm))]", + "wby-pr-[calc(theme(padding.xl)-theme(borderWidth.sm))]" + ] + }, + invalid: { + true: "" + } + }, + compoundVariants: [ + // Prevent text overlap with icons, add extra padding for icons. + { + size: "lg", + iconPosition: "start", + class: "wby-pl-[calc(theme(padding.xl)-theme(borderWidth.sm))]" + }, + { + size: "lg", + iconPosition: "end", + class: "wby-pr-[calc(theme(padding.xl)-theme(borderWidth.sm))]" + }, + { + size: "lg", + iconPosition: "both", + class: [ + "wby-pl-[calc(theme(padding.xl)-theme(borderWidth.sm))]", + "wby-pr-[calc(theme(padding.xl)-theme(borderWidth.sm))]" + ] + }, + { + size: "xl", + iconPosition: "start", + class: "wby-pl-[calc(theme(padding.xxl)+theme(padding.xs)-theme(borderWidth.sm))]" + }, + { + size: "xl", + iconPosition: "end", + class: "wby-pr-[calc(theme(padding.xxl)+theme(padding.xs)-theme(borderWidth.sm))]" + }, + { + size: "xl", + iconPosition: "both", + class: [ + "wby-pl-[calc(theme(padding.xxl)+theme(padding.xs)-theme(borderWidth.sm))]", + "wby-pr-[calc(theme(padding.xxl)+theme(padding.xs)-theme(borderWidth.sm))]" + ] + }, + // Add specific classNames in case of invalid inputs: note the difference between the ghost and the other variants. + { + variant: "primary", + invalid: true, + class: "!wby-border-destructive-default" + }, + { + variant: "secondary", + invalid: true, + class: "!wby-border-destructive-default" + }, + { + variant: "ghost", + invalid: true, + class: "!wby-border-destructive-subtle !wby-bg-destructive-subtle" + } + ], + defaultVariants: { + size: "lg", + variant: "primary" + } + } +); + +type InputPrimitiveProps = Omit< + React.InputHTMLAttributes, + "size" | "onChange" +> & + VariantProps & { + /** + * Icon to be displayed at the start of the input field. + */ + startIcon?: React.ReactElement | React.ReactElement; + /** + * Icon to be displayed at the end of the input field. + */ + endIcon?: React.ReactElement | React.ReactElement; + /** + * Maximum length of the input field. + */ + maxLength?: React.InputHTMLAttributes["size"]; + /** + * Reference to the input element. + */ + inputRef?: React.Ref; + /** + * If true, it will pass the native `event` to the `onChange` callback + */ + forwardEventOnChange?: boolean; + /** + * Callback function to be called when the Enter key is pressed. + */ + onEnter?: () => void; + /** + * A callback that is executed each time a value is changed. + */ + onChange?: (value: TValue) => void; + }; + +const getIconPosition = ( + startIcon?: InputPrimitiveProps["startIcon"], + endIcon?: InputPrimitiveProps["endIcon"] +): "start" | "end" | "both" | undefined => { + if (startIcon && endIcon) { + return "both"; + } + if (startIcon) { + return "start"; + } + if (endIcon) { + return "end"; + } + return; +}; + +const DecoratableInputPrimitive = ({ + className, + disabled, + endIcon, + forwardEventOnChange, + inputRef, + invalid, + maxLength, + onChange: originalOnChange, + onEnter, + onKeyDown: originalOnKeyDown, + size, + startIcon, + value, + variant, + ...props +}: InputPrimitiveProps) => { + const iconPosition = getIconPosition(startIcon, endIcon); + + const onChange = React.useCallback( + (event: React.SyntheticEvent) => { + if (!originalOnChange) { + return; + } + + // @ts-expect-error + originalOnChange(forwardEventOnChange ? event : event.target.value); + }, + [forwardEventOnChange, originalOnChange] + ); + + const onKeyDown = React.useCallback( + (e: React.KeyboardEvent) => { + if (typeof onEnter === "function" && e.key === "Enter") { + onEnter(); + } + + if (typeof originalOnKeyDown === "function") { + return originalOnKeyDown(e); + } + }, + [originalOnKeyDown, onEnter] + ); + + return ( +
+ {startIcon && ( + + )} + + {endIcon && ( + + )} +
+ ); +}; + +const InputPrimitive = makeDecoratable("InputPrimitive", DecoratableInputPrimitive); + +export { + InputIcon, + InputPrimitive, + getIconPosition, + inputVariants, + inputIconVariants, + type InputIconProps, + type InputPrimitiveProps +}; diff --git a/packages/admin-ui/src/Input/index.ts b/packages/admin-ui/src/Input/index.ts new file mode 100644 index 00000000000..d23d7dc8a18 --- /dev/null +++ b/packages/admin-ui/src/Input/index.ts @@ -0,0 +1,2 @@ +export * from "./Input"; +export * from "./InputPrimitive"; diff --git a/packages/admin-ui/src/Label/Label.mdx b/packages/admin-ui/src/Label/Label.mdx new file mode 100644 index 00000000000..d135a1118e8 --- /dev/null +++ b/packages/admin-ui/src/Label/Label.mdx @@ -0,0 +1,105 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; + +import * as LabelStories from './Label.stories'; + + + +# Label + +The Label component is a fundamental UI element used to provide clear text descriptions for form controls. +**While most form components accept a `label` prop, there are cases where you may need more flexibility or control — in such scenarios, you can use the Label component directly.** + +It enhances usability by clearly identifying input fields and improves accessibility by properly associating labels with their corresponding form elements using htmlFor. +The component supports a range of customization options, including descriptions, hints, required indicators, disabled and invalid states, and visual weight variants. + + +## Usage + + { + const [value, setValue] = useState(""); + + return ( +
+
+ ); +}; + +export default LabelExample; + +` } } + additionalActions={[ + { + title: 'Open in GitHub', + onClick: () => { + window.open( + 'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Label/Label.tsx', + '_blank' + ); + }, + } + ]} +/> + + + +```tsx +import React, { useState } from "react"; +import { Label, Input } from "@webiny/admin-ui"; + +const LabelExample = () => { + const [value, setValue] = useState(""); + + return ( +
+
+ ); +}; + +export default LabelExample; +``` diff --git a/packages/admin-ui/src/Label/Label.stories.tsx b/packages/admin-ui/src/Label/Label.stories.tsx new file mode 100644 index 00000000000..ce38c6b205a --- /dev/null +++ b/packages/admin-ui/src/Label/Label.stories.tsx @@ -0,0 +1,164 @@ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; + +import { Label } from "./Label"; +import { Tooltip } from "~/Tooltip"; +import { Input } from "~/Input"; + +const meta: Meta = { + title: "Components/Form/Label", + component: Label, + parameters: { + layout: "padded" + }, + decorators: [ + Story => ( + + + + ) + ] +}; + +export default meta; +type Story = StoryObj; + +export const Documentation: Story = { + render: args => { + const [value, setValue] = React.useState(""); + + return ( +
+
+ ); + }, + args: { + text: "Full Name", + htmlFor: "full-name", + description: "As shown on your government-issued ID", + hint: "Include middle name if applicable", + required: true, + disabled: false, + weight: "strong", + value: "Label value will be shown here", + invalid: false + }, + argTypes: { + text: { + description: "The text content of the label", + control: "text" + }, + htmlFor: { + description: "The ID of the form element this label is associated with", + control: "text" + }, + description: { + description: "Additional descriptive text shown next to the label", + control: "text" + }, + hint: { + description: "Tooltip hint text that appears on hover", + control: "text" + }, + required: { + description: "Whether the associated form field is required", + control: "boolean" + }, + disabled: { + description: "Whether the label should appear disabled", + control: "boolean" + }, + weight: { + description: "The font weight of the label text", + control: "select", + options: ["strong", "light"] + }, + value: { + description: "Optional value to display on the right side of the label", + control: "text" + }, + invalid: { + description: "Whether the label should appear in an invalid state", + control: "boolean" + } + } +}; + +export const Default: Story = { + args: { + text: "Test label", + htmlFor: "test-field" + }, + render: args => ( + <> + +