Shopify/polaris-tokens

Share "breakpoints" values

beefchimi opened this issue · 2 comments

I've noticed values getting hard copied between JS and CSS. For instance, in polaris-react, we have the SCSS layout value:

page-with-nav: (
  base: rem(769px),
),

and then a breakpoints.ts utility:

const Breakpoints = {
  navigationBarCollapsed: '768px',
  stackedContent: '1043px',
};

I think there is potential to consolidate some of this and reduce the chance of drift.

I unpacked what's happening when using this Sass map, there's a lot happening and I wonder if we could get this simplified:

// map converting all layout widths in rem
$layout-width-data: {
  page-with-nav: (
    base: rem(769px),
  ),
};

// breakpoint-before() called with layout-width(), which fetches rem(769px)
@include breakpoint-before(layout-width(page-with-nav), false) {}

// rem(769px) = 76.9rem is passed to breakpoint-before()
@mixin breakpoint-before($breakpoint, $inclusive: true) {
  // rem(769px) value is passed to breakpoint()
  @media (max-width: #{breakpoint($breakpoint, if($inclusive, 0, -1px))}) {
    @content;
  }
}

// breakpoint() passes 76.9rem to em() with adjustment of -1px
@function breakpoint($value, $adjustment: 0) {
  $adjusted-value: em($adjustment);

  // Reduces chances to have a style void
  // between two media queries
  // See https://github.com/sass-mq/sass-mq/issues/6
  @if ($adjustment == -1px) {
    $adjusted-value: -0.01em;
  } @else if ($adjustment == 1px) {
    $adjusted-value: 0.01em;
  }

  @return em($value) + $adjusted-value;
}

// em() transforms 76.9rem into 48.0625em - 0.01em = 48.0525em
@function em($value) {
  $unit: unit($value);

  @if $value == 0 {
    @return 0;
  } @else if $unit == 'em' {
    @return $value;
  } @else if $unit == 'rem' {
    @return $value / 1rem * 1em * ($base-font-size / $default-browser-font-size);
  } @else if $unit == 'px' {
    @return $value / $default-browser-font-size * 1em;
  } @else {
    @error 'Value must be in px, rem, or em.';
  }
}

// Output _should_ be:
@media (max-width: 48.0525em) {}

Separate issue: in JavaScript, breakpoints aren't converted to em, this can cause bugs when text zoom user preferences are changed (accessibility smell). cc @alex-page @dpersing where should we log this a11y issue? I have a feeling this may also an issue in web, as those breakpoints came from there.

I have a feeling this may also an issue in web, as those breakpoints came from there.

@kaelig If the breakpoints in polaris-react are duplicating ones in web, we should probably log issues in both places.