@ulu/frontend 0.1.0-beta.29 → 0.1.0-beta.30

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.
package/scss/_utils.scss CHANGED
@@ -465,7 +465,15 @@ $config: (
465
465
  /// @link https://stackoverflow.com/questions/12328259/how-do-you-strip-the-unit-from-any-number-in-sass/12335841#12335841 Original source (Miriam Suzanne)
466
466
 
467
467
  @function strip-unit($value) {
468
- @return math.div($value, ($value * 0 + 1));
468
+ @if (is-number($value)) {
469
+ @if (math.is-unitless($value)) {
470
+ @return $value;
471
+ } @else {
472
+ @return math.div($value, ($value * 0 + 1));
473
+ }
474
+ } @else {
475
+ @error "Expected number, got #{ $value }";
476
+ }
469
477
  }
470
478
 
471
479
  /// Calculate the size of something at a given scale (percentage/exponential)
@@ -510,4 +518,147 @@ $config: (
510
518
 
511
519
  @function hypotenuse($width, $height) {
512
520
  @return math.sqrt(math.pow($width, 2) + math.pow($height, 2));
521
+ }
522
+
523
+ /// Get's the info about a box shadow
524
+ /// @param {List} $shadow The box shadow property (ie. 0 0 4px red)
525
+ /// @return {Map} Map with info about the shadow with the following keys (inset, offset-x, offset-y, blur, spread, color)
526
+ /// @throw When shadow is not type list
527
+
528
+ @function box-shadow-info($shadow) {
529
+ @if (meta.type-of($shadow) != "list") {
530
+ @error "Box shadow passed is not correct type (list)";
531
+ }
532
+ $result: (
533
+ "inset": false,
534
+ "offset-x": 0,
535
+ "offset-y": 0,
536
+ "blur": 0,
537
+ "spread": 0,
538
+ "color": null,
539
+ );
540
+
541
+ $number-keys: ("offset-x", "offset-y", "blur", "spread");
542
+ $number-index: 1;
543
+
544
+ @each $value in $shadow {
545
+ $type: meta.type-of($value);
546
+ @if $type == "color" {
547
+ $result: map.merge($result, ("color": $value));
548
+ } @else if $type == "string" and $value == inset {
549
+ $result: map.merge($result, ("inset": true));
550
+ } @else if $type == "number" and $number-index <= 4 {
551
+ // Add each back in by key in the order they appear
552
+ // if not found it's the default
553
+ $result: map.merge($result, (list.nth($number-keys, $number-index): $value));
554
+ $number-index: $number-index + 1;
555
+ }
556
+ }
557
+
558
+ @return $result;
559
+ }
560
+
561
+ /// Get's the extent (how far the shadow extends past the box's edge)
562
+ /// - This will only work on box-shadows that have matching units for the numbers
563
+ /// @param {List} $shadow The box shadow property (ie. 0 0 4px red)
564
+ /// @param {String} $side Optionally pass the side of box to get extend for, if not specified offsets are ignored and just the extent of the shadow is passed
565
+ /// @return {Number} The size the shadow extends past it's box
566
+
567
+ @function box-shadow-extent($shadow, $side: null) {
568
+ $info: box-shadow-info($shadow);
569
+ $extent: map.get($info, "spread") + map.get($info, "blur");
570
+ $offset-x: map.get($info, "offset-x");
571
+ $offset-y: map.get($info, "offset-y");
572
+ @if (not $side) {
573
+ @return $extent;
574
+ } @else {
575
+ @if ($side == "top") {
576
+ @return $extent - $offset-y;
577
+ } @else if ($side == "bottom") {
578
+ @return $extent + $offset-y;
579
+ } @else if ($side == "left") {
580
+ @return $extent - $offset-x;
581
+ } @else if ($side == "right") {
582
+ @return $extent + $offset-x;
583
+ }
584
+ }
585
+ }
586
+
587
+ /// Determines if value passed is a list
588
+ /// @param {*} $value Value to check
589
+ /// @return {Boolean} Whether the item was type list
590
+
591
+ @function is-list($value) {
592
+ @return meta.type-of($value) == "list";
593
+ }
594
+
595
+ /// Determines if value passed is a map
596
+ /// @param {*} $value Value to check
597
+ /// @return {Boolean} Whether the item was type map
598
+
599
+ @function is-map($value) {
600
+ @return meta.type-of($value) == "map";
601
+ }
602
+
603
+ /// Determines if value passed is a number
604
+ /// @param {*} $value Value to check
605
+ /// @return {Boolean} Whether the item was type number
606
+
607
+ @function is-number($value) {
608
+ @return meta.type-of($value) == "number";
609
+ }
610
+
611
+ /// Determines if value passed is a string
612
+ /// @param {*} $value Value to check
613
+ /// @return {Boolean} Whether the item was type string
614
+
615
+ @function is-string($value) {
616
+ @return meta.type-of($value) == "string";
617
+ }
618
+
619
+ /// Determines if value passed is a color
620
+ /// @param {*} $value Value to check
621
+ /// @return {Boolean} Whether the item was type color
622
+
623
+ @function is-color($value) {
624
+ @return meta.type-of($value) == "color";
625
+ }
626
+
627
+
628
+
629
+ // /// Determines if value passed is a bool
630
+ // /// @param {*} $value Value to check
631
+ // /// @return {Boolean} Whether the item was type bool
632
+
633
+ // @function is-bool($value) {
634
+ // @return meta.type-of($value) == "bool";
635
+ // }
636
+
637
+ // /// Determines if value passed is a null
638
+ // /// @param {*} $value Value to check
639
+ // /// @return {Boolean} Whether the item was type null
640
+
641
+ // @function is-null($value) {
642
+ // @return meta.type-of($value) == "null";
643
+ // }
644
+
645
+ /// Returns true if number passed is even
646
+ /// - Allows unit and unitless numbers
647
+ /// @param {Number} $number The number to check
648
+ /// @return {Boolean} Whether or not it is an even number
649
+
650
+ @function is-even($number) {
651
+ @if (is-number($number)) {
652
+ @return strip-unit($number) % 2 == 0;
653
+ } @else {
654
+ @error "Expected Number, got #{ $number }";
655
+ }
656
+ }
657
+
658
+ /// Returns true if number passed is odd
659
+ /// @param {Number} $number The number to check
660
+ /// @return {Boolean} Whether or not it is an odd number
661
+
662
+ @function is-odd($number) {
663
+ @return not is-even($number);
513
664
  }
@@ -104,7 +104,7 @@ $config: (
104
104
  /// @example html {preview} - Basic Example
105
105
  /// <a href="#" class="button-verbose">
106
106
  /// <strong class="button-verbose__title">Example Link</strong>
107
- /// This is the body
107
+ /// <span class="button-verbose__body">This is the body</span>
108
108
  /// <span class="button-verbose__icon fas fa-arrow-right" aria-hidden="true"></span>
109
109
  /// </a>
110
110
 
@@ -161,9 +161,14 @@ $config: (
161
161
  }
162
162
  }
163
163
  }
164
- #{ $prefix }__title {
164
+ #{ $prefix }__title,
165
+ #{ $prefix }__body {
165
166
  display: block;
166
- margin-bottom: get("title-margin");
167
+ &:first-child {
168
+ margin-bottom: get("title-margin");
169
+ }
170
+ }
171
+ #{ $prefix }__title {
167
172
  color: color.get(get("title-color"));
