Search code examples
sassdart-sass

How to @forward some rules using both a `with` and a `show` clause?


The SCSS @forward rule supports a couple nice features:

  1. @forward './colors' show $red, $green, $blue; will only forward $red, $green, and $blue from ./colors. All other values that ./colors would otherwise export are ignored.
  2. @forward 'library' with ($space: 2em); will make $space available to the library, overriding any default that library may have for $space.

How can I use these both together? In my case I'm using the include-media library. I want to define a module that wraps it like this (slightly simplified):

@forward 'include-media with (
  $breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 )
) show media, media-context;

The goal here is to both provide the library the $breakpoints value it's expecting, and forward only the media and media-context mixins. Unfortunately that code fails to compile with this error:

Error: expected ";".
  ╷
3 │ ) show media, media-context;
  │   ^

I get similar results if I put the show clause before the with clause.

It seems sub-optimal, but I could imagine this working with two files:

// file _withBreakpoints.scss
@forward 'include-media' with (
  $breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 )
);
// file _filtered.scss
@forward './withBreakpoints' show media, media-context;

Surely there's a better way?


Solution

  • I checked that and cannot confirm the issue. (Tested with Compiler: VS Code extension Live SASS by(!) Glenn Marks).

    But important: hide/show must be called BEFORE with.

    Following syntax works here (just examples):

    //### forward with hide
    
    @forward 'variables' hide $color_red with(
        $color_orange: yellow,
        $color_gray: magenta,
    ); 
    
    
    
    //### forward with show
    
    @forward 'variables' show $color_red with(
        $color_red: orange,
    ); 
    

    But there seems to be some other issues in your code:

    • You try to @forward a module only showing media, media-context (that are the only members which are forwarded) but you try to change variable $breakpoints which is not shown/forwarded because it is not in the list.
    • Just as polite guessing (not knowing): You want to show/forward media, media-context. Are that functions/mixins? If var you should write them with $.
    • You missed the closing quote after the forwarded file: @forward 'include-media ...

    So, maybe you like to try something like this:

    @forward 'include-media' 
    show [$?]media, [$?]media-context, $breakpoints
    with (
      $breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 ),
    );
    
    //### Think about 'show': 
    //### What is not in the list is not fowarded and cannot be used.
    //### So I am not sure ...
    //### if your module needs more members to be forwarded so it works. 
    //### Depends on your module.