diff --git a/dist/tagin.css b/dist/tagin.css index 5c1d98f..0d30109 100644 --- a/dist/tagin.css +++ b/dist/tagin.css @@ -11,6 +11,7 @@ flex-wrap: wrap; padding: calc(0.375rem - 2px) calc(0.75rem - 2px); } + .tagin-wrapper.focus { color: #212529; outline: 0; @@ -18,15 +19,19 @@ background-color: #fff; box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); } + .tagin.is-valid + .tagin-wrapper, .was-validated .tagin:valid + .tagin-wrapper { border-color: #198754; } + .tagin.is-valid + .tagin-wrapper.focus, .was-validated .tagin:valid + .tagin-wrapper.focus { box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); } + .tagin.is-invalid + .tagin-wrapper, .was-validated .tagin:invalid + .tagin-wrapper { border-color: #dc3545; } + .tagin.is-invalid + .tagin-wrapper.focus, .was-validated .tagin:invalid + .tagin-wrapper.focus { box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); } @@ -52,6 +57,7 @@ margin-left: 2px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E"); } + .tagin-tag-remove:hover { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E"); } @@ -65,6 +71,7 @@ border-color: transparent; border-width: 1px 0; } + .tagin-input:not(.tagin-input-hidden) { width: 4px; min-width: 4px; @@ -77,6 +84,4 @@ overflow: hidden; visibility: hidden; white-space: nowrap; -} - -/*# sourceMappingURL=tagin.css.map */ +} \ No newline at end of file diff --git a/dist/tagin.css.map b/dist/tagin.css.map deleted file mode 100644 index 94bdcb2..0000000 --- a/dist/tagin.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["../src/tagin.scss","../node_modules/bootstrap/scss/_variables.scss","../node_modules/bootstrap/scss/mixins/_border-radius.scss"],"names":[],"mappings":"AAIA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACC,OCFS;EDGT;EACA,cC60BsC;ED50BtC,kBCdS;EDmBR,YCstB6B;;ADjtB/B;EAEC,cCWQ;;ADVR;EACC;;AAGF;EAEC,cCCQ;;ADAR;EACC;;;AAKH;EE7BI;EF+BH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,kBC7CU;;;ADgDX;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;;;AAIF;EACC,OC1DU;ED2DV;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA","file":"tagin.css","sourcesContent":["@import '../node_modules/bootstrap/scss/functions';\n@import '../node_modules/bootstrap/scss/variables';\n@import '../node_modules/bootstrap/scss/mixins';\n\n.tagin {\n\tdisplay: none;\n}\n\n.tagin-wrapper {\n\tcursor : text;\n\theight : auto;\n\tdisplay : flex;\n\tposition : relative;\n\toverflow : hidden;\n\tflex-wrap : wrap;\n\tpadding : calc(#{$input-padding-y} - 2px) calc(#{$input-padding-x} - 2px);\n\n\t// copied from form-control:focus\n\t&.focus {\n\t\tcolor : $input-focus-color;\n\t\toutline : 0;\n\t\tborder-color : $input-focus-border-color;\n\t\tbackground-color : $input-focus-bg;\n\n\t\t@if $enable-shadows {\n\t\t\t@include box-shadow($input-box-shadow, $input-focus-box-shadow);\n\t\t} @else {\n\t\t\tbox-shadow: $input-focus-box-shadow;\n\t\t}\n\t}\n\n\t// validation\n\t.tagin.is-valid + &,\n\t.was-validated .tagin:valid + & {\n\t\tborder-color: $form-feedback-valid-color;\n\t\t&.focus {\n\t\t\tbox-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($form-feedback-valid-color, $input-btn-focus-color-opacity);\n\t\t}\n\t}\n\t.tagin.is-invalid + &,\n\t.was-validated .tagin:invalid + & {\n\t\tborder-color: $form-feedback-invalid-color;\n\t\t&.focus {\n\t\t\tbox-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($form-feedback-invalid-color, $input-btn-focus-color-opacity);\n\t\t}\n\t}\n}\n\n.tagin-tag {\n\t@include border-radius($input-border-radius, 0);\n\tcolor : #fff;\n\theight : 24px;\n\tmargin : 2px;\n\tborder : 0;\n\tpadding : 0 4px;\n\tdisplay : inline-flex;\n\ttransition : transform 0.1s;\n\talign-items : center;\n\tfont-weight : 300;\n\tbackground-color : $secondary;\n}\n\n.tagin-tag-remove {\n\twidth : 18px;\n\theight : 18px;\n\tcursor : pointer;\n\tmargin-left : 2px;\n\tbackground-image : url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E\");\n\n\t&:hover {\n\t\tbackground-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white' width='18px' height='18px'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z'/%3E%3C/svg%3E\");\n\t}\n}\n\n.tagin-input {\n\tcolor : $input-color;\n\theight : 28px;\n\toutline : 0;\n\tpadding : 0 2px 0 0;\n\tmargin-left : 2px;\n\tborder-color : transparent;\n\tborder-width : 1px 0;\n\n\t&:not(.tagin-input-hidden) {\n\t\twidth: 4px;\n\t\tmin-width: 4px;\n\t}\n}\n\n.tagin-input-hidden {\n\ttop : 0;\n\tleft : -9999px;\n\tposition : absolute;\n\toverflow : hidden;\n\tvisibility : hidden;\n\twhite-space : nowrap;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n// scss-docs-start gray-color-variables\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n// scss-docs-end gray-color-variables\n\n// fusv-disable\n// scss-docs-start gray-colors-map\n$grays: (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n) !default;\n// scss-docs-end gray-colors-map\n// fusv-enable\n\n// scss-docs-start color-variables\n$blue: #0d6efd !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #d63384 !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #198754 !default;\n$teal: #20c997 !default;\n$cyan: #0dcaf0 !default;\n// scss-docs-end color-variables\n\n// scss-docs-start colors-map\n$colors: (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n) !default;\n// scss-docs-end colors-map\n\n// scss-docs-start theme-color-variables\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-900 !default;\n// scss-docs-end theme-color-variables\n\n// scss-docs-start theme-colors-map\n$theme-colors: (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n) !default;\n// scss-docs-end theme-colors-map\n\n// scss-docs-start theme-colors-rgb\n$theme-colors-rgb: map-loop($theme-colors, to-rgb, \"$value\") !default;\n// scss-docs-end theme-colors-rgb\n\n// The contrast ratio to reach against white, to determine if color changes from \"light\" to \"dark\". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.\n// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast\n$min-contrast-ratio: 4.5 !default;\n\n// Customize the light and dark text colors for use in our color contrast function.\n$color-contrast-dark: $black !default;\n$color-contrast-light: $white !default;\n\n// fusv-disable\n$blue-100: tint-color($blue, 80%) !default;\n$blue-200: tint-color($blue, 60%) !default;\n$blue-300: tint-color($blue, 40%) !default;\n$blue-400: tint-color($blue, 20%) !default;\n$blue-500: $blue !default;\n$blue-600: shade-color($blue, 20%) !default;\n$blue-700: shade-color($blue, 40%) !default;\n$blue-800: shade-color($blue, 60%) !default;\n$blue-900: shade-color($blue, 80%) !default;\n\n$indigo-100: tint-color($indigo, 80%) !default;\n$indigo-200: tint-color($indigo, 60%) !default;\n$indigo-300: tint-color($indigo, 40%) !default;\n$indigo-400: tint-color($indigo, 20%) !default;\n$indigo-500: $indigo !default;\n$indigo-600: shade-color($indigo, 20%) !default;\n$indigo-700: shade-color($indigo, 40%) !default;\n$indigo-800: shade-color($indigo, 60%) !default;\n$indigo-900: shade-color($indigo, 80%) !default;\n\n$purple-100: tint-color($purple, 80%) !default;\n$purple-200: tint-color($purple, 60%) !default;\n$purple-300: tint-color($purple, 40%) !default;\n$purple-400: tint-color($purple, 20%) !default;\n$purple-500: $purple !default;\n$purple-600: shade-color($purple, 20%) !default;\n$purple-700: shade-color($purple, 40%) !default;\n$purple-800: shade-color($purple, 60%) !default;\n$purple-900: shade-color($purple, 80%) !default;\n\n$pink-100: tint-color($pink, 80%) !default;\n$pink-200: tint-color($pink, 60%) !default;\n$pink-300: tint-color($pink, 40%) !default;\n$pink-400: tint-color($pink, 20%) !default;\n$pink-500: $pink !default;\n$pink-600: shade-color($pink, 20%) !default;\n$pink-700: shade-color($pink, 40%) !default;\n$pink-800: shade-color($pink, 60%) !default;\n$pink-900: shade-color($pink, 80%) !default;\n\n$red-100: tint-color($red, 80%) !default;\n$red-200: tint-color($red, 60%) !default;\n$red-300: tint-color($red, 40%) !default;\n$red-400: tint-color($red, 20%) !default;\n$red-500: $red !default;\n$red-600: shade-color($red, 20%) !default;\n$red-700: shade-color($red, 40%) !default;\n$red-800: shade-color($red, 60%) !default;\n$red-900: shade-color($red, 80%) !default;\n\n$orange-100: tint-color($orange, 80%) !default;\n$orange-200: tint-color($orange, 60%) !default;\n$orange-300: tint-color($orange, 40%) !default;\n$orange-400: tint-color($orange, 20%) !default;\n$orange-500: $orange !default;\n$orange-600: shade-color($orange, 20%) !default;\n$orange-700: shade-color($orange, 40%) !default;\n$orange-800: shade-color($orange, 60%) !default;\n$orange-900: shade-color($orange, 80%) !default;\n\n$yellow-100: tint-color($yellow, 80%) !default;\n$yellow-200: tint-color($yellow, 60%) !default;\n$yellow-300: tint-color($yellow, 40%) !default;\n$yellow-400: tint-color($yellow, 20%) !default;\n$yellow-500: $yellow !default;\n$yellow-600: shade-color($yellow, 20%) !default;\n$yellow-700: shade-color($yellow, 40%) !default;\n$yellow-800: shade-color($yellow, 60%) !default;\n$yellow-900: shade-color($yellow, 80%) !default;\n\n$green-100: tint-color($green, 80%) !default;\n$green-200: tint-color($green, 60%) !default;\n$green-300: tint-color($green, 40%) !default;\n$green-400: tint-color($green, 20%) !default;\n$green-500: $green !default;\n$green-600: shade-color($green, 20%) !default;\n$green-700: shade-color($green, 40%) !default;\n$green-800: shade-color($green, 60%) !default;\n$green-900: shade-color($green, 80%) !default;\n\n$teal-100: tint-color($teal, 80%) !default;\n$teal-200: tint-color($teal, 60%) !default;\n$teal-300: tint-color($teal, 40%) !default;\n$teal-400: tint-color($teal, 20%) !default;\n$teal-500: $teal !default;\n$teal-600: shade-color($teal, 20%) !default;\n$teal-700: shade-color($teal, 40%) !default;\n$teal-800: shade-color($teal, 60%) !default;\n$teal-900: shade-color($teal, 80%) !default;\n\n$cyan-100: tint-color($cyan, 80%) !default;\n$cyan-200: tint-color($cyan, 60%) !default;\n$cyan-300: tint-color($cyan, 40%) !default;\n$cyan-400: tint-color($cyan, 20%) !default;\n$cyan-500: $cyan !default;\n$cyan-600: shade-color($cyan, 20%) !default;\n$cyan-700: shade-color($cyan, 40%) !default;\n$cyan-800: shade-color($cyan, 60%) !default;\n$cyan-900: shade-color($cyan, 80%) !default;\n\n$blues: (\n \"blue-100\": $blue-100,\n \"blue-200\": $blue-200,\n \"blue-300\": $blue-300,\n \"blue-400\": $blue-400,\n \"blue-500\": $blue-500,\n \"blue-600\": $blue-600,\n \"blue-700\": $blue-700,\n \"blue-800\": $blue-800,\n \"blue-900\": $blue-900\n) !default;\n\n$indigos: (\n \"indigo-100\": $indigo-100,\n \"indigo-200\": $indigo-200,\n \"indigo-300\": $indigo-300,\n \"indigo-400\": $indigo-400,\n \"indigo-500\": $indigo-500,\n \"indigo-600\": $indigo-600,\n \"indigo-700\": $indigo-700,\n \"indigo-800\": $indigo-800,\n \"indigo-900\": $indigo-900\n) !default;\n\n$purples: (\n \"purple-100\": $purple-200,\n \"purple-200\": $purple-100,\n \"purple-300\": $purple-300,\n \"purple-400\": $purple-400,\n \"purple-500\": $purple-500,\n \"purple-600\": $purple-600,\n \"purple-700\": $purple-700,\n \"purple-800\": $purple-800,\n \"purple-900\": $purple-900\n) !default;\n\n$pinks: (\n \"pink-100\": $pink-100,\n \"pink-200\": $pink-200,\n \"pink-300\": $pink-300,\n \"pink-400\": $pink-400,\n \"pink-500\": $pink-500,\n \"pink-600\": $pink-600,\n \"pink-700\": $pink-700,\n \"pink-800\": $pink-800,\n \"pink-900\": $pink-900\n) !default;\n\n$reds: (\n \"red-100\": $red-100,\n \"red-200\": $red-200,\n \"red-300\": $red-300,\n \"red-400\": $red-400,\n \"red-500\": $red-500,\n \"red-600\": $red-600,\n \"red-700\": $red-700,\n \"red-800\": $red-800,\n \"red-900\": $red-900\n) !default;\n\n$oranges: (\n \"orange-100\": $orange-100,\n \"orange-200\": $orange-200,\n \"orange-300\": $orange-300,\n \"orange-400\": $orange-400,\n \"orange-500\": $orange-500,\n \"orange-600\": $orange-600,\n \"orange-700\": $orange-700,\n \"orange-800\": $orange-800,\n \"orange-900\": $orange-900\n) !default;\n\n$yellows: (\n \"yellow-100\": $yellow-100,\n \"yellow-200\": $yellow-200,\n \"yellow-300\": $yellow-300,\n \"yellow-400\": $yellow-400,\n \"yellow-500\": $yellow-500,\n \"yellow-600\": $yellow-600,\n \"yellow-700\": $yellow-700,\n \"yellow-800\": $yellow-800,\n \"yellow-900\": $yellow-900\n) !default;\n\n$greens: (\n \"green-100\": $green-100,\n \"green-200\": $green-200,\n \"green-300\": $green-300,\n \"green-400\": $green-400,\n \"green-500\": $green-500,\n \"green-600\": $green-600,\n \"green-700\": $green-700,\n \"green-800\": $green-800,\n \"green-900\": $green-900\n) !default;\n\n$teals: (\n \"teal-100\": $teal-100,\n \"teal-200\": $teal-200,\n \"teal-300\": $teal-300,\n \"teal-400\": $teal-400,\n \"teal-500\": $teal-500,\n \"teal-600\": $teal-600,\n \"teal-700\": $teal-700,\n \"teal-800\": $teal-800,\n \"teal-900\": $teal-900\n) !default;\n\n$cyans: (\n \"cyan-100\": $cyan-100,\n \"cyan-200\": $cyan-200,\n \"cyan-300\": $cyan-300,\n \"cyan-400\": $cyan-400,\n \"cyan-500\": $cyan-500,\n \"cyan-600\": $cyan-600,\n \"cyan-700\": $cyan-700,\n \"cyan-800\": $cyan-800,\n \"cyan-900\": $cyan-900\n) !default;\n// fusv-enable\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-reduced-motion: true !default;\n$enable-smooth-scroll: true !default;\n$enable-grid-classes: true !default;\n$enable-cssgrid: false !default;\n$enable-button-pointers: true !default;\n$enable-rfs: true !default;\n$enable-validation-icons: true !default;\n$enable-negative-margins: false !default;\n$enable-deprecation-messages: true !default;\n$enable-important-utilities: true !default;\n\n// Prefix for :root CSS variables\n\n$variable-prefix: bs- !default;\n\n// Gradient\n//\n// The gradient which is added to components if `$enable-gradients` is `true`\n// This gradient is also added to elements with `.bg-gradient`\n// scss-docs-start variable-gradient\n$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;\n// scss-docs-end variable-gradient\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n// scss-docs-start spacer-variables-maps\n$spacer: 1rem !default;\n$spacers: (\n 0: 0,\n 1: $spacer * .25,\n 2: $spacer * .5,\n 3: $spacer,\n 4: $spacer * 1.5,\n 5: $spacer * 3,\n) !default;\n\n$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;\n// scss-docs-end spacer-variables-maps\n\n// Position\n//\n// Define the edge positioning anchors of the position utilities.\n\n// scss-docs-start position-map\n$position-values: (\n 0: 0,\n 50: 50%,\n 100: 100%\n) !default;\n// scss-docs-end position-map\n\n// Body\n//\n// Settings for the `` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n$body-text-align: null !default;\n\n// Utilities maps\n//\n// Extends the default `$theme-colors` maps to help create our utilities.\n\n// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign.\n// scss-docs-start utilities-colors\n$utilities-colors: $theme-colors-rgb !default;\n// scss-docs-end utilities-colors\n\n// scss-docs-start utilities-text-colors\n$utilities-text: map-merge(\n $utilities-colors,\n (\n \"black\": to-rgb($black),\n \"white\": to-rgb($white),\n \"body\": to-rgb($body-color)\n )\n) !default;\n$utilities-text-colors: map-loop($utilities-text, rgba-css-var, \"$key\", \"text\") !default;\n// scss-docs-end utilities-text-colors\n\n// scss-docs-start utilities-bg-colors\n$utilities-bg: map-merge(\n $utilities-colors,\n (\n \"black\": to-rgb($black),\n \"white\": to-rgb($white),\n \"body\": to-rgb($body-bg)\n )\n) !default;\n$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, \"$key\", \"bg\") !default;\n// scss-docs-end utilities-bg-colors\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: $primary !default;\n$link-decoration: underline !default;\n$link-shade-percentage: 20% !default;\n$link-hover-color: shift-color($link-color, $link-shade-percentage) !default;\n$link-hover-decoration: null !default;\n\n$stretched-link-pseudo-element: after !default;\n$stretched-link-z-index: 1 !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n// scss-docs-start grid-breakpoints\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px,\n xxl: 1400px\n) !default;\n// scss-docs-end grid-breakpoints\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n// scss-docs-start container-max-widths\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px,\n xxl: 1320px\n) !default;\n// scss-docs-end container-max-widths\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 1.5rem !default;\n$grid-row-columns: 6 !default;\n\n$gutters: $spacers !default;\n\n// Container padding\n\n$container-padding-x: $grid-gutter-width * .5 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n// scss-docs-start border-variables\n$border-width: 1px !default;\n$border-widths: (\n 1: 1px,\n 2: 2px,\n 3: 3px,\n 4: 4px,\n 5: 5px\n) !default;\n\n$border-color: $gray-300 !default;\n// scss-docs-end border-variables\n\n// scss-docs-start border-radius-variables\n$border-radius: .25rem !default;\n$border-radius-sm: .2rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-pill: 50rem !default;\n// scss-docs-end border-radius-variables\n\n// scss-docs-start box-shadow-variables\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default;\n// scss-docs-end box-shadow-variables\n\n$component-active-color: $white !default;\n$component-active-bg: $primary !default;\n\n// scss-docs-start caret-variables\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n// scss-docs-end caret-variables\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n// scss-docs-start collapse-transition\n$transition-collapse: height .35s ease !default;\n$transition-collapse-width: width .35s ease !default;\n// scss-docs-end collapse-transition\n\n// stylelint-disable function-disallowed-list\n// scss-docs-start aspect-ratios\n$aspect-ratios: (\n \"1x1\": 100%,\n \"4x3\": calc(3 / 4 * 100%),\n \"16x9\": calc(9 / 16 * 100%),\n \"21x9\": calc(9 / 21 * 100%)\n) !default;\n// scss-docs-end aspect-ratios\n// stylelint-enable function-disallowed-list\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// scss-docs-start font-variables\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n// stylelint-enable value-keyword-case\n$font-family-base: var(--#{$variable-prefix}font-sans-serif) !default;\n$font-family-code: var(--#{$variable-prefix}font-monospace) !default;\n\n// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins\n// $font-size-base affects the font size of the body text\n$font-size-root: null !default;\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-sm: $font-size-base * .875 !default;\n$font-size-lg: $font-size-base * 1.25 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n\n$line-height-base: 1.5 !default;\n$line-height-sm: 1.25 !default;\n$line-height-lg: 2 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n// scss-docs-end font-variables\n\n// scss-docs-start font-sizes\n$font-sizes: (\n 1: $h1-font-size,\n 2: $h2-font-size,\n 3: $h3-font-size,\n 4: $h4-font-size,\n 5: $h5-font-size,\n 6: $h6-font-size\n) !default;\n// scss-docs-end font-sizes\n\n// scss-docs-start headings-variables\n$headings-margin-bottom: $spacer * .5 !default;\n$headings-font-family: null !default;\n$headings-font-style: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n// scss-docs-end headings-variables\n\n// scss-docs-start display-headings\n$display-font-sizes: (\n 1: 5rem,\n 2: 4.5rem,\n 3: 4rem,\n 4: 3.5rem,\n 5: 3rem,\n 6: 2.5rem\n) !default;\n\n$display-font-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n// scss-docs-end display-headings\n\n// scss-docs-start type-variables\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: .875em !default;\n\n$sub-sup-font-size: .75em !default;\n\n$text-muted: $gray-600 !default;\n\n$initialism-font-size: $small-font-size !default;\n\n$blockquote-margin-y: $spacer !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n$blockquote-footer-color: $gray-600 !default;\n$blockquote-footer-font-size: $small-font-size !default;\n\n$hr-margin-y: $spacer !default;\n$hr-color: inherit !default;\n$hr-height: $border-width !default;\n$hr-opacity: .25 !default;\n\n$legend-margin-bottom: .5rem !default;\n$legend-font-size: 1.5rem !default;\n$legend-font-weight: null !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n// scss-docs-end type-variables\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n// scss-docs-start table-variables\n$table-cell-padding-y: .5rem !default;\n$table-cell-padding-x: .5rem !default;\n$table-cell-padding-y-sm: .25rem !default;\n$table-cell-padding-x-sm: .25rem !default;\n\n$table-cell-vertical-align: top !default;\n\n$table-color: $body-color !default;\n$table-bg: transparent !default;\n$table-accent-bg: transparent !default;\n\n$table-th-font-weight: null !default;\n\n$table-striped-color: $table-color !default;\n$table-striped-bg-factor: .05 !default;\n$table-striped-bg: rgba($black, $table-striped-bg-factor) !default;\n\n$table-active-color: $table-color !default;\n$table-active-bg-factor: .1 !default;\n$table-active-bg: rgba($black, $table-active-bg-factor) !default;\n\n$table-hover-color: $table-color !default;\n$table-hover-bg-factor: .075 !default;\n$table-hover-bg: rgba($black, $table-hover-bg-factor) !default;\n\n$table-border-factor: .1 !default;\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-striped-order: odd !default;\n\n$table-group-separator-color: currentColor !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-scale: -80% !default;\n// scss-docs-end table-variables\n\n// scss-docs-start table-loop\n$table-variants: (\n \"primary\": shift-color($primary, $table-bg-scale),\n \"secondary\": shift-color($secondary, $table-bg-scale),\n \"success\": shift-color($success, $table-bg-scale),\n \"info\": shift-color($info, $table-bg-scale),\n \"warning\": shift-color($warning, $table-bg-scale),\n \"danger\": shift-color($danger, $table-bg-scale),\n \"light\": $light,\n \"dark\": $dark,\n) !default;\n// scss-docs-end table-loop\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n// scss-docs-start input-btn-variables\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .25rem !default;\n$input-btn-focus-color-opacity: .25 !default;\n$input-btn-focus-color: rgba($component-active-bg, $input-btn-focus-color-opacity) !default;\n$input-btn-focus-blur: 0 !default;\n$input-btn-focus-box-shadow: 0 0 $input-btn-focus-blur $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n\n$input-btn-border-width: $border-width !default;\n// scss-docs-end input-btn-variables\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n// scss-docs-start btn-variables\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-color: $link-color !default;\n$btn-link-hover-color: $link-hover-color !default;\n$btn-link-disabled-color: $gray-600 !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$btn-hover-bg-shade-amount: 15% !default;\n$btn-hover-bg-tint-amount: 15% !default;\n$btn-hover-border-shade-amount: 20% !default;\n$btn-hover-border-tint-amount: 10% !default;\n$btn-active-bg-shade-amount: 20% !default;\n$btn-active-bg-tint-amount: 20% !default;\n$btn-active-border-shade-amount: 25% !default;\n$btn-active-border-tint-amount: 10% !default;\n// scss-docs-end btn-variables\n\n\n// Forms\n\n// scss-docs-start form-text-variables\n$form-text-margin-top: .25rem !default;\n$form-text-font-size: $small-font-size !default;\n$form-text-font-style: null !default;\n$form-text-font-weight: null !default;\n$form-text-color: $text-muted !default;\n// scss-docs-end form-text-variables\n\n// scss-docs-start form-label-variables\n$form-label-margin-bottom: .5rem !default;\n$form-label-font-size: null !default;\n$form-label-font-style: null !default;\n$form-label-font-weight: null !default;\n$form-label-color: null !default;\n// scss-docs-end form-label-variables\n\n// scss-docs-start form-input-variables\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n\n$input-bg: $body-bg !default;\n$input-disabled-bg: $gray-200 !default;\n$input-disabled-border-color: null !default;\n\n$input-color: $body-color !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: $box-shadow-inset !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-sm: $border-radius-sm !default;\n$input-border-radius-lg: $border-radius-lg !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: tint-color($component-active-bg, 50%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-color-width: 3rem !default;\n// scss-docs-end form-input-variables\n\n// scss-docs-start form-check-variables\n$form-check-input-width: 1em !default;\n$form-check-min-height: $font-size-base * $line-height-base !default;\n$form-check-padding-start: $form-check-input-width + .5em !default;\n$form-check-margin-bottom: .125rem !default;\n$form-check-label-color: null !default;\n$form-check-label-cursor: null !default;\n$form-check-transition: null !default;\n\n$form-check-input-active-filter: brightness(90%) !default;\n\n$form-check-input-bg: $input-bg !default;\n$form-check-input-border: 1px solid rgba($black, .25) !default;\n$form-check-input-border-radius: .25em !default;\n$form-check-radio-border-radius: 50% !default;\n$form-check-input-focus-border: $input-focus-border-color !default;\n$form-check-input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$form-check-input-checked-color: $component-active-color !default;\n$form-check-input-checked-bg-color: $component-active-bg !default;\n$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default;\n$form-check-input-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-check-radio-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-indeterminate-color: $component-active-color !default;\n$form-check-input-indeterminate-bg-color: $component-active-bg !default;\n$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default;\n$form-check-input-indeterminate-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-disabled-opacity: .5 !default;\n$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default;\n$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default;\n\n$form-check-inline-margin-end: 1rem !default;\n// scss-docs-end form-check-variables\n\n// scss-docs-start form-switch-variables\n$form-switch-color: rgba($black, .25) !default;\n$form-switch-width: 2em !default;\n$form-switch-padding-start: $form-switch-width + .5em !default;\n$form-switch-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-border-radius: $form-switch-width !default;\n$form-switch-transition: background-position .15s ease-in-out !default;\n\n$form-switch-focus-color: $input-focus-border-color !default;\n$form-switch-focus-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-switch-checked-color: $component-active-color !default;\n$form-switch-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-checked-bg-position: right center !default;\n// scss-docs-end form-switch-variables\n\n// scss-docs-start input-group-variables\n$input-group-addon-padding-y: $input-padding-y !default;\n$input-group-addon-padding-x: $input-padding-x !default;\n$input-group-addon-font-weight: $input-font-weight !default;\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n// scss-docs-end input-group-variables\n\n// scss-docs-start form-select-variables\n$form-select-padding-y: $input-padding-y !default;\n$form-select-padding-x: $input-padding-x !default;\n$form-select-font-family: $input-font-family !default;\n$form-select-font-size: $input-font-size !default;\n$form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image\n$form-select-font-weight: $input-font-weight !default;\n$form-select-line-height: $input-line-height !default;\n$form-select-color: $input-color !default;\n$form-select-bg: $input-bg !default;\n$form-select-disabled-color: null !default;\n$form-select-disabled-bg: $gray-200 !default;\n$form-select-disabled-border-color: $input-disabled-border-color !default;\n$form-select-bg-position: right $form-select-padding-x center !default;\n$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions\n$form-select-indicator-color: $gray-800 !default;\n$form-select-indicator: url(\"data:image/svg+xml,\") !default;\n\n$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;\n$form-select-feedback-icon-position: center right $form-select-indicator-padding !default;\n$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$form-select-border-width: $input-border-width !default;\n$form-select-border-color: $input-border-color !default;\n$form-select-border-radius: $input-border-radius !default;\n$form-select-box-shadow: $box-shadow-inset !default;\n\n$form-select-focus-border-color: $input-focus-border-color !default;\n$form-select-focus-width: $input-focus-width !default;\n$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;\n\n$form-select-padding-y-sm: $input-padding-y-sm !default;\n$form-select-padding-x-sm: $input-padding-x-sm !default;\n$form-select-font-size-sm: $input-font-size-sm !default;\n$form-select-border-radius-sm: $input-border-radius-sm !default;\n\n$form-select-padding-y-lg: $input-padding-y-lg !default;\n$form-select-padding-x-lg: $input-padding-x-lg !default;\n$form-select-font-size-lg: $input-font-size-lg !default;\n$form-select-border-radius-lg: $input-border-radius-lg !default;\n\n$form-select-transition: $input-transition !default;\n// scss-docs-end form-select-variables\n\n// scss-docs-start form-range-variables\n$form-range-track-width: 100% !default;\n$form-range-track-height: .5rem !default;\n$form-range-track-cursor: pointer !default;\n$form-range-track-bg: $gray-300 !default;\n$form-range-track-border-radius: 1rem !default;\n$form-range-track-box-shadow: $box-shadow-inset !default;\n\n$form-range-thumb-width: 1rem !default;\n$form-range-thumb-height: $form-range-thumb-width !default;\n$form-range-thumb-bg: $component-active-bg !default;\n$form-range-thumb-border: 0 !default;\n$form-range-thumb-border-radius: 1rem !default;\n$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge\n$form-range-thumb-active-bg: tint-color($component-active-bg, 70%) !default;\n$form-range-thumb-disabled-bg: $gray-500 !default;\n$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n// scss-docs-end form-range-variables\n\n// scss-docs-start form-file-variables\n$form-file-button-color: $input-color !default;\n$form-file-button-bg: $input-group-addon-bg !default;\n$form-file-button-hover-bg: shade-color($form-file-button-bg, 5%) !default;\n// scss-docs-end form-file-variables\n\n// scss-docs-start form-floating-variables\n$form-floating-height: add(3.5rem, $input-height-border) !default;\n$form-floating-line-height: 1.25 !default;\n$form-floating-padding-x: $input-padding-x !default;\n$form-floating-padding-y: 1rem !default;\n$form-floating-input-padding-t: 1.625rem !default;\n$form-floating-input-padding-b: .625rem !default;\n$form-floating-label-opacity: .65 !default;\n$form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default;\n$form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default;\n// scss-docs-end form-floating-variables\n\n// Form validation\n\n// scss-docs-start form-feedback-variables\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $form-text-font-size !default;\n$form-feedback-font-style: $form-text-font-style !default;\n$form-feedback-valid-color: $success !default;\n$form-feedback-invalid-color: $danger !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end form-feedback-variables\n\n// scss-docs-start form-validation-states\n$form-validation-states: (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n )\n) !default;\n// scss-docs-end form-validation-states\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n// scss-docs-start zindex-stack\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-offcanvas-backdrop: 1040 !default;\n$zindex-offcanvas: 1045 !default;\n$zindex-modal-backdrop: 1050 !default;\n$zindex-modal: 1055 !default;\n$zindex-popover: 1070 !default;\n$zindex-tooltip: 1080 !default;\n// scss-docs-end zindex-stack\n\n\n// Navs\n\n// scss-docs-start nav-variables\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-font-size: null !default;\n$nav-link-font-weight: null !default;\n$nav-link-color: $link-color !default;\n$nav-link-hover-color: $link-hover-color !default;\n$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n// scss-docs-end nav-variables\n\n\n// Navbar\n\n// scss-docs-start navbar-variables\n$navbar-padding-y: $spacer * .5 !default;\n$navbar-padding-x: null !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default;\n$navbar-brand-margin-end: 1rem !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n$navbar-toggler-focus-width: $btn-focus-width !default;\n$navbar-toggler-transition: box-shadow .15s ease-in-out !default;\n// scss-docs-end navbar-variables\n\n// scss-docs-start navbar-theme-variables\n$navbar-dark-color: rgba($white, .55) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .55) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n// scss-docs-end navbar-theme-variables\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n// scss-docs-start dropdown-variables\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $dropdown-border-color !default;\n$dropdown-divider-margin-y: $spacer * .5 !default;\n$dropdown-box-shadow: $box-shadow !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: shade-color($dropdown-link-color, 10%) !default;\n$dropdown-link-hover-bg: $gray-200 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-500 !default;\n\n$dropdown-item-padding-y: $spacer * .25 !default;\n$dropdown-item-padding-x: $spacer !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n// scss-docs-end dropdown-variables\n\n// scss-docs-start dropdown-dark-variables\n$dropdown-dark-color: $gray-300 !default;\n$dropdown-dark-bg: $gray-800 !default;\n$dropdown-dark-border-color: $dropdown-border-color !default;\n$dropdown-dark-divider-bg: $dropdown-divider-bg !default;\n$dropdown-dark-box-shadow: null !default;\n$dropdown-dark-link-color: $dropdown-dark-color !default;\n$dropdown-dark-link-hover-color: $white !default;\n$dropdown-dark-link-hover-bg: rgba($white, .15) !default;\n$dropdown-dark-link-active-color: $dropdown-link-active-color !default;\n$dropdown-dark-link-active-bg: $dropdown-link-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-500 !default;\n$dropdown-dark-header-color: $gray-500 !default;\n// scss-docs-end dropdown-dark-variables\n\n\n// Pagination\n\n// scss-docs-start pagination-variables\n$pagination-padding-y: .375rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-radius: $border-radius !default;\n$pagination-margin-start: -$pagination-border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-color: $link-hover-color !default;\n$pagination-focus-bg: $gray-200 !default;\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n$pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$pagination-border-radius-sm: $border-radius-sm !default;\n$pagination-border-radius-lg: $border-radius-lg !default;\n// scss-docs-end pagination-variables\n\n\n// Placeholders\n\n// scss-docs-start placeholders\n$placeholder-opacity-max: .5 !default;\n$placeholder-opacity-min: .2 !default;\n// scss-docs-end placeholders\n\n// Cards\n\n// scss-docs-start card-variables\n$card-spacer-y: $spacer !default;\n$card-spacer-x: $spacer !default;\n$card-title-spacer-y: $spacer * .5 !default;\n$card-border-width: $border-width !default;\n$card-border-color: rgba($black, .125) !default;\n$card-border-radius: $border-radius !default;\n$card-box-shadow: null !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-padding-y: $card-spacer-y * .5 !default;\n$card-cap-padding-x: $card-spacer-x !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n$card-img-overlay-padding: $spacer !default;\n$card-group-margin: $grid-gutter-width * .5 !default;\n// scss-docs-end card-variables\n\n// Accordion\n\n// scss-docs-start accordion-variables\n$accordion-padding-y: 1rem !default;\n$accordion-padding-x: 1.25rem !default;\n$accordion-color: $body-color !default;\n$accordion-bg: $body-bg !default;\n$accordion-border-width: $border-width !default;\n$accordion-border-color: rgba($black, .125) !default;\n$accordion-border-radius: $border-radius !default;\n$accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default;\n\n$accordion-body-padding-y: $accordion-padding-y !default;\n$accordion-body-padding-x: $accordion-padding-x !default;\n\n$accordion-button-padding-y: $accordion-padding-y !default;\n$accordion-button-padding-x: $accordion-padding-x !default;\n$accordion-button-color: $accordion-color !default;\n$accordion-button-bg: $accordion-bg !default;\n$accordion-transition: $btn-transition, border-radius .15s ease !default;\n$accordion-button-active-bg: tint-color($component-active-bg, 90%) !default;\n$accordion-button-active-color: shade-color($primary, 10%) !default;\n\n$accordion-button-focus-border-color: $input-focus-border-color !default;\n$accordion-button-focus-box-shadow: $btn-focus-box-shadow !default;\n\n$accordion-icon-width: 1.25rem !default;\n$accordion-icon-color: $accordion-button-color !default;\n$accordion-icon-active-color: $accordion-button-active-color !default;\n$accordion-icon-transition: transform .2s ease-in-out !default;\n$accordion-icon-transform: rotate(-180deg) !default;\n\n$accordion-button-icon: url(\"data:image/svg+xml,\") !default;\n$accordion-button-active-icon: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end accordion-variables\n\n// Tooltips\n\n// scss-docs-start tooltip-variables\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: $spacer * .25 !default;\n$tooltip-padding-x: $spacer * .5 !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n// scss-docs-end tooltip-variables\n\n// Form tooltips must come after regular tooltips\n// scss-docs-start tooltip-feedback-variables\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: null !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n// scss-docs-end tooltip-feedback-variables\n\n\n// Popovers\n\n// scss-docs-start popover-variables\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: $box-shadow !default;\n\n$popover-header-bg: shade-color($popover-bg, 6%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: $spacer !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $spacer !default;\n$popover-body-padding-x: $spacer !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n// scss-docs-end popover-variables\n\n\n// Toasts\n\n// scss-docs-start toast-variables\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .5rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba($black, .1) !default;\n$toast-border-radius: $border-radius !default;\n$toast-box-shadow: $box-shadow !default;\n$toast-spacing: $container-padding-x !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba($black, .05) !default;\n// scss-docs-end toast-variables\n\n\n// Badges\n\n// scss-docs-start badge-variables\n$badge-font-size: .75em !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-color: $white !default;\n$badge-padding-y: .35em !default;\n$badge-padding-x: .65em !default;\n$badge-border-radius: $border-radius !default;\n// scss-docs-end badge-variables\n\n\n// Modals\n\n// scss-docs-start modal-variables\n$modal-inner-padding: $spacer !default;\n\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: $box-shadow-sm !default;\n$modal-content-box-shadow-sm-up: $box-shadow !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: $modal-inner-padding !default;\n$modal-header-padding-x: $modal-inner-padding !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-sm: 300px !default;\n$modal-md: 500px !default;\n$modal-lg: 800px !default;\n$modal-xl: 1140px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n// scss-docs-end modal-variables\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n// scss-docs-start alert-variables\n$alert-padding-y: $spacer !default;\n$alert-padding-x: $spacer !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n$alert-bg-scale: -80% !default;\n$alert-border-scale: -70% !default;\n$alert-color-scale: 40% !default;\n$alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side\n// scss-docs-end alert-variables\n\n\n// Progress bars\n\n// scss-docs-start progress-variables\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: $box-shadow-inset !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: $primary !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n// scss-docs-end progress-variables\n\n\n// List group\n\n// scss-docs-start list-group-variables\n$list-group-color: $gray-900 !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: $spacer * .5 !default;\n$list-group-item-padding-x: $spacer !default;\n$list-group-item-bg-scale: -80% !default;\n$list-group-item-color-scale: 40% !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n// scss-docs-end list-group-variables\n\n\n// Image thumbnails\n\n// scss-docs-start thumbnail-variables\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: $box-shadow-sm !default;\n// scss-docs-end thumbnail-variables\n\n\n// Figures\n\n// scss-docs-start figure-variables\n$figure-caption-font-size: $small-font-size !default;\n$figure-caption-color: $gray-600 !default;\n// scss-docs-end figure-variables\n\n\n// Breadcrumbs\n\n// scss-docs-start breadcrumb-variables\n$breadcrumb-font-size: null !default;\n$breadcrumb-padding-y: 0 !default;\n$breadcrumb-padding-x: 0 !default;\n$breadcrumb-item-padding-x: .5rem !default;\n$breadcrumb-margin-bottom: 1rem !default;\n$breadcrumb-bg: null !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n$breadcrumb-divider-flipped: $breadcrumb-divider !default;\n$breadcrumb-border-radius: null !default;\n// scss-docs-end breadcrumb-variables\n\n// Carousel\n\n// scss-docs-start carousel-variables\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-opacity: .5 !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-active-opacity: 1 !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n$carousel-caption-padding-y: 1.25rem !default;\n$carousel-caption-spacer: 1.25rem !default;\n\n$carousel-control-icon-width: 2rem !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n$carousel-dark-indicator-active-bg: $black !default;\n$carousel-dark-caption-color: $black !default;\n$carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;\n// scss-docs-end carousel-variables\n\n\n// Spinners\n\n// scss-docs-start spinner-variables\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-vertical-align: -.125em !default;\n$spinner-border-width: .25em !default;\n$spinner-animation-speed: .75s !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n// scss-docs-end spinner-variables\n\n\n// Close\n\n// scss-docs-start close-variables\n$btn-close-width: 1em !default;\n$btn-close-height: $btn-close-width !default;\n$btn-close-padding-x: .25em !default;\n$btn-close-padding-y: $btn-close-padding-x !default;\n$btn-close-color: $black !default;\n$btn-close-bg: url(\"data:image/svg+xml,\") !default;\n$btn-close-focus-shadow: $input-btn-focus-box-shadow !default;\n$btn-close-opacity: .5 !default;\n$btn-close-hover-opacity: .75 !default;\n$btn-close-focus-opacity: 1 !default;\n$btn-close-disabled-opacity: .25 !default;\n$btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default;\n// scss-docs-end close-variables\n\n\n// Offcanvas\n\n// scss-docs-start offcanvas-variables\n$offcanvas-padding-y: $modal-inner-padding !default;\n$offcanvas-padding-x: $modal-inner-padding !default;\n$offcanvas-horizontal-width: 400px !default;\n$offcanvas-vertical-height: 30vh !default;\n$offcanvas-transition-duration: .3s !default;\n$offcanvas-border-color: $modal-content-border-color !default;\n$offcanvas-border-width: $modal-content-border-width !default;\n$offcanvas-title-line-height: $modal-title-line-height !default;\n$offcanvas-bg-color: $modal-content-bg !default;\n$offcanvas-color: $modal-content-color !default;\n$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;\n$offcanvas-backdrop-bg: $modal-backdrop-bg !default;\n$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;\n// scss-docs-end offcanvas-variables\n\n// Code\n\n$code-font-size: $small-font-size !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: null !default;\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n// scss-docs-start border-radius-mixins\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-end-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-start-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-start-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-end-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-end-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-start-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n// scss-docs-end border-radius-mixins\n"]} \ No newline at end of file diff --git a/dist/tagin.d.ts b/dist/tagin.d.ts index 733cfc3..8537c03 100644 --- a/dist/tagin.d.ts +++ b/dist/tagin.d.ts @@ -1,3 +1,4 @@ +import './tagin.scss'; declare class Tagin { private classElement; private classWrapper; diff --git a/dist/tagin.js b/dist/tagin.js index a9d1315..8828042 100644 --- a/dist/tagin.js +++ b/dist/tagin.js @@ -1,165 +1,160 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; +var __publicField = (obj, key, value2) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2); + return value2; +}; /*! * Tagin v2.0.2 (https://tagin.netlify.app/) -* Copyright 2020-2021 Erwin Heldy G +* Copyright 2020-2022 Erwin Heldy G * Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tagin = factory()); -})(this, (function () { 'use strict'; - - class Tagin { - classElement = 'tagin'; - classWrapper = 'tagin-wrapper'; - classTag = 'tagin-tag'; - classRemove = 'tagin-tag-remove'; - classInput = 'tagin-input'; - classInputHidden = 'tagin-input-hidden'; - target; - wrapper; - input; - separator; - placeholder; - duplicate; - transform; - enter; - constructor(inputElement, options) { - this.target = inputElement; - this.separator = options?.separator || inputElement.dataset.taginSeparator || ','; - this.placeholder = options?.placeholder || inputElement.dataset.taginPlaceholder || ''; - this.duplicate = options?.duplicate || inputElement.dataset.taginDuplicate !== undefined; - this.transform = options?.transform || inputElement.dataset.taginTransform || 'input => input'; - this.enter = options?.enter || inputElement.dataset.taginEnter !== undefined; - this.createWrapper(); - this.autowidth(); - this.addEventListener(); - } - createWrapper() { - const tags = this.getValue() === '' ? '' : this.getValues().map(val => this.createTag(val)).join(''); - const input = document.createElement('input'); - input.type = 'text'; - input.className = this.classInput; - input.placeholder = this.placeholder; - const wrapper = document.createElement('div'); - wrapper.className = `${this.classWrapper} ${this.target.className}`; - wrapper.classList.remove(this.classElement); - wrapper.insertAdjacentHTML('afterbegin', tags); - wrapper.insertAdjacentElement('beforeend', input); - this.target.insertAdjacentElement('afterend', wrapper); // insert wrapper after input - this.wrapper = wrapper; - this.input = input; - } - createTag(value) { - const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; - return `${value}`; - } - getValue() { - return this.target.value.trim(); - } - getValues() { - return this.getValue().split(this.separator); - } - getTags() { - return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(tag => tag.textContent); - } - getTag() { - return this.getTags().join(this.separator); - } - updateValue() { - this.target.value = this.getTag(); - this.target.dispatchEvent(new Event('change')); - } - autowidth() { - const fakeEl = document.createElement('div'); - fakeEl.classList.add(this.classInput, this.classInputHidden); - const string = this.input.value || this.input.placeholder || ''; - fakeEl.innerHTML = string.replace(/ /g, ' '); - document.body.appendChild(fakeEl); - this.input.style.setProperty('width', Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace('px', ''))) + 1 + 'px'); - fakeEl.remove(); - } - addEventListener() { - const wrapper = this.wrapper; - const input = this.input; - // Focus to input - wrapper.addEventListener('click', () => input.focus()); - // Toggle focus class - input.addEventListener('focus', () => wrapper.classList.add('focus')); - input.addEventListener('blur', () => wrapper.classList.remove('focus')); - // Add tag when input - input.addEventListener('input', () => { - this.appendTag(); - this.autowidth(); - }); - // Add tag when blur - input.addEventListener('blur', () => { - this.appendTag(true); - this.autowidth(); - }); - input.addEventListener('keydown', (e) => { - // Remove with backspace - if (input.value === '' && e.key === 'Backspace' && wrapper.getElementsByClassName(this.classTag).length) { - wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); - this.updateValue(); - } - // Add with Enter - if (input.value !== '' && e.key === 'Enter' && this.enter) { - this.appendTag(true); - this.autowidth(); - e.preventDefault(); - } - }); - wrapper.addEventListener('tagin:remove', (e) => { - if (e['detail'] instanceof HTMLSpanElement) { - e['detail'].parentElement.remove(); - this.updateValue(); - } - }); - this.target.addEventListener('change', () => this.updateTag()); - } - appendTag(force = false) { - const input = this.input; - const value = eval(this.transform)(input.value.trim()); - if (value === '') - input.value = ''; - if (input.value.includes(this.separator) || (force && input.value !== '')) { - value - .split(this.separator) - .filter((i) => i !== '') - .forEach((val) => { - if (this.getTags().includes(val) && this.duplicate === false) { - this.alertExist(val); - } - else { - input.insertAdjacentHTML('beforebegin', this.createTag(val)); - this.updateValue(); - } - }); - input.value = ''; - input.removeAttribute('style'); - } +(function(global, factory) { + typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.Tagin = factory()); +})(this, function() { + "use strict"; + var tagin = ""; + class Tagin { + constructor(inputElement, options) { + __publicField(this, "classElement", "tagin"); + __publicField(this, "classWrapper", "tagin-wrapper"); + __publicField(this, "classTag", "tagin-tag"); + __publicField(this, "classRemove", "tagin-tag-remove"); + __publicField(this, "classInput", "tagin-input"); + __publicField(this, "classInputHidden", "tagin-input-hidden"); + __publicField(this, "target"); + __publicField(this, "wrapper"); + __publicField(this, "input"); + __publicField(this, "separator"); + __publicField(this, "placeholder"); + __publicField(this, "duplicate"); + __publicField(this, "transform"); + __publicField(this, "enter"); + this.target = inputElement; + this.separator = (options == null ? void 0 : options.separator) || inputElement.dataset.taginSeparator || ","; + this.placeholder = (options == null ? void 0 : options.placeholder) || inputElement.dataset.taginPlaceholder || ""; + this.duplicate = (options == null ? void 0 : options.duplicate) || inputElement.dataset.taginDuplicate !== void 0; + this.transform = (options == null ? void 0 : options.transform) || inputElement.dataset.taginTransform || "input => input"; + this.enter = (options == null ? void 0 : options.enter) || inputElement.dataset.taginEnter !== void 0; + this.createWrapper(); + this.autowidth(); + this.addEventListener(); + } + createWrapper() { + const tags = this.getValue() === "" ? "" : this.getValues().map((val) => this.createTag(val)).join(""); + const input2 = document.createElement("input"); + input2.type = "text"; + input2.className = this.classInput; + input2.placeholder = this.placeholder; + const wrapper = document.createElement("div"); + wrapper.className = `${this.classWrapper} ${this.target.className}`; + wrapper.classList.remove(this.classElement); + wrapper.insertAdjacentHTML("afterbegin", tags); + wrapper.insertAdjacentElement("beforeend", input2); + this.target.insertAdjacentElement("afterend", wrapper); + this.wrapper = wrapper; + this.input = input2; + } + createTag(value2) { + const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; + return `${value2}`; + } + getValue() { + return this.target.value.trim(); + } + getValues() { + return this.getValue().split(this.separator); + } + getTags() { + return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map((tag) => tag.textContent); + } + getTag() { + return this.getTags().join(this.separator); + } + updateValue() { + this.target.value = this.getTag(); + this.target.dispatchEvent(new Event("change")); + } + autowidth() { + const fakeEl = document.createElement("div"); + fakeEl.classList.add(this.classInput, this.classInputHidden); + const string = this.input.value || this.input.placeholder || ""; + fakeEl.innerHTML = string.replace(/ /g, " "); + document.body.appendChild(fakeEl); + this.input.style.setProperty("width", Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace("px", ""))) + 1 + "px"); + fakeEl.remove(); + } + addEventListener() { + const wrapper = this.wrapper; + const input2 = this.input; + wrapper.addEventListener("click", () => input2.focus()); + input2.addEventListener("focus", () => wrapper.classList.add("focus")); + input2.addEventListener("blur", () => wrapper.classList.remove("focus")); + input2.addEventListener("input", () => { + this.appendTag(); + this.autowidth(); + }); + input2.addEventListener("blur", () => { + this.appendTag(true); + this.autowidth(); + }); + input2.addEventListener("keydown", (e) => { + if (input2.value === "" && e.key === "Backspace" && wrapper.getElementsByClassName(this.classTag).length) { + wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); + this.updateValue(); } - alertExist(value) { - for (const el of this.wrapper.getElementsByClassName(this.classTag)) { - if (el.textContent === value && el instanceof HTMLSpanElement) { - el.style.transform = 'scale(1.09)'; - setTimeout(() => { el.removeAttribute('style'); }, 150); - } - } + if (input2.value !== "" && e.key === "Enter" && this.enter) { + this.appendTag(true); + this.autowidth(); + e.preventDefault(); } - updateTag() { - if (this.getValue() !== this.getTag()) { - [...this.wrapper.getElementsByClassName(this.classTag)].map(tag => tag.remove()); - this.getValue().trim() !== '' && this.input.insertAdjacentHTML('beforebegin', this.getValues().map(val => this.createTag(val)).join('')); - } + }); + wrapper.addEventListener("tagin:remove", (e) => { + if (e["detail"] instanceof HTMLSpanElement) { + e["detail"].parentElement.remove(); + this.updateValue(); } - addTag(tag) { - this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; - this.input.dispatchEvent(new Event('input')); + }); + this.target.addEventListener("change", () => this.updateTag()); + } + appendTag(force = false) { + const input = this.input; + const value = eval(this.transform)(input.value.trim()); + if (value === "") + input.value = ""; + if (input.value.includes(this.separator) || force && input.value !== "") { + value.split(this.separator).filter((i) => i !== "").forEach((val) => { + if (this.getTags().includes(val) && this.duplicate === false) { + this.alertExist(val); + } else { + input.insertAdjacentHTML("beforebegin", this.createTag(val)); + this.updateValue(); + } + }); + input.value = ""; + input.removeAttribute("style"); + } + } + alertExist(value2) { + for (const el of this.wrapper.getElementsByClassName(this.classTag)) { + if (el.textContent === value2 && el instanceof HTMLSpanElement) { + el.style.transform = "scale(1.09)"; + setTimeout(() => { + el.removeAttribute("style"); + }, 150); } + } + } + updateTag() { + if (this.getValue() !== this.getTag()) { + [...this.wrapper.getElementsByClassName(this.classTag)].map((tag) => tag.remove()); + this.getValue().trim() !== "" && this.input.insertAdjacentHTML("beforebegin", this.getValues().map((val) => this.createTag(val)).join("")); + } + } + addTag(tag) { + this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; + this.input.dispatchEvent(new Event("input")); } - - return Tagin; - -})); + } + return Tagin; +}); diff --git a/dist/tagin.min.js b/dist/tagin.min.js index ca6f76c..514b0e9 100644 --- a/dist/tagin.min.js +++ b/dist/tagin.min.js @@ -1,5 +1,5 @@ -/*! +var r=Object.defineProperty;var n=(e,t,a)=>t in e?r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[t]=a;var s=(e,t,a)=>(n(e,typeof t!="symbol"?t+"":t,a),a);/*! * Tagin v2.0.2 (https://tagin.netlify.app/) -* Copyright 2020-2021 Erwin Heldy G +* Copyright 2020-2022 Erwin Heldy G * Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) -*/(function(t,e){typeof exports=="object"&&typeof module!="undefined"?module.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis!="undefined"?globalThis:t||self,t.Tagin=e())})(this,function(){"use strict";class Tagin{classElement="tagin";classWrapper="tagin-wrapper";classTag="tagin-tag";classRemove="tagin-tag-remove";classInput="tagin-input";classInputHidden="tagin-input-hidden";target;wrapper;input;separator;placeholder;duplicate;transform;enter;constructor(t,e){this.target=t,this.separator=e?.separator||t.dataset.taginSeparator||",",this.placeholder=e?.placeholder||t.dataset.taginPlaceholder||"",this.duplicate=e?.duplicate||t.dataset.taginDuplicate!==void 0,this.transform=e?.transform||t.dataset.taginTransform||"input => input",this.enter=e?.enter||t.dataset.taginEnter!==void 0,this.createWrapper(),this.autowidth(),this.addEventListener()}createWrapper(){const t=this.getValue()===""?"":this.getValues().map(s=>this.createTag(s)).join(""),e=document.createElement("input");e.type="text",e.className=this.classInput,e.placeholder=this.placeholder;const a=document.createElement("div");a.className=`${this.classWrapper} ${this.target.className}`,a.classList.remove(this.classElement),a.insertAdjacentHTML("afterbegin",t),a.insertAdjacentElement("beforeend",e),this.target.insertAdjacentElement("afterend",a),this.wrapper=a,this.input=e}createTag(t){const e="this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))";return`${t}`}getValue(){return this.target.value.trim()}getValues(){return this.getValue().split(this.separator)}getTags(){return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(t=>t.textContent)}getTag(){return this.getTags().join(this.separator)}updateValue(){this.target.value=this.getTag(),this.target.dispatchEvent(new Event("change"))}autowidth(){const t=document.createElement("div");t.classList.add(this.classInput,this.classInputHidden);const e=this.input.value||this.input.placeholder||"";t.innerHTML=e.replace(/ /g," "),document.body.appendChild(t),this.input.style.setProperty("width",Math.ceil(parseInt(window.getComputedStyle(t).width.replace("px","")))+1+"px"),t.remove()}addEventListener(){const t=this.wrapper,e=this.input;t.addEventListener("click",()=>e.focus()),e.addEventListener("focus",()=>t.classList.add("focus")),e.addEventListener("blur",()=>t.classList.remove("focus")),e.addEventListener("input",()=>{this.appendTag(),this.autowidth()}),e.addEventListener("blur",()=>{this.appendTag(!0),this.autowidth()}),e.addEventListener("keydown",a=>{e.value===""&&a.key==="Backspace"&&t.getElementsByClassName(this.classTag).length&&(t.querySelector(`.${this.classTag}:last-of-type`).remove(),this.updateValue()),e.value!==""&&a.key==="Enter"&&this.enter&&(this.appendTag(!0),this.autowidth(),a.preventDefault())}),t.addEventListener("tagin:remove",a=>{a.detail instanceof HTMLSpanElement&&(a.detail.parentElement.remove(),this.updateValue())}),this.target.addEventListener("change",()=>this.updateTag())}appendTag(force=!1){const input=this.input,value=eval(this.transform)(input.value.trim());value===""&&(input.value=""),(input.value.includes(this.separator)||force&&input.value!=="")&&(value.split(this.separator).filter(t=>t!=="").forEach(t=>{this.getTags().includes(t)&&this.duplicate===!1?this.alertExist(t):(input.insertAdjacentHTML("beforebegin",this.createTag(t)),this.updateValue())}),input.value="",input.removeAttribute("style"))}alertExist(t){for(const e of this.wrapper.getElementsByClassName(this.classTag))e.textContent===t&&e instanceof HTMLSpanElement&&(e.style.transform="scale(1.09)",setTimeout(()=>{e.removeAttribute("style")},150))}updateTag(){this.getValue()!==this.getTag()&&([...this.wrapper.getElementsByClassName(this.classTag)].map(t=>t.remove()),this.getValue().trim()!==""&&this.input.insertAdjacentHTML("beforebegin",this.getValues().map(t=>this.createTag(t)).join("")))}addTag(t){this.input.value=(Array.isArray(t)?t.join(this.separator):t)+this.separator,this.input.dispatchEvent(new Event("input"))}}return Tagin}); +*/(function(e,t){typeof exports=="object"&&typeof module!="undefined"?module.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis!="undefined"?globalThis:e||self,e.Tagin=t())})(this,function(){"use strict";var tagin="";class Tagin{constructor(e,t){s(this,"classElement","tagin");s(this,"classWrapper","tagin-wrapper");s(this,"classTag","tagin-tag");s(this,"classRemove","tagin-tag-remove");s(this,"classInput","tagin-input");s(this,"classInputHidden","tagin-input-hidden");s(this,"target");s(this,"wrapper");s(this,"input");s(this,"separator");s(this,"placeholder");s(this,"duplicate");s(this,"transform");s(this,"enter");this.target=e,this.separator=(t==null?void 0:t.separator)||e.dataset.taginSeparator||",",this.placeholder=(t==null?void 0:t.placeholder)||e.dataset.taginPlaceholder||"",this.duplicate=(t==null?void 0:t.duplicate)||e.dataset.taginDuplicate!==void 0,this.transform=(t==null?void 0:t.transform)||e.dataset.taginTransform||"input => input",this.enter=(t==null?void 0:t.enter)||e.dataset.taginEnter!==void 0,this.createWrapper(),this.autowidth(),this.addEventListener()}createWrapper(){const e=this.getValue()===""?"":this.getValues().map(i=>this.createTag(i)).join(""),t=document.createElement("input");t.type="text",t.className=this.classInput,t.placeholder=this.placeholder;const a=document.createElement("div");a.className=`${this.classWrapper} ${this.target.className}`,a.classList.remove(this.classElement),a.insertAdjacentHTML("afterbegin",e),a.insertAdjacentElement("beforeend",t),this.target.insertAdjacentElement("afterend",a),this.wrapper=a,this.input=t}createTag(e){const t="this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))";return`${e}`}getValue(){return this.target.value.trim()}getValues(){return this.getValue().split(this.separator)}getTags(){return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(e=>e.textContent)}getTag(){return this.getTags().join(this.separator)}updateValue(){this.target.value=this.getTag(),this.target.dispatchEvent(new Event("change"))}autowidth(){const e=document.createElement("div");e.classList.add(this.classInput,this.classInputHidden);const t=this.input.value||this.input.placeholder||"";e.innerHTML=t.replace(/ /g," "),document.body.appendChild(e),this.input.style.setProperty("width",Math.ceil(parseInt(window.getComputedStyle(e).width.replace("px","")))+1+"px"),e.remove()}addEventListener(){const e=this.wrapper,t=this.input;e.addEventListener("click",()=>t.focus()),t.addEventListener("focus",()=>e.classList.add("focus")),t.addEventListener("blur",()=>e.classList.remove("focus")),t.addEventListener("input",()=>{this.appendTag(),this.autowidth()}),t.addEventListener("blur",()=>{this.appendTag(!0),this.autowidth()}),t.addEventListener("keydown",a=>{t.value===""&&a.key==="Backspace"&&e.getElementsByClassName(this.classTag).length&&(e.querySelector(`.${this.classTag}:last-of-type`).remove(),this.updateValue()),t.value!==""&&a.key==="Enter"&&this.enter&&(this.appendTag(!0),this.autowidth(),a.preventDefault())}),e.addEventListener("tagin:remove",a=>{a.detail instanceof HTMLSpanElement&&(a.detail.parentElement.remove(),this.updateValue())}),this.target.addEventListener("change",()=>this.updateTag())}appendTag(force=!1){const input=this.input,value=eval(this.transform)(input.value.trim());value===""&&(input.value=""),(input.value.includes(this.separator)||force&&input.value!=="")&&(value.split(this.separator).filter(e=>e!=="").forEach(e=>{this.getTags().includes(e)&&this.duplicate===!1?this.alertExist(e):(input.insertAdjacentHTML("beforebegin",this.createTag(e)),this.updateValue())}),input.value="",input.removeAttribute("style"))}alertExist(e){for(const t of this.wrapper.getElementsByClassName(this.classTag))t.textContent===e&&t instanceof HTMLSpanElement&&(t.style.transform="scale(1.09)",setTimeout(()=>{t.removeAttribute("style")},150))}updateTag(){this.getValue()!==this.getTag()&&([...this.wrapper.getElementsByClassName(this.classTag)].map(e=>e.remove()),this.getValue().trim()!==""&&this.input.insertAdjacentHTML("beforebegin",this.getValues().map(e=>this.createTag(e)).join("")))}addTag(e){this.input.value=(Array.isArray(e)?e.join(this.separator):e)+this.separator,this.input.dispatchEvent(new Event("input"))}}return Tagin}); diff --git a/dist/tagin.module.d.ts b/dist/tagin.module.d.ts deleted file mode 100644 index 733cfc3..0000000 --- a/dist/tagin.module.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -declare class Tagin { - private classElement; - private classWrapper; - private classTag; - private classRemove; - private classInput; - private classInputHidden; - private target; - private wrapper; - private input; - private separator; - private placeholder; - private duplicate; - private transform; - private enter; - constructor(inputElement: HTMLInputElement, options?: Options); - private createWrapper; - private createTag; - private getValue; - private getValues; - getTags(): string[]; - getTag(): string; - private updateValue; - private autowidth; - private addEventListener; - private appendTag; - private alertExist; - private updateTag; - addTag(tag: string | string[]): void; -} -export default Tagin; -interface Options { - separator?: string; - placeholder?: string; - duplicate?: boolean; - transform?: string; - enter?: boolean; -} diff --git a/dist/tagin.module.js b/dist/tagin.module.js index b7b2b2d..c96fec8 100644 --- a/dist/tagin.module.js +++ b/dist/tagin.module.js @@ -1,157 +1,155 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; +var __publicField = (obj, key, value2) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2); + return value2; +}; /*! * Tagin v2.0.2 (https://tagin.netlify.app/) -* Copyright 2020-2021 Erwin Heldy G +* Copyright 2020-2022 Erwin Heldy G * Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) */ +var tagin = ""; class Tagin { - classElement = 'tagin'; - classWrapper = 'tagin-wrapper'; - classTag = 'tagin-tag'; - classRemove = 'tagin-tag-remove'; - classInput = 'tagin-input'; - classInputHidden = 'tagin-input-hidden'; - target; - wrapper; - input; - separator; - placeholder; - duplicate; - transform; - enter; - constructor(inputElement, options) { - this.target = inputElement; - this.separator = options?.separator || inputElement.dataset.taginSeparator || ','; - this.placeholder = options?.placeholder || inputElement.dataset.taginPlaceholder || ''; - this.duplicate = options?.duplicate || inputElement.dataset.taginDuplicate !== undefined; - this.transform = options?.transform || inputElement.dataset.taginTransform || 'input => input'; - this.enter = options?.enter || inputElement.dataset.taginEnter !== undefined; - this.createWrapper(); + constructor(inputElement, options) { + __publicField(this, "classElement", "tagin"); + __publicField(this, "classWrapper", "tagin-wrapper"); + __publicField(this, "classTag", "tagin-tag"); + __publicField(this, "classRemove", "tagin-tag-remove"); + __publicField(this, "classInput", "tagin-input"); + __publicField(this, "classInputHidden", "tagin-input-hidden"); + __publicField(this, "target"); + __publicField(this, "wrapper"); + __publicField(this, "input"); + __publicField(this, "separator"); + __publicField(this, "placeholder"); + __publicField(this, "duplicate"); + __publicField(this, "transform"); + __publicField(this, "enter"); + this.target = inputElement; + this.separator = (options == null ? void 0 : options.separator) || inputElement.dataset.taginSeparator || ","; + this.placeholder = (options == null ? void 0 : options.placeholder) || inputElement.dataset.taginPlaceholder || ""; + this.duplicate = (options == null ? void 0 : options.duplicate) || inputElement.dataset.taginDuplicate !== void 0; + this.transform = (options == null ? void 0 : options.transform) || inputElement.dataset.taginTransform || "input => input"; + this.enter = (options == null ? void 0 : options.enter) || inputElement.dataset.taginEnter !== void 0; + this.createWrapper(); + this.autowidth(); + this.addEventListener(); + } + createWrapper() { + const tags = this.getValue() === "" ? "" : this.getValues().map((val) => this.createTag(val)).join(""); + const input2 = document.createElement("input"); + input2.type = "text"; + input2.className = this.classInput; + input2.placeholder = this.placeholder; + const wrapper = document.createElement("div"); + wrapper.className = `${this.classWrapper} ${this.target.className}`; + wrapper.classList.remove(this.classElement); + wrapper.insertAdjacentHTML("afterbegin", tags); + wrapper.insertAdjacentElement("beforeend", input2); + this.target.insertAdjacentElement("afterend", wrapper); + this.wrapper = wrapper; + this.input = input2; + } + createTag(value2) { + const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; + return `${value2}`; + } + getValue() { + return this.target.value.trim(); + } + getValues() { + return this.getValue().split(this.separator); + } + getTags() { + return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map((tag) => tag.textContent); + } + getTag() { + return this.getTags().join(this.separator); + } + updateValue() { + this.target.value = this.getTag(); + this.target.dispatchEvent(new Event("change")); + } + autowidth() { + const fakeEl = document.createElement("div"); + fakeEl.classList.add(this.classInput, this.classInputHidden); + const string = this.input.value || this.input.placeholder || ""; + fakeEl.innerHTML = string.replace(/ /g, " "); + document.body.appendChild(fakeEl); + this.input.style.setProperty("width", Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace("px", ""))) + 1 + "px"); + fakeEl.remove(); + } + addEventListener() { + const wrapper = this.wrapper; + const input2 = this.input; + wrapper.addEventListener("click", () => input2.focus()); + input2.addEventListener("focus", () => wrapper.classList.add("focus")); + input2.addEventListener("blur", () => wrapper.classList.remove("focus")); + input2.addEventListener("input", () => { + this.appendTag(); + this.autowidth(); + }); + input2.addEventListener("blur", () => { + this.appendTag(true); + this.autowidth(); + }); + input2.addEventListener("keydown", (e) => { + if (input2.value === "" && e.key === "Backspace" && wrapper.getElementsByClassName(this.classTag).length) { + wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); + this.updateValue(); + } + if (input2.value !== "" && e.key === "Enter" && this.enter) { + this.appendTag(true); this.autowidth(); - this.addEventListener(); - } - createWrapper() { - const tags = this.getValue() === '' ? '' : this.getValues().map(val => this.createTag(val)).join(''); - const input = document.createElement('input'); - input.type = 'text'; - input.className = this.classInput; - input.placeholder = this.placeholder; - const wrapper = document.createElement('div'); - wrapper.className = `${this.classWrapper} ${this.target.className}`; - wrapper.classList.remove(this.classElement); - wrapper.insertAdjacentHTML('afterbegin', tags); - wrapper.insertAdjacentElement('beforeend', input); - this.target.insertAdjacentElement('afterend', wrapper); // insert wrapper after input - this.wrapper = wrapper; - this.input = input; - } - createTag(value) { - const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; - return `${value}`; - } - getValue() { - return this.target.value.trim(); - } - getValues() { - return this.getValue().split(this.separator); - } - getTags() { - return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(tag => tag.textContent); - } - getTag() { - return this.getTags().join(this.separator); - } - updateValue() { - this.target.value = this.getTag(); - this.target.dispatchEvent(new Event('change')); - } - autowidth() { - const fakeEl = document.createElement('div'); - fakeEl.classList.add(this.classInput, this.classInputHidden); - const string = this.input.value || this.input.placeholder || ''; - fakeEl.innerHTML = string.replace(/ /g, ' '); - document.body.appendChild(fakeEl); - this.input.style.setProperty('width', Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace('px', ''))) + 1 + 'px'); - fakeEl.remove(); - } - addEventListener() { - const wrapper = this.wrapper; - const input = this.input; - // Focus to input - wrapper.addEventListener('click', () => input.focus()); - // Toggle focus class - input.addEventListener('focus', () => wrapper.classList.add('focus')); - input.addEventListener('blur', () => wrapper.classList.remove('focus')); - // Add tag when input - input.addEventListener('input', () => { - this.appendTag(); - this.autowidth(); - }); - // Add tag when blur - input.addEventListener('blur', () => { - this.appendTag(true); - this.autowidth(); - }); - input.addEventListener('keydown', (e) => { - // Remove with backspace - if (input.value === '' && e.key === 'Backspace' && wrapper.getElementsByClassName(this.classTag).length) { - wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); - this.updateValue(); - } - // Add with Enter - if (input.value !== '' && e.key === 'Enter' && this.enter) { - this.appendTag(true); - this.autowidth(); - e.preventDefault(); - } - }); - wrapper.addEventListener('tagin:remove', (e) => { - if (e['detail'] instanceof HTMLSpanElement) { - e['detail'].parentElement.remove(); - this.updateValue(); - } - }); - this.target.addEventListener('change', () => this.updateTag()); - } - appendTag(force = false) { - const input = this.input; - const value = eval(this.transform)(input.value.trim()); - if (value === '') - input.value = ''; - if (input.value.includes(this.separator) || (force && input.value !== '')) { - value - .split(this.separator) - .filter((i) => i !== '') - .forEach((val) => { - if (this.getTags().includes(val) && this.duplicate === false) { - this.alertExist(val); - } - else { - input.insertAdjacentHTML('beforebegin', this.createTag(val)); - this.updateValue(); - } - }); - input.value = ''; - input.removeAttribute('style'); + e.preventDefault(); + } + }); + wrapper.addEventListener("tagin:remove", (e) => { + if (e["detail"] instanceof HTMLSpanElement) { + e["detail"].parentElement.remove(); + this.updateValue(); + } + }); + this.target.addEventListener("change", () => this.updateTag()); + } + appendTag(force = false) { + const input = this.input; + const value = eval(this.transform)(input.value.trim()); + if (value === "") + input.value = ""; + if (input.value.includes(this.separator) || force && input.value !== "") { + value.split(this.separator).filter((i) => i !== "").forEach((val) => { + if (this.getTags().includes(val) && this.duplicate === false) { + this.alertExist(val); + } else { + input.insertAdjacentHTML("beforebegin", this.createTag(val)); + this.updateValue(); } + }); + input.value = ""; + input.removeAttribute("style"); } - alertExist(value) { - for (const el of this.wrapper.getElementsByClassName(this.classTag)) { - if (el.textContent === value && el instanceof HTMLSpanElement) { - el.style.transform = 'scale(1.09)'; - setTimeout(() => { el.removeAttribute('style'); }, 150); - } - } - } - updateTag() { - if (this.getValue() !== this.getTag()) { - [...this.wrapper.getElementsByClassName(this.classTag)].map(tag => tag.remove()); - this.getValue().trim() !== '' && this.input.insertAdjacentHTML('beforebegin', this.getValues().map(val => this.createTag(val)).join('')); - } + } + alertExist(value2) { + for (const el of this.wrapper.getElementsByClassName(this.classTag)) { + if (el.textContent === value2 && el instanceof HTMLSpanElement) { + el.style.transform = "scale(1.09)"; + setTimeout(() => { + el.removeAttribute("style"); + }, 150); + } } - addTag(tag) { - this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; - this.input.dispatchEvent(new Event('input')); + } + updateTag() { + if (this.getValue() !== this.getTag()) { + [...this.wrapper.getElementsByClassName(this.classTag)].map((tag) => tag.remove()); + this.getValue().trim() !== "" && this.input.insertAdjacentHTML("beforebegin", this.getValues().map((val) => this.createTag(val)).join("")); } + } + addTag(tag) { + this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; + this.input.dispatchEvent(new Event("input")); + } } - export { Tagin as default }; diff --git a/dist/tagin.module.min.js b/dist/tagin.module.min.js index e49302d..c96fec8 100644 --- a/dist/tagin.module.min.js +++ b/dist/tagin.module.min.js @@ -1,5 +1,155 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; +var __publicField = (obj, key, value2) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2); + return value2; +}; /*! * Tagin v2.0.2 (https://tagin.netlify.app/) -* Copyright 2020-2021 Erwin Heldy G +* Copyright 2020-2022 Erwin Heldy G * Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) -*/class Tagin{classElement="tagin";classWrapper="tagin-wrapper";classTag="tagin-tag";classRemove="tagin-tag-remove";classInput="tagin-input";classInputHidden="tagin-input-hidden";target;wrapper;input;separator;placeholder;duplicate;transform;enter;constructor(t,e){this.target=t,this.separator=e?.separator||t.dataset.taginSeparator||",",this.placeholder=e?.placeholder||t.dataset.taginPlaceholder||"",this.duplicate=e?.duplicate||t.dataset.taginDuplicate!==void 0,this.transform=e?.transform||t.dataset.taginTransform||"input => input",this.enter=e?.enter||t.dataset.taginEnter!==void 0,this.createWrapper(),this.autowidth(),this.addEventListener()}createWrapper(){const t=this.getValue()===""?"":this.getValues().map(s=>this.createTag(s)).join(""),e=document.createElement("input");e.type="text",e.className=this.classInput,e.placeholder=this.placeholder;const a=document.createElement("div");a.className=`${this.classWrapper} ${this.target.className}`,a.classList.remove(this.classElement),a.insertAdjacentHTML("afterbegin",t),a.insertAdjacentElement("beforeend",e),this.target.insertAdjacentElement("afterend",a),this.wrapper=a,this.input=e}createTag(t){const e="this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))";return`${t}`}getValue(){return this.target.value.trim()}getValues(){return this.getValue().split(this.separator)}getTags(){return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(t=>t.textContent)}getTag(){return this.getTags().join(this.separator)}updateValue(){this.target.value=this.getTag(),this.target.dispatchEvent(new Event("change"))}autowidth(){const t=document.createElement("div");t.classList.add(this.classInput,this.classInputHidden);const e=this.input.value||this.input.placeholder||"";t.innerHTML=e.replace(/ /g," "),document.body.appendChild(t),this.input.style.setProperty("width",Math.ceil(parseInt(window.getComputedStyle(t).width.replace("px","")))+1+"px"),t.remove()}addEventListener(){const t=this.wrapper,e=this.input;t.addEventListener("click",()=>e.focus()),e.addEventListener("focus",()=>t.classList.add("focus")),e.addEventListener("blur",()=>t.classList.remove("focus")),e.addEventListener("input",()=>{this.appendTag(),this.autowidth()}),e.addEventListener("blur",()=>{this.appendTag(!0),this.autowidth()}),e.addEventListener("keydown",a=>{e.value===""&&a.key==="Backspace"&&t.getElementsByClassName(this.classTag).length&&(t.querySelector(`.${this.classTag}:last-of-type`).remove(),this.updateValue()),e.value!==""&&a.key==="Enter"&&this.enter&&(this.appendTag(!0),this.autowidth(),a.preventDefault())}),t.addEventListener("tagin:remove",a=>{a.detail instanceof HTMLSpanElement&&(a.detail.parentElement.remove(),this.updateValue())}),this.target.addEventListener("change",()=>this.updateTag())}appendTag(force=!1){const input=this.input,value=eval(this.transform)(input.value.trim());value===""&&(input.value=""),(input.value.includes(this.separator)||force&&input.value!=="")&&(value.split(this.separator).filter(t=>t!=="").forEach(t=>{this.getTags().includes(t)&&this.duplicate===!1?this.alertExist(t):(input.insertAdjacentHTML("beforebegin",this.createTag(t)),this.updateValue())}),input.value="",input.removeAttribute("style"))}alertExist(t){for(const e of this.wrapper.getElementsByClassName(this.classTag))e.textContent===t&&e instanceof HTMLSpanElement&&(e.style.transform="scale(1.09)",setTimeout(()=>{e.removeAttribute("style")},150))}updateTag(){this.getValue()!==this.getTag()&&([...this.wrapper.getElementsByClassName(this.classTag)].map(t=>t.remove()),this.getValue().trim()!==""&&this.input.insertAdjacentHTML("beforebegin",this.getValues().map(t=>this.createTag(t)).join("")))}addTag(t){this.input.value=(Array.isArray(t)?t.join(this.separator):t)+this.separator,this.input.dispatchEvent(new Event("input"))}}export{Tagin as default}; +*/ +var tagin = ""; +class Tagin { + constructor(inputElement, options) { + __publicField(this, "classElement", "tagin"); + __publicField(this, "classWrapper", "tagin-wrapper"); + __publicField(this, "classTag", "tagin-tag"); + __publicField(this, "classRemove", "tagin-tag-remove"); + __publicField(this, "classInput", "tagin-input"); + __publicField(this, "classInputHidden", "tagin-input-hidden"); + __publicField(this, "target"); + __publicField(this, "wrapper"); + __publicField(this, "input"); + __publicField(this, "separator"); + __publicField(this, "placeholder"); + __publicField(this, "duplicate"); + __publicField(this, "transform"); + __publicField(this, "enter"); + this.target = inputElement; + this.separator = (options == null ? void 0 : options.separator) || inputElement.dataset.taginSeparator || ","; + this.placeholder = (options == null ? void 0 : options.placeholder) || inputElement.dataset.taginPlaceholder || ""; + this.duplicate = (options == null ? void 0 : options.duplicate) || inputElement.dataset.taginDuplicate !== void 0; + this.transform = (options == null ? void 0 : options.transform) || inputElement.dataset.taginTransform || "input => input"; + this.enter = (options == null ? void 0 : options.enter) || inputElement.dataset.taginEnter !== void 0; + this.createWrapper(); + this.autowidth(); + this.addEventListener(); + } + createWrapper() { + const tags = this.getValue() === "" ? "" : this.getValues().map((val) => this.createTag(val)).join(""); + const input2 = document.createElement("input"); + input2.type = "text"; + input2.className = this.classInput; + input2.placeholder = this.placeholder; + const wrapper = document.createElement("div"); + wrapper.className = `${this.classWrapper} ${this.target.className}`; + wrapper.classList.remove(this.classElement); + wrapper.insertAdjacentHTML("afterbegin", tags); + wrapper.insertAdjacentElement("beforeend", input2); + this.target.insertAdjacentElement("afterend", wrapper); + this.wrapper = wrapper; + this.input = input2; + } + createTag(value2) { + const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; + return `${value2}`; + } + getValue() { + return this.target.value.trim(); + } + getValues() { + return this.getValue().split(this.separator); + } + getTags() { + return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map((tag) => tag.textContent); + } + getTag() { + return this.getTags().join(this.separator); + } + updateValue() { + this.target.value = this.getTag(); + this.target.dispatchEvent(new Event("change")); + } + autowidth() { + const fakeEl = document.createElement("div"); + fakeEl.classList.add(this.classInput, this.classInputHidden); + const string = this.input.value || this.input.placeholder || ""; + fakeEl.innerHTML = string.replace(/ /g, " "); + document.body.appendChild(fakeEl); + this.input.style.setProperty("width", Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace("px", ""))) + 1 + "px"); + fakeEl.remove(); + } + addEventListener() { + const wrapper = this.wrapper; + const input2 = this.input; + wrapper.addEventListener("click", () => input2.focus()); + input2.addEventListener("focus", () => wrapper.classList.add("focus")); + input2.addEventListener("blur", () => wrapper.classList.remove("focus")); + input2.addEventListener("input", () => { + this.appendTag(); + this.autowidth(); + }); + input2.addEventListener("blur", () => { + this.appendTag(true); + this.autowidth(); + }); + input2.addEventListener("keydown", (e) => { + if (input2.value === "" && e.key === "Backspace" && wrapper.getElementsByClassName(this.classTag).length) { + wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); + this.updateValue(); + } + if (input2.value !== "" && e.key === "Enter" && this.enter) { + this.appendTag(true); + this.autowidth(); + e.preventDefault(); + } + }); + wrapper.addEventListener("tagin:remove", (e) => { + if (e["detail"] instanceof HTMLSpanElement) { + e["detail"].parentElement.remove(); + this.updateValue(); + } + }); + this.target.addEventListener("change", () => this.updateTag()); + } + appendTag(force = false) { + const input = this.input; + const value = eval(this.transform)(input.value.trim()); + if (value === "") + input.value = ""; + if (input.value.includes(this.separator) || force && input.value !== "") { + value.split(this.separator).filter((i) => i !== "").forEach((val) => { + if (this.getTags().includes(val) && this.duplicate === false) { + this.alertExist(val); + } else { + input.insertAdjacentHTML("beforebegin", this.createTag(val)); + this.updateValue(); + } + }); + input.value = ""; + input.removeAttribute("style"); + } + } + alertExist(value2) { + for (const el of this.wrapper.getElementsByClassName(this.classTag)) { + if (el.textContent === value2 && el instanceof HTMLSpanElement) { + el.style.transform = "scale(1.09)"; + setTimeout(() => { + el.removeAttribute("style"); + }, 150); + } + } + } + updateTag() { + if (this.getValue() !== this.getTag()) { + [...this.wrapper.getElementsByClassName(this.classTag)].map((tag) => tag.remove()); + this.getValue().trim() !== "" && this.input.insertAdjacentHTML("beforebegin", this.getValues().map((val) => this.createTag(val)).join("")); + } + } + addTag(tag) { + this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; + this.input.dispatchEvent(new Event("input")); + } +} +export { Tagin as default }; diff --git a/package.json b/package.json index c70002b..da28b70 100644 --- a/package.json +++ b/package.json @@ -17,31 +17,31 @@ "tag input" ], "files": [ - "dist" + "dist", + "src/tagin.scss" ], + "sass": "src/tagin.scss", "scripts": { "clean": "rimraf dist/tagin*", - "build": "npm run clean --silent && run-p build:css build:js", - "build:css": "run-s build:css:sass build:css:min", - "build:css:sass": "sass --source-map --embed-sources src/tagin.scss:dist/tagin.css", - "build:css:min": "cssmin-recursive dist", - "build:js": "run-s build:js:ts build:js:min", - "build:js:ts": "rollup -c --silent", - "build:js:min": "jsmin-recursive dist", - "dev": "run-p dev:css dev:js", - "dev:css": "sass --source-map --embed-sources src/tagin.scss:dist/tagin.css -w", - "dev:js": "rollup -c -w" + "build": "run-s build:nomin build:min build:dts", + "build:min": "vite build -c vite.min.config.ts", + "build:nomin": "vite build", + "build:dts": "tsc", + "dev": "vite" }, "devDependencies": { - "@rollup/plugin-typescript": "8.3.0", + "@popperjs/core": "^2.11.2", + "@types/node": "^17.0.16", "bootstrap": "5.1.3", - "cssmin-recursive": "1.0.0", - "jsmin-recursive": "1.0.0", - "npm-run-all": "4.1.5", + "npm-run-all": "^4.1.5", "rimraf": "3.0.2", - "rollup": "2.61.1", "sass": "1.45.0", + "tsdef": "^0.0.14", "tslib": "2.3.1", - "typescript": "4.5.4" + "typescript": "4.5.4", + "vite": "^2.7.13" + }, + "peerDependencies": { + "@popperjs/core": "^2.11.2" } } diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index ca76b14..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,32 +0,0 @@ -import fs from 'fs' -import pkg from './package.json' -import typescript from '@rollup/plugin-typescript' - -const name = pkg.name.charAt(0).toUpperCase() + pkg.name.slice(1) -const banner = `/*! -* ${name} v${pkg.version} (${pkg.homepage}) -* Copyright 2020-${new Date().getFullYear()} ${pkg.author} -* Licensed under ${pkg.license} (${pkg.repository.replace('.git', '')}/blob/master/LICENSE) -*/` - -export default { - input: pkg.source, - output: [ - { banner, format: 'umd', file: pkg.main, name }, - { banner, format: 'es', file: pkg.module }, - ], - plugins: [ - typescript({ tsconfig: './tsconfig.json' }), - { - generateBundle() { - setTimeout(() => fs.copyFileSync(pkg.types, pkg.module.replace('.js', '.d.ts')), 200) - }, - }, - ], - onwarn: function (message) { - if (/Use of eval/.test(message)) { - return - } - console.error(message) - }, -} diff --git a/src/tagin.scss b/src/tagin.scss index 2271bf9..61d63d0 100644 --- a/src/tagin.scss +++ b/src/tagin.scss @@ -1,6 +1,6 @@ -@import '../node_modules/bootstrap/scss/functions'; -@import '../node_modules/bootstrap/scss/variables'; -@import '../node_modules/bootstrap/scss/mixins'; +@import 'bootstrap/scss/functions'; +@import 'bootstrap/scss/variables'; +@import 'bootstrap/scss/mixins'; .tagin { display: none; diff --git a/src/tagin.ts b/src/tagin.ts index 1770b55..72ec3f6 100644 --- a/src/tagin.ts +++ b/src/tagin.ts @@ -1,3 +1,5 @@ +import './tagin.scss' + class Tagin { private classElement : string = 'tagin' private classWrapper : string = 'tagin-wrapper' diff --git a/tsconfig.json b/tsconfig.json index 6d7e663..b9ba72e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,16 @@ { - "include": ["src"], - "exclude": ["dist", "node_modules"], - "compilerOptions": { + "include": ["src/*"], + "exclude": ["dist", "node_modules", "vite.config", "vite.min.config"], + "compilerOptions": { + "rootDir": "src", + "isolatedModules": true, "target": "ESNext", - "outDir": "dist", - "declaration": true, - "declarationDir": ".", - "emitDeclarationOnly": true - } + "outDir": "dist", + "declaration": true, + "declarationDir": "dist", + "emitDeclarationOnly": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "allowSyntheticDefaultImports": true + } } diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..cfa1f7b --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,45 @@ +import { defineConfig, mergeConfig, type UserConfigExport } from 'vite' +import type { DeepPartial } from 'tsdef' +// HACK: there doesn't seem to be a way to get json intellisense and properly generated declarations at the same time. +// @ts-expect-error disable editor warnings, the compiled output for this is correct. +import pkg from './package.json' + +export const pkgName = pkg.name +const name = pkgName.charAt(0).toUpperCase() + pkgName.slice(1) +const banner = `/*! +* ${name} v${pkg.version} (${pkg.homepage}) +* Copyright 2020-${new Date().getFullYear()} ${pkg.author} +* Licensed under ${pkg.license} (${pkg.repository.replace('.git', '')}/blob/master/LICENSE) +*/` + +export const sharedConfig = defineConfig({ + build: { + sourcemap: false, + lib: { + formats: ['es', 'umd'], + entry: pkg.source, + name, + }, + rollupOptions: { + external: ['bootstrap'], + output: { + banner, + }, + }, + }, +}) + +export default mergeConfig(sharedConfig, ({ + build: { + minify: false, + lib: { + fileName: (format) => `${pkgName}${format === 'es' ? '.module' : ''}.js`, + }, + rollupOptions: { + output: { + // HACK: this won't work with more than one (s)css file. + assetFileNames: 'tagin[extname]', + }, + }, + }, +}) as DeepPartial) diff --git a/vite.min.config.ts b/vite.min.config.ts new file mode 100644 index 0000000..8d03202 --- /dev/null +++ b/vite.min.config.ts @@ -0,0 +1,20 @@ +import { mergeConfig, UserConfigExport } from 'vite' +import { sharedConfig, pkgName } from './vite.config' +import { DeepPartial } from 'tsdef' + +export default mergeConfig(sharedConfig, ({ + build: { + // XXX: currently only umd builds are minified: https://github.com/vitejs/vite/issues/6555 + minify: 'esbuild', + lib: { + fileName: (format) => `${pkgName}${format === 'es' ? '.module' : ''}.min.js`, + }, + emptyOutDir: false, + rollupOptions: { + output: { + // HACK: this won't work with more than one (s)css file. + assetFileNames: 'tagin.min[extname]', + }, + }, + }, +}) as DeepPartial)