{"version":3,"file":"ToggleOption-b70mFFJc.js","sources":["../../../app/javascript/src/components/Theme/SearchableSelect.vue","../../../app/javascript/src/modules/Explore/ToggleInput.vue","../../../app/javascript/src/modules/LiteCMS/Common/ToggleOption.vue"],"sourcesContent":["<template>\n  <div ref=\"wrapperEl\" class=\"theme-select\">\n    <div class=\"theme-select__body\">\n      <div class=\"select\">\n        <div class=\"form-control form-input current\"\n             :class=\"{ placeholder: showPlaceholder }\"\n             @click=\"dropdown = !dropdown\"\n             v-html=\"displayValue\"\n        ></div>\n\n        <div class=\"dropdown\" v-show=\"dropdown\">\n          <div class=\"search\" v-if=\"searchable\">\n            <input class=\"form-input\"\n                   ref=\"searchInput\"\n                   type=\"search\"\n                   v-model=\"search\"\n                   @keydown.up.prevent=\"highlightPrev()\"\n                   @keydown.down.prevent=\"highlightNext()\"\n                   @keydown.tab.prevent=\"highlightNext()\"\n                   @keydown.enter.prevent=\"selectHighlightedOption()\"\n            />\n            <i class=\"icon icon-search\" />\n          </div>\n          <div class=\"options\" v-if=\"filteredOptions.length > 0\">\n            <div class=\"option\"\n                 :class=\"{ highlight: highlightIndex === i }\"\n                 v-for=\"(option, i) in filteredOptions\" :key=\"i\"\n                 @mouseover=\"highlightIndex = i\"\n                 @click=\"selectOption(option)\"\n            >\n              {{ option.label }}\n            </div>\n          </div>\n        </div>\n      </div>\n      <i class=\"icon icon-arrow-down-1\" />\n    </div>\n  </div>\n</template>\n\n<script setup>\nimport { computed, nextTick, ref, watch } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport Fuse from 'fuse.js'\n\nconst props = defineProps({\n  placeholder: String,\n  value: { type: [String, Number] },\n  options: Array, // [{value, label}, ...]\n  searchable: {\n    type: Boolean,\n    default: true\n  }\n});\nconst emit = defineEmits(['select']);\n\nconst fuse = new Fuse(props.options, { keys: ['label', 'value'] });\n\nconst search = ref('');\nconst dropdown = ref(false);\nconst highlightIndex = ref(null);\nconst searchInput = ref(null);\nconst wrapperEl = ref();\n\nconst filteredOptions = computed(() => {\n  return search.value ? fuse.search(search.value).map(r => r.item) : props.options;\n});\n\nconst showPlaceholder = computed(() => props.placeholder && !props.value);\n\nconst displayValue = computed(() => {\n  if (showPlaceholder.value) {\n    return props.placeholder;\n  }\n  const matched = props.options.find(opt => opt.value === props.value);\n  return matched ? matched.label : '&nbsp;';\n});\n\nwatch(dropdown, (open) => nextTick(() => {\n  if (open) searchInput.value?.focus();\n}));\n\nwatch(filteredOptions, (rows) => {\n  highlightIndex.value = rows.length > 0 ? 0 : null;\n  showHighlightedOption();\n});\n\nonClickOutside(wrapperEl, () => dropdown.value = false);\n\nfunction highlightPrev() {\n  if (highlightIndex.value === null) {\n    highlightIndex.value = filteredOptions.value.length - 1;\n  }\n  else if (highlightIndex.value > 0) {\n    highlightIndex.value -= 1;\n  }\n  showHighlightedOption();\n}\n\nfunction highlightNext() {\n  if (highlightIndex.value === null) {\n    highlightIndex.value = 0;\n  }\n  else if (highlightIndex.value < (filteredOptions.value.length - 1)) {\n    highlightIndex.value += 1;\n  }\n  showHighlightedOption();\n}\n\nfunction selectOption(option) {\n  emit('select', option.value);\n  dropdown.value = false;\n  search.value = '';\n}\n\nfunction selectHighlightedOption() {\n  const option = filteredOptions.value[highlightIndex.value];\n  if (option) selectOption(option);\n}\n\nfunction showHighlightedOption() {\n  if (highlightIndex.value !== null) {\n    nextTick(() => document.querySelector('.option.highlight').scrollIntoViewIfNeeded(false));\n  }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n$search-icon-size: 16px;\n\n.theme-select__body {\n  position: relative;\n  line-height: 1.15;\n  display: flex;\n  align-items: center;\n}\n\n.theme-select .icon {\n  position: absolute;\n  right: $spacing-5;\n  color: $gray;\n  pointer-events: none;\n}\n\n.select {\n  flex: 1;\n  cursor: pointer;\n  position: relative;\n\n  .placeholder {\n    color: $gray;\n  }\n\n  .dropdown {\n    background: $white;\n    position: absolute;\n    z-index: 100;\n    left: 0;\n    right: auto;\n    min-width: 100%;\n    top: calc(100% + $spacing-1);\n    border: 1px solid $gray-lighter;\n    border-radius: $rounded;\n    max-height: 280px;\n    @include flex-column;\n    flex-shrink: 0;\n\n    @media (max-width: $breakpoint-m) {\n      max-height: 240px;\n    }\n\n    .options {\n      flex: 1;\n      padding: $spacing-3;\n      overflow-y: auto;\n      scrollbar-color: $gray $white;\n\n      .option {\n        border-radius: $rounded;\n        padding: $spacing-2;\n        line-height: $leading-snug;\n        cursor: pointer;\n        white-space: nowrap;\n\n        &.highlight {\n          background: $brand-tertiary-light;\n        }\n      }\n    }\n\n    .search {\n      position: relative;\n      margin: $spacing-3 $spacing-3 $spacing-1;\n      .icon {\n        position: absolute;\n        left: $spacing-5;\n        height: $search-icon-size;\n        width: $search-icon-size;\n        top: 15px;\n      }\n      input {\n        padding-left: calc($spacing-5 + $search-icon-size + 10px);\n      }\n    }\n  }\n}\n</style>\n","<template>\n  <div class=\"toggle-input\" :class=\"{'toggle-input_disabled': disabled}\">\n    <label class=\"toggle-input__switch\">\n      <input type=\"checkbox\" @change=\"change\" v-bind=\"$attrs\" :disabled=\"disabled\">\n      <span class=\"toggle-input__slider\"/>\n    </label>\n  </div>\n</template>\n\n<script setup>\ndefineProps({\n  disabled: { type: Boolean, default: false }\n});\nconst emit = defineEmits(['change']);\n\nfunction change(evt) {\n  emit('change', evt.target.checked);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n$slider-size: 20px;\n$slider-margin: 2px; /* (switchHeight - sliderSize) / 2 */\n$switch-height: 24px;\n$switch-width: 44px; /* (switchHeight - sliderMargin) * 2 */\n\n.toggle-input {\n  display: inline-block;\n\n  input:checked + .toggle-input__slider {\n    background-color: $brand-tertiary;\n  }\n\n  input:focus + .toggle-input__slider {\n    box-shadow: 0 0 1px $brand-tertiary;\n  }\n\n  input:checked + .toggle-input__slider:before {\n    transform: translateX($slider-size);\n  }\n\n  &_disabled {\n    input:checked + .toggle-input__slider {\n      background-color: $gray-lighter;\n    }\n  }\n}\n\n.toggle-input__switch {\n  position: relative;\n  display: inline-block;\n  width: $switch-width;\n  height: $switch-height;\n}\n\n.toggle-input__switch input {\n  opacity: 0;\n  width: 0;\n  height: 0;\n}\n\n.toggle-input__slider {\n  position: absolute;\n  cursor: pointer;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background-color: $gray-lighter;\n  transition: .4s;\n  border-radius: $switch-height;\n}\n\n.toggle-input__slider:before {\n  position: absolute;\n  content: '';\n  height: $slider-size;\n  width: $slider-size;\n  left: $slider-margin;\n  bottom: $slider-margin;\n  background-color: white;\n  transition: .4s;\n  border-radius: 50%;\n}\n</style>\n","<template>\n  <div class=\"toggle-option\">\n    <div :class=\"{'toggle-option_disabled': disabled}\">\n      <slot/>\n    </div>\n\n    <ToggleInput :checked=\"model\" @change=\"model = $event\" v-bind=\"$attrs\" :disabled=\"disabled\" />\n  </div>\n</template>\n\n<script setup>\nimport ToggleInput from \"@/modules/Explore/ToggleInput.vue\";\n\ndefineProps({\n  disabled: { type: Boolean, default: false }\n});\n\nconst model = defineModel();\n</script>\n\n<style lang=\"scss\" scoped>\n@import \"app/assets/stylesheets/litecms\";\n\n$slider-size: 26px;\n$slider-margin: 2px; /* (switchHeight - sliderSize) / 2 */\n$switch-height: 30px;\n$switch-width: 50px; /* (switchHeight - sliderMargin) * 2 */\n\n.toggle-option {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  gap: $spacing-6;\n}\n\n.toggle-option :deep(.toggle-input) {\n  input:checked + .toggle-input__slider:before {\n    transform: translateX(20px);\n  }\n\n  .toggle-input__switch {\n    width: $switch-width;\n    height: $switch-height;\n  }\n\n  .toggle-input__slider {\n    border-radius: $switch-height;\n  }\n\n  .toggle-input__slider:before {\n    height: $slider-size;\n    width: $slider-size;\n    left: $slider-margin;\n    bottom: $slider-margin;\n    box-shadow: 0 3px 1px 0 #0000000F, 0 3px 8px 0 #00000026;\n  }\n}\n\n.toggle-option_disabled {\n  color: $gray;\n}\n</style>\n"],"names":["props","__props","emit","__emit","fuse","Fuse","search","ref","dropdown","highlightIndex","searchInput","wrapperEl","filteredOptions","computed","r","showPlaceholder","displayValue","matched","opt","watch","open","nextTick","_a","rows","showHighlightedOption","onClickOutside","highlightPrev","highlightNext","selectOption","option","selectHighlightedOption","change","evt","model","_useModel"],"mappings":"uoBA6CA,MAAMA,EAAQC,EASRC,EAAOC,EAEPC,EAAO,IAAIC,EAAKL,EAAM,QAAS,CAAE,KAAM,CAAC,QAAS,OAAO,EAAG,EAE3DM,EAASC,EAAI,EAAE,EACfC,EAAWD,EAAI,EAAK,EACpBE,EAAiBF,EAAI,IAAI,EACzBG,EAAcH,EAAI,IAAI,EACtBI,EAAYJ,EAAK,EAEjBK,EAAkBC,EAAS,IACxBP,EAAO,MAAQF,EAAK,OAAOE,EAAO,KAAK,EAAE,IAAIQ,GAAKA,EAAE,IAAI,EAAId,EAAM,OAC1E,EAEKe,EAAkBF,EAAS,IAAMb,EAAM,aAAe,CAACA,EAAM,KAAK,EAElEgB,EAAeH,EAAS,IAAM,CAClC,GAAIE,EAAgB,MAClB,OAAOf,EAAM,YAEf,MAAMiB,EAAUjB,EAAM,QAAQ,KAAKkB,GAAOA,EAAI,QAAUlB,EAAM,KAAK,EACnE,OAAOiB,EAAUA,EAAQ,MAAQ,QACnC,CAAC,EAEDE,EAAMX,EAAWY,GAASC,EAAS,IAAM,OACnCD,KAAME,EAAAZ,EAAY,QAAZ,MAAAY,EAAmB,QAC/B,CAAC,CAAC,EAEFH,EAAMP,EAAkBW,GAAS,CAC/Bd,EAAe,MAAQc,EAAK,OAAS,EAAI,EAAI,KAC7CC,EAAuB,CACzB,CAAC,EAEDC,EAAed,EAAW,IAAMH,EAAS,MAAQ,EAAK,EAEtD,SAASkB,GAAgB,CACnBjB,EAAe,QAAU,KAC3BA,EAAe,MAAQG,EAAgB,MAAM,OAAS,EAE/CH,EAAe,MAAQ,IAC9BA,EAAe,OAAS,GAE1Be,EAAuB,CACzB,CAEA,SAASG,GAAgB,CACnBlB,EAAe,QAAU,KAC3BA,EAAe,MAAQ,EAEhBA,EAAe,MAASG,EAAgB,MAAM,OAAS,IAC9DH,EAAe,OAAS,GAE1Be,EAAuB,CACzB,CAEA,SAASI,EAAaC,EAAQ,CAC5B3B,EAAK,SAAU2B,EAAO,KAAK,EAC3BrB,EAAS,MAAQ,GACjBF,EAAO,MAAQ,EACjB,CAEA,SAASwB,GAA0B,CACjC,MAAMD,EAASjB,EAAgB,MAAMH,EAAe,KAAK,EACrDoB,GAAQD,EAAaC,CAAM,CACjC,CAEA,SAASL,GAAwB,CAC3Bf,EAAe,QAAU,MAC3BY,EAAS,IAAM,SAAS,cAAc,mBAAmB,EAAE,uBAAuB,EAAK,CAAC,CAE5F,krCC/GA,MAAMnB,EAAOC,EAEb,SAAS4B,EAAOC,EAAK,CACnB9B,EAAK,SAAU8B,EAAI,OAAO,OAAO,CACnC,4dCAA,MAAMC,EAAQC,gBAAY"}