@ulu/frontend 0.2.0-beta.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.dev.md +52 -13
  2. package/README.md +3 -1
  3. package/dist/es/core/events.js +36 -25
  4. package/dist/es/core/settings.js +33 -22
  5. package/dist/es/index.js +47 -45
  6. package/dist/es/ui/dialog.d.ts +3 -1
  7. package/dist/es/ui/dialog.d.ts.map +1 -1
  8. package/dist/es/ui/dialog.js +70 -53
  9. package/dist/es/ui/index.d.ts +1 -0
  10. package/dist/es/ui/modal-builder.d.ts +6 -0
  11. package/dist/es/ui/modal-builder.d.ts.map +1 -1
  12. package/dist/es/ui/modal-builder.js +66 -47
  13. package/dist/es/ui/overflow-scroller.js +30 -24
  14. package/dist/es/ui/proxy-click.js +37 -26
  15. package/dist/es/ui/resizer.js +57 -49
  16. package/dist/es/ui/slider.d.ts.map +1 -1
  17. package/dist/es/ui/slider.js +90 -67
  18. package/dist/es/ui/tab-manager.d.ts +145 -0
  19. package/dist/es/ui/tab-manager.d.ts.map +1 -0
  20. package/dist/es/ui/tab-manager.js +155 -0
  21. package/dist/es/ui/tabs.d.ts +5 -5
  22. package/dist/es/ui/tabs.d.ts.map +1 -1
  23. package/dist/es/ui/tabs.js +34 -51
  24. package/dist/es/ui/theme-toggle.js +80 -69
  25. package/dist/es/ui/tooltip.js +53 -44
  26. package/dist/es/utils/dialog.d.ts +14 -0
  27. package/dist/es/utils/dialog.d.ts.map +1 -0
  28. package/dist/es/utils/dialog.js +16 -0
  29. package/dist/es/utils/floating-ui.js +35 -24
  30. package/dist/es/utils/iframe.d.ts +15 -0
  31. package/dist/es/utils/iframe.d.ts.map +1 -0
  32. package/dist/es/utils/iframe.js +33 -0
  33. package/dist/umd/frontend.css +1 -0
  34. package/dist/umd/ulu-frontend.umd.js +40 -47
  35. package/lib/js/exports.md +1 -0
  36. package/lib/js/ui/dialog.js +23 -3
  37. package/lib/js/ui/index.js +4 -0
  38. package/lib/js/ui/modal-builder.js +21 -0
  39. package/lib/js/ui/slider.js +3 -3
  40. package/lib/js/ui/tab-manager.js +324 -0
  41. package/lib/js/ui/tabs.js +33 -92
  42. package/lib/js/utils/dialog.js +29 -0
  43. package/lib/js/utils/iframe.js +59 -0
  44. package/lib/scss/_breakpoint.scss +3 -3
  45. package/lib/scss/_button.scss +3 -3
  46. package/lib/scss/_color.scss +4 -3
  47. package/lib/scss/_element.scss +25 -4
  48. package/lib/scss/_layout.scss +11 -4
  49. package/lib/scss/_selector.scss +2 -1
  50. package/lib/scss/_typography.scss +9 -10
  51. package/lib/scss/_utils.scss +74 -19
  52. package/lib/scss/base/_elements.scss +4 -1
  53. package/lib/scss/components/_accordion.scss +7 -2
  54. package/lib/scss/components/_badge.scss +1 -1
  55. package/lib/scss/components/_basic-hero.scss +1 -1
  56. package/lib/scss/components/_button-group.scss +8 -3
  57. package/lib/scss/components/_button-verbose.scss +2 -2
  58. package/lib/scss/components/_callout.scss +3 -4
  59. package/lib/scss/components/_card-grid.scss +8 -14
  60. package/lib/scss/components/_card.scss +15 -13
  61. package/lib/scss/components/_css-icon.scss +2 -2
  62. package/lib/scss/components/_data-grid.scss +5 -5
  63. package/lib/scss/components/_data-list.scss +270 -0
  64. package/lib/scss/components/_data-table.scss +3 -1
  65. package/lib/scss/components/_flipcard.scss +3 -2
  66. package/lib/scss/components/_index.scss +18 -0
  67. package/lib/scss/components/_menu-stack.scss +1 -1
  68. package/lib/scss/components/_modal.scss +97 -19
  69. package/lib/scss/components/_panel.scss +1 -1
  70. package/lib/scss/components/_popover.scss +9 -6
  71. package/lib/scss/components/_ratio-box.scss +11 -10
  72. package/lib/scss/components/_table-scroller.scss +63 -0
  73. package/lib/scss/components/_tabs.scss +20 -5
  74. package/lib/scss/components/_tagged.scss +59 -0
  75. package/lib/scss/helpers/_utilities.scss +23 -1
  76. package/package.json +28 -35
  77. package/dist/umd/style.css +0 -1
  78. package/lib/js/ui/dialog.todo +0 -3
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @module utils/iframe
3
+ */
4
+
5
+ import { separateCssUnit } from "@ulu/utils/string.js";
6
+
7
+ const staticSizeRegex = /^\d+$/;
8
+
9
+ /**
10
+ * Checks if an element's sole content is an iframe, and determines its layout type.
11
+ * Useful for determining if layout fixes should be applied to containers.
12
+ * @param {HTMLElement} container The container to check
13
+ * @returns {{iframe: HTMLIFrameElement, isStaticSize: boolean, width: string|null, height: string|null, aspectRatio: string|null, fillHeight: string|null}|null} Returns an object with iframe details, or null if not a sole iframe
14
+ */
15
+ export function getSoleIframeLayout(container) {
16
+ const iframes = container.querySelectorAll("iframe");
17
+
18
+ if (iframes.length === 1 && container.textContent.trim() === '') {
19
+ const iframe = iframes[0];
20
+ const attrW = iframe.getAttribute("width");
21
+ const attrH = iframe.getAttribute("height");
22
+ const isStaticSize = Boolean(attrW && attrH && staticSizeRegex.test(attrW) && staticSizeRegex.test(attrH));
23
+
24
+ let fillHeight = null;
25
+
26
+ if (!isStaticSize) {
27
+ // Check inline style first, then fallback to attribute
28
+ const rawHeight = iframe.style.height || attrH;
29
+
30
+ if (rawHeight) {
31
+ // If it's just numbers, treat it as pixels
32
+ if (staticSizeRegex.test(rawHeight)) {
33
+ fillHeight = `${rawHeight}px`;
34
+ } else {
35
+ try {
36
+ const parsed = separateCssUnit(rawHeight);
37
+ // Ignore percentages as they rely on parent height which we are trying to fix
38
+ if (parsed && parsed.unit && parsed.unit !== "%") {
39
+ fillHeight = rawHeight;
40
+ }
41
+ } catch (e) {
42
+ // separateCssUnit throws if no pattern matches, ignore silently
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ return {
49
+ iframe,
50
+ isStaticSize,
51
+ width: isStaticSize ? attrW : null,
52
+ height: isStaticSize ? attrH : null,
53
+ aspectRatio: isStaticSize ? `${attrW} / ${attrH}` : null,
54
+ fillHeight
55
+ };
56
+ }
57
+
58
+ return null;
59
+ }
@@ -116,13 +116,13 @@ $sizes: (
116
116
  /// @return {Boolean}
117
117
  /// @example scss {compile} Example usage
118
118
  /// .test-exists {
119
- /// @if(ulu.breakpoint-exists("medium")) {
119
+ /// @if (ulu.breakpoint-exists("medium")) {
120
120
  /// @include ulu.breakpoint-min("medium") {
121
121
  /// padding: 2rem;
122
122
  /// }
123
123
  /// }
124
124
  /// // The below content doesn't print because the size doesn't exist.
125
- /// @if(ulu.breakpoint-exists("too-large")) {
125
+ /// @if (ulu.breakpoint-exists("too-large")) {
126
126
  /// @include ulu.breakpoint-min("too-large") {
127
127
  /// padding: 20000rem;
128
128
  /// }
@@ -131,7 +131,7 @@ $sizes: (
131
131
 
132
132
  @function exists($name) {
133
133
  $size: map.get($sizes, $name);
134
- @return if($size != null, true, false);
134
+ @return utils.when($size != null, true, false);
135
135
  }
136
136
 
137
137
  /// Create a media query that matches the min-width for a given size
@@ -296,15 +296,15 @@ $styles: (
296
296
  // If a specific state [hover, active] grab that map
297
297
  @if ($state) {
298
298
  $state-style: map.get($style, $state);
299
- $state-style: if($state-style, $state-style, ());
299
+ $state-style: utils.when($state-style, $state-style, ());
300
300
  }
301
301
  // From is the map to grab styles from
302
- $from: if($state, $state-style, $style);
302
+ $from: utils.when($state, $state-style, $style);
303
303
  $value: map.get($from, $prop);
304
304
 
305
305
  // Fallback to parent (if hover)
306
306
  @if ($state == "hover") {
307
- $value: if($value, $value, map.get($style, $prop));
307
+ $value: utils.when($value, $value, map.get($style, $prop));
308
308
  }
309
309
 
310
310
  @if (meta.type-of($value) == "string" and string.index($prop, "color")) {
@@ -20,7 +20,7 @@ $palette: (
20
20
  "white": white,
21
21
  "type": black,
22
22
  "type-secondary": rgb(82, 82, 82),
23
- "type-tertiary": rgb(125, 125, 125),
23
+ "type-tertiary": rgb(110, 110, 110),
24
24
  "type-disabled": rgb(160, 160, 160),
25
25
  "headline": inherit,
26
26
  "background": white,
@@ -38,6 +38,7 @@ $palette: (
38
38
  "placeholder-background": #e2e2e2,
39
39
  "placeholder-background-alt": #bababa,
40
40
  "selected": green,
41
+ "selected-background": rgb(184, 202, 184),
41
42
  "box-shadow": rgba(0, 0, 0, 0.349),
42
43
  "box-shadow-hover": rgba(0, 0, 0, 0.5),
43
44
  "rule": gray,
@@ -133,13 +134,13 @@ $color-classes: (
133
134
 
134
135
  @function exists($name) {
135
136
  $color: map.get($palette, $name);
136
- @return if($color != null, true, false);
137
+ @return utils.when($color != null, true, false);
137
138
  }
138
139
 
139
140
  /// Set color contexts
140
141
  /// @param {Map} $changes A map to merge
141
142
  /// @param {Map} $deep Use deep merge
142
- /// @param {Map} $overwrite Overwrite the completly (cannot be used with deep)
143
+ /// @param {Map} $overwrite Overwrite the completely (cannot be used with deep)
143
144
  /// @example scss Overwriting contexts
144
145
  /// @include ulu.color-set-contexts((
145
146
  /// "dark" : (
@@ -4,6 +4,7 @@
4
4
 
5
5
  @use "sass:map";
6
6
  @use "sass:meta";
7
+
7
8
  @use "color";
8
9
  @use "utils";
9
10
 
@@ -175,7 +176,12 @@ $rule-margins: (
175
176
  /// @param {String} $name ["default"] name of rule style
176
177
 
177
178
  @mixin rule-margin($name: null) {
178
- $margin: if($name, get-rule-margin($name), get("margin"));
179
+ $margin: null;
180
+ @if ($name) {
181
+ $margin: get-rule-margin($name);
182
+ } @else {
183
+ $margin: get("margin");
184
+ }
179
185
  margin-top: $margin;
180
186
  margin-bottom: $margin;
181
187
  }
@@ -337,7 +343,7 @@ $rule-margins: (
337
343
  "padding-adjust" : null,
338
344
  );
339
345
  $config: map.merge($defaults, $options);
340
- $element: if($before, "::before", "::after");
346
+ $element: utils.when($before, "::before", "::after");
341
347
 
342
348
  &#{ $element } {
343
349
  content: "";
@@ -362,14 +368,14 @@ $rule-margins: (
362
368
  $options: (),
363
369
  $before: true
364
370
  ) {
365
- $element: if($before, "::before", "::after");
371
+ $element: utils.when($before, "::before", "::after");
366
372
  $size: map.get($options, "size");
367
373
  $offset: map.get($options, "offset");
368
374
  $border-radius: map.get($options, "border-radius");
369
375
  $padding-adjust: map.get($options, "padding-adjust");
370
376
 
371
377
  $end: $side == "top" or $side == "bottom";
372
- $position: if($offset, 0 - $offset, null);
378
+ $position: utils.when($offset, 0 - $offset, null);
373
379
 
374
380
  @if ($padding-adjust and $size) {
375
381
  padding-#{ $side }: calc($padding-adjust + $size);
@@ -424,3 +430,18 @@ $rule-margins: (
424
430
  content: "";
425
431
  }
426
432
  }
433
+
434
+ /// Helper function to construct a border using the color module
435
+ /// Returns null if the required parameters are missing or zero, preventing output
436
+ /// @param {Dimension} $width The border width
437
+ /// @param {String|Color} $color The color value/key to resolve through color.get()
438
+ /// @param {String} $style [solid] The border style
439
+ /// @return {List|Null} The combined border shorthand, or null
440
+
441
+ @function optional-border($width, $color, $style: solid) {
442
+ // Not using () breaks syntax highlighting
443
+ @if $width and $width != 0 and $width != none and $color {
444
+ @return $width $style color.get($color);
445
+ }
446
+ @return null;
447
+ }
@@ -5,6 +5,7 @@
5
5
  @use "sass:map";
6
6
  @use "sass:list";
7
7
  @use "sass:meta";
8
+
8
9
  @use "utils";
9
10
  @use "breakpoint";
10
11
  @use "color";
@@ -128,14 +129,20 @@ $containers: (
128
129
  @mixin match-container-margin($property, $name: "container", $include-padding: true) {
129
130
  $container: get-container($name);
130
131
  $breakpoints: map.get($container, "breakpoints");
131
- $padding: if($include-padding, get-container-padding($name, true), 0);
132
+ $padding: 0;
133
+ @if ($include-padding) {
134
+ $padding: get-container-padding($name, true);
135
+ }
132
136
  $max: map.get($container, "max-width");
133
137
  #{ $property }: max(((100vw - $max) / 2) + $padding, $padding);
134
138
  @if $breakpoints {
135
139
  @each $breakpoint, $props in $breakpoints {
136
140
  $direction: map.get($props, "direction");
137
141
  @include breakpoint.from($breakpoint, $direction) {
138
- $pad: if($include-padding, get-container-padding($name, true, $breakpoint), 0);
142
+ $pad: 0;
143
+ @if ($include-padding) {
144
+ $pad: get-container-padding($name, true, $breakpoint);
145
+ }
139
146
  #{ $property }: max(((100vw - $max) / 2) + $pad, $pad);
140
147
  }
141
148
  }
@@ -154,7 +161,7 @@ $containers: (
154
161
  @if (not $is-list) {
155
162
  @return $padding;
156
163
  } @else {
157
- @return list.nth($padding, if($sides, 2, 1));
164
+ @return list.nth($padding, utils.when($sides, 2, 1));
158
165
  }
159
166
  }
160
167
 
@@ -168,7 +175,7 @@ $containers: (
168
175
  $responsive: map.get($container, "responsive");
169
176
  $x: get-container-padding-x($name, $specific-breakpoint);
170
177
  $y: get-container-padding-y($name, $specific-breakpoint);
171
- $resp-amount: if(meta.type-of($responsive) == number, $responsive, utils.get("responsive-change"));
178
+ $resp-amount: utils.when(meta.type-of($responsive) == number, $responsive, utils.get("responsive-change"));
172
179
 
173
180
  @if $responsive {
174
181
  @if $sides {
@@ -5,6 +5,7 @@
5
5
 
6
6
  @use "sass:string";
7
7
  @use "sass:map";
8
+
8
9
  @use "utils";
9
10
 
10
11
  /// Module Settings
@@ -67,7 +68,7 @@ $-class-wildcards: ();
67
68
  // Check if it's a wildcard
68
69
  $wildcard: -get-class-wildcard($class);
69
70
  $override: map.get($-class-overrides, $class);
70
- $updated: if($override, $override, if($wildcard, $wildcard, $class));
71
+ $updated: utils.fallback($override, $wildcard, $class);
71
72
  $name: "#{ get("prefix") }#{ $updated }";
72
73
  @if $name-only {
73
74
  @return $name;
@@ -115,9 +115,8 @@ $config: (
115
115
  /// @param {Number} $base Conversion base (defaults to font-size)
116
116
  /// @return {Number} Rem value
117
117
 
118
- @function em($value, $base: null) {
118
+ @function em($value, $base: get("font-size")) {
119
119
  @if (math.unit($value) == "px") {
120
- $base: if($base, $base, get("font-size"));
121
120
  @return math.div($base, $value) * 1em;
122
121
  } @else {
123
122
  @return $value;
@@ -128,7 +127,7 @@ $config: (
128
127
  /// @param {Boolean} $force Force words to break (will have unusual breaks)
129
128
 
130
129
  @mixin word-break($force: false) {
131
- word-break: if($force, break-all, normal);
130
+ word-break: utils.when($force, break-all, normal);
132
131
  word-break: break-word;
133
132
  hyphens: auto;
134
133
  }
@@ -144,16 +143,16 @@ $config: (
144
143
  @function new-size($font-size, $line-height: true, $is-headline: false) {
145
144
  @return (
146
145
  "font-size": $font-size,
147
- "font-weight" : if($is-headline, get("font-weight-bold"), null),
146
+ "font-weight" : utils.when($is-headline, get("font-weight-bold"), null),
148
147
  "line-height": $line-height,
149
- "margin-bottom" : if($is-headline, get("margin-bottom"), null),
150
- "margin-top" : if($is-headline, get("margin-top"), null),
148
+ "margin-bottom" : utils.when($is-headline, get("margin-bottom"), null),
149
+ "margin-top" : utils.when($is-headline, get("margin-top"), null),
151
150
  "responsive" : true,
152
- "helper-class" : if($is-headline, false, true),
151
+ "helper-class" : utils.when($is-headline, false, true),
153
152
  "helper-class-prefixed" : true,
154
- "base-class" : if($is-headline, true, false),
153
+ "base-class" : utils.when($is-headline, true, false),
155
154
  "base-class-prefixed" : false,
156
- "color" : if($is-headline, color.get("headline"), null)
155
+ "color" : utils.when($is-headline, color.get("headline"), null)
157
156
  );
158
157
  }
159
158
 
@@ -353,7 +352,7 @@ $sizes: get-default-sizes() !default;
353
352
  line-height: get-size-converted-value($size, "line-height");
354
353
  margin-top: get-size-converted-value($size, "margin-top");
355
354
  margin-bottom: get-size-converted-value($size, "margin-bottom");
356
- color: if($color, color.get($color), null);
355
+ color: utils.when($color, color.get($color), null);
357
356
  }
358
357
 
359
358
  // If they have breakpoints, process them
@@ -106,12 +106,12 @@ $config: (
106
106
  /// "h2" : true,
107
107
  /// "h3" : false
108
108
  /// );
109
- /// @if(ulu.utils-included("h2", $include-styles)) {
109
+ /// @if (ulu.utils-included("h2", $include-styles)) {
110
110
  /// h2 {
111
111
  /// font-size: 24px;
112
112
  /// }
113
113
  /// }
114
- /// @if(ulu.utils-included("h3", $include-styles)) {
114
+ /// @if (ulu.utils-included("h3", $include-styles)) {
115
115
  /// h3 {
116
116
  /// font-size: 18px;
117
117
  /// }
@@ -136,6 +136,26 @@ $config: (
136
136
  }
137
137
  }
138
138
 
139
+ /// Selects a value based on a condition (Ternary Function)
140
+ /// - To replace SASS if() which is deprecated see
141
+ /// - Eagerly evaluates arguments (use native @if or if(sass()... if you need lazy evaluation).
142
+ /// @param {*} $condition The condition/value to test for truthiness
143
+ /// @param {*} $true Value if true
144
+ /// @param {*} $false Value if false
145
+ /// @link https://sass-lang.com/documentation/breaking-changes/if-function/
146
+ /// @example scss {compile} Example usage
147
+ /// .test {
148
+ /// color: ulu.utils-when(true, red, blue)
149
+ /// }
150
+ /// @return {*} Either true or false value based on conditions truthiness
151
+
152
+ @function when($condition, $value-true, $value-false) {
153
+ @if $condition {
154
+ @return $value-true;
155
+ }
156
+ @return $value-false;
157
+ }
158
+
139
159
  /// Provide a default when value type is not correct
140
160
  /// @param {String} $type type of value it should be
141
161
  /// @param {String} $value the value to provide if it is that type
@@ -177,13 +197,19 @@ $config: (
177
197
  @function number-info($number, $errors: false) {
178
198
 
179
199
  @if (meta.type-of($number) == 'number') {
180
- $is-unitless: math.is-unitless($number);
181
- @return (
182
- "unit": if($is-unitless, null, math.unit($number)),
183
- "value": if($is-unitless, $number, strip-unit($number)),
184
- "invalid" : false
185
- );
186
-
200
+ @if (math.is-unitless($number)) {
201
+ @return (
202
+ "unit": null,
203
+ "value": $number,
204
+ "invalid" : false
205
+ );
206
+ } @else {
207
+ @return (
208
+ "unit": math.unit($number),
209
+ "value": strip-unit($number),
210
+ "invalid" : false
211
+ );
212
+ }
187
213
  } @else {
188
214
  @if ($errors) {
189
215
  @error "Expected Number, got #{ meta.type-of($number) } for #{ $number }";
@@ -442,7 +468,7 @@ $config: (
442
468
  /// @param {*} $value The value to check
443
469
  /// @param {*} $default The value to return when true
444
470
  @function default($value, $default) {
445
- @return if($value == true, $default, $value);
471
+ @return when($value == true, $default, $value);
446
472
  }
447
473
 
448
474
  /// Replaces all or one occurrence of a string within a string
@@ -456,7 +482,7 @@ $config: (
456
482
  $index: string.index($string, $find);
457
483
 
458
484
  @if ($index) {
459
- $start: if($index == 1, "", string.slice($string, 1, string.length($find) - 1));
485
+ $start: when($index == 1, "", string.slice($string, 1, string.length($find) - 1));
460
486
  $end: string.slice($string, $index + string.length($find));
461
487
  $new: $start + $replace;
462
488
  @if ($all) {
@@ -542,10 +568,17 @@ $config: (
542
568
  /// @throw If the list length > 4 (incorrect syntax for shorthand)
543
569
 
544
570
  @function get-spacing($value) {
545
- $is-list: meta.type-of($value) == "list";
546
- $length: if($is-list, list.length($value), 1);
547
- $single: $length == 1;
548
- $top: if($is-list, list.nth($value, 1), $value); // Top is always the same
571
+ @if (meta.type-of($value) != "list") {
572
+ @return (
573
+ "top" : $value,
574
+ "right" : $value,
575
+ "bottom" : $value,
576
+ "left" : $value,
577
+ );
578
+ }
579
+
580
+ $length: list.length($value);
581
+ $top: list.nth($value, 1); // Top is always the same
549
582
 
550
583
  @if ($length > 4) {
551
584
  @error "Spacing has more than 4 arguments (not correct shorthand)";
@@ -553,9 +586,9 @@ $config: (
553
586
 
554
587
  @return (
555
588
  "top" : $top,
556
- "right" : if($single, $top, list.nth($value, 2)),
557
- "bottom" : if($single, $top, list.nth($value, if($length >= 3, 3, 1))),
558
- "left" : if($single, $top, list.nth($value, if($length == 4, 4, 2)))
589
+ "right" : list.nth($value, 1),
590
+ "bottom" : list.nth($value, when($length >= 3, 3, 1)),
591
+ "left" : list.nth($value, when($length == 4, 4, 2))
559
592
  );
560
593
  }
561
594
 
@@ -831,7 +864,7 @@ $config: (
831
864
  /// @return {Map} The $value if it was a map, else empty map
832
865
 
833
866
  @function ensure-map($value) {
834
- @return if(is-map($value), $value, ());
867
+ @return when(is-map($value), $value, ());
835
868
  }
836
869
 
837
870
  /// Returns true if edge passed is an end (top/bottom)
@@ -856,4 +889,26 @@ $config: (
856
889
 
857
890
  @function is-side($edge) {
858
891
  @return not is-end($edge);
892
+ }
893
+
894
+ /// For legacy aspect ratio conversion
895
+ /// - For a given value if it's a percentage number convert to css aspect ratio like 16/9
896
+ /// @param {String|Number} $value The ratio value to normalize.
897
+ /// @return {String} Either the original value or a converted value depending on if it was a percentage number
898
+
899
+ @function normalize-aspect-ratio($value) {
900
+ @if is-number($value) and not math.is-unitless($value) {
901
+ $info: number-info($value);
902
+ @if ($info) {
903
+ $u: map.get($info, "unit");
904
+ $v: map.get($info, "value");
905
+ @if $u == "%" {
906
+ @return string.unquote("100 / #{ $v }");
907
+ }
908
+ }
909
+ }
910
+ @if is-string($value) {
911
+ @return string.unquote($value);
912
+ }
913
+ @return $value;
859
914
  }
@@ -88,7 +88,7 @@ $config: (
88
88
  }
89
89
  p {
90
90
  $margin-top: typography.get("margin-top");
91
- margin-top: if($margin-top, $margin-top, 0);
91
+ margin-top: utils.when($margin-top, $margin-top, 0);
92
92
  margin-bottom: typography.get("margin-bottom");
93
93
  }
94
94
  sub, sup {
@@ -180,6 +180,9 @@ $config: (
180
180
  blockquote {
181
181
  margin: 0;
182
182
  }
183
+ summary {
184
+ cursor: pointer;
185
+ }
183
186
  @if get("details-animation") {
184
187
  details {
185
188
  &[open] {
@@ -163,7 +163,7 @@ $config: (
163
163
  border-bottom-left-radius: 0;
164
164
  border-bottom-right-radius: 0;
165
165
 
166
- @if (get("summary-border-enabled")) {
166
+ @if (get("summary-border-enabled")) {
167
167
  &::after {
168
168
  content: "";
169
169
  position: absolute;
@@ -191,7 +191,7 @@ $config: (
191
191
  align-items: center;
192
192
 
193
193
  @include typography.optional-size(get("summary-type-size"), $only-font-size: true);
194
- @include element.summary-remove-marker;
194
+ @include element.summary-remove-marker();
195
195
  &:hover,
196
196
  &:focus {
197
197
  background-color: color.get(get("summary-background-color-hover"));
@@ -262,6 +262,11 @@ $config: (
262
262
  & > #{ $prefix }__summary {
263
263
  border-radius: get("border-radius");
264
264
  border-bottom: none;
265
+ @if (get("summary-border-enabled")) {
266
+ &::after {
267
+ content: none;
268
+ }
269
+ }
265
270
  }
266
271
  }
267
272
  }
@@ -42,7 +42,7 @@ $config: (
42
42
  "sizes" : (
43
43
  "small" : (
44
44
  "font-size" : 1.2rem,
45
- "width" : 5rem
45
+ "width" : 4rem
46
46
  ),
47
47
  "large" : (
48
48
  "font-size" : 2.75rem,
@@ -81,7 +81,7 @@ $config: (
81
81
  padding-bottom: get("padding-bottom");
82
82
  }
83
83
  #{ $prefix }__content-main {
84
- $min-width: if(get("main-min-width"), get("main-min-width"), get("main-max-width"));
84
+ $min-width: utils.fallback(get("main-min-width"), get("main-max-width"));
85
85
  // Using max/min-width so that we don't need to add selectors to change flex-basis
86
86
  // when centered. Using flex-basis: 0 to allow flexbox to decide the items width
87
87
  // allows it to expand/shrink within. min(100%... Never larger than parent
@@ -13,11 +13,13 @@
13
13
 
14
14
  /// Module Settings
15
15
  /// @type Map
16
- /// @prop {Dimension} gap [0.45em] Gap between buttons
16
+ /// @prop {Dimension} gap [0.45em] Gap between buttons
17
+ /// @prop {Dimension} gap-joined [0] When using --joined modifier optional gap, if 0 the buttons borders will overlap, joined-gap is useful if your buttons don't have borders
17
18
  /// @prop {Boolean} no-min-width [true] Buttons within the button group should have no min width
18
19
 
19
20
  $config: (
20
21
  "gap": 0.45em,
22
+ "gap-joined" : 0,
21
23
  "no-min-width" : true
22
24
  ) !default;
23
25
 
@@ -61,13 +63,16 @@ $config: (
61
63
  #{ $prefix }--joined {
62
64
  flex-wrap: nowrap;
63
65
  overflow-x: auto;
64
- gap: 0;
66
+ gap: get("gap-joined");
65
67
  // border-radius: button.get("border-radius");
66
68
  #{ $prefix-button } {
67
69
  position: relative; // To move to front when hover/active
68
70
  border-radius: 0;
69
71
  min-width: 0;
70
- margin-left: -(button.get("border-width"));
72
+ @if (get("gap-joined") == 0) {
73
+ margin-left: -(button.get("border-width"));
74
+ }
75
+
71
76
  &:first-child {
72
77
  border-top-left-radius: $button-radius;
73
78
  border-bottom-left-radius: $button-radius;
@@ -136,8 +136,8 @@ $config: (
136
136
  $cap-side: get("cap-side");
137
137
  $cap-defaults: (
138
138
  "offset" : utils.if-type("number", get("border-width"), 0),
139
- "border-radius" : if(get("cap-match-radius"), get("border-radius"), 0),
140
- "padding-adjust" : if(utils.is-side($cap-side), $padding-x, $padding-y)
139
+ "border-radius" : utils.when(get("cap-match-radius"), get("border-radius"), 0),
140
+ "padding-adjust" : utils.when(utils.is-side($cap-side), $padding-x, $padding-y)
141
141
  );
142
142
 
143
143
  #{ $prefix } {
@@ -6,7 +6,6 @@
6
6
  @use "sass:map";
7
7
  @use "sass:meta";
8
8
 
9
-
10
9
  @use "../utils";
11
10
  @use "../selector";
12
11
  @use "../element";
@@ -132,7 +131,7 @@ $styles: (
132
131
  @if (not get("caps-disabled")) {
133
132
  $cap-defaults: (
134
133
  "offset" : get("border-width"),
135
- "border-radius" : if(get("cap-match-radius"), get("border-radius"), null),
134
+ "border-radius" : utils.when(get("cap-match-radius"), get("border-radius"), null),
136
135
  // "padding-adjust" : map.get($padding-info, $cap-side)
137
136
  );
138
137
  @include element.cap(
@@ -187,14 +186,14 @@ $styles: (
187
186
  @if ($cap and $caps-enabled) {
188
187
  $match-radius: utils.if-type("bool", $cap-match-radius, get("cap-match-radius"));
189
188
  // Padding adjust always has to be set (since size could change or padding)
190
- $padding-info: utils.get-spacing(if($padding, $padding, get("padding")));
189
+ $padding-info: utils.get-spacing(utils.fallback($padding, get("padding")));
191
190
  $cap-radius: utils.if-type("number", $border-radius, get("border-radius"));
192
191
  $cap-options: utils.ensure-map(map.get($style, "cap-options"));
193
192
  $cap-defaults: (
194
193
  "size" : map.get(get("cap-options"), "size"),
195
194
  "padding-adjust" : map.get($padding-info, $cap-side),
196
195
  "offset" : $border-width,
197
- "border-radius" : if($match-radius, $cap-radius, null)
196
+ "border-radius" : utils.when($match-radius, $cap-radius, null)
198
197
  );
199
198
 
200
199
  @include element.cap-appearance(