diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
new file mode 100644
index 00000000000..f149df6a2b6
--- /dev/null
+++ b/.github/workflows/chromatic.yml
@@ -0,0 +1,41 @@
+---
+name: Chromatic
+
+on: push
+
+jobs:
+ chromatic:
+ name: Chromatic
+ runs-on: ubuntu-20.04
+
+ steps:
+ - name: Set up Node
+ uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5
+ with:
+ node-version: "16"
+
+ - name: Checkout repo
+ uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
+ with:
+ fetch-depth: 0
+
+ - name: Cache npm
+ id: npm-cache
+ uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353 # v2.1.6
+ with:
+ path: "~/.npm"
+ key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }}
+
+ - name: Install Node dependencies
+ run: npm ci
+ working-directory: ./components
+
+ - name: Publish to Chromatic
+ uses: chromaui/action@c72f0b48c8887c0ef0abe18ad865a6c1e01e73c6
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
+ workingDir: ./components
+ exitOnceUploaded: true
+ onlyChanged: true
+ externals: "[\"components/**/*.scss\", \"components/tailwind.config*.js\"]"
diff --git a/components/.storybook/main.js b/components/.storybook/main.js
index e7c9115aad5..ed4cd08e109 100644
--- a/components/.storybook/main.js
+++ b/components/.storybook/main.js
@@ -1,6 +1,6 @@
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
- addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
+ addons: ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-a11y"],
framework: "@storybook/angular",
core: {
builder: "webpack5",
diff --git a/components/package-lock.json b/components/package-lock.json
index 86bdc41e1ad..bf65bcd09a8 100644
--- a/components/package-lock.json
+++ b/components/package-lock.json
@@ -17,6 +17,7 @@
"@angular/platform-browser": "^12.2.13",
"@angular/platform-browser-dynamic": "^12.2.13",
"@bitwarden/jslib-angular": "file:../angular",
+ "bootstrap": "4.6.0",
"tslib": "^2.3.0"
},
"devDependencies": {
@@ -26,6 +27,7 @@
"@angular/elements": "^12.2.13",
"@babel/core": "^7.16.10",
"@compodoc/compodoc": "^1.1.16",
+ "@storybook/addon-a11y": "^6.4.19",
"@storybook/addon-actions": "^6.4.18",
"@storybook/addon-essentials": "^6.4.18",
"@storybook/addon-links": "^6.4.18",
@@ -37,6 +39,7 @@
"@webcomponents/custom-elements": "^1.5.0",
"autoprefixer": "^10.4.2",
"babel-loader": "^8.2.3",
+ "chromatic": "^6.5.2",
"jasmine-core": "~3.10.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
@@ -4757,6 +4760,46 @@
"node": ">= 0.6.0"
}
},
+ "node_modules/@storybook/addon-a11y": {
+ "version": "6.4.19",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.4.19.tgz",
+ "integrity": "sha512-dG6easap6W4AqyggVZPq8lBrhza8StA8J4eYz/GVdoXINSGtq/casV0rkmY3+SUXhPYux5oGavHo86j5I4Q/0Q==",
+ "dev": true,
+ "dependencies": {
+ "@storybook/addons": "6.4.19",
+ "@storybook/api": "6.4.19",
+ "@storybook/channels": "6.4.19",
+ "@storybook/client-logger": "6.4.19",
+ "@storybook/components": "6.4.19",
+ "@storybook/core-events": "6.4.19",
+ "@storybook/csf": "0.0.2--canary.87bc651.0",
+ "@storybook/theming": "6.4.19",
+ "axe-core": "^4.2.0",
+ "core-js": "^3.8.2",
+ "global": "^4.4.0",
+ "lodash": "^4.17.21",
+ "react-sizeme": "^3.0.1",
+ "regenerator-runtime": "^0.13.7",
+ "ts-dedent": "^2.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@storybook/addon-actions": {
"version": "6.4.19",
"resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.4.19.tgz",
@@ -13487,6 +13530,15 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/axe-core": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz",
+ "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/babel-loader": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz",
@@ -14023,6 +14075,19 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true
},
+ "node_modules/bootstrap": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
+ "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ },
+ "peerDependencies": {
+ "jquery": "1.9.1 - 3",
+ "popper.js": "^1.16.1"
+ }
+ },
"node_modules/boxen": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
@@ -14694,6 +14759,17 @@
"node": ">=10"
}
},
+ "node_modules/chromatic": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-6.5.2.tgz",
+ "integrity": "sha512-TiAJAF2we4BUflKEfiXs2CiBFvW6yNWkiXKIuBtlSLl2fj1cuueXlV5dYVVoyMDfzTX5JdEn/Bd5CVlpKCeY6A==",
+ "dev": true,
+ "bin": {
+ "chroma": "bin/main.cjs",
+ "chromatic": "bin/main.cjs",
+ "chromatic-cli": "bin/main.cjs"
+ }
+ },
"node_modules/chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
@@ -21897,6 +21973,12 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/jquery": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
+ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==",
+ "peer": true
+ },
"node_modules/js-string-escape": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -25131,6 +25213,17 @@
"node": ">=6.9.0"
}
},
+ "node_modules/popper.js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
+ "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
@@ -37713,6 +37806,30 @@
"integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
"dev": true
},
+ "@storybook/addon-a11y": {
+ "version": "6.4.19",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.4.19.tgz",
+ "integrity": "sha512-dG6easap6W4AqyggVZPq8lBrhza8StA8J4eYz/GVdoXINSGtq/casV0rkmY3+SUXhPYux5oGavHo86j5I4Q/0Q==",
+ "dev": true,
+ "requires": {
+ "@storybook/addons": "6.4.19",
+ "@storybook/api": "6.4.19",
+ "@storybook/channels": "6.4.19",
+ "@storybook/client-logger": "6.4.19",
+ "@storybook/components": "6.4.19",
+ "@storybook/core-events": "6.4.19",
+ "@storybook/csf": "0.0.2--canary.87bc651.0",
+ "@storybook/theming": "6.4.19",
+ "axe-core": "^4.2.0",
+ "core-js": "^3.8.2",
+ "global": "^4.4.0",
+ "lodash": "^4.17.21",
+ "react-sizeme": "^3.0.1",
+ "regenerator-runtime": "^0.13.7",
+ "ts-dedent": "^2.0.0",
+ "util-deprecate": "^1.0.2"
+ }
+ },
"@storybook/addon-actions": {
"version": "6.4.19",
"resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.4.19.tgz",
@@ -44584,6 +44701,12 @@
"postcss-value-parser": "^4.2.0"
}
},
+ "axe-core": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz",
+ "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==",
+ "dev": true
+ },
"babel-loader": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz",
@@ -45025,6 +45148,12 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true
},
+ "bootstrap": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
+ "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
+ "requires": {}
+ },
"boxen": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
@@ -45548,6 +45677,12 @@
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true
},
+ "chromatic": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-6.5.2.tgz",
+ "integrity": "sha512-TiAJAF2we4BUflKEfiXs2CiBFvW6yNWkiXKIuBtlSLl2fj1cuueXlV5dYVVoyMDfzTX5JdEn/Bd5CVlpKCeY6A==",
+ "dev": true
+ },
"chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
@@ -51165,6 +51300,12 @@
}
}
},
+ "jquery": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
+ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==",
+ "peer": true
+ },
"js-string-escape": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -53720,6 +53861,12 @@
}
}
},
+ "popper.js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
+ "peer": true
+ },
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
diff --git a/components/package.json b/components/package.json
index 99c7c49c021..7b43f9d72ff 100644
--- a/components/package.json
+++ b/components/package.json
@@ -9,7 +9,8 @@
"test": "ng test",
"docs:json": "compodoc -p ./tsconfig.json -e json -d .",
"storybook": "npm run docs:json && start-storybook -p 6006",
- "build-storybook": "npm run docs:json && build-storybook"
+ "build-storybook": "npm run docs:json && build-storybook",
+ "chromatic": "chromatic --exit-zero-on-changes"
},
"private": true,
"dependencies": {
@@ -22,6 +23,7 @@
"@angular/platform-browser": "^12.2.13",
"@angular/platform-browser-dynamic": "^12.2.13",
"@bitwarden/jslib-angular": "file:../angular",
+ "bootstrap": "4.6.0",
"tslib": "^2.3.0"
},
"devDependencies": {
@@ -31,6 +33,7 @@
"@angular/elements": "^12.2.13",
"@babel/core": "^7.16.10",
"@compodoc/compodoc": "^1.1.16",
+ "@storybook/addon-a11y": "^6.4.19",
"@storybook/addon-actions": "^6.4.18",
"@storybook/addon-essentials": "^6.4.18",
"@storybook/addon-links": "^6.4.18",
@@ -42,6 +45,7 @@
"@webcomponents/custom-elements": "^1.5.0",
"autoprefixer": "^10.4.2",
"babel-loader": "^8.2.3",
+ "chromatic": "^6.5.2",
"jasmine-core": "~3.10.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
diff --git a/components/src/stories/Introduction.stories.mdx b/components/src/stories/Introduction.stories.mdx
index a69b74b3d9d..5b798704973 100644
--- a/components/src/stories/Introduction.stories.mdx
+++ b/components/src/stories/Introduction.stories.mdx
@@ -1,6 +1,6 @@
import { Meta } from "@storybook/addon-docs";
-
+
-# Welcome to Storybook
+# Bitwarden Component Library
Storybook helps you build UI components in isolation from your app's business logic, data, and context.
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
@@ -188,8 +161,3 @@ We recommend building UIs with a [**component-driven**](https://componentdriven.
-
-
- TipEdit the Markdown in{" "}
- src/stories/Introduction.stories.mdx
-
diff --git a/components/src/stories/colors.stories.mdx b/components/src/stories/colors.stories.mdx
new file mode 100644
index 00000000000..f311013544d
--- /dev/null
+++ b/components/src/stories/colors.stories.mdx
@@ -0,0 +1,85 @@
+import { Meta } from "@storybook/addon-docs";
+
+
+
+export const Row = (name) => (
+
+ | {name} |
+ |
+
+);
+
+export const Table = (args) => (
+
+
+
+ | General usage |
+ |
+
+
+
+ {Row("background")}
+ {Row("background-alt")}
+ {Row("background-alt2")}
+
+
+ {Row("primary-300")}
+ {Row("primary-500")}
+ {Row("primary-700")}
+
+
+ {Row("secondary-100")}
+ {Row("secondary-300")}
+ {Row("secondary-500")}
+ {Row("secondary-700")}
+
+
+ {Row("success-500")}
+ {Row("success-700")}
+
+
+ {Row("danger-500")}
+ {Row("danger-700")}
+
+
+ {Row("warning-500")}
+ {Row("warning-700")}
+
+
+ {Row("info-500")}
+ {Row("info-700")}
+
+
+ {Row("text-main")}
+ {Row("text-muted")}
+ {Row("text-contrast")}
+
+
+);
+
+
+
+# Colors
+
+
diff --git a/components/src/styles.scss b/components/src/styles.scss
index beb241daa46..8729b921b8a 100644
--- a/components/src/styles.scss
+++ b/components/src/styles.scss
@@ -1,5 +1,5 @@
@import "../../angular/src/scss/webfonts.css";
-@import "./../../../src/scss/variables";
+@import "./variables";
@import "../../angular/src/scss/bwicons/styles/style.scss";
@import "../../angular/src/scss/icons.scss";
diff --git a/components/src/variables.scss b/components/src/variables.scss
new file mode 100644
index 00000000000..a0bc2d88526
--- /dev/null
+++ b/components/src/variables.scss
@@ -0,0 +1,357 @@
+$dark-icon-themes: "theme_dark";
+
+$primary: #175ddc;
+$primary-accent: #1252a3;
+$secondary: #ced4da;
+$secondary-alt: #1a3b66;
+$success: #00a65a;
+$info: #555555;
+$warning: #bf7e16;
+$danger: #dd4b39;
+$white: #ffffff;
+
+// Bootstrap Variable Overrides
+
+$theme-colors: (
+ "primary-accent": $primary-accent,
+ "secondary-alt": $secondary-alt,
+);
+
+$body-bg: $white;
+$body-color: #333333;
+
+$font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+
+$h1-font-size: 1.7rem;
+$h2-font-size: 1.3rem;
+$h3-font-size: 1rem;
+$h4-font-size: 1rem;
+$h5-font-size: 1rem;
+$h6-font-size: 1rem;
+
+$small-font-size: 90%;
+$font-size-lg: 1.15rem;
+$code-font-size: 100%;
+
+$navbar-padding-y: 0.75rem;
+$grid-gutter-width: 20px;
+$card-spacer-y: 0.6rem;
+
+$list-group-item-padding-y: 0.6rem;
+$list-group-active-color: $body-color;
+$list-group-active-bg: $white;
+$list-group-active-border-color: rgba(#000000, 0.125);
+
+$dropdown-link-color: $body-color;
+$dropdown-link-hover-bg: rgba(#000000, 0.06);
+$dropdown-link-active-color: $dropdown-link-color;
+$dropdown-link-active-bg: rgba(#000000, 0.1);
+$dropdown-item-padding-x: 1rem;
+
+$navbar-brand-font-size: 35px;
+$navbar-brand-height: 35px;
+$navbar-brand-padding-y: 0;
+$navbar-dark-color: rgba($white, 0.7);
+$navbar-dark-hover-color: rgba($white, 0.9);
+$navbar-nav-link-padding-x: 0.8rem;
+
+$input-bg: #fbfbfb;
+$input-focus-bg: $white;
+$input-disabled-bg: #e0e0e0;
+$input-placeholder-color: #b4b4b4;
+
+$table-accent-bg: rgba(#000000, 0.02);
+$table-hover-bg: rgba(#000000, 0.03);
+
+$modal-backdrop-opacity: 0.3;
+$btn-font-weight: 600;
+$lead-font-weight: normal;
+
+$grid-breakpoints: (
+ xs: 0,
+ sm: 1px,
+ md: 2px,
+ lg: 3px,
+ xl: 4px,
+);
+
+$border-color: $secondary;
+
+// MFA Types for logo styling with no dark theme alternative
+
+$mfaTypes: 0, 2, 3, 4, 6;
+
+// Theme Variables
+// Light
+
+$lightDangerHover: #c43421;
+$lightInputColor: #465057;
+$lightInputPlaceholderColor: #b6b8b8;
+
+// Dark
+
+$darkPrimary: #6a99f0;
+$darkPrimary-alt: #b4ccf9;
+$darkDanger: #ff8d85;
+$darkDangerHover: #ffbfbb;
+$darkSuccess: #52e07c;
+$darkWarning: #ffeb66;
+$darkInfo: #a4b0c6;
+$darkLinks: #6a99f0;
+$darkGrey1: #bac0ce;
+$darkGrey2: #8d94a5;
+$darkBlue1: #4c525f;
+$darkBlue2: #3c424e;
+$darkDarkBlue1: #2f343d;
+$darkDarkBlue2: #1f242e;
+$darkInputColor: $white;
+$darkInputPlaceholderColor: $darkGrey1;
+
+$themes: (
+ light: (
+ primary: $primary,
+ primaryAlt: $primary-accent,
+ danger: $danger,
+ info: #343a40,
+ success: $success,
+ warning: $warning,
+ backgroundColor: $white,
+ badgeDangerBackground: $danger,
+ badgeDangerText: $white,
+ badgeInfoBackground: #555555,
+ badgeInfoText: $white,
+ badgePrimaryBackground: $primary,
+ badgePrimaryBackgroundHover: #134eb9,
+ badgePrimaryText: $white,
+ badgeSecondaryBackground: #ced4da,
+ badgeSecondaryText: #212529,
+ bgLightColor: #f8f9fa,
+ bgPrimaryColor: $primary,
+ borderColor: $border-color,
+ borderPrimaryColor: $primary,
+ browserInputIconsFilter: invert(0),
+ btnDanger: $danger,
+ btnDangerHover: $lightDangerHover,
+ btnDangerText: $white,
+ btnLinkText: $primary,
+ btnLinkTextHover: #104097,
+ btnOutlineDangerBackground: $input-bg,
+ btnOutlineDangerBackgroundHover: $danger,
+ btnOutlineDangerBorder: #ced4da,
+ btnOutlineDangerBorderHover: $danger,
+ btnOutlineDangerText: $danger,
+ btnOutlineDangerTextHover: $white,
+ btnOutlinePrimaryBackground: $input-bg,
+ btnOutlinePrimaryBackgroundHover: $primary,
+ btnOutlinePrimaryBorder: #ced4da,
+ btnOutlinePrimaryBorderHover: $primary,
+ btnOutlinePrimaryText: $primary,
+ btnOutlinePrimaryTextHover: $white,
+ btnOutlineSecondaryBackground: $input-bg,
+ btnOutlineSecondaryBackgroundHover: #ced4da,
+ btnOutlineSecondaryBorder: #ced4da,
+ btnOutlineSecondaryBorderHover: #ced4da,
+ btnOutlineSecondaryText: #6c757d,
+ btnOutlineSecondaryTextHover: #333333,
+ btnPrimary: $primary,
+ btnPrimaryBorderHover: #1249ae,
+ btnPrimaryHover: #134eb9,
+ btnPrimaryText: $white,
+ btnSecondary: $secondary,
+ btnSecondaryBorder: $secondary,
+ btnSecondaryBorderHover: #b1bbc4,
+ btnSecondaryHover: #b8c1ca,
+ btnSecondaryText: #212529,
+ btnSecondaryTextHover: #212529,
+ calloutBackground: #fafafa,
+ calloutColor: #212529,
+ cdkDraggingBackground: $white,
+ codeColor: #e83e8c,
+ dropdownBackground: $white,
+ dropdownHover: rgba(0, 0, 0, 0.06),
+ dropdownTextColor: $body-color,
+ dropdownTextMuted: #6c757d,
+ focus: rgb(23 93 220 / 25%),
+ footerBackgroundColor: #fbfbfb,
+ foregroundColor: $white,
+ headerColor: rgba(0, 0, 0, 0.03),
+ iconColor: #777777,
+ iconHover: $body-color,
+ imgFilter: invert(0) grayscale(0),
+ inputBackgroundColor: $input-bg,
+ inputBorderColor: $border-color,
+ inputDisabledBackground: #e0e0e0,
+ inputDisabledColor: #6c757d,
+ inputPlaceholderColor: $lightInputPlaceholderColor,
+ inputTextColor: $lightInputColor,
+ layoutFrontendColor: #ecf0f5,
+ learnMoreHover: #104097,
+ linkColor: $primary,
+ linkColorHover: #104097,
+ linkWeight: 400,
+ listItemActive: $body-color,
+ listItemBorder: rgba(0, 0, 0, 0.125),
+ loadingSvg: url("../images/loading.svg"),
+ logoSuffix: "dark",
+ mfaLogoSuffix: ".png",
+ navActiveBackground: $white,
+ navActiveWeight: 600,
+ navBackground: $primary,
+ navBackgroundAlt: $secondary-alt,
+ navOrgBackgroundColor: #fbfbfb,
+ navWeight: 600,
+ pwLetter: $body-color,
+ pwNumber: #007fde,
+ pwSpecial: #c40800,
+ pwStrengthBackground: #e9ecef,
+ separator: $secondary,
+ separatorHr: rgb(0, 0, 0, 0.1),
+ tableColorHover: #333333,
+ tableLinkColor: $primary,
+ tableLinkColorHover: #104097,
+ tableRowHover: rgba(0, 0, 0, 0.03),
+ tableSeparator: #dee2e6,
+ textColor: $body-color,
+ textDangerColor: $white,
+ textInfoColor: $white,
+ textHeadingColor: #333333,
+ textMuted: #6c757d,
+ textSuccessColor: $white,
+ textWarningColor: $white,
+ ),
+ dark: (
+ primary: $darkPrimary,
+ primaryAlt: $darkPrimary-alt,
+ danger: $darkDanger,
+ info: $darkInfo,
+ success: $darkSuccess,
+ warning: $darkWarning,
+ backgroundColor: $darkDarkBlue2,
+ badgeDangerBackground: $darkDanger,
+ badgeDangerText: $darkDarkBlue2,
+ badgeInfoBackground: $darkInfo,
+ badgeInfoText: $darkDarkBlue2,
+ badgePrimaryBackground: $darkLinks,
+ badgePrimaryBackgroundHover: $darkPrimary-alt,
+ badgePrimaryText: $darkDarkBlue2,
+ badgeSecondaryBackground: $darkGrey2,
+ badgeSecondaryText: $darkDarkBlue2,
+ bgLightColor: $darkDarkBlue2,
+ bgPrimaryColor: $darkPrimary,
+ borderColor: $darkBlue1,
+ borderPrimaryColor: $darkPrimary,
+ browserInputIconsFilter: invert(1),
+ btnDanger: $darkDanger,
+ btnDangerHover: $darkDangerHover,
+ btnDangerText: $darkDarkBlue2,
+ btnLinkText: $white,
+ btnLinkTextHover: $darkGrey1,
+ btnOutlineDangerBackground: $darkDanger,
+ btnOutlineDangerBackgroundHover: $darkDangerHover,
+ btnOutlineDangerBorder: $darkDanger,
+ btnOutlineDangerBorderHover: $darkDangerHover,
+ btnOutlineDangerText: $darkDarkBlue2,
+ btnOutlineDangerTextHover: $darkDarkBlue2,
+ btnOutlinePrimaryBackground: $darkPrimary,
+ btnOutlinePrimaryBackgroundHover: $darkPrimary-alt,
+ btnOutlinePrimaryBorder: $darkPrimary,
+ btnOutlinePrimaryBorderHover: $darkPrimary-alt,
+ btnOutlinePrimaryText: $darkDarkBlue2,
+ btnOutlinePrimaryTextHover: $darkDarkBlue2,
+ btnOutlineSecondaryBackground: transparent,
+ btnOutlineSecondaryBackgroundHover: transparent,
+ btnOutlineSecondaryBorder: $darkGrey1,
+ btnOutlineSecondaryBorderHover: $darkGrey2,
+ btnOutlineSecondaryText: $white,
+ btnOutlineSecondaryTextHover: $darkGrey2,
+ btnPrimary: $darkLinks,
+ btnPrimaryBorderHover: $darkPrimary-alt,
+ btnPrimaryHover: $darkPrimary-alt,
+ btnPrimaryText: $darkDarkBlue2,
+ btnSecondary: transparent,
+ btnSecondaryBorder: $darkGrey1,
+ btnSecondaryBorderHover: $darkGrey2,
+ btnSecondaryHover: transparent,
+ btnSecondaryText: $white,
+ btnSecondaryTextHover: $darkGrey2,
+ calloutBackground: $darkBlue2,
+ calloutColor: $white,
+ cdkDraggingBackground: $darkDarkBlue1,
+ codeColor: #e83e8c,
+ dropdownBackground: $darkDarkBlue1,
+ dropdownHover: rgba(255, 255, 255, 0.03),
+ dropdownTextColor: $white,
+ dropdownTextMuted: #bec6cf,
+ focus: rgb(106 153 240 / 25%),
+ footerBackgroundColor: $darkBlue1,
+ foregroundColor: $darkDarkBlue1,
+ headerColor: $darkBlue1,
+ iconColor: #777777,
+ iconHover: $darkGrey2,
+ imgFilter: invert(1) grayscale(1),
+ inputBackgroundColor: transparent,
+ inputBorderColor: $darkGrey1,
+ inputDisabledBackground: $darkBlue2,
+ inputDisabledColor: $darkGrey1,
+ inputPlaceholderColor: $darkInputPlaceholderColor,
+ inputTextColor: $darkInputColor,
+ layoutFrontendColor: $darkDarkBlue2,
+ learnMoreHover: $darkPrimary-alt,
+ linkColor: $darkLinks,
+ linkColorHover: $darkLinks,
+ linkWeight: 600,
+ listItemActive: $darkPrimary,
+ listItemBorder: $darkBlue1,
+ loadingSvg: url("../images/loading-white.svg"),
+ logoSuffix: "white",
+ mfaLogoSuffix: "-w.png",
+ navActiveBackground: $darkDarkBlue2,
+ navActiveWeight: 600,
+ navBackground: $darkDarkBlue1,
+ navBackgroundAlt: $darkDarkBlue1,
+ navOrgBackgroundColor: #161c26,
+ navWeight: 400,
+ pwLetter: $white,
+ pwNumber: #52bdfb,
+ pwSpecial: #ff7c70,
+ pwStrengthBackground: $darkBlue2,
+ separator: $darkBlue1,
+ separatorHr: $darkBlue1,
+ tableColorHover: $darkGrey1,
+ tableLinkColor: $white,
+ tableLinkColorHover: $white,
+ tableRowHover: rgba(255, 255, 255, 0.03),
+ tableSeparator: $darkBlue1,
+ textColor: $darkGrey1,
+ textDangerColor: $darkDarkBlue2,
+ textHeadingColor: $white,
+ textInfoColor: $darkDarkBlue2,
+ textMuted: $darkGrey1,
+ textSuccessColor: $darkDarkBlue2,
+ textWarningColor: $darkDarkBlue2,
+ ),
+);
+
+@mixin themify($themes: $themes) {
+ @each $theme, $map in $themes {
+ html.theme_#{$theme} & {
+ $theme-map: () !global;
+ @each $key, $submap in $map {
+ $value: map-get(map-get($themes, $theme), "#{$key}");
+ $theme-map: map-merge(
+ $theme-map,
+ (
+ $key: $value,
+ )
+ ) !global;
+ }
+ @content;
+ $theme-map: null !global;
+ }
+ }
+}
+
+@function themed($key) {
+ @return map-get($theme-map, $key);
+} ;
diff --git a/components/tailwind.config.base.js b/components/tailwind.config.base.js
index 8f515f3cd5b..8b1afb165fd 100644
--- a/components/tailwind.config.base.js
+++ b/components/tailwind.config.base.js
@@ -37,7 +37,11 @@ module.exports = {
500: "var(--color-info-500)",
700: "var(--color-info-700)",
},
- "text-muted": "var(--color-text-muted)",
+ text: {
+ main: "var(--color-text-main)",
+ muted: "var(--color-text-muted)",
+ contrast: "var(--color-text-contrast)",
+ },
background: {
DEFAULT: "var(--color-background)",
alt: "var(--color-background-alt)",
diff --git a/components/tailwind.config.js b/components/tailwind.config.js
index c458a0abb19..5f7eb29829e 100644
--- a/components/tailwind.config.js
+++ b/components/tailwind.config.js
@@ -1,6 +1,11 @@
/* eslint-disable */
const config = require("./tailwind.config.base");
-config.content = ["./src/**/*.{html,ts}", "./.storybook/preview.js"];
+config.content = ["./src/**/*.{html,ts,mdx}", "./.storybook/preview.js"];
+config.safelist = [
+ {
+ pattern: /tw-bg-(.*)/,
+ },
+];
module.exports = config;