Skip to content

Commit

Permalink
feat(theme): allow lists in replace maps
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 353273244
  • Loading branch information
asyncLiz authored and copybara-github committed Jan 22, 2021
1 parent 07deaec commit d2959b1
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 10 deletions.
41 changes: 41 additions & 0 deletions packages/mdc-theme/_replace.scss
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,44 @@

@return $string;
}

/// Replaces all value instances in the provided list with values from the
/// provided replacement Map whose keys correspond to the name instances.
/// Returns a new list with the replacements applied.
///
/// @example
/// replace-list(0 value, (value: 16px)); // (0 16px)
///
/// @see {mixin} replace-string
///
/// @access private
/// @param {List} $list - The list to make replacements on.
/// @param {Map} $replace-map - A Map of name/value replacements. The keys of
/// the Map are names that will be replaced in the list with the keys'
/// respective values.
/// @param {Bool} $fallback - If true, use the fallback value of any custom
/// property value replacements instead of the `var()` declaration.
/// @return {List} A new list with replacements made, if any.
@function replace-list($list, $replace-map, $fallback: false) {
$separator: list.separator($list);
$replaced-list: ();
@each $value in $list {
@if meta.type-of($value) == 'string' {
$replaced-list: list.append(
$replaced-list,
replace-string($value, $replace-map, $fallback),
$separator
);
} @else if meta.type-of($value) == 'list' {
$replaced-list: list.append(
$replaced-list,
replace-list($value, $replace-map, $fallback),
$separator
);
} @else {
$replaced-list: list.append($replaced-list, $value, $separator);
}
}

@return $replaced-list;
}
31 changes: 21 additions & 10 deletions packages/mdc-theme/_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,29 @@
// $value is a standard CSS value
$fallback: null;
@if $replace {
@if meta.type-of($value) != 'string' {
// theme.property() should support non-string replacements in the
// future, such as List types
// e.g. theme.property(border-radius, 8px foo, $replace: (foo: $foo));
@error 'mdc-theme: Invalid replacement value #{$value}. $replace may only be used with string values.';
@if meta.type-of($replace) != 'map' {
@error 'mdc-theme: Invalid replacement #{$replace}. Must be a Map.';
}

$fallback: replace.replace-string($value, $replace, $fallback: true);
$value: replace.replace-string($value, $replace);
@if $fallback == $value {
// The replacements don't contain custom properties with fallbacks
$fallback: null;
$needs-fallback: false;
@each $name, $value in $replace {
@if custom-properties.is-custom-prop($value) {
$needs-fallback: true;
}
}

@if meta.type-of($value) == 'string' {
@if $needs-fallback {
$fallback: replace.replace-string($value, $replace, $fallback: true);
}
$value: replace.replace-string($value, $replace);
} @else if meta.type-of($value) == 'list' {
@if $needs-fallback {
$fallback: replace.replace-list($value, $replace, $fallback: true);
}
$value: replace.replace-list($value, $replace);
} @else {
@error 'mdc-theme: Invalid replacement value #{$value}. $replace may only be used with string or list values.';
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/mdc-theme/test/replace.test.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@
.multiple {
@include theme.property(width, calc(x + x + x), $replace: (x: 8px));
}

.list {
@include theme.property(padding, 0 value, $replace: (value: 16px));
}
4 changes: 4 additions & 0 deletions packages/mdc-theme/test/theme.scss.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ describe('theme.test.scss', () => {
.multiple {
width: calc(8px + 8px + 8px);
}
.list {
padding: 0 16px;
}`);
});

Expand Down

0 comments on commit d2959b1

Please sign in to comment.