168
173
  }
169
174
  #{ $prefix }__icon {
@@ -46,66 +46,66 @@ $-fallbacks: (
46
46
  /// @prop {Dimension} item-border-radius [null] Border radius for __item.
47
47
  /// @prop {Dimension} item-highlight-width [6px] Width of the item box highlight.
48
48
  /// @prop {Color} required-color ["danger"] Color for required text.
49
- /// @prop {Dimension} text-input-margin-bottom [0.5em]
50
- /// @prop {Dimension} text-input-margin-top [1em]
51
- /// @prop {Color} warning-color ["warning"]
52
- /// @prop {Color} warning-highlight-color [rgb(255, 249, 237)]
53
- /// @prop {String} warning-selector [".is-warning"]
54
- /// @prop {Color} check-input-color [currentColor]
55
- /// @prop {Dimension} check-input-size [1.15em]
56
- /// @prop {Dimension} check-input-touch-size [2em]
57
- /// @prop {Color} check-input-background-color [white]
58
- /// @prop {Color} check-input-background-color-checked [white]
59
- /// @prop {Color} check-input-background-color-hover [white]
60
- /// @prop {Color} check-input-background-color-indeterminate [white]
49
+ /// @prop {Dimension} text-input-margin-bottom [0.5em] Bottom margin for the label.
50
+ /// @prop {Dimension} text-input-margin-top [1em] Top margin for the label.
51
+ /// @prop {Color} warning-color ["warning"] The warning text color.
52
+ /// @prop {Color} warning-highlight-color [rgb(255, 249, 237)] Outline color of the warning.
53
+ /// @prop {String} warning-selector [".is-warning"] Selector for adding warning styles.
54
+ /// @prop {Color} check-input-color [currentColor] @joe-check unused
55
+ /// @prop {Dimension} check-input-size [1.15em] Size of input box.
56
+ /// @prop {Dimension} check-input-touch-size [2em] Touchable size of the input box.
57
+ /// @prop {Color} check-input-background-color [white] Background color for the check input.
58
+ /// @prop {Color} check-input-background-color-checked [white] Background color for the check input when checked.
59
+ /// @prop {Color} check-input-background-color-hover [white] Background color for the check input when hovered or focused.
60
+ /// @prop {Color} check-input-background-color-indeterminate [white] Background color for the indeterminate check input.
61
61
  /// @prop {} check-input-border [null] @joe-check check how this is called with a fallback in the styles mixin
62
- /// @prop {Color} check-input-border-color-hover [null]
63
- /// @prop {Color} check-input-border-color-checked [null]
64
- /// @prop {Color} check-input-border-color-indeterminate [null]
65
- /// @prop {Color} check-input-border-color-focus [null]
66
- /// @prop {} check-input-outline [null]
67
- /// @prop {} check-input-outline-hover [null]
68
- /// @prop {} check-input-outline-checked [null]
69
- /// @prop {} check-input-outline-focus [1px solid white]
70
- /// @prop {} check-input-touch-color-hover [#e8e8e8]
71
- /// @prop {} check-input-touch-color-focus [null]
72
- /// @prop {} check-input-radio-size [0.3em]
73
- /// @prop {} check-input-checkmark-width [0.38em]
74
- /// @prop {} check-input-checkmark-height [0.68em]
75
- /// @prop {} check-input-checkmark-offset-y [-0.2em]
76
- /// @prop {} check-input-checkmark-stroke-size [0.18em]
77
- /// @prop {} check-input-mark-color [currentColor]
78
- /// @prop {} check-input-mark-color-hover [null]
79
- /// @prop {} check-input-mark-color-focus [null]
80
- /// @prop {} check-input-mark-color-checked [null]
81
- /// @prop {} check-input-mark-color-indeterminate [null]
82
- /// @prop {} check-input-disabled-opacity [0.6]
83
- /// @prop {} check-input-border-radius [null]
84
- /// @prop {} description-color [false]
85
- /// @prop {} description-margin [(0.25em 0)]
86
- /// @prop {} description-max-width [25em]
62
+ /// @prop {Color} check-input-border-color-hover [null] Check input border color.
63
+ /// @prop {Color} check-input-border-color-checked [null] Check input border color when checked.
64
+ /// @prop {Color} check-input-border-color-indeterminate [null] Indeterminate check input border color.
65
+ /// @prop {Color} check-input-border-color-focus [null] Check input border color when hovered or focused.
66
+ /// @prop {CssValue} check-input-outline [null] Check input outline.
67
+ /// @prop {CssValue} check-input-outline-hover [null]
68
+ /// @prop {CssValue} check-input-outline-checked [null]
69
+ /// @prop {CssValue} check-input-outline-focus [1px solid white]
70
+ /// @prop {Color} check-input-touch-color-hover [#e8e8e8]
71
+ /// @prop {Color} check-input-touch-color-focus [null]
72
+ /// @prop {Dimension} check-input-radio-size [0.3em]
73
+ /// @prop {Dimension} check-input-checkmark-width [0.38em]
74
+ /// @prop {Dimension} check-input-checkmark-height [0.68em]
75
+ /// @prop {Dimension} check-input-checkmark-offset-y [-0.2em]
76
+ /// @prop {Dimension} check-input-checkmark-stroke-size [0.18em]
77
+ /// @prop {Color} check-input-mark-color [currentColor]
78
+ /// @prop {Color} check-input-mark-color-hover [null]
79
+ /// @prop {Color} check-input-mark-color-focus [null]
80
+ /// @prop {Color} check-input-mark-color-checked [null]
81
+ /// @prop {Color} check-input-mark-color-indeterminate [null]
82
+ /// @prop {Number} check-input-disabled-opacity [0.6]
83
+ /// @prop {Dimension} check-input-border-radius [null]
84
+ /// @prop {Color} description-color [false]
85
+ /// @prop {CssValue} description-margin [(0.25em 0)]
86
+ /// @prop {Dimension} description-max-width [25em]
87
87
  /// @prop {Number} description-line-height [true] Line height for description element, defaults to typograpahy line-height-dense
88
- /// @prop {} fieldset-background [transparent]
89
- /// @prop {} fieldset-border [none]
90
- /// @prop {} fieldset-margin-bottom [1rem]
91
- /// @prop {} fieldset-margin-top [1rem]
92
- /// @prop {} fieldset-padding [0]
93
- /// @prop {} fieldset-margin-compact [0]
94
- /// @prop {} fieldset-border-bottom [0]
95
- /// @prop {} fieldset-border-radius [0]
96
- /// @prop {} fieldset-legend-color [inherit]
97
- /// @prop {} fieldset-legend-border-bottom [null]
98
- /// @prop {} fieldset-legend-padding-bottom [null]
99
- /// @prop {} select-border-radius [4px]
100
- /// @prop {} select-background-color [null]
101
- /// @prop {} select-border [null]
102
- /// @prop {} select-padding-x [null]
103
- /// @prop {} select-padding-y [null]
104
- /// @prop {} select-image [null]
105
- /// @prop {} select-image-size [0.9em]
106
- /// @prop {} select-image-offset [0.7em]
107
- /// @prop {} select-image-margin [0.65em]
108
- /// @prop {Unit} inline-gap [1em] Gap between items that are inline like checkboxes
88
+ /// @prop {Color} fieldset-background [transparent]
89
+ /// @prop {CssValue} fieldset-border [none]
90
+ /// @prop {Dimension} fieldset-margin-bottom [1rem]
91
+ /// @prop {Dimension} fieldset-margin-top [1rem]
92
+ /// @prop {Dimension} fieldset-padding [0]
93
+ /// @prop {Dimension} fieldset-margin-compact [0]
94
+ /// @prop {Dimension} fieldset-border-bottom [0]
95
+ /// @prop {Dimension} fieldset-border-radius [0]
96
+ /// @prop {Color} fieldset-legend-color [inherit]
97
+ /// @prop {Dimension} fieldset-legend-border-bottom [null]
98
+ /// @prop {Dimension} fieldset-legend-padding-bottom [null]
99
+ /// @prop {Dimension} select-border-radius [4px]
100
+ /// @prop {Color} select-background-color [null]
101
+ /// @prop {CssValue} select-border [null]
102
+ /// @prop {Dimension} select-padding-x [null]
103
+ /// @prop {Dimension} select-padding-y [null]
104
+ /// @prop {CssValue} select-image [null]
105
+ /// @prop {Dimension} select-image-size [0.9em]
106
+ /// @prop {Dimension} select-image-offset [0.7em]
107
+ /// @prop {Dimension} select-image-margin [0.65em]
108
+ /// @prop {Dimension} inline-gap [1em] Gap between items that are inline like checkboxes
109
109
 
110
110
  $config: (
111
111
  "color" : inherit,
@@ -30,7 +30,8 @@ $-fallbacks: (
30
30
  /// Module Settings
31
31
  /// @type Map
32
32
  /// @prop {Dimension} arrow-size [16px] Size of the dropdown arrow.
33
- /// @prop {Dimension} arrow-mask-overlap [4px] Size that the mask extends beyond the arrow size (which covers up the arrow box shadow inside the popover content). This should be adjusted based on the size of the box-shadow being used)
33
+ /// @prop {Boolean} arrow-box-shadow [true] When true the arrow will get the popover's box shadow. Note if the box shadow is not a list (for example custom property), the mask won't be calculated from the box-shadow (use arrow-box-shadow-extent to specify manually)
34
+ /// @prop {Number} arrow-box-shadow-extent [null] If set will determine the amount of overlap added to the arrow mask, else it's calculated automatically by the box-shadow option (can be used if box-shadow is custom property)
34
35
  /// @prop {Color} background-color [white] Background color of the popover.
35
36
  /// @prop {Dimension} border-radius [6px] Border radius of the popover.
36
37
  /// @prop {Color} color [inherit] Text color of the popover.
@@ -61,7 +62,8 @@ $-fallbacks: (
61
62
 
62
63
  $config: (
63
64
  "arrow-size" : 16px,
64
- "arrow-mask-overlap" : 4px,
65
+ "arrow-box-shadow" : true,
66
+ "arrow-box-shadow-extent" : null,
65
67
  "background-color" : white,
66
68
  "border-radius" : 6px,
67
69
  "color" : inherit,
@@ -232,18 +234,79 @@ $config: (
232
234
  }
233
235
 
234
236
  @mixin -arrow-styles() {
237
+ @if get("arrow-box-shadow") {
238
+ @include -arrow-styles-with-box-shadow();
239
+ } @else {
240
+ @include -arrow-styles-simple();
241
+ }
242
+ }
243
+
244
+ // Internal mixin for original arrow styles without box-shadow
245
+ @mixin -arrow-styles-simple() {
235
246
  $prefix: selector.class("popover");
236
247
  $size: get("arrow-size");
237
248
  $half: math.div($size, 2);
249
+
250
+ #{ $prefix }__arrow {
251
+ visibility: hidden;
252
+ z-index: 1;
253
+ &,
254
+ &:before {
255
+ display: block;
256
+ position: absolute;
257
+ width: $size;
258
+ height: $size;
259
+ background: inherit;
260
+ }
261
+ &:before {
262
+ visibility: visible;
263
+ content: '';
264
+ transform: rotate(45deg);
265
+ }
266
+ [data-placement^="top"] > & {
267
+ bottom: -($half);
268
+ }
269
+ [data-placement^="bottom"] > & {
270
+ top: -($half);
271
+ }
272
+ [data-placement^="left"] > & {
273
+ right: -($half);
274
+ }
275
+ [data-placement^="right"] > & {
276
+ left: -($half);
277
+ }
278
+ }
279
+ // Account for footer and change arrow color when positioned next to it
280
+ #{ $prefix }__footer ~ #{ $prefix }__arrow {
281
+ [data-placement^="top"] > & {
282
+ &:before {
283
+ background-color: get("footer-background-color");
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ // Internal mixin for arrow styles when using the mask (extra pseudo element)
290
+ @mixin -arrow-styles-with-box-shadow() {
291
+ $prefix: selector.class("popover");
292
+ $box-shadow: get("box-shadow");
293
+ $size: get("arrow-size");
294
+ $half: math.div($size, 2);
238
295
  $size-info: utils.number-info($size);
239
296
  $unitless: map.get($size-info, "value");
240
297
  $unit: map.get($size-info, "unit");
241
298
  $hypotenuse: utils.hypotenuse($unitless, $unitless);
242
299
  $hypotenuse-half: math.div($hypotenuse, 2);
243
- $overlap: utils.strip-unit(get("arrow-mask-overlap"));
300
+ $manual-extent: get("arrow-box-shadow-extent");
301
+ $shadow-extent: if(
302
+ $manual-extent,
303
+ $manual-extent,
304
+ if(utils.is-list($box-shadow), utils.box-shadow-extent($box-shadow), 5px)
305
+ );
306
+ $overlap: utils.strip-unit($shadow-extent);
244
307
  $mask-height: utils.add-unit($hypotenuse-half + $overlap, $unit);
245
308
  $mask-width: utils.add-unit($hypotenuse + $overlap, $unit);
246
-
309
+
247
310
  #{ $prefix }__arrow {
248
311
  visibility: hidden;
249
312
  z-index: 1;