mySitio / ui / static / sass / libs / _vendor.scss
_vendor.scss
Raw
// vendor.scss v1.0 | @ajlkn | MIT licensed */

// Vars.

	/// Vendor prefixes.
	/// @var {list}
	$vendor-prefixes: (
		'-moz-',
		'-webkit-',
		'-ms-',
		''
	);

	/// Properties that should be vendorized.
	/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
	/// @var {list}
	$vendor-properties: (

		// Animation.
			'animation',
			'animation-delay',
			'animation-direction',
			'animation-duration',
			'animation-fill-mode',
			'animation-iteration-count',
			'animation-name',
			'animation-play-state',
			'animation-timing-function',

		// Appearance.
			'appearance',

		// Backdrop filter.
			'backdrop-filter',

		// Background image options.
			'background-clip',
			'background-origin',
			'background-size',

		// Box sizing.
			'box-sizing',

		// Clip path.
			'clip-path',

		// Filter effects.
			'filter',

		// Flexbox.
			'align-content',
			'align-items',
			'align-self',
			'flex',
			'flex-basis',
			'flex-direction',
			'flex-flow',
			'flex-grow',
			'flex-shrink',
			'flex-wrap',
			'justify-content',
			'order',

		// Font feature.
			'font-feature-settings',
			'font-language-override',
			'font-variant-ligatures',

		// Font kerning.
			'font-kerning',

		// Fragmented borders and backgrounds.
			'box-decoration-break',

		// Grid layout.
			'grid-column',
			'grid-column-align',
			'grid-column-end',
			'grid-column-start',
			'grid-row',
			'grid-row-align',
			'grid-row-end',
			'grid-row-start',
			'grid-template-columns',
			'grid-template-rows',

		// Hyphens.
			'hyphens',
			'word-break',

		// Masks.
			'mask',
			'mask-border',
			'mask-border-outset',
			'mask-border-repeat',
			'mask-border-slice',
			'mask-border-source',
			'mask-border-width',
			'mask-clip',
			'mask-composite',
			'mask-image',
			'mask-origin',
			'mask-position',
			'mask-repeat',
			'mask-size',

		// Multicolumn.
			'break-after',
			'break-before',
			'break-inside',
			'column-count',
			'column-fill',
			'column-gap',
			'column-rule',
			'column-rule-color',
			'column-rule-style',
			'column-rule-width',
			'column-span',
			'column-width',
			'columns',

		// Object fit.
			'object-fit',
			'object-position',

		// Regions.
			'flow-from',
			'flow-into',
			'region-fragment',

		// Scroll snap points.
			'scroll-snap-coordinate',
			'scroll-snap-destination',
			'scroll-snap-points-x',
			'scroll-snap-points-y',
			'scroll-snap-type',

		// Shapes.
			'shape-image-threshold',
			'shape-margin',
			'shape-outside',

		// Tab size.
			'tab-size',

		// Text align last.
			'text-align-last',

		// Text decoration.
			'text-decoration-color',
			'text-decoration-line',
			'text-decoration-skip',
			'text-decoration-style',

		// Text emphasis.
			'text-emphasis',
			'text-emphasis-color',
			'text-emphasis-position',
			'text-emphasis-style',

		// Text size adjust.
			'text-size-adjust',

		// Text spacing.
			'text-spacing',

		// Transform.
			'transform',
			'transform-origin',

		// Transform 3D.
			'backface-visibility',
			'perspective',
			'perspective-origin',
			'transform-style',

		// Transition.
			'transition',
			'transition-delay',
			'transition-duration',
			'transition-property',
			'transition-timing-function',

		// Unicode bidi.
			'unicode-bidi',

		// User select.
			'user-select',

		// Writing mode.
			'writing-mode',

	);

	/// Values that should be vendorized.
	/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
	/// @var {list}
	$vendor-values: (

		// Cross fade.
			'cross-fade',

		// Element function.
			'element',

		// Filter function.
			'filter',

		// Flexbox.
			'flex',
			'inline-flex',

		// Grab cursors.
			'grab',
			'grabbing',

		// Gradients.
			'linear-gradient',
			'repeating-linear-gradient',
			'radial-gradient',
			'repeating-radial-gradient',

		// Grid layout.
			'grid',
			'inline-grid',

		// Image set.
			'image-set',

		// Intrinsic width.
			'max-content',
			'min-content',
			'fit-content',
			'fill',
			'fill-available',
			'stretch',

		// Sticky position.
			'sticky',

		// Transform.
			'transform',

		// Zoom cursors.
			'zoom-in',
			'zoom-out',

	);

// Functions.

	/// Removes a specific item from a list.
	/// @author Hugo Giraudel
	/// @param {list} $list List.
	/// @param {integer} $index Index.
	/// @return {list} Updated list.
	@function remove-nth($list, $index) {

		$result: null;

		@if type-of($index) != number {
			@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
		}
		@else if $index == 0 {
			@warn "List index 0 must be a non-zero integer for `remove-nth`.";
		}
		@else if abs($index) > length($list) {
			@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
		}
		@else {

			$result: ();
			$index: if($index < 0, length($list) + $index + 1, $index);

			@for $i from 1 through length($list) {

				@if $i != $index {
					$result: append($result, nth($list, $i));
				}

			}

		}

		@return $result;

	}

	/// Replaces a substring within another string.
	/// @author Hugo Giraudel
	/// @param {string} $string String.
	/// @param {string} $search Substring.
	/// @param {string} $replace Replacement.
	/// @return {string} Updated string.
	@function str-replace($string, $search, $replace: '') {

		$index: str-index($string, $search);

		@if $index {
			@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
		}

		@return $string;

	}

	/// Replaces a substring within each string in a list.
	/// @param {list} $strings List of strings.
	/// @param {string} $search Substring.
	/// @param {string} $replace Replacement.
	/// @return {list} Updated list of strings.
	@function str-replace-all($strings, $search, $replace: '') {

		@each $string in $strings {
			$strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
		}

		@return $strings;

	}

// Mixins.

	/// Wraps @content in vendorized keyframe blocks.
	/// @param {string} $name Name.
	@mixin keyframes($name) {

		@-moz-keyframes #{$name} { @content; }
		@-webkit-keyframes #{$name} { @content; }
		@-ms-keyframes #{$name} { @content; }
		@keyframes #{$name} { @content; }

	}

	/// Vendorizes a declaration's property and/or value(s).
	/// @param {string} $property Property.
	/// @param {mixed} $value String/list of value(s).
	@mixin vendor($property, $value) {

		// Determine if property should expand.
			$expandProperty: index($vendor-properties, $property);

		// Determine if value should expand (and if so, add '-prefix-' placeholder).
			$expandValue: false;

			@each $x in $value {
				@each $y in $vendor-values {
					@if $y == str-slice($x, 1, str-length($y)) {

						$value: set-nth($value, index($value, $x), '-prefix-' + $x);
						$expandValue: true;

					}
				}
			}

		// Expand property?
			@if $expandProperty {
			    @each $vendor in $vendor-prefixes {
			        #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
			    }
			}

		// Expand just the value?
			@elseif $expandValue {
			    @each $vendor in $vendor-prefixes {
			        #{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
			    }
			}

		// Neither? Treat them as a normal declaration.
			@else {
		        #{$property}: #{$value};
			}

	}