impulse_view_components 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +17 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +32 -0
  5. data/app/assets/dist/impulse_view_components.css +6 -0
  6. data/app/assets/dist/impulse_view_components.css.map +1 -0
  7. data/app/assets/dist/impulse_view_components.js +1 -0
  8. data/app/components/impulse/ajax_select_component.html.erb +4 -0
  9. data/app/components/impulse/ajax_select_component.rb +34 -0
  10. data/app/components/impulse/application_component.rb +19 -0
  11. data/app/components/impulse/autocomplete/option_component.html.erb +6 -0
  12. data/app/components/impulse/autocomplete/option_component.rb +30 -0
  13. data/app/components/impulse/autocomplete_component.html.erb +84 -0
  14. data/app/components/impulse/autocomplete_component.rb +71 -0
  15. data/app/components/impulse/base_renderer.rb +19 -0
  16. data/app/components/impulse/popover_component.html.erb +9 -0
  17. data/app/components/impulse/popover_component.rb +50 -0
  18. data/app/components/impulse/select_component.html.erb +13 -0
  19. data/app/components/impulse/select_component.rb +38 -0
  20. data/app/components/impulse/spinner_component.rb +31 -0
  21. data/lib/impulse/forms/builder.rb +31 -0
  22. data/lib/impulse/forms/tags/ajax_select.rb +27 -0
  23. data/lib/impulse/forms/tags/base.rb +27 -0
  24. data/lib/impulse/forms/tags/select.rb +27 -0
  25. data/lib/impulse/helpers/attributes_helper.rb +18 -0
  26. data/lib/impulse/helpers/form_helper.rb +9 -0
  27. data/lib/impulse/view_components/engine.rb +28 -0
  28. data/lib/impulse/view_components/version.rb +5 -0
  29. data/lib/impulse/view_components.rb +9 -0
  30. metadata +175 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a44c0c95f56430686a74bc78dd50b150ccc487816373013ee86bcc0f7f633c5e
