oddbird / accoutrement

Combined Sass Accoutrement tools, with option for individual module imports
MIT License
37 stars 6 forks source link

Automatically traversing nested maps #12

Closed joelschou closed 5 years ago

joelschou commented 6 years ago

In your QuickStart: Core documentation, you have this example for internal references in nested maps:

Nested maps will compare #tags internally, before looking at the parent keys:

$map: (
  'root': 16px,
  'large-screen': (
    'root': 24px,

    // 'alias' == 24px
    'alias': '#root'
  ),
);

Which is cool! However, what I can't figure out is if there's a way to access alias with a single command without resorting to nested get-token()s.

get-token( $map, 'alias' );
// alias πŸ‘Ž 
get-token( $map, 'large-screen' );
// ("root": 24px, "alias": 24px) πŸ‘Ž 
get-token( get-token( $map, 'large-screen' ), 'alias' );
// 24px πŸ‘ 

It would be really cool to be able to do something like this, whether it's a ., :, >, -> or whatever:

get-token( $map, 'large-screen.alias' )
// 24px πŸ‘ 

If there is a way to do that and I just can't find it, please do share. Thanks!

mirisuzanne commented 6 years ago

We don't have that feature currently, no. The nested-map support that we built is specifically to handle aliases inside adjustment-maps. I'd consider adding that feature, but I generally do this with multiple maps:

$small-screen: (
  'root': 16px,
);

$large-screen: (
  'root': 24px,
  'alias': '#root',
);

get-token( $large-screen, 'alias' ); // 24px

Also, if you have 'alias' based on 'root', and change 'root' at some point, 'alias' will update:

$small-screen: (
  'root': 16px,
  'alias': '#root',
);

$large-screen: map-merge($small-screen, ('root': 24px));

get-token( $large-screen, 'alias' ); // 24px

Or you could write a function that accepts a list of keys, and finds them in order… I haven't tested, but something like this:

@function get-nested(
  $map,
  $keys...
){
  @each $key in $keys {
    $map: token-get($map, $key);
  }

  @return $map;
}
joelschou commented 6 years ago

Took a swing at this with PR #18. Used -> for a separator to avoid conflicts with normal CSS punctuation such as . or : or >.

joelschou commented 6 years ago

As you noted, moved to #22