diff --git a/README.md b/README.md index 50c6ce39..03928458 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,15 @@ We use: - [TailwindCSS](https://tailwindcss.com) - [TailwindUI](https://tailwindui.com) -- [FontAwesome 6](https://fontawesome.com/v6.0/) +- [FontAwesome 7](https://fontawesome.com/v7.0/) - [ViewComponent](https://viewcomponent.org) - [HotWired](https://hotwired.dev) - [BEM](https://cssguidelin.es/#bem-like-naming) +## Upgrade + +* From 2.3.0 onwards, we will no longer ship Fontawesome free. It conflicts with Fontawesome Pro. You can easily add the javascript files, you can download them from here: https://fontawesome.com/download. Use the files from the `js` folder. Put these in a folder which is in your manifest and it should just work. + ## Installation Your main app needs to have at least the following config/postcss.config.js: diff --git a/app/assets/config/satis_manifest.js b/app/assets/config/satis_manifest.js index 7c7a38ef..134e1c03 100644 --- a/app/assets/config/satis_manifest.js +++ b/app/assets/config/satis_manifest.js @@ -1,5 +1,4 @@ //= link_tree ../images -//= link_directory ../fontawesome //= link_directory ../../javascript/satis .js //= link_directory ../../javascript/satis/controllers .js //= link_directory ../../javascript/satis/elements .js diff --git a/app/assets/fontawesome/brands.js b/app/assets/fontawesome/brands.js deleted file mode 100644 index d80911f7..00000000 --- a/app/assets/fontawesome/brands.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license (Commercial License) - * Copyright 2023 Fonticons, Inc. - */ -!function(){"use strict";var c={},l={};try{"undefined"!=typeof window&&(c=window),"undefined"!=typeof document&&(l=document)}catch(c){}var z=(c.navigator||{}).userAgent,h=void 0===z?"":z,a=c,m=l;a.document,m.documentElement&&m.head&&"function"==typeof m.addEventListener&&m.createElement,~h.indexOf("MSIE")||h.indexOf("Trident/");function v(l,c){var z,h=Object.keys(l);return Object.getOwnPropertySymbols&&(z=Object.getOwnPropertySymbols(l),c&&(z=z.filter(function(c){return Object.getOwnPropertyDescriptor(l,c).enumerable})),h.push.apply(h,z)),h}function C(l){for(var c=1;cc.length)&&(l=c.length);for(var z=0,h=new Array(l);zt.length)&&(a=t.length);for(var e=0,n=new Array(a);e>>0;e--;)a[e]=t[e];return a}function nt(t){return t.classList?et(t.classList):(t.getAttribute("class")||"").split(" ").filter(function(t){return t})}function it(t){return"".concat(t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function rt(e){return Object.keys(e||{}).reduce(function(t,a){return t+"".concat(a,": ").concat(e[a].trim(),";")},"")}function ot(t){return t.size!==$.size||t.x!==$.x||t.y!==$.y||t.rotate!==$.rotate||t.flipX||t.flipY}function st(){var t,a,e=A,n=J.cssPrefix,i=J.replacementClass,r=':host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Solid";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Regular";--fa-font-light:normal 300 1em/1 "Font Awesome 6 Light";--fa-font-thin:normal 100 1em/1 "Font Awesome 6 Thin";--fa-font-duotone:normal 900 1em/1 "Font Awesome 6 Duotone";--fa-font-sharp-solid:normal 900 1em/1 "Font Awesome 6 Sharp";--fa-font-sharp-regular:normal 400 1em/1 "Font Awesome 6 Sharp";--fa-font-sharp-light:normal 300 1em/1 "Font Awesome 6 Sharp";--fa-font-sharp-thin:normal 100 1em/1 "Font Awesome 6 Sharp";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}svg:not(:host).svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible;box-sizing:content-box}.svg-inline--fa{display:var(--fa-display,inline-block);height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-2xs{vertical-align:.1em}.svg-inline--fa.fa-xs{vertical-align:0}.svg-inline--fa.fa-sm{vertical-align:-.0714285705em}.svg-inline--fa.fa-lg{vertical-align:-.2em}.svg-inline--fa.fa-xl{vertical-align:-.25em}.svg-inline--fa.fa-2xl{vertical-align:-.3125em}.svg-inline--fa.fa-pull-left{margin-right:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-pull-right{margin-left:var(--fa-pull-margin,.3em);width:auto}.svg-inline--fa.fa-li{width:var(--fa-li-width,2em);top:.25em}.svg-inline--fa.fa-fw{width:var(--fa-fw-width,1.25em)}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:var(--fa-counter-background-color,#ff253a);border-radius:var(--fa-counter-border-radius,1em);box-sizing:border-box;color:var(--fa-inverse,#fff);line-height:var(--fa-counter-line-height,1);max-width:var(--fa-counter-max-width,5em);min-width:var(--fa-counter-min-width,1.5em);overflow:hidden;padding:var(--fa-counter-padding,.25em .5em);right:var(--fa-right,0);text-overflow:ellipsis;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-counter-scale,.25));transform:scale(var(--fa-counter-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:var(--fa-bottom,0);right:var(--fa-right,0);top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:var(--fa-bottom,0);left:var(--fa-left,0);right:auto;top:auto;-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{top:var(--fa-top,0);right:var(--fa-right,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:var(--fa-left,0);right:auto;top:var(--fa-top,0);-webkit-transform:scale(var(--fa-layers-scale,.25));transform:scale(var(--fa-layers-scale,.25));-webkit-transform-origin:top left;transform-origin:top left}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.0833333337em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.0714285718em;vertical-align:.0535714295em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.0416666682em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width,2em) * -1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-color:var(--fa-border-color,#eee);border-radius:var(--fa-border-radius,.1em);border-style:var(--fa-border-style,solid);border-width:var(--fa-border-width,.08em);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-duration:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1,1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}100%{-webkit-transform:scale(1,1) translateY(0);transform:scale(1,1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}100%,40%{-webkit-transform:rotate(0);transform:rotate(0)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;vertical-align:middle;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;z-index:var(--fa-stack-z-index,auto)}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-sr-only,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.fa-sr-only-focusable:not(:focus),.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fa-duotone.fa-inverse,.fad.fa-inverse{color:var(--fa-inverse,#fff)}';return"fa"===n&&i===e||(t=new RegExp("\\.".concat("fa","\\-"),"g"),a=new RegExp("\\--".concat("fa","\\-"),"g"),e=new RegExp("\\.".concat(e),"g"),r=r.replace(t,".".concat(n,"-")).replace(a,"--".concat(n,"-")).replace(e,".".concat(i))),r}var ct=!1;function ft(){J.autoAddCss&&!ct&&(function(t){if(t&&y){var a=h.createElement("style");a.setAttribute("type","text/css"),a.innerHTML=t;for(var e=h.head.childNodes,n=null,i=e.length-1;-1").concat(n.map(pt).join(""),"")}function vt(t,a,e){if(t&&t[a]&&t[a][e])return{prefix:a,iconName:e,icon:t[a][e]}}y&&((dt=(h.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(h.readyState))||h.addEventListener("DOMContentLoaded",lt));function gt(t,a,e,n){for(var i,r,o=Object.keys(t),s=o.length,c=void 0!==n?ht(a,n):a,f=void 0===e?(i=1,t[o[0]]):(i=0,e);ic.length)&&(s=c.length);for(var l=0,z=new Array(s);l= this.minSearchQueryLengthValue && + if (this.filteredSearchQuery?.length >= this.minSearchQueryLengthValue && matches[0].getAttribute("data-satis-dropdown-item-text").toLowerCase().indexOf(this.lastSearch.toLowerCase()) >= 0) { const dataDiv = matches[0].closest('[data-satis-dropdown-target="item"]') this.selectItem(dataDiv) @@ -601,15 +604,14 @@ export default class DropdownComponentController extends ApplicationController { this.fetchResultsWith(ourUrl).then((itemCount) => { if (this.hasResults) { this.filterResultsChainTo() - - if (!this.resultsShown && !this.chainToValue) { + if (!this.resultsShown) { this.showResultsList() } // auto select when there is only 1 value - if (this.filteredSearchQuery.length >= this.minSearchQueryLengthValue && this.nrOfItems === 1 && !this.freeTextValue) { + if (this.filteredSearchQuery?.length >= this.minSearchQueryLengthValue && this.nrOfItems === 1 && !this.freeTextValue) { const dataDiv = this.itemTargets[0].closest('[data-satis-dropdown-target="item"]') - this.selectItem(dataDiv) + this.selectItem(dataDiv, true) this.setSelectedItem(dataDiv.getAttribute("data-satis-dropdown-item-value")) this.searchQueryValue = "" } else if (this.searchQueryValue?.length > 0) { diff --git a/app/components/satis/sidebar/component.css b/app/components/satis/sidebar/component.css index e5b3210e..8b87ad93 100644 --- a/app/components/satis/sidebar/component.css +++ b/app/components/satis/sidebar/component.css @@ -1,3 +1,4 @@ +/* ── Sidebar container ── */ .h-screen.flex .sidebar { @apply dark:bg-gray-700 bg-white; width: 260px; @@ -6,77 +7,44 @@ left: 0; margin-top: 4rem; position: absolute; - overflow: visible; - overflow-y: scroll; + overflow-x: hidden; + overflow-y: auto; scrollbar-width: none; z-index: 999; - transition: backdrop-filter 0.3s ease-in-out, transform 0.3s ease-in-out; - -} - -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item{ - z-index: 1100; - position: relative; - opacity: 0.99; - margin-left: 10px; - transition: backdrop-filter 0.3s ease-in-out, transform 0.3s ease-in-out; + transition: width 0.3s ease-in-out; } - .h-screen.flex .sidebar.close { - position: absolute; - overflow: visible; - top: 0; - left: 0; - height: calc(100% - 4rem); - margin-top: 4rem; width: 60px; - z-index: 999; - scrollbar-width: none; + overflow: visible; } .sidebar::-webkit-scrollbar { display: none; } +.dark .h-screen.flex .sidebar { + @apply bg-gray-800; +} +/* ── Topbar ── */ .h-screen.flex .topbar { @apply bg-white dark:bg-gray-800; height: 4rem; display: flex; max-width: 100%; - left:0; - margin-left: 0; position: relative; - z-index: 10000; - transition: backdrop-filter 0.3s ease-in-out, transform 0.3s ease-in-out; + z-index: 1000; } +/* ── Page body ── */ .page_body.close { - margin-left: 50px; - max-width: 97%; -} - -.h-screen.flex .sidebar .boxture-logo{ - margin-top: 30px; -} - -.sidebar.close .boxture-logo { - opacity: 0; -} - -.h-screen.flex .sidebar.close .icon-link { - margin-top: 0; - transition: 0.3s ease; - transition-delay: 0.1s; + margin-left: 60px; + max-width: calc(100% - 60px); } - -.sidebar.close .sts-sidebar-menu-item{ - margin-left: 2px; -} - -.sidebar .boxture-logo { +/* ── Logo ── */ +.h-screen.flex .sidebar .boxture-logo { height: 52px; width: 52px; opacity: 0.5; @@ -84,66 +52,76 @@ border-radius: 16px; font-size: 30px; color: #fff; - margin-top: 80px; + margin-top: 30px; mix-blend-mode: multiply; + transition: opacity 0.3s ease-in-out; } .dark .sidebar .boxture-logo { mix-blend-mode: normal; } -.sidebar.close .profile-logo { - display: none; +.sidebar.close .boxture-logo { + opacity: 0; + pointer-events: none; } -.sidebar .arrow:hover { - color: #555555; - cursor: pointer; +.sidebar .logo_name { + font-size: 10px; + opacity: 0.5; + text-align: center; + display: block; } -.dark .sidebar .arrow:hover { - color: #c0c0c0; +.sidebar.close .logo_name { + display: none; } -.dark .sidebar .arrow { - color: #ffffff; - opacity: 1; - margin-top: 20px; +.dark .sidebar .logo_name { + color: #edecec; +} + +.sidebar.close .profile-logo { + display: none; } +/* ── Collapse arrow ── */ .h-screen.flex .sidebar .arrow { margin-top: 20px; font-size: 20px; opacity: 0.5; - left: 0; margin-left: 10px; margin-right: 10px; transform: scaleX(-1); - transition: backdrop-filter 0.3s ease-in-out, transform 0.3s ease-in-out; + transition: transform 0.3s ease-in-out; } -.h-screen.flex .sidebar.close .arrow{ +.h-screen.flex .sidebar.close .arrow { margin-left: 15px; - left: 0; transform: scaleX(1); } -.sidebar .logo_name { - font-size: 10px; - opacity: 0.5; - text-align: center; - display: block; +.sidebar .arrow:hover { + color: #555555; + cursor: pointer; } -.sidebar.close .logo_name { - display: none; +.dark .sidebar .arrow { + color: #ffffff; + opacity: 1; + margin-top: 20px; } -.dark .h-screen.flex .sidebar { - @apply bg-gray-800; +.dark .sidebar .arrow:hover { + color: #c0c0c0; } -.dark .sidebar .logo_name { - color: #edecec; +.h-screen.flex .sidebar.close .icon-link { + margin-top: 0; + transition: 0.3s ease; + transition-delay: 0.1s; } +.sidebar.close .sts-sidebar-menu-item { + margin-left: 2px; +} diff --git a/app/components/satis/sidebar_menu_item/component.css b/app/components/satis/sidebar_menu_item/component.css index a0159a7f..04bbbfb0 100644 --- a/app/components/satis/sidebar_menu_item/component.css +++ b/app/components/satis/sidebar_menu_item/component.css @@ -1,5 +1,8 @@ +/* ── Base menu item ── */ .sts-sidebar-menu-item { @apply pt-1; + position: relative; + & a.focus { background: rgba(1, 1, 1, 0.1); @@ -15,9 +18,8 @@ @apply rotate-90; } - &__link { - @apply text-gray-800 dark:text-gray-300 hover:bg-gray-50 dark:text-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 w-full flex items-center pl-2 pr-1 py-2 text-left text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 + @apply text-gray-800 dark:text-gray-300 hover:bg-gray-50 dark:text-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 w-full flex items-center pl-2 pr-1 py-2 text-left text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500; } &__icon { @@ -34,166 +36,143 @@ } } - -.sidebar.close .sts-sidebar-menu-item__label { +/* submenu-label always hidden in expanded sidebar */ +.sidebar .sts-sidebar-menu-item .submenu-label { display: none; } -.sidebar.close .sts-sidebar-menu-item:hover > .sts-sidebar-menu-item__link { - width: 40px; -} - +/* =================================== + COLLAPSED SIDEBAR (.sidebar.close) + =================================== */ -.sidebar.close .sts-sidebar-menu-item [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item{ - display: none; - visibility: hidden; - opacity: 0; +/* Center icons in collapsed sidebar */ +.sidebar.close .icon-link > .sts-sidebar-menu-item { + margin-left: 6px; } -.sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item > [data-satis-sidebar-menu-item-target="submenu"]{ - opacity: 0; +/* Hide labels and chevrons */ +.sidebar.close .sts-sidebar-menu-item__label { display: none; - visibility: hidden; } - -.sidebar.close .sts-sidebar-menu-item .sts-sidebar-menu-item__link .sts-sidebar-menu-item__menu-icon{ +.sidebar.close .sts-sidebar-menu-item__menu-icon { display: none; - visibility: hidden; - opacity: 0; -} - -.sidebar.close .icon-link > .sts-sidebar-menu-item:hover:not(:has([data-satis-sidebar-menu-item-target="submenu"])) .sts-sidebar-menu-item__label { - @apply rounded-md bg-gray-50 dark:bg-gray-900 shadow-md py-2; - text-decoration-thickness: 2px; - display: block; - position: absolute; - padding-right: 20px; - padding-left: 20px; - margin-left: 40px; } -.sidebar.close .icon-link > .sts-sidebar-menu-item:has([data-satis-sidebar-menu-item-target="submenu"]):hover > .sts-sidebar-menu-item__link > .sts-sidebar-menu-item__label { - @apply text-white dark:bg-gray-600; - display: block; +/* ── Flyout panel (shown via JS .flyout-visible) ── */ +.sidebar.close .sts-sidebar-menu-item > [data-satis-sidebar-menu-item-target="submenu"].flyout-visible { + @apply bg-white dark:bg-gray-800 shadow-lg ring-1 ring-black/5 dark:ring-white/10; + display: block !important; position: absolute; - background-color: rgba(0, 0, 0, 1); - padding: 5px 10px; - border-radius: 4px; + left: 54px; width: 220px; - margin-left: 22px; - margin-bottom: 80px; + padding: 4px 0; + z-index: 1100; + border-radius: 0 0.5rem 0.5rem 0.5rem; } - -.sidebar.close .icon-link > .sts-sidebar-menu-item:has([data-satis-sidebar-menu-item-target="submenu"]):last-child:hover > .sts-sidebar-menu-item__link > .sts-sidebar-menu-item__label { - margin-top: -760px; - margin-left: 20px; +/* Invisible bridge: prevents hover gap between sidebar icon and flyout */ +.sidebar.close .sts-sidebar-menu-item > [data-satis-sidebar-menu-item-target="submenu"].flyout-visible::before { + content: ''; + position: absolute; + top: -10px; + left: -20px; + width: 20px; + bottom: 0; } -.fontawesome-i2svg-active .h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] { - @apply rounded-md bg-white dark:bg-gray-900 py-0 px-0 shadow-lg; - display: block; - visibility: visible; - opacity: 1; +/* Nested flyout panels (level 3+) */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible [data-satis-sidebar-menu-item-target="submenu"].flyout-visible { + @apply bg-white dark:bg-gray-800 shadow-lg ring-1 ring-black/5 dark:ring-white/10 rounded-lg; + display: block !important; position: absolute; - margin-left: 30px; - margin-top: -45px; - + left: 100%; width: 220px; - + padding: 4px 0; + z-index: 1100; } -.fontawesome-i2svg-active .h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:only-child { - @apply rounded-md bg-white dark:bg-gray-900 py-0 px-0 shadow-lg; - display: block; - visibility: visible; - opacity: 1; - position: fixed; - width: 220px; - margin-left: 0; - +/* Nested bridge */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible [data-satis-sidebar-menu-item-target="submenu"].flyout-visible::before { + content: ''; + position: absolute; + top: 0; + left: -8px; + width: 8px; + bottom: 0; } -.fontawesome-i2svg-active .h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item { +/* Items inside a visible flyout */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible > .sts-sidebar-menu-item { @apply py-0 px-0; + display: block; margin-left: 0; } -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item a.focus{ - @apply bg-white dark:bg-gray-900; +/* Flyout item links: Tailwind UI dropdown style */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__link { + @apply rounded-none px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white; } -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item a.focus{ - @apply bg-white dark:bg-gray-900; -} - -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item.pl-4 { - @apply py-0 px-0 ; +/* Show regular labels inside flyout (not submenu-label) */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__label:not(.submenu-label) { display: block; - visibility: visible; - opacity: 100; - -} - -.sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item .sts-sidebar-menu-item__label { background: none; - display:block; - overflow: visible; padding: 0; } - -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:last-child:hover > [data-satis-sidebar-menu-item-target="submenu"] { - margin-top: -425px; -} - -.h-screen.flex .sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] { - position: fixed; - margin-left: 185px; - margin-top: -80px; +/* Reset focus style inside flyout */ +.sidebar.close .icon-link .sts-sidebar-menu-item a.focus { + @apply bg-white dark:bg-gray-800; } - -.sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"]::-webkit-scrollbar { - display: none; +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item a.focus { + @apply bg-gray-100 dark:bg-gray-700; } -.h-screen.flex .sidebar .icon-link .sts-sidebar-menu-item .submenu-label { - display: none; +/* ── Tooltip label for items without submenus (shown via JS .tooltip-visible) ── */ +.sidebar.close .sts-sidebar-menu-item__label.tooltip-visible { + @apply bg-gray-900 dark:bg-gray-700 text-white text-xs font-medium shadow-lg ring-1 ring-black/5 rounded-md; + display: block !important; + position: absolute; + left: 54px; + padding: 6px 12px; + white-space: nowrap; + z-index: 1100; } -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item .submenu-label { - display: none; +/* Invisible bridge for tooltip */ +.sidebar.close .sts-sidebar-menu-item__label.tooltip-visible::before { + content: ''; + position: absolute; + top: 0; + left: -20px; + width: 20px; + bottom: 0; } -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover .submenu-label { - @apply text-white dark:bg-gray-600; - display: block; +/* ── Submenu-label header (shown via JS .tooltip-visible) — flush with flyout ── */ +.sidebar.close .submenu-label.tooltip-visible { + @apply bg-gray-900 dark:bg-gray-700 text-white text-xs font-semibold; + display: block !important; position: absolute; - background-color: rgba(0, 0, 0, 1); - padding: 5px 10px; - border-radius: 4px; - z-index: 10; + left: 54px; + padding: 6px 12px; + white-space: nowrap; + z-index: 1100; width: 220px; - margin-left: 177px; - margin-top: 0; - margin-bottom: 150px; + border-radius: 0.5rem 0.5rem 0 0; } -.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item .submenu-label { - display: none; +/* Nested submenu-label tooltips position off the flyout edge */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .submenu-label.tooltip-visible { + @apply rounded-lg; + left: 100%; + width: max-content; + max-width: 220px; } -.fontawesome-i2svg-active .h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover .submenu-label { - @apply text-white dark:bg-gray-600; - display: block; - position: absolute; - background-color: rgba(0, 0, 0, 1); - padding: 5px 10px; - border-radius: 4px; - z-index: 10; - width: 220px; - margin-left: 177px; - margin-bottom: 150px; +/* Nested tooltip labels shouldn't show (already visible in flyout) */ +.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__label.tooltip-visible { + display: none !important; } diff --git a/app/components/satis/sidebar_menu_item/component_controller.js b/app/components/satis/sidebar_menu_item/component_controller.js index 1925ea9a..1a2c664e 100644 --- a/app/components/satis/sidebar_menu_item/component_controller.js +++ b/app/components/satis/sidebar_menu_item/component_controller.js @@ -15,18 +15,131 @@ export default class SidebarMenuItemComponentController extends ApplicationContr this.boundUpdateFocus = this.updateFocus.bind(this) this.boundOpenListener = this.openListener.bind(this) + this.boundShowFlyout = this.showFlyout.bind(this) + this.boundHideFlyout = this.hideFlyout.bind(this) + this.hideTimer = null this.updateFocus(true) this.element.addEventListener('sts-sidebar-menu-item:open', this.boundOpenListener) + this.element.addEventListener('mouseenter', this.boundShowFlyout) + this.element.addEventListener('mouseleave', this.boundHideFlyout) window.addEventListener('popstate', debounce(this.boundUpdateFocus, 200)) } disconnect() { super.disconnect() + clearTimeout(this.hideTimer) this.element.removeEventListener('sts-sidebar-menu-item:open', this.boundOpenListener) + this.element.removeEventListener('mouseenter', this.boundShowFlyout) + this.element.removeEventListener('mouseleave', this.boundHideFlyout) window.removeEventListener('popstate', debounce(this.boundUpdateFocus, 200)) } + // ── Collapsed sidebar flyout logic ── + + get isSidebarClosed() { + const sidebar = this.element.closest('.sidebar') + return sidebar?.classList.contains('close') + } + + get isInsideFlyout() { + return !!this.element.closest('[data-satis-sidebar-menu-item-target="submenu"].flyout-visible') + } + + showFlyout() { + if (!this.isSidebarClosed) return + + // Cancel any pending hide + clearTimeout(this.hideTimer) + + if (this.hasSubmenuTarget) { + const submenuLabel = this.element.querySelector(':scope > .sts-sidebar-menu-item__link > .submenu-label') + + this.submenuTarget.classList.add('flyout-visible') + if (submenuLabel) submenuLabel.classList.add('tooltip-visible') + + this.positionFlyout(this.submenuTarget, submenuLabel) + } else if (!this.isInsideFlyout) { + const label = this.element.querySelector(':scope > .sts-sidebar-menu-item__link > .sts-sidebar-menu-item__label:not(.submenu-label)') + if (label) { + label.classList.add('tooltip-visible') + this.positionWithinViewport(label) + } + } + } + + hideFlyout() { + if (!this.isSidebarClosed) return + + // Delay hiding so the user can move to the flyout without it disappearing + this.hideTimer = setTimeout(() => { + if (this.hasSubmenuTarget) { + this.submenuTarget.classList.remove('flyout-visible') + this.submenuTarget.style.top = '' + } + + this.element.querySelectorAll('.tooltip-visible').forEach(el => { + el.classList.remove('tooltip-visible') + el.style.top = '' + }) + }, 150) + } + + positionFlyout(flyout, label) { + requestAnimationFrame(() => { + const flyoutRect = flyout.getBoundingClientRect() + if (flyoutRect.height === 0) return + + const viewportHeight = window.innerHeight + const margin = 8 + const labelHeight = label ? label.getBoundingClientRect().height : 0 + + let flyoutTop = parseFloat(getComputedStyle(flyout).top) || 0 + + // Check if flyout overflows bottom + if (flyoutRect.bottom > viewportHeight - margin) { + const overflow = flyoutRect.bottom - viewportHeight + margin + flyoutTop -= overflow + } + + // Check if label above flyout would overflow top + const parentRect = flyout.offsetParent?.getBoundingClientRect() + const parentTop = parentRect?.top || 0 + if (parentTop + flyoutTop - labelHeight < margin) { + flyoutTop = margin - parentTop + labelHeight + } + + flyout.style.top = `${flyoutTop}px` + + // Position label flush against the top of the flyout panel (no gap) + if (label) { + label.style.top = `${flyoutTop - labelHeight}px` + } + }) + } + + positionWithinViewport(el) { + requestAnimationFrame(() => { + const rect = el.getBoundingClientRect() + if (rect.height === 0) return + + const viewportHeight = window.innerHeight + const margin = 8 + + if (rect.bottom > viewportHeight - margin) { + const overflow = rect.bottom - viewportHeight + margin + const currentTop = parseFloat(getComputedStyle(el).top) || 0 + el.style.top = `${currentTop - overflow}px` + } + + if (rect.top < margin) { + el.style.top = `${margin - el.parentElement.getBoundingClientRect().top}px` + } + }) + } + + // ── Submenu expand/collapse (expanded sidebar) ── + open(event) { if (this.hasSubmenuTarget) { const sidebar = this.element.closest('.sidebar') @@ -43,8 +156,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr event.preventDefault() } } - // This breaks turbo, so we need to keep the propagation. - // event.stopPropagation(); } openListener(event) { @@ -54,7 +165,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr } } - // This method is used to show the submenu showSubmenu() { if (!this.hasSubmenuTarget || this.isSubmenuVisible) return @@ -62,7 +172,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr this.element.classList.toggle("active", true) } - // This method is used to hide the submenu hideSubmenu() { if (!this.hasSubmenuTarget || !this.isSubmenuVisible) return @@ -110,12 +219,7 @@ export default class SidebarMenuItemComponentController extends ApplicationContr return this.openSubmenus.length > 0 } - /** - * Get a list of all open submenus - * @returns {NodeListOf} - */ get openSubmenus() { - // scope to first match. check if there are any submenus that are not hidden return this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="submenu"]:not([class*="hidden"])') } diff --git a/app/javascript/satis/controllers/fields_for_controller.js b/app/javascript/satis/controllers/fields_for_controller.js index 7721b0c4..a63ff016 100644 --- a/app/javascript/satis/controllers/fields_for_controller.js +++ b/app/javascript/satis/controllers/fields_for_controller.js @@ -132,7 +132,7 @@ export default class FieldsForController extends ApplicationController { } monitorChanges(event) { - if (event?.detail?.src == "satis-dropdown") { + if (event?.detail?.src == "satis-dropdown" || event?.detail?.src == "prepopulate" ) { // Skip events caused by the initial load of a satis-dropdown return } diff --git a/app/javascript/satis/controllers/index.js b/app/javascript/satis/controllers/index.js index 711b21e6..fc87c949 100644 --- a/app/javascript/satis/controllers/index.js +++ b/app/javascript/satis/controllers/index.js @@ -6,6 +6,9 @@ application.register("satis-appearance-switcher", AppearanceSwitcherComponentCon import DateTimePickerComponentController from "satis/components/date_time_picker/component_controller"; application.register("satis-date-time-picker", DateTimePickerComponentController); +import CardComponentController from "satis/components/card/component_controller"; +application.register("satis-card", CardComponentController); + import DropdownComponentController from "satis/components/dropdown/component_controller"; application.register("satis-dropdown", DropdownComponentController); diff --git a/app/javascript/satis/utility_controllers/show_hide_controller.js b/app/javascript/satis/utility_controllers/show_hide_controller.js index d1922186..88ff8fac 100644 --- a/app/javascript/satis/utility_controllers/show_hide_controller.js +++ b/app/javascript/satis/utility_controllers/show_hide_controller.js @@ -20,7 +20,7 @@ export default class extends ApplicationController { this.boundUpdate = this.update.bind(this) this.watchOn = "input" - if (this.inputTarget.type == "hidden") { + if (this.inputTarget.type == "hidden" || this.inputTarget.type == "select-one") { this.watchOn = "change" } diff --git a/lib/satis/version.rb b/lib/satis/version.rb index fff54ebb..3647c497 100644 --- a/lib/satis/version.rb +++ b/lib/satis/version.rb @@ -1,3 +1,3 @@ module Satis - VERSION = "2.1.63" + VERSION = "2.3.5" end