4
+ data.tar.gz: a1a948d4ef115812dc4c8d02a503093b3997e11cd0bc27f34f0851a4f6d01065
5
+ SHA512:
6
+ metadata.gz: c07939341df8d3bf96459b5d6bb8e506f2600eb55d9dde35db34068496d7d44fdde505cb954473042bb3f3978fae680523b5e9006062a86b969c8a463ab84430
7
+ data.tar.gz: 9ffbcafb938bb1762dae85a5741968d36824e09c0123803dabd084be126693fbb17b6d1c776c510aaf215a10f46fb15d0b63404f4a52741f35caaf80d69e6788
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2023-07-31
11
+
12
+ ### Added
13
+
14
+ - Everything!
15
+
16
+ [unreleased]: https://github.com/Ambiki/impulse_view_components/compare/v0.1.0...HEAD
17
+ [0.1.0]: https://github.com/Ambiki/impulse_view_components/releases/tag/v0.1.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Ambitious Idea Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # ImpulseViewComponents
2
+
3
+ View components for Ruby on Rails.
4
+
5
+ ## Development
6
+
7
+ After cloning the repo, run:
8
+
9
+ ```bash
10
+ yarn install
11
+ bundle install
12
+ cd demo && bundle install
13
+ ```
14
+
15
+ After installing the dependencies, you can run the project by running:
16
+
17
+ ```bash
18
+ yarn build:watch
19
+ cd demo && rails server
20
+ ```
21
+
22
+ Visit [localhost:3000/components](localhost:3000/components) to view the list of available components.
23
+
24
+ To run the tests, run:
25
+
26
+ ```bash
27
+ bundle exec rake test
28
+ ```
29
+
30
+ ## License
31
+
32
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ :root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #6c757d;--gray-dark: #343a40;--primary: #007bff;--secondary: #6c757d;--success: #28a745;--info: #17a2b8;--warning: #ffc107;--danger: #dc3545;--light: #f8f9fa;--dark: #343a40;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}:root{--awc-autocomplete-control-min-height: calc(1.5em + .75rem + 2px);--awc-autocomplete-control-min-height-sm: calc(1.5em + .5rem + 2px);--awc-autocomplete-control-min-height-lg: calc(1.5em + 1rem + 2px);--awc-autocomplete-control-focus-color: #495057;--awc-autocomplete-control-focus-border-color: #80bdff;--awc-autocomplete-control-disabled-bg-color: #eef4ff;--awc-autocomplete-control-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);--awc-autocomplete-control-focus-box-shadow: 0 0 0 .2rem rgba(0,123,255,0.25);--awc-autocomplete-input-min-width: 2rem;--awc-autocomplete-input-height: calc(calc(1.5em + .75rem + 2px) - (.375rem * 2) - (1px * 2));--awc-autocomplete-input-bg-color: #fff;--awc-autocomplete-adornment-item-size: 1.5rem;--awc-autocomplete-listbox-font-size: 0.875rem;--awc-autocomplete-listbox-max-height: 256px;--awc-autocomplete-option-padding-x: 1rem;--awc-autocomplete-option-padding-y: 0.5rem;--awc-autocomplete-option-font-size: 0.875rem;--awc-autocomplete-option-lh: 1.25rem;--awc-autocomplete-option-hover-bg-color: #e9ecef;--awc-autocomplete-option-check-color: #38b57c;--awc-autocomplete-option-check-disabled-color: #afe1cb;--awc-autocomplete-group-header-padding-x: var(--awc-autocomplete-option-padding-x);--awc-autocomplete-group-header-padding-y: 0.25rem;--awc-autocomplete-group-header-color: #384b6e;--awc-autocomplete-group-header-bg-color: #eef4ff;--awc-autocomplete-group-header-font-size: 0.75rem;--awc-autocomplete-group-header-lh: 18px;--awc-autocomplete-group-header-fw: 400;--awc-autocomplete-tag-padding-x: 0.5rem;--awc-autocomplete-tag-btn-size: 1.25rem;--awc-autocomplete-tag-btn-bg-hover-color: #627291;--awc-autocomplete-tag-gap: 0.25rem;--awc-autocomplete-tag-max-width: 24rem;--awc-autocomplete-tag-bg-color: #e0e7f7;--awc-autocomplete-tag-border-color: #c4cdde;--awc-autocomplete-tag-border-radius: 0.125rem;--awc-autocomplete-tag-font-size: 0.75rem;--awc-autocomplete-blankslate-color: #384b6e;--awc-autocomplete-blankslate-padding-x: 1rem;--awc-autocomplete-blankslate-padding-y: 0.5rem;--awc-autocomplete-error-color: #c01303;--awc-autocomplete-input-height-sm: calc(
2
+ calc(1.5em + .5rem + 2px) - (.25rem * 2) - (1px * 2)
3
+ );--awc-autocomplete-input-height-lg: calc(
4
+ calc(1.5em + 1rem + 2px) - (.5rem * 2) - (1px * 2)
5
+ );--awc-autocomplete-tag-font-size-lg: 0.875rem;--awc-autocomplete-tag-gap-lg: 0.375rem}[hidden][hidden]{display:none !important}.awc-autocomplete{position:relative;display:block}.awc-autocomplete-control{display:flex;align-items:center;position:relative;cursor:text;padding-right:2.5rem;height:100%;min-height:var(--awc-autocomplete-control-min-height)}.awc-autocomplete[data-focus] .awc-autocomplete-control{color:var(--awc-autocomplete-control-focus-color);background-color:#fff;border-color:var(--awc-autocomplete-control-focus-border-color);outline:0;box-shadow:var(--awc-autocomplete-control-focus-box-shadow)}.awc-autocomplete[disabled] .awc-autocomplete-control{cursor:default;background-color:var(--awc-autocomplete-control-disabled-bg-color)}.awc-autocomplete[disabled] .awc-autocomplete-clear-btn{background-color:var(--awc-autocomplete-control-disabled-bg-color);border-color:var(--awc-autocomplete-control-disabled-bg-color)}.awc-autocomplete-input{display:block;min-width:var(--awc-autocomplete-input-min-width);height:var(--awc-autocomplete-input-height);width:100%;margin:0;padding:0;flex:1 1 0%;font:inherit;letter-spacing:inherit;background:none;color:currentColor;border:0;outline:none;background-clip:padding-box}.awc-autocomplete-end-adornment{flex-shrink:0;position:absolute;right:.75rem;top:0;bottom:0;display:flex;align-items:center;margin-right:calc(.75rem / 2 * -1)}.awc-autocomplete-adornment-btn,.awc-autocomplete-adornment-decorator{width:var(--awc-autocomplete-adornment-item-size);height:var(--awc-autocomplete-adornment-item-size);padding:0;display:flex;align-items:center;justify-content:center;border-radius:0.125rem}.awc-autocomplete-clear-btn{display:none;background-color:var(--awc-autocomplete-input-bg-color)}.awc-autocomplete-adornment-decorator{pointer-events:none}.awc-autocomplete-listbox{font-size:var(--awc-autocomplete-listbox-font-size);max-height:var(--awc-autocomplete-listbox-max-height);overflow-y:auto}.awc-autocomplete-listbox.dropdown-menu{display:block}.awc-autocomplete-options{margin:0;padding:0}.awc-autocomplete-group-header{padding:var(--awc-autocomplete-group-header-padding-y) var(--awc-autocomplete-group-header-padding-x);background-color:var(--awc-autocomplete-group-header-bg-color);line-height:var(--awc-autocomplete-group-header-lh);font-size:var(--awc-autocomplete-group-header-font-size);font-weight:var(--awc-autocomplete-group-header-fw);color:var(--awc-autocomplete-group-header-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.awc-autocomplete-option-check{color:var(--awc-autocomplete-option-check-color);flex-shrink:0;visibility:hidden}.awc-autocomplete-option{display:flex;align-items:center;justify-content:space-between;padding:var(--awc-autocomplete-option-padding-y) var(--awc-autocomplete-option-padding-x);line-height:var(--awc-autocomplete-option-lh);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;text-decoration:none;font-size:var(--awc-autocomplete-option-font-size)}.awc-autocomplete-option[data-active],.awc-autocomplete-option:active,.awc-autocomplete-option .active{color:#16181b;background-color:var(--awc-autocomplete-option-hover-bg-color)}.awc-autocomplete-option.disabled{pointer-events:auto}.awc-autocomplete-option[data-active].disabled{color:#adb5bd}.awc-autocomplete-option.disabled .awc-autocomplete-option-check{color:var(--awc-autocomplete-option-check-disabled-color)}.awc-autocomplete-option[aria-selected='true'] .awc-autocomplete-option-check{visibility:visible}.awc-autocomplete-option-text{display:block;flex:1 1 0%;margin-right:0.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.awc-autocomplete-tag{display:flex;align-items:center;-moz-column-gap:0.25rem;column-gap:0.25rem;padding-inline:var(--awc-autocomplete-tag-padding-x);min-width:0;max-width:var(--awc-autocomplete-tag-max-width);height:var(--awc-autocomplete-input-height);vertical-align:middle;background-color:var(--awc-autocomplete-tag-bg-color);border-radius:var(--awc-autocomplete-tag-border-radius);border:1px solid var(--awc-autocomplete-tag-border-color);-webkit-user-select:none;-moz-user-select:none;user-select:none}.awc-autocomplete-tag-text{display:block;line-height:var(--awc-autocomplete-tag-btn-size);font-size:var(--awc-autocomplete-tag-font-size);text-decoration:none;flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.awc-autocomplete-tag-end-adornment{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;margin-right:calc(var(--awc-autocomplete-tag-padding-x) / 2 * -1)}.awc-autocomplete-tag-dismiss-btn{padding:0;display:inline-flex;align-items:center;justify-content:center;height:var(--awc-autocomplete-tag-btn-size);width:var(--awc-autocomplete-tag-btn-size);border-radius:0.125rem}.awc-autocomplete-tag-dismiss-btn:hover{background-color:var(--awc-autocomplete-tag-btn-bg-hover-color);color:#fff}.awc-autocomplete-tag-dismiss-btn[disabled]{background-color:transparent;color:inherit}.awc-autocomplete-blankslate{display:none;text-align:center;padding:var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x);color:var(--awc-autocomplete-blankslate-color)}.awc-autocomplete-error{display:none;text-align:center;padding:var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x);color:var(--awc-autocomplete-error-color)}.awc-autocomplete-spinner{display:flex;align-items:center;justify-content:center;padding:var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x)}.awc-autocomplete--selected .awc-autocomplete-adornment-decorator{display:none}.awc-autocomplete--selected .awc-autocomplete-clear-btn{display:inline-flex}.awc-autocomplete[no-options] .awc-autocomplete-options{display:none}.awc-autocomplete[no-options]:not([error]) .awc-autocomplete-blankslate{display:block}.awc-autocomplete[error] .awc-autocomplete-error{display:block}.awc-autocomplete[error] .awc-autocomplete-spinner{display:none}.awc-autocomplete[multiple] .awc-autocomplete-control{flex-wrap:wrap;gap:var(--awc-autocomplete-tag-gap)}.awc-autocomplete--sm{--awc-autocomplete-input-height: var(--awc-autocomplete-input-height-sm);--awc-autocomplete-tag-btn-size: 1rem}.awc-autocomplete--sm .awc-autocomplete-control{min-height:var(--awc-autocomplete-control-min-height-sm);padding-right:2.25rem}.awc-autocomplete--sm .awc-autocomplete-end-adornment{right:.5rem;margin-right:calc(.5rem / 2 * -1)}.awc-autocomplete--lg{--awc-autocomplete-input-height: var(--awc-autocomplete-input-height-lg);--awc-autocomplete-tag-font-size: var(--awc-autocomplete-tag-font-size-lg);--awc-autocomplete-tag-gap: var(--awc-autocomplete-tag-gap-lg)}.awc-autocomplete--lg .awc-autocomplete-control{min-height:var(--awc-autocomplete-control-min-height-lg);padding-right:2.75rem}.awc-autocomplete--lg .awc-autocomplete-end-adornment{right:1rem;margin-right:calc(1rem / 2 * -1)}.popover{outline:none}.bs-popover-auto[x-placement^='top']{margin-bottom:0}.bs-popover-auto[x-placement^='top']>.arrow{bottom:-.5rem;margin-left:0;margin-right:0}.bs-popover-auto[x-placement^='right']{margin-left:0}.bs-popover-auto[x-placement^='right']>.arrow{left:-.5rem;margin-top:0;margin-bottom:0}.bs-popover-auto[x-placement^='bottom']{margin-top:0}.bs-popover-auto[x-placement^='bottom']>.arrow{top:-.5rem;margin-left:0;margin-right:0}.bs-popover-auto[x-placement^='left']{margin-right:0}.bs-popover-auto[x-placement^='left']>.arrow{right:-.5rem;margin-top:0;margin-bottom:0}
6
+ /*# sourceMappingURL=impulse_view_components.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/bootstrap/scss/_root.scss","../../../src/styles/variables.scss","../../../src/styles/base.scss","../../../src/elements/autocomplete/index.scss","../../../node_modules/bootstrap/scss/_variables.scss","../../../node_modules/bootstrap/scss/mixins/_text-truncate.scss","../../../node_modules/bootstrap/scss/mixins/_gradients.scss","../../../src/elements/popover/index.scss"],"names":[],"mappings":"AAAA,MAGI,eAAc,CAAd,iBAAc,CAAd,iBAAc,CAAd,eAAc,CAAd,cAAc,CAAd,iBAAc,CAAd,iBAAc,CAAd,gBAAc,CAAd,eAAc,CAAd,eAAc,CAAd,aAAc,CAAd,eAAc,CAAd,oBAAc,CAId,kBAAc,CAAd,oBAAc,CAAd,kBAAc,CAAd,eAAc,CAAd,kBAAc,CAAd,iBAAc,CAAd,gBAAc,CAAd,eAAc,CAId,kBAAiC,CAAjC,sBAAiC,CAAjC,sBAAiC,CAAjC,sBAAiC,CAAjC,uBAAiC,CAKnC,kOAAyB,CACzB,6GAAwB,CACzB,MChBC,iEAAsC,CACtC,mEAAyC,CACzC,kEAAyC,CACzC,+CAAuC,CACvC,sDAA8C,CAC9C,qDAA6C,CAC7C,wEAAsC,CACtC,6EAA4C,CAC5C,wCAAmC,CACnC,6FAAgC,CAChC,uCAAkC,CAClC,8CAAuC,CACvC,8CAAqC,CACrC,4CAAsC,CACtC,yCAAoC,CACpC,2CAAoC,CACpC,6CAAoC,CACpC,qCAA6B,CAC7B,iDAAyC,CACzC,8CAAsC,CACtC,uDAA+C,CAC/C,mFAA0C,CAC1C,kDAA0C,CAC1C,8CAAsC,CACtC,iDAAyC,CACzC,kDAA0C,CAC1C,wCAAmC,CACnC,uCAAmC,CACnC,wCAAiC,CACjC,wCAAgC,CAChC,kDAA0C,CAC1C,mCAA2B,CAC3B,uCAAiC,CACjC,wCAAgC,CAChC,4CAAoC,CACpC,8CAAqC,CACrC,yCAAiC,CACjC,4CAAoC,CACpC,6CAAwC,CACxC,+CAAwC,CACxC,uCAA+B,CAE/B;;GAAmC,CAInC;;GAAmC,CAGnC,6CAAoC,CACpC,uCAA8B,CAC/B,iBCpDC,uBAAwB,CACzB,kBCDC,iBAAkB,CAClB,aAAc,CACf,0BAGC,YAAa,CACb,kBAAmB,CACnB,iBAAkB,CAClB,WAAY,CACZ,oBAAqB,CACrB,WAAY,CACZ,qDAAsD,CACvD,wDAKC,iDAAkD,CAClD,qBCZa,CDab,+DAAgE,CAChE,SAAU,CAKR,2DAA4D,CAE/D,sDAIG,cAAe,CACf,kEAAmE,CAHvE,wDAOI,kEAAmE,CACnE,8DAA+D,CAChE,wBAID,aAAc,CACd,iDAAkD,CAClD,2CAA4C,CAC5C,UAAW,CACX,QAAS,CACT,SAAU,CACV,WAAY,CACZ,YAAa,CACb,sBAAuB,CACvB,eAAgB,CAChB,kBAAmB,CACnB,QAAS,CACT,YAAa,CACb,2BAA4B,CAC7B,gCAGC,aAAc,CACd,iBAAkB,CAClB,YCsUkC,CDrUlC,KAAM,CACN,QAAS,CACT,YAAa,CACb,kBAAmB,CACnB,kCAAgD,CACjD,sEAIC,iDAAkD,CAClD,kDAAmD,CACnD,SAAU,CACV,YAAa,CACb,kBAAmB,CACnB,sBAAuB,CACvB,sBAAuB,CACxB,4BAIC,YAAa,CACb,uDAAwD,CACzD,sCAGC,mBAAoB,CACrB,0BAGC,mDAAoD,CACpD,qDAAsD,CACtD,eAAgB,CAHlB,wCAOI,aAAc,CACf,0BAID,QAAS,CACT,SAAU,CACX,+BAIC,qGAAsG,CACtG,8DAA+D,CAC/D,mDAAoD,CACpD,wDAAyD,CACzD,mDAAoD,CACpD,gDAAiD,CE9GjD,eAAgB,CAChB,sBAAuB,CACvB,kBAAmB,CF8GpB,+BAGC,gDAAiD,CACjD,aAAc,CACd,iBAAkB,CACnB,yBAGC,YAAa,CACb,kBAAmB,CACnB,6BAA8B,CAC9B,yFAA0F,CAC1F,6CAA8C,CAC9C,cAAe,CACf,wBAAiB,CAAjB,qBAAiB,CAAjB,gBAAiB,CACjB,oBAAqB,CACrB,kDAAmD,CATrD,uGAgBI,aC4nBqD,CElwBrD,8DHuIkE,CAjBtE,kCAuBI,mBAAoB,CAvBxB,+CA6BI,aC7Ic,CDgHlB,iEAiCI,yDAA0D,CAC3D,8EAID,kBAAmB,CACpB,8BAGC,aAAc,CACd,WAAY,CACZ,oBAAqB,CEpKrB,eAAgB,CAChB,sBAAuB,CACvB,kBAAmB,CFoKpB,sBAIC,YAAa,CACb,kBAAmB,CACnB,uBAAmB,CAAnB,kBAAmB,CACnB,oDAAqD,CACrD,WAAY,CACZ,+CAAgD,CAChD,2CAA4C,CAC5C,qBAAsB,CACtB,qDAAsD,CACtD,uDAAwD,CACxD,yDAA0D,CAC1D,wBAAa,CAAb,qBAAa,CAAb,gBAAiB,CAClB,2BAGC,aAAc,CACd,gDAAiD,CACjD,+CAAgD,CAChD,oBAAqB,CACrB,WAAY,CE7LZ,eAAgB,CAChB,sBAAuB,CACvB,kBAAmB,CF6LpB,oCAGC,aAAc,CACd,mBAAoB,CACpB,kBAAmB,CACnB,sBAAuB,CACvB,iEAAkE,CACnE,kCAGC,SAAU,CACV,mBAAoB,CACpB,kBAAmB,CACnB,sBAAuB,CACvB,2CAA4C,CAC5C,0CAA2C,CAC3C,sBAAuB,CAPzB,wCAUI,+DAAgE,CAChE,UCjNW,CDsMf,4CAeI,4BAA6B,CAC7B,aAAc,CACf,6BAKD,YAAa,CACb,iBAAkB,CAClB,iGAAkG,CAClG,8CAA+C,CAChD,wBAIC,YAAa,CACb,iBAAkB,CAClB,iGAAkG,CAClG,yCAA0C,CAC3C,0BAIC,YAAa,CACb,kBAAmB,CACnB,sBAAuB,CACvB,iGAAkG,CACnG,kEAMC,YAAa,CACd,wDAIC,mBAAoB,CACrB,wDAKG,YAAa,CAFjB,wEAMI,aAAc,CACf,iDAMC,aAAc,CAFlB,mDAMI,YAAa,CACd,sDAKD,cAAe,CACf,mCAAoC,CACrC,sBAOC,wEAAgC,CAChC,qCAAgC,CAFlC,gDAKI,wDAAyD,CACzD,qBAAsB,CAN1B,sDAUI,WC+F+B,CD9F/B,iCAAmD,CACpD,sBAMD,wEAAgC,CAChC,0EAAiC,CACjC,8DAA2B,CAH7B,gDAMI,wDAAyD,CACzD,qBAAsB,CAP1B,sDAWI,UCkF8B,CDjF9B,gCAAmD,CACpD,SIlUD,YAAa,CACd,qCAKG,eAAgB,CAFpB,4CAKM,aH43BmC,CG33BnC,aAAc,CACd,cAAe,CAPrB,uCAYI,aAAc,CAZlB,8CAeM,WHk3BmC,CGj3BnC,YAAa,CACb,eAAgB,CAjBtB,wCAsBI,YAAa,CAtBjB,+CAyBM,UHw2BmC,CGv2BnC,aAAc,CACd,cAAe,CA3BrB,sCAgCI,cAAe,CAhCnB,6CAmCM,YH81BmC,CG71BnC,YAAa,CACb,eAAgB","file":"impulse_view_components.css","sourcesContent":[":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n",":root {\n /** Autocomplete */\n --awc-autocomplete-control-min-height: #{$input-height};\n --awc-autocomplete-control-min-height-sm: #{$input-height-sm};\n --awc-autocomplete-control-min-height-lg: #{$input-height-lg};\n --awc-autocomplete-control-focus-color: #{$input-focus-color};\n --awc-autocomplete-control-focus-border-color: #{$input-focus-border-color};\n --awc-autocomplete-control-disabled-bg-color: #eef4ff; // n20\n --awc-autocomplete-control-box-shadow: #{$input-box-shadow};\n --awc-autocomplete-control-focus-box-shadow: #{$input-focus-box-shadow};\n --awc-autocomplete-input-min-width: 2rem;\n --awc-autocomplete-input-height: calc(#{$input-height} - (#{$input-padding-y} * 2) - (#{$input-border-width} * 2));\n --awc-autocomplete-input-bg-color: #{$input-bg};\n --awc-autocomplete-adornment-item-size: 1.5rem;\n --awc-autocomplete-listbox-font-size: 0.875rem;\n --awc-autocomplete-listbox-max-height: 256px;\n --awc-autocomplete-option-padding-x: 1rem;\n --awc-autocomplete-option-padding-y: 0.5rem;\n --awc-autocomplete-option-font-size: 0.875rem;\n --awc-autocomplete-option-lh: 1.25rem;\n --awc-autocomplete-option-hover-bg-color: #{$dropdown-link-hover-bg};\n --awc-autocomplete-option-check-color: #38b57c; // green-light-500\n --awc-autocomplete-option-check-disabled-color: #afe1cb; // green-light-200\n --awc-autocomplete-group-header-padding-x: var(--awc-autocomplete-option-padding-x);\n --awc-autocomplete-group-header-padding-y: 0.25rem;\n --awc-autocomplete-group-header-color: #384b6e; // n600\n --awc-autocomplete-group-header-bg-color: #eef4ff; // n20\n --awc-autocomplete-group-header-font-size: 0.75rem;\n --awc-autocomplete-group-header-lh: 18px;\n --awc-autocomplete-group-header-fw: 400;\n --awc-autocomplete-tag-padding-x: 0.5rem;\n --awc-autocomplete-tag-btn-size: 1.25rem;\n --awc-autocomplete-tag-btn-bg-hover-color: #627291; // n300\n --awc-autocomplete-tag-gap: 0.25rem;\n --awc-autocomplete-tag-max-width: 24rem;\n --awc-autocomplete-tag-bg-color: #e0e7f7; // n30\n --awc-autocomplete-tag-border-color: #c4cdde; // n50\n --awc-autocomplete-tag-border-radius: 0.125rem;\n --awc-autocomplete-tag-font-size: 0.75rem;\n --awc-autocomplete-blankslate-color: #384b6e; // n600\n --awc-autocomplete-blankslate-padding-x: 1rem;\n --awc-autocomplete-blankslate-padding-y: 0.5rem;\n --awc-autocomplete-error-color: #c01303; // red-500\n // sm\n --awc-autocomplete-input-height-sm: calc(\n #{$input-height-sm} - (#{$input-padding-y-sm} * 2) - (#{$input-border-width} * 2)\n );\n // lg\n --awc-autocomplete-input-height-lg: calc(\n #{$input-height-lg} - (#{$input-padding-y-lg} * 2) - (#{$input-border-width} * 2)\n );\n --awc-autocomplete-tag-font-size-lg: 0.875rem;\n --awc-autocomplete-tag-gap-lg: 0.375rem;\n}\n","[hidden][hidden] {\n display: none !important;\n}\n",".awc-autocomplete {\n position: relative;\n display: block;\n}\n\n.awc-autocomplete-control {\n display: flex;\n align-items: center;\n position: relative;\n cursor: text;\n padding-right: 2.5rem;\n height: 100%;\n min-height: var(--awc-autocomplete-control-min-height);\n}\n\n// https://github.com/twbs/bootstrap/blob/v4.6.0/scss/mixins/_forms.scss#L13\n// Mimic input focus state.\n.awc-autocomplete[data-focus] .awc-autocomplete-control {\n color: var(--awc-autocomplete-control-focus-color);\n background-color: $input-focus-bg;\n border-color: var(--awc-autocomplete-control-focus-border-color);\n outline: 0;\n\n @if $enable-shadows {\n @include box-shadow(var(--awc-autocomplete-control-box-shadow), var(--awc-autocomplete-control-focus-box-shadow));\n } @else {\n box-shadow: var(--awc-autocomplete-control-focus-box-shadow);\n }\n}\n\n.awc-autocomplete[disabled] {\n .awc-autocomplete-control {\n cursor: default;\n background-color: var(--awc-autocomplete-control-disabled-bg-color);\n }\n\n .awc-autocomplete-clear-btn {\n background-color: var(--awc-autocomplete-control-disabled-bg-color);\n border-color: var(--awc-autocomplete-control-disabled-bg-color);\n }\n}\n\n.awc-autocomplete-input {\n display: block;\n min-width: var(--awc-autocomplete-input-min-width);\n height: var(--awc-autocomplete-input-height);\n width: 100%;\n margin: 0;\n padding: 0;\n flex: 1 1 0%;\n font: inherit;\n letter-spacing: inherit;\n background: none;\n color: currentColor;\n border: 0;\n outline: none;\n background-clip: padding-box;\n}\n\n.awc-autocomplete-end-adornment {\n flex-shrink: 0;\n position: absolute;\n right: $input-padding-x;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n margin-right: calc(#{$input-padding-x} / 2 * -1);\n}\n\n.awc-autocomplete-adornment-btn,\n.awc-autocomplete-adornment-decorator {\n width: var(--awc-autocomplete-adornment-item-size);\n height: var(--awc-autocomplete-adornment-item-size);\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 0.125rem;\n}\n\n// Hide clear btn when there are no selections\n.awc-autocomplete-clear-btn {\n display: none;\n background-color: var(--awc-autocomplete-input-bg-color);\n}\n\n.awc-autocomplete-adornment-decorator {\n pointer-events: none;\n}\n\n.awc-autocomplete-listbox {\n font-size: var(--awc-autocomplete-listbox-font-size);\n max-height: var(--awc-autocomplete-listbox-max-height);\n overflow-y: auto;\n\n // Use native [hidden] attribute to show/hide listbox.\n &.dropdown-menu {\n display: block;\n }\n}\n\n.awc-autocomplete-options {\n margin: 0;\n padding: 0;\n}\n\n// Group header\n.awc-autocomplete-group-header {\n padding: var(--awc-autocomplete-group-header-padding-y) var(--awc-autocomplete-group-header-padding-x);\n background-color: var(--awc-autocomplete-group-header-bg-color);\n line-height: var(--awc-autocomplete-group-header-lh);\n font-size: var(--awc-autocomplete-group-header-font-size);\n font-weight: var(--awc-autocomplete-group-header-fw);\n color: var(--awc-autocomplete-group-header-color);\n @include text-truncate();\n}\n\n.awc-autocomplete-option-check {\n color: var(--awc-autocomplete-option-check-color);\n flex-shrink: 0;\n visibility: hidden;\n}\n\n.awc-autocomplete-option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--awc-autocomplete-option-padding-y) var(--awc-autocomplete-option-padding-x);\n line-height: var(--awc-autocomplete-option-lh);\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n font-size: var(--awc-autocomplete-option-font-size);\n\n // https://github.com/twbs/bootstrap/blob/v4.6.0/scss/_dropdown.scss#L148C27-L148C27\n // Mimic dropdown-item hover state.\n &[data-active],\n &:active,\n .active {\n color: $dropdown-link-hover-color;\n @include gradient-bg(var(--awc-autocomplete-option-hover-bg-color));\n }\n\n // Enable hover state.\n // TODO: Disabled options cannot be activated. Need to fix this in the combobox package.\n &.disabled {\n pointer-events: auto;\n }\n\n // https://github.com/twbs/bootstrap/blob/v4.6.0/scss/_dropdown.scss#L161\n // Mimic dropdown-item disabled state.\n &[data-active].disabled {\n color: $dropdown-link-disabled-color;\n }\n\n &.disabled .awc-autocomplete-option-check {\n color: var(--awc-autocomplete-option-check-disabled-color);\n }\n}\n\n.awc-autocomplete-option[aria-selected='true'] .awc-autocomplete-option-check {\n visibility: visible;\n}\n\n.awc-autocomplete-option-text {\n display: block;\n flex: 1 1 0%;\n margin-right: 0.25rem;\n @include text-truncate();\n}\n\n// Tag\n.awc-autocomplete-tag {\n display: flex;\n align-items: center;\n column-gap: 0.25rem;\n padding-inline: var(--awc-autocomplete-tag-padding-x);\n min-width: 0;\n max-width: var(--awc-autocomplete-tag-max-width);\n height: var(--awc-autocomplete-input-height);\n vertical-align: middle;\n background-color: var(--awc-autocomplete-tag-bg-color);\n border-radius: var(--awc-autocomplete-tag-border-radius);\n border: 1px solid var(--awc-autocomplete-tag-border-color);\n user-select: none;\n}\n\n.awc-autocomplete-tag-text {\n display: block;\n line-height: var(--awc-autocomplete-tag-btn-size);\n font-size: var(--awc-autocomplete-tag-font-size);\n text-decoration: none;\n flex: 1 1 0%;\n @include text-truncate();\n}\n\n.awc-autocomplete-tag-end-adornment {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: calc(var(--awc-autocomplete-tag-padding-x) / 2 * -1);\n}\n\n.awc-autocomplete-tag-dismiss-btn {\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--awc-autocomplete-tag-btn-size);\n width: var(--awc-autocomplete-tag-btn-size);\n border-radius: 0.125rem;\n\n &:hover {\n background-color: var(--awc-autocomplete-tag-btn-bg-hover-color);\n color: $white;\n }\n\n &[disabled] {\n background-color: transparent;\n color: inherit;\n }\n}\n\n// Blankslate\n.awc-autocomplete-blankslate {\n display: none;\n text-align: center;\n padding: var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x);\n color: var(--awc-autocomplete-blankslate-color);\n}\n\n// Error\n.awc-autocomplete-error {\n display: none;\n text-align: center;\n padding: var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x);\n color: var(--awc-autocomplete-error-color);\n}\n\n// Spinner\n.awc-autocomplete-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--awc-autocomplete-blankslate-padding-y) var(--awc-autocomplete-blankslate-padding-x);\n}\n\n/** States **/\n\n// Selected\n.awc-autocomplete--selected .awc-autocomplete-adornment-decorator {\n display: none;\n}\n\n// Show clear btn\n.awc-autocomplete--selected .awc-autocomplete-clear-btn {\n display: inline-flex;\n}\n\n// No options\n.awc-autocomplete[no-options] {\n .awc-autocomplete-options {\n display: none;\n }\n\n &:not([error]) .awc-autocomplete-blankslate {\n display: block;\n }\n}\n\n// Error\n.awc-autocomplete[error] {\n .awc-autocomplete-error {\n display: block;\n }\n\n .awc-autocomplete-spinner {\n display: none;\n }\n}\n\n// Multiple\n.awc-autocomplete[multiple] .awc-autocomplete-control {\n flex-wrap: wrap;\n gap: var(--awc-autocomplete-tag-gap);\n}\n\n/** Sizes **/\n\n// sm\n// https://github.com/twbs/bootstrap/blob/v4.6.0/scss/_forms.scss#L152\n.awc-autocomplete--sm {\n --awc-autocomplete-input-height: var(--awc-autocomplete-input-height-sm);\n --awc-autocomplete-tag-btn-size: 1rem;\n\n .awc-autocomplete-control {\n min-height: var(--awc-autocomplete-control-min-height-sm);\n padding-right: 2.25rem;\n }\n\n .awc-autocomplete-end-adornment {\n right: $input-padding-x-sm;\n margin-right: calc(#{$input-padding-x-sm} / 2 * -1);\n }\n}\n\n// lg\n// https://github.com/twbs/bootstrap/blob/v4.6.0/scss/_forms.scss#L160\n.awc-autocomplete--lg {\n --awc-autocomplete-input-height: var(--awc-autocomplete-input-height-lg);\n --awc-autocomplete-tag-font-size: var(--awc-autocomplete-tag-font-size-lg);\n --awc-autocomplete-tag-gap: var(--awc-autocomplete-tag-gap-lg);\n\n .awc-autocomplete-control {\n min-height: var(--awc-autocomplete-control-min-height-lg);\n padding-right: 2.75rem;\n }\n\n .awc-autocomplete-end-adornment {\n right: $input-padding-x-lg;\n margin-right: calc(#{$input-padding-x-lg} / 2 * -1);\n }\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$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\n$grays: () !default;\n$grays: map-merge(\n (\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 ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\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 ),\n $colors\n);\n\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-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\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 ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\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\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-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\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$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !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$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\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$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\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: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n$transition-collapse-width: width .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"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$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !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$line-height-base: 1.5 !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\n$headings-margin-bottom: $spacer * .5 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\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$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\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: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $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$input-btn-line-height-sm: $line-height-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$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\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$btn-line-height-sm: $input-btn-line-height-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$btn-line-height-lg: $input-btn-line-height-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-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !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\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\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$input-line-height-sm: $input-btn-line-height-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$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !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-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 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-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\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\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size * .5 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-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,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\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 ),\n $form-validation-states\n);\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$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !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\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer * .5 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer * .5 !default;\n$navbar-padding-x: $spacer !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\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\n$navbar-nav-scroll-max-height: 75vh !default;\n\n$navbar-dark-color: rgba($white, .5) !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,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !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,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !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\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\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: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !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: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !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$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\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-border-radius-sm: $border-radius-sm !default;\n$pagination-border-radius-lg: $border-radius-lg !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !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\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width * .5 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\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: .25rem !default;\n$tooltip-padding-x: .5rem !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\n// Form tooltips must come after regular tooltips\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: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\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: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !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\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !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(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\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: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !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: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !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\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !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\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\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: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !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: .75rem !default;\n$list-group-item-padding-x: 1.25rem !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\n\n// Image thumbnails\n\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: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\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-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !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\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-vertical-align: -.125em !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !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: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n",".popover {\n outline: none;\n}\n\n// FloatingUI changes\n.bs-popover-auto {\n &[x-placement^='top'] {\n margin-bottom: 0;\n\n > .arrow {\n bottom: -$popover-arrow-height;\n margin-left: 0;\n margin-right: 0;\n }\n }\n\n &[x-placement^='right'] {\n margin-left: 0;\n\n > .arrow {\n left: -$popover-arrow-height;\n margin-top: 0;\n margin-bottom: 0;\n }\n }\n\n &[x-placement^='bottom'] {\n margin-top: 0;\n\n > .arrow {\n top: -$popover-arrow-height;\n margin-left: 0;\n margin-right: 0;\n }\n }\n\n &[x-placement^='left'] {\n margin-right: 0;\n\n > .arrow {\n right: -$popover-arrow-height;\n margin-top: 0;\n margin-bottom: 0;\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@floating-ui/dom")):"function"==typeof define&&define.amd?define(["@floating-ui/dom"],e):e(("undefined"!=typeof globalThis?globalThis:t||self).FloatingUIDOM)}(this,function(g){"use strict";function t(t,e,i,s){var n,o=arguments.length,r=o<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,i,s);else for(var a=t.length-1;0<=a;a--)(n=t[a])&&(r=(o<3?n(r):3<o?n(e,i,r):n(e,i))||r);return 3<o&&r&&Object.defineProperty(e,i,r),r}var e=0;function s(){return e+=1,`ambiki-${Math.random().toString().slice(2,6)}-`+e}function i(t){return!t.hasAttribute("disabled")&&"true"!==t.getAttribute("aria-disabled")}var D=!!navigator.userAgent.match(/Macintosh/),K=class{input;list;multiple;isMouseMoving=!1;constructor(t,e,{multiple:i=!1}={}){this.input=t,this.list=e,this.multiple=i,this.list.id||(this.list.id=s()),this.input.getAttribute("aria-expanded")||this.input.setAttribute("aria-expanded","false"),this.multiple&&this.input.setAttribute("aria-multiselectable","true"),this.input.setAttribute("role","combobox"),this.input.setAttribute("aria-haspopup","listbox"),this.input.setAttribute("aria-autocomplete","list"),this.list.setAttribute("role","listbox"),this.onKeydown=this.onKeydown.bind(this),this.onClick=this.onClick.bind(this),this.onListMouseover=this.onListMouseover.bind(this),this.onListMousemove=this.onListMousemove.bind(this)}start(){this.isMouseMoving=!1,this.input.setAttribute("aria-expanded","true"),this.input.setAttribute("aria-controls",this.list.id),this.input.addEventListener("keydown",this.onKeydown),this.list.addEventListener("click",this.onClick),this.list.addEventListener("mouseover",this.onListMouseover),this.list.addEventListener("mousemove",this.onListMousemove),this.initializeOptions()}stop(){this.isMouseMoving=!1,this.input.setAttribute("aria-expanded","false"),this.input.removeAttribute("aria-controls"),this.input.removeEventListener("keydown",this.onKeydown),this.list.removeEventListener("click",this.onClick),this.list.removeEventListener("mouseover",this.onListMouseover),this.list.removeEventListener("mousemove",this.onListMousemove),this.deselectAll(),this.deactivate()}onKeydown(t){if(this.isMouseMoving=!1,!(t.shiftKey||t.metaKey||t.altKey||!D&&t.ctrlKey))switch(t.key){case"Enter":case"Tab":this.activeOption&&i(this.activeOption)&&(t.preventDefault(),t.stopPropagation(),this.activeOption.click());break;case"Escape":this.deactivate();break;case"ArrowDown":t.preventDefault(),t.stopPropagation(),this.activeOption?this.move(1):this.activate(this.visibleOptions[0],{scroll:!0});break;case"ArrowUp":t.preventDefault(),t.stopPropagation(),this.activeOption?this.move(-1):this.activate(this.visibleOptions[this.visibleOptions.length-1],{scroll:!0});break;case"Home":t.preventDefault(),t.stopPropagation(),this.activate(this.visibleOptions[0],{scroll:!0});break;case"End":t.preventDefault(),t.stopPropagation(),this.activate(this.visibleOptions[this.visibleOptions.length-1],{scroll:!0});break;default:t.ctrlKey||this.deactivate()}}onClick(t){t=n(t.target);t&&i(t)&&(this.multiple&&this.isSelected(t)?this.deselect(t):this.select(t),t.dispatchEvent(new CustomEvent("combobox:commit",{bubbles:!0})))}onListMouseover(t){var e;this.isMouseMoving?(e=n(t.target))&&this.activate(e):t.preventDefault()}onListMousemove(t){!this.isMouseMoving&&(this.isMouseMoving=!0,t=n(t.target))&&this.activate(t)}select(t){if(this.multiple)t.setAttribute("aria-selected","true");else for(var e of this.options)e.setAttribute("aria-selected",(e===t).toString())}deselect(t){t.setAttribute("aria-selected","false")}deselectAll(){for(var t of this.options)this.deselect(t)}activate(t,{scroll:e=!1}={}){for(var i of this.options)i.id===t.id?(i.setAttribute("data-active",""),this.input.setAttribute("aria-activedescendant",i.id),e&&i.scrollIntoView({block:"nearest"})):i.removeAttribute("data-active")}deactivate(){this.input.removeAttribute("aria-activedescendant");for(var t of Array.from(this.list.querySelectorAll('[role="option"][data-active]')))t.removeAttribute("data-active")}isSelected(t){return"true"===t.getAttribute("aria-selected")}get options(){return Array.from(this.list.querySelectorAll('[role="option"]'))}get visibleOptions(){return this.options.filter(q)}get activeOption(){return this.list.querySelector("[data-active]")}move(t){this.activeOption&&(t=function(t,e,i){let s=t.indexOf(e),n=(s===t.length-1&&1===i&&(s=-1),1===i?0:t.length-1);return t[n=e&&0<=s&&0<=(e=s+i)&&e<t.length?e:n]}(this.visibleOptions,this.activeOption,t),this.activate(t,{scroll:!0}))}initializeOptions(){for(var t of this.options)t.setAttribute("tabindex","-1"),t.id||(t.id=s()),t.hasAttribute("aria-selected")||this.deselect(t)}};function n(t){return t&&t.closest('[role="option"]')||!1}function q(t){return!t.hidden&&!(t instanceof HTMLInputElement&&"hidden"===t.type)&&(0<t.offsetWidth||0<t.offsetHeight)}function o({type:i=String}={}){return(t,e)=>{t.constructor.addProperty(e,{type:i})}}function r(e){return t=>{try{window.customElements.define(e,t),window[t.name]=customElements.get(e)}catch(t){if(!(t instanceof DOMException&&"NotSupportedError"===t.name))throw t}}}function a(){return(t,e)=>{t.constructor.registerTarget(e)}}const F=/^(?:(.+?)?(?:@(window|document))?->)?(.+)#(.+)?$/;function U(t){var[,t,e,i,s]=t.trim().match(F)||[];return{eventName:t,eventTarget:"window"===(t=e)?window:"document"===t?document:void 0,methodName:s,identifier:i}}class j{constructor(){this.map=new Map}add(t,e){l(this.map,t).add(e)}delete(t,e){l(this.map,t).delete(e),0===this.get(t)?.size&&this.map.delete(t)}clear(){this.map.clear()}get values(){return Array.from(this.map.values()).reduce((t,e)=>t.concat(Array.from(e)),[])}get(t){return this.map.get(t)}has(t,e){return!!this.get(t)?.has(e)}}function l(t,e){let i=t.get(e);return i||(i=new Set,t.set(e,i)),i}class B{constructor(t,e,i,s){this.instance=t,this.eventTarget=e,this.eventName=i,this.methodName=s,this.instance=t,this.eventTarget=e,this.eventName=i,this.methodName=s}start(){this.eventTarget.addEventListener(this.eventName,this)}stop(){this.eventTarget.removeEventListener(this.eventName,this)}handleEvent(t){var e=this.instance[this.methodName];"function"==typeof e&&e.call(this.instance,t)}}function c(t,e){return t.getAttribute(e)?.trim().split(/\s+/)||[]}class ${constructor(t,e,i){this.element=t,this.delegate=e,this.observerOptions=i,this.started=!1,this.element=t,this.delegate=e,this.observer=new MutationObserver(t=>this.processMutations(t)),this.observerOptions=i}start(){this.started||(this.started=!0,this.observer.observe(this.element,{childList:!0,subtree:!0,...this.observerOptions}))}stop(){this.started&&(this.observer.takeRecords(),this.observer.disconnect(),this.started=!1)}processMutations(t){if(this.started)for(const e of t)this.processMutation(e)}processMutation(t){"attributes"===t.type&&t.target instanceof Element?this.processAttributeChange(t.target,t.attributeName):"childList"===t.type&&(this.processRemovedNodes(t.removedNodes),this.processAddedNodes(t.addedNodes))}processAttributeChange(t,e){e&&this.delegate.elementAttributeChanged(t,e)}processRemovedNodes(t){for(const i of Array.from(t)){var e=this.elementFromNode(i);e&&this.delegate.elementDisconnected(e)}}processAddedNodes(t){for(const i of Array.from(t)){var e=this.elementFromNode(i);e&&this.elementIsActive(e)&&this.delegate.elementConnected(e)}}elementFromNode(t){if(t.nodeType===Node.ELEMENT_NODE)return t}elementIsActive(t){return t.isConnected===this.element.isConnected&&this.element.contains(t)}}class h{constructor(t,e,i){this.instance=t,this.attributeName=e,this.delegate=i,this.instance=t,this.attributeName=e,this.elementObserver=new $(this.instance,this,{attributeFilter:[this.attributeName]}),this.delegate=i}start(){this.elementObserver.start()}stop(){this.elementObserver.stop()}elementConnected(t){var e=Array.from(t.querySelectorAll(`[${this.attributeName}]`));t.hasAttribute(this.attributeName)&&e.push(t);for(const i of e)this.delegate.elementConnected(i)}elementDisconnected(t){var e=Array.from(t.querySelectorAll(`[${this.attributeName}]`));t.hasAttribute(this.attributeName)&&e.push(t);for(const i of e)this.delegate.elementDisconnected(i)}elementAttributeChanged(t,e){e===this.attributeName&&this.delegate.elementAttributeChanged?.(t,e)}}const u="data-action";class z{constructor(t){this.instance=t,this.eventListenerMap=new j,this.instance=t,this.attributeObserver=new h(this.instance,u,this)}start(){this.attributeObserver.start();var t=Array.from(this.instance.querySelectorAll(`[${u}]`));this.instance.hasAttribute(u)&&t.push(this.instance),t.forEach(t=>this.bindActions(t))}stop(){this.eventListenerMap.values.forEach(t=>t.stop()),this.eventListenerMap.clear(),this.attributeObserver.stop()}elementConnected(t){this.bindActions(t)}elementDisconnected(t){this.unbindActions(t)}elementAttributeChanged(t){this.unbindActions(t),this.bindActions(t)}bindActions(n){c(n,u).forEach(t=>{var{eventName:t,eventTarget:e,methodName:i,identifier:s}=U(t);t&&s===this.identifier&&i&&(s=new B(this.instance,e||n,t,i),this.eventListenerMap.add(n,s),s.start())})}unbindActions(e){var t=this.eventListenerMap.get(e);t&&t.forEach(t=>{t.stop(),this.eventListenerMap.delete(e,t)})}get identifier(){return this.instance.identifier}}const _=/(-|_|\.|\s)+(.)?/g,H=/(^|\/)([A-Z])/g,J=/[ _]/g,Q=/([a-z\d])([A-Z])/g;function d(t){return t.replace(Q,"$1_$2").toLowerCase().replace(J,"-")}function p(t,e=""){if(!t)return e;try{return JSON.parse(t)}catch{return e}}class Z{constructor(t){this.instance=t,this.instance=t}start(){for(var[t,{type:e}]of this.values.entries())this.initializeProperty(t,e)}stop(){}initializeProperty(t,e){var i=d(t),s=this.instance[t],e={configurable:!0,...function(e,i,t){switch(t){case Number:return{get:()=>Number(e.getAttribute(i)||0),set:t=>e.setAttribute(i,(t||0).toString())};case Boolean:return{get:()=>e.hasAttribute(i)&&"false"!==e.getAttribute(i),set:t=>{t?e.setAttribute(i,""):e.removeAttribute(i)}};case Array:return{get:()=>JSON.parse(e.getAttribute(i)||"[]"),set:t=>e.setAttribute(i,JSON.stringify(t)||"[]")};case Object:return{get:()=>JSON.parse(e.getAttribute(i)||"{}"),set:t=>e.setAttribute(i,JSON.stringify(t)||"{}")};default:return{get:()=>e.getAttribute(i)||"",set:t=>e.setAttribute(i,t||"")}}}(this.instance,i,e)};Object.defineProperty(this.instance,t,e),this.instance.hasAttribute(i)||e.set?.(s)}get values(){return Object.getPrototypeOf(this.instance).constructor.properties}}const m="data-target";class G{constructor(t){this.instance=t,this.instance=t,this.attributeObserver=new h(this.instance,m,this)}start(){this.attributeObserver.start();for(var[t]of this.targetKeys.entries())this.initializeKey(t)}stop(){for(var[t]of this.targetKeys.entries())this.terminateKey(t);this.attributeObserver.stop()}elementConnected(i){c(i,m).forEach(t=>{var[t,e]=t.split(".");t&&e&&t===this.identifier&&this.targetKeys.has(e)&&(this.defineProperty(e,i),this.processAddedElement(e,i))})}elementDisconnected(i){c(i,m).forEach(t=>{var[t,e]=t.split(".");t&&e&&t===this.identifier&&this.targetKeys.has(e)&&(this.processRemovedElement(e,i),this.defineProperty(e,null))})}initializeKey(t){var e;this.targetKeys.has(t)&&(e=this.findTarget(t),this.defineProperty(t,e),e)&&this.processAddedElement(t,e)}terminateKey(t){var e;this.targetKeys.has(t)&&(e=this.findTarget(t))&&this.processRemovedElement(t,e)}defineProperty(t,e){Object.defineProperty(this.instance,t,{configurable:!0,get:()=>e})}processAddedElement(t,e){t=this.instance[t+"Connected"];"function"==typeof t&&t.call(this.instance,e)}processRemovedElement(t,e){t=this.instance[t+"Disconnected"];"function"==typeof t&&t.call(this.instance,e)}findTarget(t){t=`[${m}~="${this.identifier}.${t}"]`;return this.instance.querySelector(t)}get targetKeys(){return Object.getPrototypeOf(this.instance).constructor.targetKeys}get identifier(){return this.instance.identifier}}const f="data-target";class W{constructor(t){this.instance=t,this.instance=t,this.attributeObserver=new h(this.instance,f,this)}start(){this.attributeObserver.start();for(var[t]of this.targetKeys.entries())this.initializeKey(t)}stop(){for(var[t]of this.targetKeys.entries())this.terminateKey(t);this.attributeObserver.stop()}elementConnected(i){c(i,f).forEach(t=>{var[t,e]=t.split(".");t&&e&&t===this.identifier&&this.targetKeys.has(e)&&(this.defineProperty(e,this.findTargets(e)),this.processAddedElement(e,i))})}elementDisconnected(i){c(i,f).forEach(t=>{var[t,e]=t.split(".");t&&e&&t===this.identifier&&this.targetKeys.has(e)&&(this.processRemovedElement(e,i),this.defineProperty(e,this.findTargets(e)))})}initializeKey(e){var t;this.targetKeys.has(e)&&(t=this.findTargets(e),this.defineProperty(e,t),t.forEach(t=>this.processAddedElement(e,t)))}terminateKey(e){this.targetKeys.has(e)&&this.findTargets(e).forEach(t=>this.processRemovedElement(e,t))}defineProperty(t,e){Object.defineProperty(this.instance,t,{configurable:!0,get:()=>e})}processAddedElement(t,e){t=this.instance[t+"Connected"];"function"==typeof t&&t.call(this.instance,e)}processRemovedElement(t,e){t=this.instance[t+"Disconnected"];"function"==typeof t&&t.call(this.instance,e)}findTargets(t){t=`[${f}~="${this.identifier}.${t}"]`;return Array.from(this.instance.querySelectorAll(t))}get targetKeys(){return Object.getPrototypeOf(this.instance).constructor.targetsKeys}get identifier(){return this.instance.identifier}}class v extends HTMLElement{constructor(){super(...arguments),this.property=new Z(this),this.targets=new W(this),this.target=new G(this),this.action=new z(this),this._started=!1}async connectedCallback(){await new Promise(t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>t()):t()}),customElements.upgrade(this),this.property.start(),await this._resolveUndefinedElements(),this.targets.start(),this.target.start(),this.action.start(),this._started=!0,this.setAttribute("data-impulse-element",""),this.connected()}static get observedAttributes(){return Array.from(this.properties.keys()).map(t=>d(t))}attributeChangedCallback(t,e,i){if(this._started&&e!==i){var s=t.replace(_,(t,e,i)=>i?i.toUpperCase():"").replace(H,t=>t.toLowerCase()),n=this[s+"Changed"];if("function"==typeof n){var o=Object.getPrototypeOf(this).constructor["properties"],o=o.get(s);if(!o)throw new Error(`Unregistered attribute changed: ${t}. Register the attribute using the @property() decorator.`);var{newValue:s,oldValue:t}=function(t,e,i){switch(i){case Boolean:var s=t=>null!==t&&"false"!==t;return{newValue:s(t),oldValue:s(e)};case Number:return{newValue:Number(t),oldValue:Number(e)};case Array:return{newValue:p(t,[]),oldValue:p(e,[])};case Object:return{newValue:p(t,{}),oldValue:p(e,{})};default:return{newValue:t,oldValue:e}}}(i,e,o.type);n.call(this,s,t)}}}disconnectedCallback(){this.action.stop(),this.target.stop(),this.targets.stop(),this.property.stop(),this.disconnected(),this._started=!1}connected(){}disconnected(){}static addProperty(t,{type:e}){this.properties.set(t,{type:e})}static registerTargets(t){this.targetsKeys.add(t)}static registerTarget(t){this.targetKeys.add(t)}emit(t,{target:e=this,prefix:i=this.identifier,detail:s={},...n}={}){i=new CustomEvent(i?i+":"+t:t,{bubbles:!0,composed:!0,detail:s,...n});return e.dispatchEvent(i),i}get identifier(){return this.tagName.toLowerCase()}async _resolveUndefinedElements(){var t=Array.from(this.querySelectorAll(":not(:defined)")).map(t=>customElements.whenDefined(t.localName));await Promise.all(t)}}function b(r,{referenceElement:a,popupElement:l,arrowElement:c,arrowPadding:h=0,middleware:u=[],offsetOptions:d=0,placement:p="bottom-start",flipOptions:m,shiftOptions:f,strategy:v="fixed",sync:b}){let e;async function t(){if(r.open&&a){var t=[g.offset(d)];b?t.push(g.size({apply:({rects:t})=>{var e="height"===b||"both"===b;l.style.width="width"===b||"both"===b?t.reference.width+"px":"",l.style.height=e?t.reference.height+"px":""}})):(l.style.width="",l.style.height=""),t.push(g.flip(m)),t.push(g.shift(f)),c&&t.push(g.arrow({element:c,padding:h})),t.concat(u);const{x:e,y:i,placement:s,strategy:n,middlewareData:o}=await g.computePosition(a,l,{placement:p,middleware:t,strategy:v});if(Object.assign(l.style,{left:e+"px",top:i+"px",position:n}),o.arrow&&c){const{x:e,y:i}=o.arrow;Object.assign(c.style,{left:"number"==typeof e?e+"px":"",top:"number"==typeof i?i+"px":""})}l.setAttribute("x-placement",s)}}function i(){l.style.position=v,l.style.top="0px",l.style.left="0px",a&&(e=g.autoUpdate(a,l,t))}async function s(){return new Promise(t=>{e?(e(),e=void 0,requestAnimationFrame(()=>t())):t()})}i();const n=r.disconnected.bind(r);return Object.assign(r,{disconnected(){s(),n()}}),{start:i,update:async function(){await t()},stop:s}}function y(n,{boundaries:o,callback:r}){let a=null;function t(t){a=t.composedPath?.()?.[0]||t.target}function e(t,e){if(a&&n.open&&!t.defaultPrevented){var i=e(t);if(i&&i.getRootNode().contains(i)){for(const s of o)if(null!==s){if(s.contains(i))return;if(t.composed&&t.composedPath().includes(s))return}r(t,i),a=null}}}document.addEventListener("mousedown",t,!0),document.addEventListener("click",t=>e(t,()=>a),!0);const i=n.disconnected.bind(n);Object.assign(n,{disconnected(){document.removeEventListener("mousedown",t,!0),document.removeEventListener("click",t=>e(t,()=>a),!0),i()}})}function w(t){return t.getAttribute("value")||""}function A(t){return t.getAttribute("data-text")||t.innerText.trim()}v.properties=new Map,v.targetsKeys=new Set,v.targetKeys=new Set;class X{constructor(t){this.autocomplete=t,this.selectedValues=new Set,this.defaultSelectedValues=[],this.autocomplete=t}connected(){(function(t){try{return JSON.parse(t).map(t=>t.toString())}catch{return[]}})(this.autocomplete.value).forEach(t=>this.selectedValues.add(t)),this.defaultSelectedValues=this.persistedTags.map(t=>({value:w(t),text:A(t)}))}disconnected(){this.clear(),this.defaultSelectedValues.length=0}start(){for(const t of this.autocomplete.options)this.selectedValues.has(w(t))?this.autocomplete.combobox.select(t):this.autocomplete.combobox.deselect(t)}stop(){this.clearInputField()}async commit(t){this.clearInputField();const e=w(t);t=A(t);if(this.selectedValues.has(e)?this.removeValue(e):this.setValue(e,t),this.autocomplete.src){await this.autocomplete.makeRequest(""),this.start();t=this.autocomplete.visibleOptions.find(t=>w(t)===e)||this.autocomplete.visibleOptions[0];t&&this.autocomplete.activate(t)}else for(const t of this.autocomplete.options)t.hidden=!1}clear(){this.selectedValues.forEach(t=>this.removeValue(t))}reset(){this.clear(),this.defaultSelectedValues.forEach(({value:t,text:e})=>this.setValue(t,e,{persisted:!0}))}setValue(e,t,{persisted:i=!1}={}){this.selectedValues.has(e)||(this.selectedValues.add(e),this.insertTag(e,t,{persisted:i}),this.updateElementValue(),this.setRequiredAttribute(this.autocomplete.required),this.autocomplete.open&&(t=this.autocomplete.options.find(t=>w(t)===e))&&this.autocomplete.combobox.select(t))}removeValue(e){var t;this.selectedValues.has(e)&&(this.selectedValues.delete(e),this.removeTag(e),this.updateElementValue(),this.setRequiredAttribute(this.autocomplete.required),t=this.autocomplete.options.find(t=>w(t)===e))&&this.autocomplete.combobox.deselect(t)}setRequiredAttribute(t){!t||0<this.selectedValues.size?this.autocomplete.input.required=!1:this.autocomplete.input.required=!0}insertTag(t,e,{persisted:i=!1}={}){var s=this.template.content.cloneNode(!0),n=s.querySelector('[data-behavior="tag"]'),o=s.querySelector('[data-behavior="text"]'),r=s.querySelector('[data-behavior="hidden-field"]');n?.setAttribute("value",t),n?.toggleAttribute("data-persisted",i),o&&(o.innerText=e),r&&(r.value=t),this.autocomplete.control.insertBefore(s,this.template)}removeTag(e){this.tags.find(t=>w(t)===e)?.remove()}updateElementValue(){var t=Array.from(this.selectedValues.values());this.autocomplete.value=JSON.stringify(t)}clearInputField(){this.autocomplete.input.value&&(this.autocomplete.input.value="")}get firstActiveOption(){return this.autocomplete.visibleOptions.find(t=>this.selectedValues.has(w(t)))||this.autocomplete.visibleOptions[0]}get tags(){return Array.from(this.autocomplete.querySelectorAll('[data-behavior="tag"]'))}get persistedTags(){return this.tags.filter(t=>t.hasAttribute("data-persisted"))}get template(){return this.autocomplete.querySelector('[data-behavior="tag-template"]')}}class Y{constructor(t){this.autocomplete=t,this.defaultValue="",this.defaultText="",this.autocomplete=t}connected(){this.defaultValue=this.hiddenField.value,this.defaultText=this.hiddenField.getAttribute("data-text")||""}disconnected(){this.clear(),this.defaultValue="",this.defaultText=""}start(){this.selectedOption&&this.autocomplete.combobox.select(this.selectedOption)}stop(){this.autocomplete.input.value=this.hiddenField.getAttribute("data-text")||""}commit(t){var e=w(t),t=A(t);this.setValue(e,t),this.autocomplete.open=!1}clear(){this.setValue(null,null)}reset(){this.setValue(this.defaultValue,this.defaultText)}setValue(t,e){this.autocomplete.value=t||"",this.autocomplete.input.value=e||"",this.hiddenField.value=t||"",this.hiddenField.setAttribute("data-text",e||""),null===t?this.autocomplete.combobox.deselectAll():this.autocomplete.open&&(e=this.autocomplete.options.find(t=>w(t)===this.defaultValue))&&this.autocomplete.combobox.select(e)}removeValue(){this.clear()}setRequiredAttribute(t){this.autocomplete.input.required=t}get firstActiveOption(){return this.selectedOption||this.autocomplete.visibleOptions[0]}get selectedOption(){return this.autocomplete.options.find(t=>this.isSelected(t))}isSelected(t){return w(t)===this.autocomplete.value}get hiddenField(){return this.autocomplete.querySelector('[data-behavior="hidden-field"]')}}let E=class extends v{constructor(){super(),this.open=!1,this.disabled=!1,this.required=!1,this.multiple=!1,this.param="q",this.singleSelect=new Y(this),this.multipleSelect=new X(this),this.firstFocus=!0,this.remoteSearch=function(e,i){let s;function t(...t){clearTimeout(s),s=setTimeout(()=>{e.apply(this,t)},i)}return t.clear=()=>{clearTimeout(s)},t}(this.remoteSearch.bind(this),300),this.handleFormReset=this.handleFormReset.bind(this)}connected(){this.floatingUI=b(this,{referenceElement:this.control,popupElement:this.listbox,placement:"bottom",sync:"width",offsetOptions:4}),y(this,{boundaries:[this.control,this.listbox],callback:()=>{this.open=!1}}),this.combobox=new K(this.input,this.listbox,{multiple:this.multiple}),this.selectVariant=this.multiple?this.multipleSelect:this.singleSelect,this.selectVariant.connected(),this.form?.addEventListener("reset",this.handleFormReset),this.selectVariant.setRequiredAttribute(this.required)}disconnected(){this.open=!1,this.removeAttribute("data-focus"),this.firstFocus=!0,this.selectVariant.disconnected(),this.abortController=void 0,this.form?.removeEventListener("reset",this.handleFormReset)}async openChanged(t){if(t)this.emit("show"),this.combobox.start(),this.listbox.hidden=!1,this.floatingUI.start(),this.src?await this.makeRequest(""):this.checkIfListIsEmpty(),this.selectVariant.start(),this.selectVariant.firstActiveOption&&this.activate(this.selectVariant.firstActiveOption),this.emit("shown");else{if(this.emit("hide"),this.listbox.hidden=!0,this.abortController?.abort(),this.selectVariant.stop(),this.combobox.stop(),!this.src)for(const e of this.options)e.hidden=!1;this.removeAttribute("no-options"),this.removeAttribute("error"),this.currentQuery=void 0,await this.floatingUI.stop(),this.emit("hidden")}}valueChanged(t){this.classList.toggle("awc-autocomplete--selected",""!==t&&"[]"!==t)}disabledChanged(t){if(this.input.disabled=t,this.clearBtn.disabled=t,this.multiple&&this.tagDismissBtns)for(const e of this.tagDismissBtns)e.disabled=t}requiredChanged(t){this.selectVariant.setRequiredAttribute(t)}handleMousedown(t){t.target!==this.input&&t.preventDefault()}handleClick(t){this.disabled||(this.input.focus(),t=t.target["classList"],(t.contains("awc-autocomplete-control")||t.contains("awc-autocomplete-end-adornment"))&&(this.open=!0),this.firstFocus&&this.input.value&&this.input.select(),this.firstFocus=!1)}handleInputMousedown(){this.open=!0}handleInputFocus(){this.setAttribute("data-focus","")}handleInputBlur(){this.open=!1,this.removeAttribute("data-focus"),this.firstFocus=!0}handleInputKeydown(t){switch(t.key){case"Enter":this.open&&t.preventDefault();break;case"Escape":this.open&&(t.preventDefault(),t.stopPropagation(),this.open=!1);break;case"ArrowDown":t.altKey&&!this.open&&(t.preventDefault(),this.open=!0);break;case"ArrowUp":t.altKey&&this.open&&(t.preventDefault(),this.open=!1);break;case"Backspace":var e;""===this.input.value&&this.multiple&&(e=this.multipleSelect["tags"],e=e[e.length-1])&&(t.preventDefault(),this.multipleSelect.removeValue(w(e)))}}async handleInput(t){var t=t["target"];t instanceof HTMLInputElement&&(t=t.value.trim(),this.src?await this.remoteSearch(t):this.search(t))}async handleCommit(t){t.stopPropagation();t=t.target;t instanceof HTMLElement&&(await this.selectVariant.commit(t),this.emit("commit",{detail:{target:t}}))}handleClear(){this.open=!1,this.clear(),this.emit("clear")}handleTagRemove(t){t=t.target.closest('[data-behavior="tag"]');t&&(this.multipleSelect.removeValue(w(t)),this.emit("remove",{detail:{target:t}}))}handleFormReset(){this.open=!1,this.reset(),this.emit("reset")}setValue(t,e){this.selectVariant.setValue(t,e)}removeValue(t){this.multiple&&t?this.multipleSelect.removeValue(t):this.singleSelect.removeValue()}activate(t,{scroll:e=!0}={}){this.combobox.activate(t,{scroll:e})}deactivate(){this.combobox.deactivate()}clear(){this.selectVariant.clear(),this.currentQuery=void 0}reset(){this.selectVariant.reset(),this.currentQuery=void 0}search(t){var i;this.open=!0,this.options.forEach((i=t,t=>{var e;i?(e=A(t)?.toLowerCase().includes(i.toLowerCase()),t.hidden=!e):t.hidden=!1})),this.checkIfListIsEmpty(),this.visibleOptions[0]&&this.activate(this.visibleOptions[0])}async remoteSearch(t){this.open=!0,await this.makeRequest(t),this.selectVariant.start(),this.visibleOptions[0]&&this.activate(this.visibleOptions[0])}async makeRequest(t){if(this.currentQuery!==t){this.currentQuery=t,this.abortController?this.abortController.abort():(this.setAttribute("loading",""),this.emit("loadstart",{bubbles:!1,prefix:!1})),this.removeAttribute("error"),this.abortController=new AbortController;var e=new URL(this.src,window.location.href),i=new URLSearchParams(e.search.slice(1));i.append(this.param,t),e.search=i.toString();try{var s=await fetch(e.toString(),{signal:this.abortController.signal,credentials:"same-origin",headers:{accept:"text/fragment+html"}});if(!s.ok)throw new Error;this.optionsContainer.innerHTML=await s.text(),this.checkIfListIsEmpty(),this.combobox.initializeOptions(),this.abortController=void 0,await this.floatingUI.update(),this.emit("load",{bubbles:!1,prefix:!1})}catch(t){t instanceof Error&&"AbortError"!==t.name&&(this.abortController=void 0,this.setAttribute("error",""),this.emit("error",{bubbles:!1,prefix:!1}))}finally{this.removeAttribute("loading"),this.emit("loadend",{bubbles:!1,prefix:!1})}}}checkIfListIsEmpty(){this.toggleAttribute("no-options",0===this.visibleOptions.length)}get activeOption(){return this.combobox.activeOption}get visibleOptions(){return this.options.filter(t=>!t.hidden)}get options(){return this.combobox.options}get form(){return this.closest("form")}};t([o({type:Boolean})],E.prototype,"open",void 0),t([o()],E.prototype,"value",void 0),t([o({type:Boolean})],E.prototype,"disabled",void 0),t([o({type:Boolean})],E.prototype,"required",void 0),t([o({type:Boolean})],E.prototype,"multiple",void 0),t([o()],E.prototype,"src",void 0),t([o()],E.prototype,"param",void 0),t([a()],E.prototype,"input",void 0),t([a()],E.prototype,"listbox",void 0),t([a()],E.prototype,"control",void 0),t([a()],E.prototype,"optionsContainer",void 0),t([a()],E.prototype,"clearBtn",void 0),t([(t,e)=>{t.constructor.registerTargets(e)}],E.prototype,"tagDismissBtns",void 0),E=t([r("awc-autocomplete")],E);function O(t,e){void 0===e&&(e=!0);var i=null==t||null==(i=t.getAttribute)?void 0:i.call(t,"inert");return""===i||"true"===i||e&&t&&O(t.parentNode)}function S(t){return!isNaN(parseInt(t.getAttribute("tabindex"),10))}function x(t){var e,i;if(t)return t.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(t.tagName)||""===(i=null==(e=t)||null==(i=e.getAttribute)?void 0:i.call(e,"contenteditable"))||"true"===i)&&!S(t)?0:t.tabIndex;throw new Error("No node provided")}function tt(t,e){return t.tabIndex===e.tabIndex?t.documentOrder-e.documentOrder:t.tabIndex-e.tabIndex}function C(t){return"INPUT"===t.tagName}function et(t){if(!t.name)return 1;function e(t){return i.querySelectorAll('input[type="radio"][name="'+t+'"]')}var i=t.form||k(t);if("undefined"!=typeof window&&void 0!==window.CSS&&"function"==typeof window.CSS.escape)s=e(window.CSS.escape(t.name));else try{s=e(t.name)}catch(t){return console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s",t.message),0}var s=function(t,e){for(var i=0;i<t.length;i++)if(t[i].checked&&t[i].form===e)return t[i]}(s,t.form);return!s||s===t}function it(t){return C(e=t)&&"radio"===e.type&&!et(t);var e}function N(t){var e=(t=t.getBoundingClientRect()).width,t=t.height;return 0===e&&0===t}function st(t,e){var i=e.displayCheck,s=e.getShadowRoot;if("hidden"===getComputedStyle(t).visibility)return 1;if(e=T.call(t,"details>summary:first-of-type")?t.parentElement:t,T.call(e,"details:not([open]) *"))return 1;if(i&&"full"!==i&&"legacy-full"!==i){if("non-zero-area"===i)return N(t)}else{if("function"==typeof s){for(e=t;t;){var n=t.parentElement,o=k(t);if(n&&!n.shadowRoot&&!0===s(n))return N(t);t=t.assignedSlot||(n||o===t.ownerDocument?n:o.host)}t=e}if(function(t){var e,i=t&&k(t),s=null==(e=i)?void 0:e.host,n=!1;if(i&&i!==t)for(n=!!(null!=(e=s)&&null!=(e=e.ownerDocument)&&e.contains(s)||null!=t&&null!=(e=t.ownerDocument)&&e.contains(t));!n&&s;)var o,n=!(null==(o=s=null==(o=i=k(s))?void 0:o.host)||null==(o=o.ownerDocument)||!o.contains(s));return n}(t))return!t.getClientRects().length;if("legacy-full"!==i)return 1}}var V=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"].join(","),L="undefined"==typeof Element,T=L?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,k=!L&&Element.prototype.getRootNode?function(t){var e;return null==t||null==(e=t.getRootNode)?void 0:e.call(t)}:function(t){return null==t?void 0:t.ownerDocument},M=function(t,e,i){var s;return O(t)?[]:(s=Array.prototype.slice.apply(t.querySelectorAll(V)),e&&T.call(t,V)&&s.unshift(t),s.filter(i))},nt=function t(e,i,s){for(var n=[],o=Array.from(e);o.length;){var r,a,l=o.shift();O(l,!1)||("SLOT"===l.tagName?(r=t((r=l.assignedElements()).length?r:l.children,!0,s),s.flatten?n.push.apply(n,r):n.push({scopeParent:l,candidates:r})):(T.call(l,V)&&s.filter(l)&&(i||!e.includes(l))&&n.push(l),r=l.shadowRoot||"function"==typeof s.getShadowRoot&&s.getShadowRoot(l),a=!O(r,!1)&&(!s.shadowRootFilter||s.shadowRootFilter(l)),r&&a?(a=t((!0===r?l:r).children,!0,s),s.flatten?n.push.apply(n,a):n.push({scopeParent:l,candidates:a})):o.unshift.apply(o,l.children)))}return n},R=function(t,e){var i;return!(e.disabled||O(e)||C(i=e)&&"hidden"===i.type||st(e,t)||"DETAILS"===(i=e).tagName&&Array.prototype.slice.apply(i.children).some(function(t){return"SUMMARY"===t.tagName})||function(t){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(t.tagName))for(var e=t.parentElement;e;){if("FIELDSET"===e.tagName&&e.disabled){for(var i=0;i<e.children.length;i++){var s=e.children.item(i);if("LEGEND"===s.tagName)return!!T.call(e,"fieldset[disabled] *")||!s.contains(t)}return!0}e=e.parentElement}return!1}(e))},ot=function(t,e){return!(it(e)||x(e)<0||!R(t,e))},rt=function(t){t=parseInt(t.getAttribute("tabindex"),10);return!!(isNaN(t)||0<=t)},at=function a(t){var l=[],c=[];return t.forEach(function(t,e){var i,s=!!t.scopeParent,n=s?t.scopeParent:t,o=(o=s,(i=x(r=n))<0&&o&&!S(r)?0:i),r=s?a(t.candidates):n;0===o?s?l.push.apply(l,r):l.push(n):c.push({documentOrder:e,tabIndex:o,item:t,isScope:s,content:r})}),c.sort(tt).reduce(function(t,e){return e.isScope?t.push.apply(t,e.content):t.push(e.content),t},[]).concat(l)};const P=[];function lt(t,{trap:s}){let e,n;function i(t){"Tab"===t.key&&(t.preventDefault(),r(function(t,e,i){let s=t.indexOf(e),n=(s===t.length-1&&1===i&&(s=-1),1===i?0:t.length-1);return t[n=e&&0<=s&&0<=(e=s+i)&&e<t.length?e:n]}(function(t,e){t=(e=e||{}).getShadowRoot?nt([t],e.includeContainer,{filter:ot.bind(null,e),flatten:!1,getShadowRoot:e.getShadowRoot,shadowRootFilter:rt}):M(t,e.includeContainer,ot.bind(null,e));return at(t)}(s),s.contains(document.activeElement)?document.activeElement:null,t.shiftKey?-1:1)))}function o(t){var e=t.composedPath?.()?.[0]||t.target;for(const i of P)if(i.contains(e))return void(n=e);r(n||s)}function r(t){t?t!==document.activeElement&&(t.focus({preventScroll:!0}),n=t):r(s)}function a(t){return!t.hasAttribute("data-autofocus")&&(t.querySelector("[data-autofocus]")||(e=t,((i=i||{}).getShadowRoot?nt([e],i.includeContainer,{filter:R.bind(null,i),flatten:!0,getShadowRoot:i.getShadowRoot}):M(e,i.includeContainer,R.bind(null,i)))[0]))||t;var e,i}s.addEventListener("keydown",i,!0),document.addEventListener("focusin",o,!0);const l=t.disconnected.bind(t);return Object.assign(t,{disconnected(){s.removeEventListener("keydown",i,!0),document.removeEventListener("focusin",o,!0),l()}}),{start:function(){e=document.activeElement,P.push(s),r(a(s))},stop:function(){var t=P.indexOf(s);-1!==t&&(P.splice(t,1),r(e))}}}let I=class extends v{constructor(){super(...arguments),this.open=!1,this.placement="bottom"}connected(){this.floatingUI=b(this,{referenceElement:this.button,popupElement:this.panel,arrowElement:this.arrow,arrowPadding:this.arrowPadding,placement:this.placement,offsetOptions:8,flipOptions:{fallbackAxisSideDirection:"end"}}),y(this,{boundaries:[this.button,this.panel],callback:()=>{this.open=!1}}),this.focusTrap=lt(this,{trap:this.panel}),this.open&&(this.panel.hidden=!1,this.button.setAttribute("aria-expanded","true"),this.floatingUI.start())}disconnected(){this.open=!1}async openChanged(t){t?(this.panel.hidden=!1,this.button.setAttribute("aria-expanded","true"),this.floatingUI.start(),this.focusTrap.start()):(this.panel.hidden=!0,this.button.setAttribute("aria-expanded","false"),this.button.focus(),await this.floatingUI.stop(),this.focusTrap.stop())}handleButtonClick(){this.button.hasAttribute("disabled")||"true"===this.button.getAttribute("aria-disabled")||this.toggle()}toggle(){this.open=!this.open}show(){this.open||(this.open=!0)}hide(){this.open&&(this.open=!1)}handleKeydown(t){"Escape"===t.key&&this.open&&(t.preventDefault(),t.stopPropagation(),this.open=!1)}async updatePosition(){await this.floatingUI.update()}get arrowPadding(){var t=getComputedStyle(this.panel).borderRadius;return Number(t.replace(/[^-\d.]/g,""))||2}};t([o({type:Boolean})],I.prototype,"open",void 0),t([o()],I.prototype,"placement",void 0),t([a()],I.prototype,"button",void 0),t([a()],I.prototype,"panel",void 0),t([a()],I.prototype,"arrow",void 0),I=t([r("awc-popover")],I)});
@@ -0,0 +1,4 @@
1
+ <%= render(Impulse::AutocompleteComponent.new(@object_name, @method_name, selected: value, **@system_args)) do |c| %>
2
+ <%= c.with_blankslate_content(blankslate.presence || "We couldn't find that!") %>
3
+ <%= c.with_error_content(error.presence || "An error occurred. Please try again!") %>
4
+ <% end %>
@@ -0,0 +1,34 @@
1
+ module Impulse
2
+ class AjaxSelectComponent < ApplicationComponent
3
+ renders_one :blankslate
4
+ renders_one :error
5
+
6
+ def initialize(object_name, method_name, value_method, text_method, selected: nil, **system_args)
7
+ @object_name = object_name
8
+ @method_name = method_name
9
+ @value_method = value_method
10
+ @text_method = text_method
11
+ @selected = selected
12
+ @system_args = system_args
13
+
14
+ raise ArgumentError, "`src` attribute is missing" unless @system_args[:src]
15
+ end
16
+
17
+ private
18
+
19
+ def value
20
+ return if @selected.nil?
21
+ return @selected.map { |element| build_option(element) } if multiple?
22
+ build_option(@selected)
23
+ end
24
+
25
+ def build_option(element)
26
+ tuple = [value_for_collection(element, @text_method), value_for_collection(element, @value_method)]
27
+ OpenStruct.new(value: tuple.last, text: tuple.first)
28
+ end
29
+
30
+ def multiple?
31
+ @system_args[:multiple]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module Impulse
2
+ class ApplicationComponent < ViewComponent::Base
3
+ include Helpers::AttributesHelper
4
+
5
+ def self.generate_id
6
+ "#{name.demodulize.underscore.dasherize}-#{SecureRandom.uuid}"
7
+ end
8
+
9
+ private
10
+
11
+ def fetch_or_fallback(variant_keys, given_value, default_value)
12
+ if given_value && variant_keys.include?(given_value.to_sym)
13
+ given_value.to_sym
14
+ else
15
+ default_value
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ <%= render(Impulse::BaseRenderer.new(**@system_args)) do %>
2
+ <span id="<%= @text_id %>" class="awc-autocomplete-option-text"><%= @text %></span>
3
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor" class="awc-autocomplete-option-check" aria-hidden="true">
4
+ <path fill="none" d="M0 0h24v24H0z"></path><path d="M10.0007 15.1709L19.1931 5.97852L20.6073 7.39273L10.0007 17.9993L3.63672 11.6354L5.05093 10.2212L10.0007 15.1709Z"></path>
5
+ </svg>
6
+ <% end %>
@@ -0,0 +1,30 @@
1
+ module Impulse
2
+ module Autocomplete
3
+ class OptionComponent < ApplicationComponent
4
+ attr_reader :value, :text, :system_args
5
+
6
+ def initialize(value:, text:, **system_args)
7
+ @value = value
8
+ @text = text
9
+ @text_id = self.class.generate_id
10
+ @system_args = system_args
11
+ @system_args[:id] = system_args.fetch(:id, self.class.generate_id)
12
+ @system_args[:tag] ||= :div
13
+ @system_args[:role] = :option
14
+ @system_args[:value] = value
15
+ @system_args[:tabindex] = "-1"
16
+
17
+ @system_args[:class] = class_names(
18
+ system_args[:class],
19
+ "awc-autocomplete-option dropdown-item",
20
+ disabled: system_args[:disabled]
21
+ )
22
+
23
+ @system_args[:"data-text"] = text
24
+ @system_args[:"aria-selected"] = "false"
25
+ @system_args[:"aria-labelledby"] = @text_id
26
+ @system_args[:"aria-disabled"] = (!!system_args[:disabled]).to_s
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,84 @@
1
+ <%= render(Impulse::BaseRenderer.new(**@system_args)) do %>
2
+ <%= content_tag :div, class: class_names("awc-autocomplete-control form-control", "form-control-sm": @size == "sm", "form-control-lg": @size == "lg"), data: { target: "awc-autocomplete.control" } do %>
3
+ <% if multiple? %>
4
+ <%= hidden_field @object_name, @method_name, id: nil, multiple: true, value: nil, data: { behavior: "hidden-field" }, **hidden_field_args if @include_hidden %>
5
+ <% @selected&.each do |selected| %>
6
+ <div class="awc-autocomplete-tag" value="<%= selected.value %>" data-behavior="tag" data-persisted>
7
+ <span class="awc-autocomplete-tag-text" data-behavior="text"><%= selected.text %></span>
8
+ <span class="awc-autocomplete-tag-end-adornment">
9
+ <%= content_tag :button, type: :button, class: "awc-autocomplete-tag-dismiss-btn btn", tabindex: "-1", title: "Remove", disabled: @disabled, data: { action: "click->awc-autocomplete#handleTagRemove", target: "awc-autocomplete.tagDismissBtns" } do %>
10
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
11
+ <path fill="none" d="M0 0h24v24H0z"></path><path d="M12.0007 10.5865L16.9504 5.63672L18.3646 7.05093L13.4149 12.0007L18.3646 16.9504L16.9504 18.3646L12.0007 13.4149L7.05093 18.3646L5.63672 16.9504L10.5865 12.0007L5.63672 7.05093L7.05093 5.63672L12.0007 10.5865Z"></path>
12
+ </svg>
13
+ <% end %>
14
+ </span>
15
+ <%= hidden_field @object_name, @method_name, id: nil, value: selected.value, multiple: true, data: { behavior: "hidden-field" }, **hidden_field_args %>
16
+ </div>
17
+ <% end %>
18
+
19
+ <template data-behavior="tag-template">
20
+ <div class="awc-autocomplete-tag" data-behavior="tag">
21
+ <span class="awc-autocomplete-tag-text" data-behavior="text"></span>
22
+ <span class="awc-autocomplete-tag-end-adornment">
23
+ <%= content_tag :button, type: :button, class: "awc-autocomplete-tag-dismiss-btn btn", tabindex: "-1", title: "Remove", data: { action: "click->awc-autocomplete#handleTagRemove", target: "awc-autocomplete.tagDismissBtns" } do %>
24
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
25
+ <path fill="none" d="M0 0h24v24H0z"></path><path d="M12.0007 10.5865L16.9504 5.63672L18.3646 7.05093L13.4149 12.0007L18.3646 16.9504L16.9504 18.3646L12.0007 13.4149L7.05093 18.3646L5.63672 16.9504L10.5865 12.0007L5.63672 7.05093L7.05093 5.63672L12.0007 10.5865Z"></path>
26
+ </svg>
27
+ <% end %>
28
+ </span>
29
+ <%= hidden_field @object_name, @method_name, id: nil, value: nil, multiple: true, data: { behavior: "hidden-field" }, **hidden_field_args %>
30
+ </div>
31
+ </template>
32
+ <% else %>
33
+ <%= hidden_field @object_name, @method_name, id: nil, value: @selected&.value, data: { behavior: "hidden-field", text: @selected&.text }, **hidden_field_args %>
34
+ <% end %>
35
+
36
+ <%= text_field @object_name,
37
+ @method_name,
38
+ class: "awc-autocomplete-input",
39
+ value: multiple? ? nil : @selected&.text,
40
+ name: nil,
41
+ autocomplete: "off",
42
+ spellcheck: false,
43
+ autocapitalize: "none",
44
+ disabled: @disabled,
45
+ data: {
46
+ target: "awc-autocomplete.input",
47
+ action: "mousedown->awc-autocomplete#handleInputMousedown focus->awc-autocomplete#handleInputFocus blur->awc-autocomplete#handleInputBlur keydown->awc-autocomplete#handleInputKeydown input->awc-autocomplete#handleInput"
48
+ },
49
+ **search_field_args %>
50
+ <div class="awc-autocomplete-end-adornment">
51
+ <%= content_tag :button, type: :button, class: "awc-autocomplete-adornment-btn awc-autocomplete-clear-btn btn btn-light", title: "Clear", disabled: @disabled, data: { action: "click->awc-autocomplete#handleClear", target: "awc-autocomplete.clearBtn" } do %>
52
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12.0007 10.5865L16.9504 5.63672L18.3646 7.05093L13.4149 12.0007L18.3646 16.9504L16.9504 18.3646L12.0007 13.4149L7.05093 18.3646L5.63672 16.9504L10.5865 12.0007L5.63672 7.05093L7.05093 5.63672L12.0007 10.5865Z"></path></svg>
53
+ <% end %>
54
+
55
+ <div aria-hidden="true" class="awc-autocomplete-adornment-decorator">
56
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 16L6 10H18L12 16Z"></path></svg>
57
+ </div>
58
+ </div>
59
+ <% end %>
60
+
61
+ <div role="listbox" class="awc-autocomplete-listbox dropdown-menu" tabindex="-1" data-target="awc-autocomplete.listbox" hidden>
62
+ <div role="presentation" class="awc-autocomplete-options" data-target="awc-autocomplete.optionsContainer">
63
+ <% if ajax? %>
64
+ <div role="presentation" class="awc-autocomplete-spinner">
65
+ <%= render(Impulse::SpinnerComponent.new(role: :none)) %>
66
+ </div>
67
+ <% else %>
68
+ <% options.each do |option| %>
69
+ <%= option %>
70
+ <% end %>
71
+ <% end %>
72
+ </div>
73
+
74
+ <div role="presentation" class="awc-autocomplete-blankslate">
75
+ <%= blankslate.presence || "We couldn't find that!" %>
76
+ </div>
77
+
78
+ <% if ajax? %>
79
+ <div role="presentation" class="awc-autocomplete-error">
80
+ <%= error.presence || "An error occurred. Please try again!" %>
81
+ </div>
82
+ <% end %>
83
+ </div>
84
+ <% end %>
@@ -0,0 +1,71 @@
1
+ module Impulse
2
+ class AutocompleteComponent < ApplicationComponent
3
+ renders_one :blankslate
4
+ renders_one :error
5
+ renders_many :options, Impulse::Autocomplete::OptionComponent
6
+
7
+ DEFAULT_SIZE = :md
8
+ SIZE_MAPPINGS = {
9
+ :sm => "awc-autocomplete--sm",
10
+ DEFAULT_SIZE => "",
11
+ :lg => "awc-autocomplete--lg"
12
+ }.freeze
13
+
14
+ def initialize(object_name, method_name, selected: nil, size: DEFAULT_SIZE, name: nil, input_id: nil, placeholder: nil, include_hidden: true, disabled: false, **system_args)
15
+ @object_name = object_name
16
+ @method_name = method_name
17
+ @selected = selected
18
+ @size = size.to_s
19
+ @name = name
20
+ @input_id = input_id
21
+ @placeholder = placeholder
22
+ @include_hidden = include_hidden
23
+ @disabled = disabled
24
+ @system_args = system_args
25
+ @system_args[:tag] = :"awc-autocomplete"
26
+ @system_args[:value] = sanitized_value
27
+ @system_args[:disabled] = disabled
28
+
29
+ @system_args[:class] = class_names(
30
+ system_args[:class],
31
+ SIZE_MAPPINGS[fetch_or_fallback(SIZE_MAPPINGS.keys, size, DEFAULT_SIZE)],
32
+ "awc-autocomplete",
33
+ "awc-autocomplete--selected": @selected.present?
34
+ )
35
+
36
+ @system_args[:data] = merge_attributes(
37
+ system_args[:data],
38
+ action: "mousedown->awc-autocomplete#handleMousedown click->awc-autocomplete#handleClick combobox:commit->awc-autocomplete#handleCommit"
39
+ )
40
+ end
41
+
42
+ private
43
+
44
+ def sanitized_value
45
+ return if @selected.nil?
46
+ return @selected.map(&:value).to_s if multiple?
47
+ @selected.value
48
+ end
49
+
50
+ def search_field_args
51
+ {}.tap do |args|
52
+ args[:id] = @input_id if @input_id
53
+ args[:placeholder] = @placeholder
54
+ end
55
+ end
56
+
57
+ def hidden_field_args
58
+ {}.tap do |args|
59
+ args[:name] = @name if @name
60
+ end
61
+ end
62
+
63
+ def multiple?
64
+ !!@system_args[:multiple]
65
+ end
66
+
67
+ def ajax?
68
+ !!@system_args[:src]
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ module Impulse
2
+ class BaseRenderer < ViewComponent::Base
3
+ SELF_CLOSING_TAGS = [:area, :base, :br, :col, :embed, :hr, :img, :input, :link, :meta, :param, :source, :track, :wbr].freeze
4
+
5
+ def initialize(tag:, **system_args)
6
+ @tag = tag
7
+ @system_args = system_args
8
+ @system_args[:"data-impulse-view-component"] = ""
9
+ end
10
+
11
+ def call
12
+ if SELF_CLOSING_TAGS.include?(@tag)
13
+ tag(@tag, **@system_args)
14
+ else
15
+ content_tag(@tag, content, **@system_args)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ <%= render(Impulse::BaseRenderer.new(**@system_args)) do %>
2
+ <%= button %>
3
+
4
+ <div id="<%= @panel_id %>" role="dialog" class="popover bs-popover-auto" tabindex="-1" data-target="awc-popover.panel" hidden>
5
+ <div class="arrow" data-target="awc-popover.arrow"></div>
6
+ <%= header %>
7
+ <%= body %>
8
+ </div>
9
+ <% end %>
@@ -0,0 +1,50 @@
1
+ module Impulse
2
+ class PopoverComponent < ApplicationComponent
3
+ renders_one :button, lambda { |**system_args|
4
+ system_args[:tag] ||= :button
5
+ system_args[:type] = system_args.fetch(:type, "button")
6
+ system_args[:role] = :button
7
+ system_args[:"aria-haspopup"] = :dialog
8
+ system_args[:"aria-expanded"] = false
9
+ system_args[:"aria-controls"] = @panel_id
10
+ system_args[:"aria-disabled"] = (!!system_args[:disabled]).to_s
11
+
12
+ system_args[:data] = merge_attributes(
13
+ system_args[:data],
14
+ action: "click->awc-popover#handleButtonClick",
15
+ target: "awc-popover.button"
16
+ )
17
+
18
+ Impulse::BaseRenderer.new(**system_args)
19
+ }
20
+
21
+ renders_one :header, lambda { |**system_args|
22
+ system_args[:tag] ||= :div
23
+ system_args[:class] = class_names(system_args[:class], "popover-header")
24
+
25
+ Impulse::BaseRenderer.new(**system_args)
26
+ }
27
+
28
+ renders_one :body, lambda { |**system_args|
29
+ system_args[:tag] ||= :div
30
+ system_args[:class] = class_names(system_args[:class], "popover-body")
31
+
32
+ Impulse::BaseRenderer.new(**system_args)
33
+ }
34
+
35
+ def initialize(**system_args)
36
+ @system_args = system_args
37
+ @system_args[:tag] = :"awc-popover"
38
+ @panel_id = self.class.generate_id
39
+
40
+ @system_args[:data] = merge_attributes(
41
+ system_args[:data],
42
+ action: "keydown->awc-popover#handleKeydown"
43
+ )
44
+ end
45
+
46
+ def render?
47
+ button.present?
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,13 @@
1
+ <%= render(Impulse::AutocompleteComponent.new(@object_name, @method_name, selected: value, **@system_args)) do |c| %>
2
+ <% if options? %>
3
+ <% options.each do |option| %>
4
+ <%= c.with_option(value: option.value, text: option.text, **option.system_args) %>
5
+ <% end %>
6
+ <% else %>
7
+ <% options_from_choices.each do |option| %>
8
+ <%= c.with_option(value: option.value, text: option.text) %>
9
+ <% end %>
10
+ <% end %>
11
+
12
+ <%= c.with_blankslate_content(blankslate.presence || "We couldn't find that!") %>
13
+ <% end %>
@@ -0,0 +1,38 @@
1
+ module Impulse
2
+ class SelectComponent < ApplicationComponent
3
+ renders_one :blankslate
4
+ renders_many :options, Impulse::Autocomplete::OptionComponent
5
+
6
+ def initialize(object_name, method_name, choices = [], selected: nil, **system_args)
7
+ @object_name = object_name
8
+ @method_name = method_name
9
+ @choices = choices
10
+ @selected = selected
11
+ @system_args = system_args
12
+ end
13
+
14
+ private
15
+
16
+ def value
17
+ return if @selected.nil?
18
+ return @selected.map { |value| find_option(value) } if multiple?
19
+ find_option(@selected)
20
+ end
21
+
22
+ def options_from_choices
23
+ return [] if @choices.nil?
24
+ @choices.map do |choice|
25
+ tuple = option_text_and_value(choice)
26
+ OpenStruct.new(value: tuple.last, text: tuple.first)
27
+ end
28
+ end
29
+
30
+ def find_option(value)
31
+ (options.presence || options_from_choices).find { |option| option.value.to_s == value.to_s }
32
+ end
33
+
34
+ def multiple?
35
+ !!@system_args[:multiple]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ module Impulse
2
+ class SpinnerComponent < ApplicationComponent
3
+ DEFAULT_VARIANT = :secondary
4
+ VARIANT_MAPPINGS = {
5
+ :primary => "text-primary",
6
+ DEFAULT_VARIANT => "text-secondary",
7
+ :success => "text-success",
8
+ :danger => "text-danger",
9
+ :warning => "text-warning",
10
+ :info => "text-info",
11
+ :light => "text-light",
12
+ :dark => "text-dark"
13
+ }.freeze
14
+
15
+ def initialize(variant: DEFAULT_VARIANT, label: "Loading", **system_args)
16
+ @system_args = system_args
17
+ @system_args[:tag] ||= :div
18
+ @system_args[:role] ||= :status
19
+ @system_args[:"aria-label"] = label
20
+ @system_args[:class] = class_names(
21
+ system_args[:class],
22
+ "spinner-border",
23
+ VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_MAPPINGS.keys, variant, DEFAULT_VARIANT)]
24
+ )
25
+ end
26
+
27
+ def call
28
+ render(Impulse::BaseRenderer.new(**@system_args))
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ module Impulse
2
+ module Forms
3
+ class Builder < ActionView::Helpers::FormBuilder
4
+ attr_reader :template
5
+ delegate :render, to: :template
6
+
7
+ def select(method_name, choices = [], **system_args, &block)
8
+ Tags::Select.new(
9
+ object:,
10
+ object_name:,
11
+ method_name:,
12
+ template:,
13
+ choices:,
14
+ **system_args
15
+ ).render_tag(&block)
16
+ end
17
+
18
+ def ajax_select(method_name, value_method, text_method, **system_args, &block)
19
+ Tags::AjaxSelect.new(
20
+ object:,
21
+ object_name:,
22
+ method_name:,
23
+ template:,
24
+ value_method:,
25
+ text_method:,
26
+ **system_args
27
+ ).render_tag(&block)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ module Impulse
2
+ module Forms
3
+ module Tags
4
+ class AjaxSelect < Base
5
+ def initialize(object:, object_name:, method_name:, template:, value_method:, text_method:, **system_args)
6
+ super(object:, object_name:, method_name:, template:, **system_args)
7
+ @value_method = value_method
8
+ @text_method = text_method
9
+ end
10
+
11
+ def render_tag(&block)
12
+ if block
13
+ render(component) { |c| yield c }
14
+ else
15
+ render(component)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def component
22
+ Impulse::AjaxSelectComponent.new(@object_name, @method_name, @value_method, @text_method, **@system_args)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module Impulse
2
+ module Forms
3
+ module Tags
4
+ class Base
5
+ attr_reader :object
6
+ delegate :render, to: :@template
7
+
8
+ def initialize(object:, object_name:, method_name:, template:, **system_args)
9
+ @object = object
10
+ @object_name = object_name
11
+ @method_name = method_name
12
+ @template = template
13
+ @system_args = system_args
14
+ end
15
+
16
+ # This is what child classes implement
17
+ def render_tag
18
+ raise NotImplementedError, "Subclasses must implement a render_tag method"
19
+ end
20
+
21
+ def value
22
+ object.public_send(@method_name) if object&.respond_to?(@method_name)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module Impulse
2
+ module Forms
3
+ module Tags
4
+ class Select < Base
5
+ def initialize(object:, object_name:, method_name:, template:, choices:, **system_args)
6
+ super(object:, object_name:, method_name:, template:, **system_args)
7
+ @choices = choices
8
+ @value = @system_args.fetch(:selected, value)
9
+ end
10
+
11
+ def render_tag(&block)
12
+ if block
13
+ render(component) { |c| yield c }
14
+ else
15
+ render(component)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def component
22
+ Impulse::SelectComponent.new(@object_name, @method_name, @choices, selected: @value, **@system_args)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module Impulse
2
+ module Helpers
3
+ module AttributesHelper
4
+ # Merges hashes that contain keys and nested keys.
5
+ # Eg. merge_attributes({ target: "item" }, action: "click->action")
6
+ # => { target: "item", action: "click->action" }
7
+ #
8
+ # You can use this method to merge data attributes and system args.
9
+ # Eg. @system_args[:data] = merge_attributes(system_args[:data], action: "click->action")
10
+ def merge_attributes(*args)
11
+ args = args.map { |el| el.presence || {} }
12
+ args.first.deep_merge(args.second) do |_key, val, other_val|
13
+ val + " #{other_val}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module Impulse
2
+ module Helpers
3
+ module FormHelper
4
+ def impulse_form_with(**args, &block)
5
+ form_with(**args, builder: Impulse::Forms::Builder, &block)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ require "rails/engine"
2
+ require "view_component"
3
+
4
+ module Impulse
5
+ module ViewComponents
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace Impulse::ViewComponents
8
+
9
+ config.autoload_paths = %W[#{root}/lib]
10
+ config.eager_load_paths = %W[#{root}/app/components]
11
+
12
+ initializer "impulse_view_components.assets" do |app|
13
+ if app.config.respond_to?(:assets)
14
+ app.config.assets.precompile += %w[impulse_view_components.js impulse_view_components.css]
15
+ end
16
+ end
17
+
18
+ initializer "impulse_view_components.helpers" do
19
+ ActiveSupport.on_load :action_controller do
20
+ require "impulse/helpers/form_helper"
21
+ helper Impulse::Helpers::FormHelper
22
+
23
+ ViewComponent::Base.prepend(Impulse::Helpers::FormHelper)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Impulse
2
+ module ViewComponents
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require "impulse/view_components/version"
2
+ require "impulse/view_components/engine"
3
+
4
+ module Impulse
5
+ autoload :AttributesHelper, "impulse/helpers/attributes_helper"
6
+
7
+ module ViewComponents
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: impulse_view_components
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - abeidahmed
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: view_component
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionview
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 6.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 6.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: capybara
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.39'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 3.39.2
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.39'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 3.39.2
61
+ - !ruby/object:Gem::Dependency
62
+ name: byebug
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '11.1'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 11.1.3
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '11.1'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 11.1.3
81
+ - !ruby/object:Gem::Dependency
82
+ name: selenium-webdriver
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '4.10'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '4.10'
95
+ - !ruby/object:Gem::Dependency
96
+ name: webmock
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '3.18'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 3.18.1
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.18'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 3.18.1
115
+ description:
116
+ email:
117
+ - info@ambiki.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - CHANGELOG.md
123
+ - LICENSE.txt
124
+ - README.md
125
+ - app/assets/dist/impulse_view_components.css
126
+ - app/assets/dist/impulse_view_components.css.map
127
+ - app/assets/dist/impulse_view_components.js
128
+ - app/components/impulse/ajax_select_component.html.erb
129
+ - app/components/impulse/ajax_select_component.rb
130
+ - app/components/impulse/application_component.rb
131
+ - app/components/impulse/autocomplete/option_component.html.erb
132
+ - app/components/impulse/autocomplete/option_component.rb
133
+ - app/components/impulse/autocomplete_component.html.erb
134
+ - app/components/impulse/autocomplete_component.rb
135
+ - app/components/impulse/base_renderer.rb
136
+ - app/components/impulse/popover_component.html.erb
137
+ - app/components/impulse/popover_component.rb
138
+ - app/components/impulse/select_component.html.erb
139
+ - app/components/impulse/select_component.rb
140
+ - app/components/impulse/spinner_component.rb
141
+ - lib/impulse/forms/builder.rb
142
+ - lib/impulse/forms/tags/ajax_select.rb
143
+ - lib/impulse/forms/tags/base.rb
144
+ - lib/impulse/forms/tags/select.rb
145
+ - lib/impulse/helpers/attributes_helper.rb
146
+ - lib/impulse/helpers/form_helper.rb
147
+ - lib/impulse/view_components.rb
148
+ - lib/impulse/view_components/engine.rb
149
+ - lib/impulse/view_components/version.rb
150
+ homepage: https://github.com/Ambiki/impulse_view_components
151
+ licenses:
152
+ - MIT
153
+ metadata:
154
+ source_code_uri: https://github.com/Ambiki/impulse_view_components
155
+ changelog_uri: https://github.com/Ambiki/impulse_view_components/blob/main/CHANGELOG.md
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 3.1.4
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubygems_version: 3.3.26
172
+ signing_key:
173
+ specification_version: 4
174
+ summary: View components for Ruby on Rails
175
+ test_files: []