-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for non-responsive values to Grid
's gap
, columns
, and areas
props.
#10489
Conversation
1826a06
to
467b197
Compare
467b197
to
c12a794
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to tell what changes to some of our utilities are necessary here and I'm afraid the scss changes only confuse things more, and also make it harder to migrate away from scss or to a post css processor.
Can you outline why these changes were made and why you couldn't fix the bug(s) by using existing utilities? I'm talking specifically about the changes in _responsive-props.scss
, css.ts
): ResponsiveProp<Output> | undefined { | ||
if (isObject(responsiveProp)) { | ||
return Object.fromEntries( | ||
(Object.entries(responsiveProp) as Entries<typeof responsiveProp>).map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're only using Entries from type-fest in this one spot, and we know the shape, and we're casting, I think we can do away with the type-fest import and type this manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't want to maintain the Entries
type - it's complicated enough that I barely understand it, but I do know it does exactly what I needed, and I landed on this solution after attempting to manually type it first (though admittedly I quickly rage quit because I'd had enough of TypeScript's cryptic errors and nonesense inability to understand basic things like JS's Object.entries
).
Just noticed you want to merge this into the next branch. Shouldn't bug fixes / minor changes go into main? We'll also want to |
9cc8232
to
48ca178
Compare
We need to ship this or a simplified version |
Yeah, but in this case I wanted to align with the changes in |
c12a794
to
61b91dc
Compare
Fair enough, there's a lot going on in this PR. The commits were split up to try make it clear which changes are related to altering the utilities and for what purpose. But to expand on each of them:
Interesting! I find the new format of the SCSS file to be much easier to read and understand with much reduced duplication and chance for human error to sneak in. It also standardizes it with all our other components, so ideally once you've groked one, you've groked them all.
I'd argue the abstraction makes it easier; Instead of having to manually migrate each instance where we have multiple breakpoints with |
61b91dc
to
0a272e4
Compare
I'll definitely need help with this one - I often struggle to get spin to do what I need / find those places of usage actually in the Admin. |
8f509a6
to
452ee6c
Compare
452ee6c
to
b6c8d1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is really close. My main concern now is that when passing in a non-responsive value it doesn't override the responsive defaults which will lead to confusion.
Secondary concern is that adding to the mixin complexity will add tech debt when trying to remove sass. Do you have a plan for that? I think we might be removing sass sooner rather than later and not sure post css conversion will work 1:1. This is not a blocker
'grid', | ||
'columns', | ||
'--pc-grid-template-columns', | ||
$default: ('xs': 6, 'lg': 12) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we override these defaults when only a single value gets passed in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, good catch - I missed that case. I'll patch that up this morning 👍
add tech debt when trying to remove sass.
Depends on what we're aiming for;
- If we're going to PostCSS, then most of the functionality can be moved into
postcss-mixins
by the looks of it. - If we're going to CSS-in-JS, then the functionality can be converted to JS fairly easily.
- If we're going to pure CSS without PostCSS plugins or CSS-in-JS then we could either fallback to creating and injecting stylesheets, or reassess the overall strategy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was able to fix the defaults issue with @gwyneplaine's help 🎉
I amended an earlier commit, so I've put the diff below for you to review.
tl;dr: Reverted back to using initial
for scoping the CSS custom properties, then moved the default into the media queries (where they should have been all along). The new find-default-with-fallback()
function matches the semantics of the consumer-facing responsive props API. ie; things like $default: ('sm': 4, 'lg': 8)
are effectively the same as: $default: ('xs': null, 'sm': 4, 'md': 4, 'lg': 8, 'xl': 8)
.
diff --git a/polaris-react/src/styles/shared/_responsive-props.scss b/polaris-react/src/styles/shared/_responsive-props.scss
index 319a70f2a..1ae4fc569 100644
--- a/polaris-react/src/styles/shared/_responsive-props.scss
+++ b/polaris-react/src/styles/shared/_responsive-props.scss
@@ -6,11 +6,37 @@
@return type-of($var) == 'null';
}
+// NOTE: Order is important here; will search backwards through this list to
+// find fallback values
+$breakpointKeys: ('xs', 'sm', 'md', 'lg', 'xl');
+
+@function find-default-with-fallback($default, $breakpoint) {
+ $initialIndex: index($breakpointKeys, $breakpoint);
+
+ // If the given '$breakpoint' doesn't exist, just return null
+ @if is-null($initialIndex) {
+ @return null;
+ }
+
+ // Search backwards until a non-null value is found in the $defaults map
+ // NOTE: Arrays in SASS are 1-based, so we're iterating down to AND INCLUDING
+ // index "1" (the first element).
+ @for $index from $initialIndex through 1 {
+ $value: map-get($default, nth($breakpointKeys, $index));
+ @if not is-null($value) {
+ @return $value;
+ }
+ }
+
+ // Couldn't find a non-null default, so return null
+ @return null;
+}
+
@function get-default($default: null, $key: null) {
$value: null;
@if is-map($default) {
@if not is-null($key) {
- $value: map-get($default, $key);
+ $value: find-default-with-fallback($default, $key);
}
} @else {
$value: $default;
@@ -21,18 +47,17 @@
@mixin scope-custom-property(
$componentName,
$componentProp,
- $responsively: false,
- $default: null
+ $responsively: false
) {
@if $responsively {
// stylelint-disable -- Polaris component custom properties
- --pc-#{$componentName}-#{$componentProp}-xs: #{get-default($default, 'xs')};
- --pc-#{$componentName}-#{$componentProp}-sm: #{get-default($default, 'sm')};
- --pc-#{$componentName}-#{$componentProp}-md: #{get-default($default, 'md')};
- --pc-#{$componentName}-#{$componentProp}-lg: #{get-default($default, 'lg')};
- --pc-#{$componentName}-#{$componentProp}-xl: #{get-default($default, 'xl')};
+ --pc-#{$componentName}-#{$componentProp}-xs: initial;
+ --pc-#{$componentName}-#{$componentProp}-sm: initial;
+ --pc-#{$componentName}-#{$componentProp}-md: initial;
+ --pc-#{$componentName}-#{$componentProp}-lg: initial;
+ --pc-#{$componentName}-#{$componentProp}-xl: initial;
} @else {
- --pc-#{$componentName}-#{$componentProp}: #{get-default($default)};
+ --pc-#{$componentName}-#{$componentProp}: initial;
}
}
@@ -42,14 +67,12 @@
$declarationProp,
$default: null
) {
- @include scope-custom-property(
- $componentName,
- $componentProp,
- false,
- $default
- );
+ @include scope-custom-property($componentName, $componentProp, false);
- #{$declarationProp}: var(--pc-#{$componentName}-#{$componentProp});
+ #{$declarationProp}: var(
+ --pc-#{$componentName}-#{$componentProp},
+ #{get-default($default)}
+ );
}
@mixin responsive-props(
@@ -58,19 +81,20 @@
$declarationProp,
$default: null
) {
- @include scope-custom-property(
- $componentName,
- $componentProp,
- true,
- $default
- );
+ @include scope-custom-property($componentName, $componentProp, true);
- #{$declarationProp}: var(--pc-#{$componentName}-#{$componentProp}-xs);
+ #{$declarationProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ #{get-default($default, 'xs')}
+ );
@media #{$p-breakpoints-sm-up} {
#{$declarationProp}: var(
--pc-#{$componentName}-#{$componentProp}-sm,
- var(--pc-#{$componentName}-#{$componentProp}-xs)
+ var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ #{get-default($default, 'sm')}
+ )
);
}
@@ -79,7 +103,10 @@
--pc-#{$componentName}-#{$componentProp}-md,
var(
--pc-#{$componentName}-#{$componentProp}-sm,
- var(--pc-#{$componentName}-#{$componentProp}-xs)
+ var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ #{get-default($default, 'md')}
+ )
)
);
}
@@ -91,7 +118,10 @@
--pc-#{$componentName}-#{$componentProp}-md,
var(
--pc-#{$componentName}-#{$componentProp}-sm,
- var(--pc-#{$componentName}-#{$componentProp}-xs)
+ var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ #{get-default($default, 'lg')}
+ )
)
)
);
@@ -106,7 +136,10 @@
--pc-#{$componentName}-#{$componentProp}-md,
var(
--pc-#{$componentName}-#{$componentProp}-sm,
- var(--pc-#{$componentName}-#{$componentProp}-xs)
+ var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ #{get-default($default, 'xl')}
+ )
)
)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kyledurand here's a local reproduction url with the above cases in playroom.
b6c8d1b
to
9ede084
Compare
/snapit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(unofficially) lgtm ✅
9ede084
to
aa81906
Compare
/snapit |
Thanks for the breakdown @jesstelford I'm pretty good with the changes, but we need to snap this and make sure it at least passes web ci before merging. Just trying to sort that out now |
Looks like the snapshots are failing to publish, but I'm not sure why... Is it because the base is |
aa81906
to
89610fb
Compare
@laurkim noticed an issue with
I've tracked it down to the difference between When a The new behaviour in this PR enforces consistency in CSS custom properties, and set the default to Here's the diff of changes made to ensure some declarations are inherited. An alternative implementation might be to mirror the existing behaviour of not passing the custom property through to the If we went down this path, we'd need to move the "default" values up into the JS, then pass those down to the media queries via |
d690c14
to
8eac426
Compare
🤔 I can't figure out what's causing these "19 changes" in Chromatic... The screenshots seem to indicate that vertical padding is different, but when I load up the snapshots (base vs this PR), there's no difference, and I can't replicate it locally. I'm wondering if it's a timing issue of some kind with client side rendering 🤔 🤷 |
8eac426
to
c1edb9f
Compare
Hi! We noticed there hasn’t been activity on this PR in a while. After 30 days, it will close automatically. If it’s still relevant, or you have updates, comment and let us know. And don’t worry, you can always re-open later if needed. |
c1edb9f
to
f548035
Compare
Localization quality issues found The following issues may affect the quality of localized translations if they are not addressed:
Please look out for other instances of this issue in your PR and fix them as well if possible. Questions about these messages? Hop in the #help-localization Slack channel. |
Builds on functionality introduced in #10404.
In service of bringing
Grid
's responsive props in line with the rest of the system, I also standardized some other parts of the system along the way.I purposely kept these as individual commits for easier reviewing and also so they retain their history, meaning we should do fast-forward merge instead of a merge commit ("Rebase and merge" in GitHub's UI) so the commits don't get squashed.
See the
commits
tab for the changes.