diff --git a/src/components/Alert/__tests__/Alert.test.jsx b/src/components/Alert/__tests__/Alert.test.jsx
index a846d99a..591cca14 100644
--- a/src/components/Alert/__tests__/Alert.test.jsx
+++ b/src/components/Alert/__tests__/Alert.test.jsx
@@ -5,7 +5,8 @@ import {
within,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { colorPropTest } from '../../../../tests/propTests/colorPropTest';
+import { feedbackColorPropTest } from '../../../../tests/propTests/feedbackColorPropTest';
+import { neutralColorPropTest } from '../../../../tests/propTests/neutralColorPropTest';
import defaultTranslations from '../../../translations/en';
import { Alert } from '../Alert';
@@ -20,7 +21,8 @@ describe('rendering', () => {
{ children:
content text
},
(rootElement) => expect(within(rootElement).getByText('content text')),
],
- ...colorPropTest,
+ ...feedbackColorPropTest,
+ ...neutralColorPropTest,
[
{ icon: (icon
) },
(rootElement) => expect(within(rootElement).getByText('icon')),
diff --git a/src/components/Badge/Badge.jsx b/src/components/Badge/Badge.jsx
index ef841489..653938ff 100644
--- a/src/components/Badge/Badge.jsx
+++ b/src/components/Badge/Badge.jsx
@@ -32,7 +32,8 @@ Badge.defaultProps = {
Badge.propTypes = {
/**
- * [Color variant](/docs/foundation/colors#component-colors) to clarify importance and meaning of the badge.
+ * Color to clarify importance and meaning of the badge. Implements
+ * [Feedback and Neutral color collections](/docs/foundation/collections#colors).
*/
color: PropTypes.oneOf(['success', 'warning', 'danger', 'help', 'info', 'note', 'light', 'dark']),
/**
diff --git a/src/components/Badge/Badge.module.scss b/src/components/Badge/Badge.module.scss
index 1949d937..7e57d903 100644
--- a/src/components/Badge/Badge.module.scss
+++ b/src/components/Badge/Badge.module.scss
@@ -2,14 +2,14 @@
@use "sass:math";
@use "../../styles/theme/borders";
@use "../../styles/theme/typography";
-
-$_badge-size: 1.25rem;
+@use "../../styles/tools/collections";
+@use "settings";
@layer components.badge {
.root {
display: inline-block;
- min-width: $_badge-size;
- height: $_badge-size;
+ min-width: settings.$badge-size;
+ height: settings.$badge-size;
padding: 0.25rem 0.35rem;
overflow: hidden;
font-weight: map.get(typography.$font-weight-values, bold);
@@ -19,7 +19,7 @@ $_badge-size: 1.25rem;
white-space: nowrap;
vertical-align: baseline;
color: var(--rui-local-color);
- border-radius: math.div($_badge-size, 2);
+ border-radius: math.div(settings.$badge-size, 2);
}
.isRootPriorityFilled {
@@ -27,45 +27,20 @@ $_badge-size: 1.25rem;
box-shadow: var(--rui-local-box-shadow, #{0 0 0 2px rgb(255 255 255 / 80%)});
}
- .isRootColorSuccess {
- --rui-local-color: var(--rui-color-feedback-on-success);
- --rui-local-background-color: var(--rui-color-feedback-success);
- }
-
- .isRootColorWarning {
- --rui-local-color: var(--rui-color-feedback-on-warning);
- --rui-local-background-color: var(--rui-color-feedback-warning);
- }
-
- .isRootColorDanger {
- --rui-local-color: var(--rui-color-feedback-on-danger);
- --rui-local-background-color: var(--rui-color-feedback-danger);
- }
-
- .isRootColorHelp {
- --rui-local-color: var(--rui-color-feedback-on-help);
- --rui-local-background-color: var(--rui-color-feedback-help);
- }
-
- .isRootColorInfo {
- --rui-local-color: var(--rui-color-feedback-on-info);
- --rui-local-background-color: var(--rui-color-feedback-info);
- }
-
- .isRootColorNote {
- --rui-local-color: var(--rui-color-feedback-on-note);
- --rui-local-background-color: var(--rui-color-feedback-note);
- }
-
- .isRootColorLight {
- --rui-local-color: var(--rui-color-neutral-on-light);
- --rui-local-background-color: var(--rui-color-neutral-light);
- --rui-local-box-shadow: none;
+ @each $color in settings.$colors {
+ @include collections.generate-properties(
+ $prefix: "rui-",
+ $component-name: "Badge",
+ $modifier-name: "priority",
+ $modifier-value: "filled",
+ $variant-name: "color",
+ $variant-value: $color,
+ $properties: settings.$themeable-properties-filled,
+ );
}
+ .isRootColorLight,
.isRootColorDark {
- --rui-local-color: var(--rui-color-neutral-on-dark);
- --rui-local-background-color: var(--rui-color-neutral-dark);
--rui-local-box-shadow: none;
}
@@ -75,35 +50,15 @@ $_badge-size: 1.25rem;
border: borders.$width solid currentcolor;
}
- .isRootPriorityOutline.isRootColorSuccess {
- --rui-local-color: var(--rui-color-feedback-success);
- }
-
- .isRootPriorityOutline.isRootColorWarning {
- --rui-local-color: var(--rui-color-feedback-warning);
- }
-
- .isRootPriorityOutline.isRootColorDanger {
- --rui-local-color: var(--rui-color-feedback-danger);
- }
-
- .isRootPriorityOutline.isRootColorHelp {
- --rui-local-color: var(--rui-color-feedback-help);
- }
-
- .isRootPriorityOutline.isRootColorInfo {
- --rui-local-color: var(--rui-color-feedback-info);
- }
-
- .isRootPriorityOutline.isRootColorNote {
- --rui-local-color: var(--rui-color-feedback-note);
- }
-
- .isRootPriorityOutline.isRootColorLight {
- --rui-local-color: var(--rui-color-neutral-light);
- }
-
- .isRootPriorityOutline.isRootColorDark {
- --rui-local-color: var(--rui-color-neutral-dark);
+ @each $color in settings.$colors {
+ @include collections.generate-properties(
+ $prefix: "rui-",
+ $component-name: "Badge",
+ $modifier-name: "priority",
+ $modifier-value: "outline",
+ $variant-name: "color",
+ $variant-value: $color,
+ $properties: settings.$themeable-properties-outline,
+ );
}
}
diff --git a/src/components/Badge/README.md b/src/components/Badge/README.md
index 84f343d2..ceec6fed 100644
--- a/src/components/Badge/README.md
+++ b/src/components/Badge/README.md
@@ -29,8 +29,9 @@ lowest:
1. filled
2. outline
-All priorities come in supported
-[component colors](/docs/foundation/colors#component-colors).
+All priorities are available in colors from supported
+[color collections](/docs/foundation/collections#colors).
+Check [API](#api) to see which collections are supported.
### Filled
@@ -102,5 +103,21 @@ helps to improve its accessibility.
+## Theming
+
+It's possible to adjust the theme of specific badge color variant. Naming
+convention looks as follows:
+
+`--rui-Badge----__`
+
+Where:
+
+- `` is one of `filled` or `outline`,
+- `` is a value from supported
+ [color collections](/docs/foundation/collections#colors)
+ (check [API](#api) to see which collections are supported),
+- `` is one of `color` (color of text) or `background-color` for the
+ filled priority, or just `color` for the outline priority.
+
[div-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
[React common props]: https://react.dev/reference/react-dom/components/common#common-props
diff --git a/src/components/Badge/__tests__/Badge.test.jsx b/src/components/Badge/__tests__/Badge.test.jsx
index 6e40cec2..37531b99 100644
--- a/src/components/Badge/__tests__/Badge.test.jsx
+++ b/src/components/Badge/__tests__/Badge.test.jsx
@@ -3,7 +3,8 @@ import {
render,
within,
} from '@testing-library/react';
-import { colorPropTest } from '../../../../tests/propTests/colorPropTest';
+import { feedbackColorPropTest } from '../../../../tests/propTests/feedbackColorPropTest';
+import { neutralColorPropTest } from '../../../../tests/propTests/neutralColorPropTest';
import { Badge } from '../Badge';
const mandatoryProps = {
@@ -12,7 +13,8 @@ const mandatoryProps = {
describe('rendering', () => {
it.each([
- ...colorPropTest,
+ ...feedbackColorPropTest,
+ ...neutralColorPropTest,
[
{ label: 'label text' },
(rootElement) => expect(within(rootElement).getByText('label text')),
diff --git a/src/components/Badge/_settings.scss b/src/components/Badge/_settings.scss
new file mode 100644
index 00000000..294181de
--- /dev/null
+++ b/src/components/Badge/_settings.scss
@@ -0,0 +1,8 @@
+@use "sass:list";
+@use "../../styles/settings/collections";
+
+$badge-size: 1.25rem;
+
+$colors: list.join(collections.$feedback-colors, collections.$neutral-colors);
+$themeable-properties-filled: color, background-color;
+$themeable-properties-outline: color;
diff --git a/src/components/Button/__tests__/Button.test.jsx b/src/components/Button/__tests__/Button.test.jsx
index 17a17491..0a5ee0a0 100644
--- a/src/components/Button/__tests__/Button.test.jsx
+++ b/src/components/Button/__tests__/Button.test.jsx
@@ -7,7 +7,8 @@ import {
import userEvent from '@testing-library/user-event';
import { actionColorPropTest } from '../../../../tests/propTests/actionColorPropTest';
import { blockPropTest } from '../../../../tests/propTests/blockPropTest';
-import { colorPropTest } from '../../../../tests/propTests/colorPropTest';
+import { feedbackColorPropTest } from '../../../../tests/propTests/feedbackColorPropTest';
+import { neutralColorPropTest } from '../../../../tests/propTests/neutralColorPropTest';
import { refPropTest } from '../../../../tests/propTests/refPropTest';
import { labelPropTest } from '../../../../tests/propTests/labelPropTest';
import { sizePropTest } from '../../../../tests/propTests/sizePropTest';
@@ -67,7 +68,8 @@ describe('rendering', () => {
],
...actionColorPropTest,
...blockPropTest,
- ...colorPropTest,
+ ...feedbackColorPropTest,
+ ...neutralColorPropTest,
[
{ disabled: true },
(rootElement) => expect(rootElement).toBeDisabled(),
diff --git a/src/components/Card/__tests__/Card.test.jsx b/src/components/Card/__tests__/Card.test.jsx
index bee505ef..3b902993 100644
--- a/src/components/Card/__tests__/Card.test.jsx
+++ b/src/components/Card/__tests__/Card.test.jsx
@@ -3,7 +3,8 @@ import {
render,
within,
} from '@testing-library/react';
-import { colorPropTest } from '../../../../tests/propTests/colorPropTest';
+import { feedbackColorPropTest } from '../../../../tests/propTests/feedbackColorPropTest';
+import { neutralColorPropTest } from '../../../../tests/propTests/neutralColorPropTest';
import { raisedPropTest } from '../../../../tests/propTests/raisedPropTest';
import { ScrollView } from '../../ScrollView';
import { Card } from '../Card';
@@ -33,7 +34,8 @@ describe('rendering', () => {
{ children: scroll view content },
(rootElement) => expect(within(rootElement).getByText('scroll view content')),
],
- ...colorPropTest,
+ ...feedbackColorPropTest,
+ ...neutralColorPropTest,
...densePropTest('Root'),
[
{ disabled: true },
diff --git a/src/styles/tools/_collections.scss b/src/styles/tools/_collections.scss
new file mode 100644
index 00000000..2d557398
--- /dev/null
+++ b/src/styles/tools/_collections.scss
@@ -0,0 +1,36 @@
+@use "string" as rui-string;
+
+@mixin generate-properties(
+ $prefix,
+ $component-name,
+ $modifier-name: null,
+ $modifier-value: null,
+ $variant-name,
+ $variant-value,
+ $properties,
+) {
+ $combined-class-name:
+ if(
+ $modifier-name and $modifier-value,
+ ".isRoot#{rui-string.capitalize($modifier-name)}#{rui-string.capitalize($modifier-value)}",
+ ""
+ );
+
+ #{$combined-class-name}.isRoot#{rui-string.capitalize($variant-name)}#{rui-string.capitalize($variant-value)} {
+ @each $property in $properties {
+ --#{$prefix}local-#{$property}:
+ var(
+ #{
+ "--"
+ + $prefix
+ + $component-name
+ + if($modifier-value, "--" + $modifier-value, "")
+ + "--"
+ + $variant-value
+ + "__"
+ + $property
+ }
+ );
+ }
+ }
+}
diff --git a/src/styles/tools/_string.scss b/src/styles/tools/_string.scss
index f0dde40c..b8dc32b9 100644
--- a/src/styles/tools/_string.scss
+++ b/src/styles/tools/_string.scss
@@ -1,7 +1,10 @@
-// Author: Hugo Giraudel
-
@use "sass:string";
+@function capitalize($string) {
+ @return string.to-upper-case(string.slice($string, 1, 1)) + string.slice($string, 2);
+}
+
+// Author: Hugo Giraudel
@function replace($string, $search, $replace: "") {
$index: string.index($string, $search);
diff --git a/src/theme.scss b/src/theme.scss
index ae0ebb51..d7537a63 100644
--- a/src/theme.scss
+++ b/src/theme.scss
@@ -306,6 +306,70 @@
--rui-Alert--dark__foreground-color: var(--rui-color-neutral-on-dark);
--rui-Alert--dark__background-color: var(--rui-color-background-dark);
+ //
+ // Badge
+ // =====
+
+ // Badge: filled priority
+
+ // Badge: filled priority: success variant
+ --rui-Badge--filled--success__color: var(--rui-color-feedback-on-success);
+ --rui-Badge--filled--success__background-color: var(--rui-color-feedback-success);
+
+ // Badge: filled priority: warning variant
+ --rui-Badge--filled--warning__color: var(--rui-color-feedback-on-warning);
+ --rui-Badge--filled--warning__background-color: var(--rui-color-feedback-warning);
+
+ // Badge: filled priority: danger variant
+ --rui-Badge--filled--danger__color: var(--rui-color-feedback-on-danger);
+ --rui-Badge--filled--danger__background-color: var(--rui-color-feedback-danger);
+
+ // Badge: filled priority: help variant
+ --rui-Badge--filled--help__color: var(--rui-color-feedback-on-help);
+ --rui-Badge--filled--help__background-color: var(--rui-color-feedback-help);
+
+ // Badge: filled priority: info variant
+ --rui-Badge--filled--info__color: var(--rui-color-feedback-on-info);
+ --rui-Badge--filled--info__background-color: var(--rui-color-feedback-info);
+
+ // Badge: filled priority: note variant
+ --rui-Badge--filled--note__color: var(--rui-color-feedback-on-note);
+ --rui-Badge--filled--note__background-color: var(--rui-color-feedback-note);
+
+ // Badge: filled priority: light variant
+ --rui-Badge--filled--light__color: var(--rui-color-neutral-on-light);
+ --rui-Badge--filled--light__background-color: var(--rui-color-neutral-light);
+
+ // Badge: filled priority: dark variant
+ --rui-Badge--filled--dark__color: var(--rui-color-neutral-on-dark);
+ --rui-Badge--filled--dark__background-color: var(--rui-color-neutral-dark);
+
+ // Badge: outline priority
+
+ // Badge: outline priority: success variant
+ --rui-Badge--outline--success__color: var(--rui-color-feedback-success);
+
+ // Badge: outline priority: warning variant
+ --rui-Badge--outline--warning__color: var(--rui-color-feedback-warning);
+
+ // Badge: outline priority: danger variant
+ --rui-Badge--outline--danger__color: var(--rui-color-feedback-danger);
+
+ // Badge: outline priority: help variant
+ --rui-Badge--outline--help__color: var(--rui-color-feedback-help);
+
+ // Badge: outline priority: info variant
+ --rui-Badge--outline--info__color: var(--rui-color-feedback-info);
+
+ // Badge: outline priority: note variant
+ --rui-Badge--outline--note__color: var(--rui-color-feedback-note);
+
+ // Badge: outline priority: light variant
+ --rui-Badge--outline--light__color: var(--rui-color-neutral-light);
+
+ // Badge: outline priority: dark variant
+ --rui-Badge--outline--dark__color: var(--rui-color-neutral-dark);
+
//
// Button
// ======
diff --git a/tests/propTests/colorPropTest.js b/tests/propTests/feedbackColorPropTest.js
similarity index 72%
rename from tests/propTests/colorPropTest.js
rename to tests/propTests/feedbackColorPropTest.js
index 0c47eec4..ff8662ee 100644
--- a/tests/propTests/colorPropTest.js
+++ b/tests/propTests/feedbackColorPropTest.js
@@ -1,8 +1,4 @@
-export const colorPropTest = [
- [
- { color: 'dark' },
- (rootElement) => expect(rootElement).toHaveClass('isRootColorDark'),
- ],
+export const feedbackColorPropTest = [
[
{ color: 'danger' },
(rootElement) => expect(rootElement).toHaveClass('isRootColorDanger'),
@@ -15,10 +11,6 @@ export const colorPropTest = [
{ color: 'info' },
(rootElement) => expect(rootElement).toHaveClass('isRootColorInfo'),
],
- [
- { color: 'light' },
- (rootElement) => expect(rootElement).toHaveClass('isRootColorLight'),
- ],
[
{ color: 'note' },
(rootElement) => expect(rootElement).toHaveClass('isRootColorNote'),
diff --git a/tests/propTests/neutralColorPropTest.js b/tests/propTests/neutralColorPropTest.js
new file mode 100644
index 00000000..3d5d294f
--- /dev/null
+++ b/tests/propTests/neutralColorPropTest.js
@@ -0,0 +1,10 @@
+export const neutralColorPropTest = [
+ [
+ { color: 'dark' },
+ (rootElement) => expect(rootElement).toHaveClass('isRootColorDark'),
+ ],
+ [
+ { color: 'light' },
+ (rootElement) => expect(rootElement).toHaveClass('isRootColorLight'),
+ ],
+];