Skip to content

Commit

Permalink
Introduce theming of Badge color variants
Browse files Browse the repository at this point in the history
`Badge` color variants are now generated using color collections.

Other components to be styled the same way already support theming,
so `Badge` needs to support theming too.

New theming options:

`--rui-Badge--<PRIORITY>--<COLOR>__<PROPERTY>`

See `theme.scss` for all available options.
  • Loading branch information
adamkudrna committed Aug 31, 2024
1 parent 0fc7be0 commit c272c09
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 76 deletions.
3 changes: 2 additions & 1 deletion src/components/Badge/Badge.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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']),
/**
Expand Down
97 changes: 26 additions & 71 deletions src/components/Badge/Badge.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -19,50 +19,25 @@ $_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);
background-color: var(--rui-local-background-color);
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;
}

Expand All @@ -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,
);
}
}
21 changes: 19 additions & 2 deletions src/components/Badge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -102,5 +103,21 @@ helps to improve its accessibility.

<docoff-react-props src="/components/Badge/Badge.jsx" />

## Theming

It's possible to adjust the theme of specific badge color variant. Naming
convention looks as follows:

`--rui-Badge--<PRIORITY>--<COLOR>__<PROPERTY>`

Where:

- `<PRIORITY>` is one of `filled` or `outline`,
- `<COLOR>` is a value from supported
[color collections](/docs/foundation/collections#colors)
(check [API](#api) to see which collections are supported),
- `<PROPERTY>` 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
8 changes: 8 additions & 0 deletions src/components/Badge/_settings.scss
Original file line number Diff line number Diff line change
@@ -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;
36 changes: 36 additions & 0 deletions src/styles/tools/_collections.scss
Original file line number Diff line number Diff line change
@@ -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
}
);
}
}
}
7 changes: 5 additions & 2 deletions src/styles/tools/_string.scss
Original file line number Diff line number Diff line change
@@ -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);

Expand Down
64 changes: 64 additions & 0 deletions src/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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
// ======
Expand Down

0 comments on commit c272c09

Please sign in to comment.