@aotearoan/neon 9.0.2-beta-1 → 9.0.4-beta-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";var d=require("./NeonSelect.ts_vue_type_script_src_37fb08e4_lang.cjs.js"),e=require("vue"),c=require("../../../_virtual/plugin-vue_export-helper.cjs.js");const p={class:"neon-select__wrapper"},u={class:"no-style neon-select__options"},m={class:"neon-select__option-container"},k={class:"neon-select__option-label"},b=["id","aria-selected","onClick","onMouseover"],y={class:"neon-select__option-container"},v={class:"neon-select__option-label"},_=["disabled","multiple"],g=["selected"],h=["label"],B=["data-index","disabled","multiple","selected","value"],V=["data-index","disabled","multiple","selected","value"];function E(l,t,f,C,S,z){const a=e.resolveComponent("neon-switch"),i=e.resolveComponent("neon-icon"),r=e.resolveComponent("neon-dropdown");return e.openBlock(),e.createElementBlock("div",p,[e.createVNode(r,e.mergeProps({id:l.id,ref:"dropdown",modelValue:l.open,"onUpdate:modelValue":t[0]||(t[0]=n=>l.open=n),"aria-activedescendant":l.multiple?l.modelValue[0]:l.modelValue,"aria-multiselectable":l.multiple,class:[[`neon-select--${l.color}`,{"neon-select--grouped":l.groupedOptions,"neon-select--multiple":l.multiple}],"neon-select"],color:l.color,disabled:l.disabled,icon:l.computedIcon,label:l.computedLabel,size:l.size,role:"listbox"},l.sanitizedAttributes,{onDropdownPlacement:l.onPlacement}),{default:e.withCtx(()=>[e.createElementVNode("ul",u,[l.placeholderAsOption?(e.openBlock(),e.createElementBlock("li",{key:0,class:e.normalizeClass([`neon-select__option--${l.size}`,"neon-select__option neon-select__option--disabled neon-select__option-placeholder"])},[e.createElementVNode("div",m,[e.createElementVNode("span",k,e.toDisplayString(l.placeholder),1)])],2)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.computedOptions,n=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[n.group!==""?(e.openBlock(),e.createElementBlock("li",{key:n.group,class:"neon-select__option-title"},e.toDisplayString(n.group),1)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,o=>(e.openBlock(),e.createElementBlock("li",{id:o.key,key:o.key,"aria-selected":l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,class:e.normalizeClass([[{"neon-select__option--disabled":o.disabled,"neon-select__option--separator-before":o.separatorBefore,"neon-select__option--selected":l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,"neon-select__option--highlighted":o.key===l.highlightedKey},`neon-select__option--${l.size}`],"neon-select__option"]),role:"option",onClick:s=>!o.disabled&&l.clickOption(o),onMouseover:s=>l.changeHighlighted(o.key)},[e.createElementVNode("div",y,[e.renderSlot(l.$slots,"option",{option:o},()=>[l.multiple?(e.openBlock(),e.createBlock(a,{key:0,color:l.color,modelValue:l.modelValue.indexOf(o.key)>=0,size:l.size==="l"?"m":"s","switch-style":"checkbox"},null,8,["color","modelValue","size"])):e.createCommentVNode("",!0),o.icon?(e.openBlock(),e.createBlock(i,{key:1,disabled:o.disabled,name:o.icon,class:"neon-select__option-icon"},null,8,["disabled","name"])):e.createCommentVNode("",!0),e.createElementVNode("span",v,e.toDisplayString(o.label),1)])])],42,b))),128))],64))),256))])]),_:3},16,["id","modelValue","aria-activedescendant","aria-multiselectable","class","color","disabled","icon","label","size","onDropdownPlacement"]),e.createElementVNode("select",e.mergeProps({disabled:l.disabled,multiple:l.multiple,class:"neon-select__native"},l.sanitizedAttributes,{onInput:t[1]||(t[1]=(...n)=>l.nativeSelectChange&&l.nativeSelectChange(...n))}),[e.createElementVNode("option",{selected:l.multiple?l.modelValue.length===0:l.modelValue==="",disabled:"",hidden:"",value:""},e.toDisplayString(l.placeholder),9,g),l.groupedOptions?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(l.groupedOptions,n=>(e.openBlock(),e.createElementBlock("optgroup",{key:n.group,label:n.group},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,(o,s)=>(e.openBlock(),e.createElementBlock("option",{key:`${o.key}-native`,"data-index":s,disabled:o.disabled,multiple:l.multiple,selected:l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,value:o.key},e.toDisplayString(o.label),9,B))),128))],8,h))),128)):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(l.options,(n,o)=>(e.openBlock(),e.createElementBlock("option",{key:`${n.key}-native`,"data-index":o,disabled:n.disabled,multiple:l.multiple,selected:l.multiple?l.modelValue.indexOf(n.key)>=0:n.key===l.modelValue,value:n.key},e.toDisplayString(n.label),9,V))),128))],16,_)])}var N=c(d,[["render",E],["__file","/Users/andrew/dev/projects/neon/src/components/user-input/select/NeonSelect.vue"]]);module.exports=N;
1
+ "use strict";var d=require("./NeonSelect.ts_vue_type_script_src_37fb08e4_lang.cjs.js"),e=require("vue"),c=require("../../../_virtual/plugin-vue_export-helper.cjs.js");const p={class:"neon-select__wrapper"},u={class:"no-style neon-select__options"},m={class:"neon-select__option-container"},k={class:"neon-select__option-label"},b=["id","aria-selected","onMouseover","onClick"],y={class:"neon-select__option-container"},v={class:"neon-select__option-label"},_=["disabled","multiple"],g=["selected"],h=["label"],B=["data-index","disabled","multiple","selected","value"],V=["data-index","disabled","multiple","selected","value"];function E(l,t,f,C,S,w){const a=e.resolveComponent("neon-switch"),i=e.resolveComponent("neon-icon"),r=e.resolveComponent("neon-dropdown");return e.openBlock(),e.createElementBlock("div",p,[e.createVNode(r,e.mergeProps({id:l.id,ref:"dropdown",modelValue:l.open,"onUpdate:modelValue":t[0]||(t[0]=n=>l.open=n),"aria-activedescendant":l.multiple?l.modelValue[0]:l.modelValue,"aria-multiselectable":l.multiple,class:[[`neon-select--${l.color}`,{"neon-select--grouped":l.groupedOptions,"neon-select--multiple":l.multiple}],"neon-select"],color:l.color,disabled:l.disabled,icon:l.computedIcon,label:l.computedLabel,size:l.size,role:"listbox"},l.sanitizedAttributes,{onDropdownPlacement:l.onPlacement}),{default:e.withCtx(()=>[e.createElementVNode("ul",u,[l.placeholderAsOption?(e.openBlock(),e.createElementBlock("li",{key:0,class:e.normalizeClass([`neon-select__option--${l.size}`,"neon-select__option neon-select__option--disabled neon-select__option-placeholder"])},[e.createElementVNode("div",m,[e.createElementVNode("span",k,e.toDisplayString(l.placeholder),1)])],2)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.computedOptions,n=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[n.group!==""?(e.openBlock(),e.createElementBlock("li",{key:n.group,class:"neon-select__option-title"},e.toDisplayString(n.group),1)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,o=>(e.openBlock(),e.createElementBlock("li",{id:o.key,key:o.key,"aria-selected":l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,class:e.normalizeClass([[{"neon-select__option--disabled":o.disabled,"neon-select__option--separator-before":o.separatorBefore,"neon-select__option--selected":l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,"neon-select__option--highlighted":o.key===l.highlightedKey},`neon-select__option--${l.size}`],"neon-select__option"]),role:"option",onMouseover:s=>l.changeHighlighted(o.key),onClick:e.withModifiers(s=>!o.disabled&&l.clickOption(o),["stop","prevent"])},[e.createElementVNode("div",y,[e.renderSlot(l.$slots,"option",{option:o},()=>[l.multiple?(e.openBlock(),e.createBlock(a,{key:0,color:l.color,modelValue:l.modelValue.indexOf(o.key)>=0,size:l.size==="l"?"m":"s","switch-style":"checkbox"},null,8,["color","modelValue","size"])):e.createCommentVNode("",!0),o.icon?(e.openBlock(),e.createBlock(i,{key:1,disabled:o.disabled,name:o.icon,class:"neon-select__option-icon"},null,8,["disabled","name"])):e.createCommentVNode("",!0),e.createElementVNode("span",v,e.toDisplayString(o.label),1)])])],42,b))),128))],64))),256))])]),_:3},16,["id","modelValue","aria-activedescendant","aria-multiselectable","class","color","disabled","icon","label","size","onDropdownPlacement"]),e.createElementVNode("select",e.mergeProps({disabled:l.disabled,multiple:l.multiple,class:"neon-select__native"},l.sanitizedAttributes,{onInput:t[1]||(t[1]=(...n)=>l.nativeSelectChange&&l.nativeSelectChange(...n))}),[e.createElementVNode("option",{selected:l.multiple?l.modelValue.length===0:l.modelValue==="",disabled:"",hidden:"",value:""},e.toDisplayString(l.placeholder),9,g),l.groupedOptions?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(l.groupedOptions,n=>(e.openBlock(),e.createElementBlock("optgroup",{key:n.group,label:n.group},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,(o,s)=>(e.openBlock(),e.createElementBlock("option",{key:`${o.key}-native`,"data-index":s,disabled:o.disabled,multiple:l.multiple,selected:l.multiple?l.modelValue.indexOf(o.key)>=0:o.key===l.modelValue,value:o.key},e.toDisplayString(o.label),9,B))),128))],8,h))),128)):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(l.options,(n,o)=>(e.openBlock(),e.createElementBlock("option",{key:`${n.key}-native`,"data-index":o,disabled:n.disabled,multiple:l.multiple,selected:l.multiple?l.modelValue.indexOf(n.key)>=0:n.key===l.modelValue,value:n.key},e.toDisplayString(n.label),9,V))),128))],16,_)])}var N=c(d,[["render",E],["__file","/Users/andrew/dev/projects/neon/src/components/user-input/select/NeonSelect.vue"]]);module.exports=N;
2
2
  //# sourceMappingURL=NeonSelect.cjs.js.map
@@ -1,11 +1,11 @@
1
1
  import _sfc_main from "./NeonSelect.ts_vue_type_script_src_37fb08e4_lang.es.js";
2
- import { resolveComponent, openBlock, createElementBlock, createVNode, mergeProps, withCtx, createElementVNode, normalizeClass, toDisplayString, createCommentVNode, Fragment, renderList, renderSlot, createBlock } from "vue";
2
+ import { resolveComponent, openBlock, createElementBlock, createVNode, mergeProps, withCtx, createElementVNode, normalizeClass, toDisplayString, createCommentVNode, Fragment, renderList, withModifiers, renderSlot, createBlock } from "vue";
3
3
  import _export_sfc from "../../../_virtual/plugin-vue_export-helper.es.js";
4
4
  const _hoisted_1 = { class: "neon-select__wrapper" };
5
5
  const _hoisted_2 = { class: "no-style neon-select__options" };
6
6
  const _hoisted_3 = { class: "neon-select__option-container" };
7
7
  const _hoisted_4 = { class: "neon-select__option-label" };
8
- const _hoisted_5 = ["id", "aria-selected", "onClick", "onMouseover"];
8
+ const _hoisted_5 = ["id", "aria-selected", "onMouseover", "onClick"];
9
9
  const _hoisted_6 = { class: "neon-select__option-container" };
10
10
  const _hoisted_7 = { class: "neon-select__option-label" };
11
11
  const _hoisted_8 = ["disabled", "multiple"];
@@ -64,8 +64,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
64
64
  `neon-select__option--${_ctx.size}`
65
65
  ], "neon-select__option"]),
66
66
  role: "option",
67
- onClick: ($event) => !option.disabled && _ctx.clickOption(option),
68
- onMouseover: ($event) => _ctx.changeHighlighted(option.key)
67
+ onMouseover: ($event) => _ctx.changeHighlighted(option.key),
68
+ onClick: withModifiers(($event) => !option.disabled && _ctx.clickOption(option), ["stop", "prevent"])
69
69
  }, [
70
70
  createElementVNode("div", _hoisted_6, [
71
71
  renderSlot(_ctx.$slots, "option", { option }, () => [
@@ -1 +1 @@
1
- {"version":3,"file":"NeonSelect.ts_vue_type_script_src_37fb08e4_lang.cjs.js","sources":["../../../../src/components/user-input/select/NeonSelect.ts?vue&type=script&src=37fb08e4&lang.ts"],"sourcesContent":["import { computed, defineComponent, onMounted, onUnmounted, ref, useAttrs, watch } from 'vue';\nimport { NeonSize } from '@/common/enums/NeonSize';\nimport type { NeonSelectGroup } from '@/common/models/NeonSelectGroup';\nimport type { NeonSelectOption } from '@/common/models/NeonSelectOption';\nimport { NeonFunctionalColor } from '@/common/enums/NeonFunctionalColor';\nimport NeonDropdown from '@/components/presentation/dropdown/NeonDropdown.vue';\nimport NeonIcon from '@/components/presentation/icon/NeonIcon.vue';\nimport NeonSwitch from '@/components/user-input/switch/NeonSwitch.vue';\nimport { NeonDropdownPlacement } from '@/common/enums/NeonDropdownPlacement';\nimport { NeonScrollUtils } from '@/common/utils/NeonScrollUtils';\n\n/**\n * <p>The <strong>NeonSelect</strong> is the equivalent of an HTML &lt;select&gt; form control. On touch devices\n * NeonSelect will use the native select for input. <strong>NeonSelect</strong> supports grouping and multiselect.</p>\n * <p><strong>Note:</strong> As well as the options described below, pass through attributes supported by\n * <a href=\"/presentation/dropdown\">NeonDropdown</a> to change the style of the dropdown button.</p>\n */\nexport default defineComponent({\n name: 'NeonSelect',\n components: {\n NeonDropdown,\n NeonIcon,\n NeonSwitch,\n },\n props: {\n /**\n * Id for the dropdown button\n */\n id: { type: String },\n /**\n * Placeholder to display as button label when there is no option selected.\n */\n placeholder: { type: String, required: true },\n /**\n * Display the placeholder as the first option in the select, this is useful as an alternative to a label.\n */\n placeholderAsOption: { type: Boolean, default: false },\n /**\n * Optional placeholder icon.\n */\n placeholderIcon: { type: String, required: false },\n /**\n * A list of options to render in the select.\n */\n options: { type: Array as () => Array<NeonSelectOption>, required: false },\n /**\n * A list of grouped options to render in the select.\n */\n groupedOptions: { type: Array as () => Array<NeonSelectGroup>, required: false },\n /**\n * Either a single string, indicating the key of the selected option or an array of selected keys in the case\n * multiple = true.\n */\n modelValue: { type: [String, Array as () => Array<string>], required: true },\n /**\n * Allow multi-select.\n */\n multiple: { type: Boolean, default: false },\n /**\n * Placeholder when multiple values are selected.\n */\n multiselectPlaceholder: { type: String, required: false },\n /**\n * Disable the select\n */\n disabled: { type: Boolean, default: false },\n /**\n * The size of the dropdown - Small, Medium or Large.\n */\n size: { type: String as () => NeonSize, default: NeonSize.Medium },\n /**\n * The color of the select.\n */\n color: { type: String as () => NeonFunctionalColor, default: NeonFunctionalColor.LowContrast },\n },\n emits: [\n /**\n * emitted when the user changes the selection.\n * @type {string | string[]} either the selected option's key (single select) or an array of the selected keys\n * (multi-select).\n */\n 'update:modelValue',\n ],\n setup(props, { emit }) {\n const attrs = useAttrs();\n\n const dropdown = ref<HTMLElement | null>(null);\n\n const open = ref(false);\n const dropdownPlacement = ref<NeonDropdownPlacement | null>(null);\n const highlightedKey = ref<string | null>(null);\n const highlightedIndex = ref(-1);\n\n const flattenedOptions = computed((): NeonSelectOption[] => {\n return props.options || props.groupedOptions?.flatMap((group) => group.options) || [];\n });\n\n const isReverse = () => {\n if (!props.groupedOptions) {\n switch (dropdownPlacement.value) {\n case NeonDropdownPlacement.TopLeft:\n case NeonDropdownPlacement.TopRight:\n case NeonDropdownPlacement.LeftBottom:\n case NeonDropdownPlacement.RightBottom:\n return true;\n }\n }\n\n return false;\n };\n\n const scrollOnNavigate = () => {\n const element = dropdown.value?.querySelector('.neon-select__option--highlighted') as HTMLElement;\n\n if (element) {\n NeonScrollUtils.scrollIntoView(element);\n }\n };\n\n const navigateBy = (offset: number, $event: KeyboardEvent) => {\n const newIndex = highlightedIndex.value + offset;\n if (newIndex >= 0 && newIndex <= flattenedOptions.value.length - 1) {\n highlightedIndex.value = newIndex;\n highlightedKey.value = flattenedOptions.value[highlightedIndex.value].key;\n $event.preventDefault();\n setTimeout(scrollOnNavigate);\n }\n };\n\n const emitInputEvent = (value: string | string[]) => {\n emit('update:modelValue', value);\n };\n\n const clickOption = (option: NeonSelectOption) => {\n if (props.multiple) {\n const values = [...props.modelValue];\n const index = values.findIndex((v) => v === option.key);\n if (index >= 0) {\n values.splice(index, 1);\n } else {\n values.push(option.key);\n }\n emitInputEvent(values);\n } else if (props.modelValue !== option.key) {\n open.value = false;\n emitInputEvent(option.key);\n }\n };\n\n const keyboardHandler = ($event: KeyboardEvent) => {\n if (open.value) {\n switch ($event.code) {\n case 'ArrowUp':\n case 'ArrowDown': {\n const reverseOffset = isReverse() ? -1 : 1;\n if ($event.code === 'ArrowUp') {\n navigateBy(-1 * reverseOffset, $event);\n } else {\n navigateBy(1 * reverseOffset, $event);\n }\n }\n break;\n case 'Enter':\n case 'Space':\n if (!flattenedOptions.value[highlightedIndex.value].disabled) {\n clickOption(flattenedOptions.value[highlightedIndex.value]);\n $event.preventDefault();\n }\n break;\n case 'Tab':\n if (!$event.ctrlKey && !$event.metaKey && !$event.altKey) {\n open.value = false;\n }\n break;\n }\n }\n };\n\n const computedOptions = computed((): Array<NeonSelectGroup> => {\n return (\n props.groupedOptions || [\n {\n group: '',\n options: props.options || [],\n },\n ]\n );\n });\n\n const sanitizedAttributes = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { ...sanitized } = attrs;\n return sanitized;\n });\n\n const computedLabel = computed(() => {\n if (props.multiple && props.modelValue.length > 0) {\n if (props.multiselectPlaceholder) {\n return props.multiselectPlaceholder;\n } else if (props.modelValue.length > 1) {\n return `${props.modelValue.length} items selected`;\n } else {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue[0]);\n return selected?.label || '';\n }\n } else if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.label;\n }\n }\n\n return props.placeholder;\n });\n\n const computedIcon = computed(() => {\n if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.icon;\n }\n }\n\n return props.placeholderIcon;\n });\n\n const nativeSelectChange = (event: Event) => {\n const selectedKeys = Array.from((event.target as HTMLSelectElement).options)\n .filter((opt) => opt.selected)\n .map((opt) => opt.value);\n const selectedOptions = flattenedOptions.value.filter((v) => selectedKeys.indexOf(v.key) >= 0);\n const value = props.multiple ? selectedOptions.map((value) => value.key) : selectedOptions[0].key;\n emitInputEvent(value);\n };\n\n const changeHighlighted = (key: string) => {\n highlightedKey.value = key;\n highlightedIndex.value = flattenedOptions.value.findIndex((opt) => opt.key === key);\n };\n\n const onPlacement = (placement: NeonDropdownPlacement) => {\n dropdownPlacement.value = placement;\n };\n\n onMounted(() => {\n document.addEventListener('keydown', keyboardHandler);\n });\n\n onUnmounted(() => {\n document.removeEventListener('keydown', keyboardHandler);\n });\n\n watch(\n () => open.value,\n (open: boolean) => {\n if (open) {\n highlightedKey.value = flattenedOptions.value[0].key;\n highlightedIndex.value = 0;\n }\n },\n );\n\n return {\n dropdown,\n open,\n highlightedKey,\n highlightedIndex,\n flattenedOptions,\n computedLabel,\n sanitizedAttributes,\n computedOptions,\n computedIcon,\n clickOption,\n nativeSelectChange,\n changeHighlighted,\n onPlacement,\n };\n },\n});\n"],"names":["_sfc_main","defineComponent","NeonDropdown","NeonIcon","NeonSwitch","NeonSize","NeonFunctionalColor","props","emit","attrs","useAttrs","dropdown","ref","open","dropdownPlacement","highlightedKey","highlightedIndex","flattenedOptions","computed","_a","group","isReverse","NeonDropdownPlacement","scrollOnNavigate","element","NeonScrollUtils","navigateBy","offset","$event","newIndex","emitInputEvent","value","clickOption","option","values","index","v","keyboardHandler","reverseOffset","computedOptions","sanitizedAttributes","sanitized","computedLabel","selected","computedIcon","nativeSelectChange","event","selectedKeys","opt","selectedOptions","changeHighlighted","key","onPlacement","placement","onMounted","onUnmounted","watch"],"mappings":"waAiBAA,EAAeC,kBAAgB,CAC7B,KAAM,aACN,WAAY,CACV,aAAAC,EACA,SAAAC,EACA,WAAAC,CACF,EACA,MAAO,CAIL,GAAI,CAAE,KAAM,MAAO,EAInB,YAAa,CAAE,KAAM,OAAQ,SAAU,EAAK,EAI5C,oBAAqB,CAAE,KAAM,QAAS,QAAS,EAAM,EAIrD,gBAAiB,CAAE,KAAM,OAAQ,SAAU,EAAM,EAIjD,QAAS,CAAE,KAAM,MAAwC,SAAU,EAAM,EAIzE,eAAgB,CAAE,KAAM,MAAuC,SAAU,EAAM,EAK/E,WAAY,CAAE,KAAM,CAAC,OAAQ,KAA4B,EAAG,SAAU,EAAK,EAI3E,SAAU,CAAE,KAAM,QAAS,QAAS,EAAM,EAI1C,uBAAwB,CAAE,KAAM,OAAQ,SAAU,EAAM,EAIxD,SAAU,CAAE,KAAM,QAAS,QAAS,EAAM,EAI1C,KAAM,CAAE,KAAM,OAA0B,QAASC,EAAAA,SAAS,MAAO,EAIjE,MAAO,CAAE,KAAM,OAAqC,QAASC,EAAAA,oBAAoB,WAAY,CAC/F,EACA,MAAO,CAML,mBACF,EACA,MAAMC,EAAO,CAAE,KAAAC,GAAQ,CACrB,MAAMC,EAAQC,EAAAA,WAERC,EAAWC,MAAwB,IAAI,EAEvCC,EAAOD,MAAI,EAAK,EAChBE,EAAoBF,MAAkC,IAAI,EAC1DG,EAAiBH,MAAmB,IAAI,EACxCI,EAAmBJ,EAAAA,IAAI,EAAE,EAEzBK,EAAmBC,EAAAA,SAAS,IAA0B,OACnD,OAAAX,EAAM,WAAWY,EAAAZ,EAAM,iBAAN,YAAAY,EAAsB,QAASC,GAAUA,EAAM,WAAY,EAAC,CACrF,EAEKC,EAAY,IAAM,CAClB,GAAA,CAACd,EAAM,eACT,OAAQO,EAAkB,YACnBQ,EAAAA,sBAAsB,aACtBA,EAAAA,sBAAsB,cACtBA,EAAAA,sBAAsB,gBACtBA,EAAsB,sBAAA,YAClB,MAAA,GAIN,MAAA,EAAA,EAGHC,EAAmB,IAAM,OAC7B,MAAMC,GAAUL,EAAAR,EAAS,QAAT,YAAAQ,EAAgB,cAAc,qCAE1CK,GACFC,kBAAgB,eAAeD,CAAO,CACxC,EAGIE,EAAa,CAACC,EAAgBC,IAA0B,CACtD,MAAAC,EAAWb,EAAiB,MAAQW,EACtCE,GAAY,GAAKA,GAAYZ,EAAiB,MAAM,OAAS,IAC/DD,EAAiB,MAAQa,EACzBd,EAAe,MAAQE,EAAiB,MAAMD,EAAiB,OAAO,IACtEY,EAAO,eAAe,EACtB,WAAWL,CAAgB,EAC7B,EAGIO,EAAkBC,GAA6B,CACnDvB,EAAK,oBAAqBuB,CAAK,CAAA,EAG3BC,EAAeC,GAA6B,CAChD,GAAI1B,EAAM,SAAU,CAClB,MAAM2B,EAAS,CAAC,GAAG3B,EAAM,UAAU,EAC7B4B,EAAQD,EAAO,UAAWE,GAAMA,IAAMH,EAAO,GAAG,EAClDE,GAAS,EACJD,EAAA,OAAOC,EAAO,CAAC,EAEfD,EAAA,KAAKD,EAAO,GAAG,EAExBH,EAAeI,CAAM,CACZ,MAAA3B,EAAM,aAAe0B,EAAO,MACrCpB,EAAK,MAAQ,GACbiB,EAAeG,EAAO,GAAG,EAC3B,EAGII,EAAmBT,GAA0B,CACjD,GAAIf,EAAK,MACP,OAAQe,EAAO,UACR,cACA,YAAa,CACV,MAAAU,EAAgBjB,EAAU,EAAI,GAAK,EACrCO,EAAO,OAAS,UACPF,EAAA,GAAKY,EAAeV,CAAM,EAE1BF,EAAA,EAAIY,EAAeV,CAAM,CAExC,CACE,UACG,YACA,QACEX,EAAiB,MAAMD,EAAiB,OAAO,WACtCgB,EAAAf,EAAiB,MAAMD,EAAiB,MAAM,EAC1DY,EAAO,eAAe,GAExB,UACG,MACC,CAACA,EAAO,SAAW,CAACA,EAAO,SAAW,CAACA,EAAO,SAChDf,EAAK,MAAQ,IAEf,MAEN,EAGI0B,EAAkBrB,EAAAA,SAAS,IAE7BX,EAAM,gBAAkB,CACtB,CACE,MAAO,GACP,QAASA,EAAM,SAAW,CAAC,CAC7B,CAAA,CAGL,EAEKiC,EAAsBtB,EAAAA,SAAS,IAAM,CAEnC,KAAA,IAAKuB,CAAc,EAAAhC,EAClB,OAAAgC,CAAA,CACR,EAEKC,EAAgBxB,EAAAA,SAAS,IAAM,CACnC,GAAIX,EAAM,UAAYA,EAAM,WAAW,OAAS,EAAG,CACjD,GAAIA,EAAM,uBACR,OAAOA,EAAM,uBACJ,GAAAA,EAAM,WAAW,OAAS,EAC5B,MAAA,GAAGA,EAAM,WAAW,wBACtB,CACC,MAAAoC,EAAW1B,EAAiB,MAAM,KAAMgB,GAAWA,EAAO,MAAQ1B,EAAM,WAAW,EAAE,EAC3F,OAAOoC,GAAA,YAAAA,EAAU,QAAS,EAC5B,CAAA,SACSpC,EAAM,WAAY,CACrB,MAAAoC,EAAW1B,EAAiB,MAAM,KAAMgB,GAAWA,EAAO,MAAQ1B,EAAM,UAAU,EAExF,GAAIoC,EACF,OAAOA,EAAS,KAEpB,CAEA,OAAOpC,EAAM,WAAA,CACd,EAEKqC,EAAe1B,EAAAA,SAAS,IAAM,CAClC,GAAIX,EAAM,WAAY,CACd,MAAAoC,EAAW1B,EAAiB,MAAM,KAAMgB,GAAWA,EAAO,MAAQ1B,EAAM,UAAU,EAExF,GAAIoC,EACF,OAAOA,EAAS,IAEpB,CAEA,OAAOpC,EAAM,eAAA,CACd,EAEKsC,EAAsBC,GAAiB,CAC3C,MAAMC,EAAe,MAAM,KAAMD,EAAM,OAA6B,OAAO,EACxE,OAAQE,GAAQA,EAAI,QAAQ,EAC5B,IAAKA,GAAQA,EAAI,KAAK,EACnBC,EAAkBhC,EAAiB,MAAM,OAAQmB,GAAMW,EAAa,QAAQX,EAAE,GAAG,GAAK,CAAC,EACvFL,EAAQxB,EAAM,SAAW0C,EAAgB,IAAKlB,GAAUA,EAAM,GAAG,EAAIkB,EAAgB,GAAG,IAC9FnB,EAAeC,CAAK,CAAA,EAGhBmB,EAAqBC,GAAgB,CACzCpC,EAAe,MAAQoC,EACNnC,EAAA,MAAQC,EAAiB,MAAM,UAAW+B,GAAQA,EAAI,MAAQG,CAAG,CAAA,EAG9EC,EAAeC,GAAqC,CACxDvC,EAAkB,MAAQuC,CAAA,EAG5BC,OAAAA,EAAAA,UAAU,IAAM,CACL,SAAA,iBAAiB,UAAWjB,CAAe,CAAA,CACrD,EAEDkB,EAAAA,YAAY,IAAM,CACP,SAAA,oBAAoB,UAAWlB,CAAe,CAAA,CACxD,EAEDmB,EAAA,MACE,IAAM3C,EAAK,MACVA,GAAkB,CACbA,IACaE,EAAA,MAAQE,EAAiB,MAAM,GAAG,IACjDD,EAAiB,MAAQ,EAE7B,CAAA,EAGK,CACL,SAAAL,EACA,KAAAE,EACA,eAAAE,EACA,iBAAAC,EACA,iBAAAC,EACA,cAAAyB,EACA,oBAAAF,EACA,gBAAAD,EACA,aAAAK,EACA,YAAAZ,EACA,mBAAAa,EACA,kBAAAK,EACA,YAAAE,CAAA,CAEJ,CACF,CAAC"}
1
+ {"version":3,"file":"NeonSelect.ts_vue_type_script_src_37fb08e4_lang.cjs.js","sources":["../../../../src/components/user-input/select/NeonSelect.ts?vue&type=script&src=37fb08e4&lang.ts"],"sourcesContent":["import { computed, defineComponent, onMounted, onUnmounted, ref, useAttrs, watch } from 'vue';\nimport { NeonSize } from '@/common/enums/NeonSize';\nimport type { NeonSelectGroup } from '@/common/models/NeonSelectGroup';\nimport type { NeonSelectOption } from '@/common/models/NeonSelectOption';\nimport { NeonFunctionalColor } from '@/common/enums/NeonFunctionalColor';\nimport NeonDropdown from '@/components/presentation/dropdown/NeonDropdown.vue';\nimport NeonIcon from '@/components/presentation/icon/NeonIcon.vue';\nimport NeonSwitch from '@/components/user-input/switch/NeonSwitch.vue';\nimport { NeonDropdownPlacement } from '@/common/enums/NeonDropdownPlacement';\nimport { NeonScrollUtils } from '@/common/utils/NeonScrollUtils';\n\n/**\n * <p>The <strong>NeonSelect</strong> is the equivalent of an HTML &lt;select&gt; form control. On touch devices\n * NeonSelect will use the native select for input. <strong>NeonSelect</strong> supports grouping and multiselect.</p>\n * <p><strong>Note:</strong> As well as the options described below, pass through attributes supported by\n * <a href=\"/presentation/dropdown\">NeonDropdown</a> to change the style of the dropdown button.</p>\n */\nexport default defineComponent({\n name: 'NeonSelect',\n components: {\n NeonDropdown,\n NeonIcon,\n NeonSwitch,\n },\n props: {\n /**\n * Id for the dropdown button\n */\n id: { type: String },\n /**\n * Placeholder to display as button label when there is no option selected.\n */\n placeholder: { type: String, required: true },\n /**\n * Display the placeholder as the first option in the select, this is useful as an alternative to a label.\n */\n placeholderAsOption: { type: Boolean, default: false },\n /**\n * Optional placeholder icon.\n */\n placeholderIcon: { type: String, required: false },\n /**\n * A list of options to render in the select.\n */\n options: { type: Array as () => Array<NeonSelectOption>, required: false },\n /**\n * A list of grouped options to render in the select.\n */\n groupedOptions: { type: Array as () => Array<NeonSelectGroup>, required: false },\n /**\n * Either a single string, indicating the key of the selected option or an array of selected keys in the case\n * multiple = true.\n */\n modelValue: { type: [String, Array as () => Array<string>], required: true },\n /**\n * Allow multi-select.\n */\n multiple: { type: Boolean, default: false },\n /**\n * Placeholder when multiple values are selected.\n */\n multiselectPlaceholder: { type: String, required: false },\n /**\n * Disable the select\n */\n disabled: { type: Boolean, default: false },\n /**\n * The size of the dropdown - Small, Medium or Large.\n */\n size: { type: String as () => NeonSize, default: NeonSize.Medium },\n /**\n * The color of the select.\n */\n color: { type: String as () => NeonFunctionalColor, default: NeonFunctionalColor.LowContrast },\n },\n emits: [\n /**\n * emitted when the user changes the selection.\n * @type {string | string[]} either the selected option's key (single select) or an array of the selected keys\n * (multi-select).\n */\n 'update:modelValue',\n ],\n setup(props, { emit }) {\n const attrs = useAttrs();\n\n const dropdown = ref<HTMLElement | null>(null);\n\n const open = ref(false);\n const dropdownPlacement = ref<NeonDropdownPlacement | null>(null);\n const highlightedKey = ref<string | null>(null);\n const highlightedIndex = ref(-1);\n\n const flattenedOptions = computed((): NeonSelectOption[] => {\n return props.options || props.groupedOptions?.flatMap((group) => group.options) || [];\n });\n\n const isReverse = () => {\n if (!props.groupedOptions) {\n switch (dropdownPlacement.value) {\n case NeonDropdownPlacement.TopLeft:\n case NeonDropdownPlacement.TopRight:\n case NeonDropdownPlacement.LeftBottom:\n case NeonDropdownPlacement.RightBottom:\n return true;\n }\n }\n\n return false;\n };\n\n const scrollOnNavigate = () => {\n const element = dropdown.value?.querySelector('.neon-select__option--highlighted') as HTMLElement;\n\n if (element) {\n NeonScrollUtils.scrollIntoView(element);\n }\n };\n\n const navigateBy = (offset: number, $event: KeyboardEvent) => {\n const newIndex = highlightedIndex.value + offset;\n if (newIndex >= 0 && newIndex <= flattenedOptions.value.length - 1) {\n highlightedIndex.value = newIndex;\n highlightedKey.value = flattenedOptions.value[highlightedIndex.value].key;\n $event.preventDefault();\n setTimeout(scrollOnNavigate);\n }\n };\n\n const emitInputEvent = (value: string | string[]) => {\n emit('update:modelValue', value);\n };\n\n const clickOption = (option: NeonSelectOption) => {\n if (props.multiple) {\n const values = [...props.modelValue];\n const index = values.findIndex((v) => v === option.key);\n if (index >= 0) {\n values.splice(index, 1);\n } else {\n values.push(option.key);\n }\n emitInputEvent(values);\n } else if (props.modelValue !== option.key) {\n open.value = false;\n emitInputEvent(option.key);\n }\n };\n\n const keyboardHandler = ($event: KeyboardEvent) => {\n if (open.value) {\n switch ($event.code) {\n case 'ArrowUp':\n case 'ArrowDown':\n {\n const reverseOffset = isReverse() ? -1 : 1;\n if ($event.code === 'ArrowUp') {\n navigateBy(-1 * reverseOffset, $event);\n } else {\n navigateBy(1 * reverseOffset, $event);\n }\n }\n break;\n case 'Enter':\n case 'Space':\n if (!flattenedOptions.value[highlightedIndex.value].disabled) {\n clickOption(flattenedOptions.value[highlightedIndex.value]);\n $event.preventDefault();\n }\n break;\n case 'Tab':\n if (!$event.ctrlKey && !$event.metaKey && !$event.altKey) {\n open.value = false;\n }\n break;\n }\n }\n };\n\n const computedOptions = computed((): Array<NeonSelectGroup> => {\n return (\n props.groupedOptions || [\n {\n group: '',\n options: props.options || [],\n },\n ]\n );\n });\n\n const sanitizedAttributes = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { ...sanitized } = attrs;\n return sanitized;\n });\n\n const computedLabel = computed(() => {\n if (props.multiple && props.modelValue.length > 0) {\n if (props.multiselectPlaceholder) {\n return props.multiselectPlaceholder;\n } else if (props.modelValue.length > 1) {\n return `${props.modelValue.length} items selected`;\n } else {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue[0]);\n return selected?.label || '';\n }\n } else if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.label;\n }\n }\n\n return props.placeholder;\n });\n\n const computedIcon = computed(() => {\n if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.icon;\n }\n }\n\n return props.placeholderIcon;\n });\n\n const nativeSelectChange = (event: Event) => {\n const selectedKeys = Array.from((event.target as HTMLSelectElement).options)\n .filter((opt) => opt.selected)\n .map((opt) => opt.value);\n const selectedOptions = flattenedOptions.value.filter((v) => selectedKeys.indexOf(v.key) >= 0);\n const value = props.multiple ? selectedOptions.map((value) => value.key) : selectedOptions[0].key;\n emitInputEvent(value);\n };\n\n const changeHighlighted = (key: string) => {\n highlightedKey.value = key;\n highlightedIndex.value = flattenedOptions.value.findIndex((opt) => opt.key === key);\n };\n\n const onPlacement = (placement: NeonDropdownPlacement) => {\n dropdownPlacement.value = placement;\n };\n\n onMounted(() => {\n document.addEventListener('keydown', keyboardHandler);\n });\n\n onUnmounted(() => {\n document.removeEventListener('keydown', keyboardHandler);\n });\n\n watch(\n () => open.value,\n (open: boolean) => {\n if (open) {\n highlightedKey.value = flattenedOptions.value[0].key;\n highlightedIndex.value = 0;\n }\n },\n );\n\n return {\n dropdown,\n open,\n highlightedKey,\n highlightedIndex,\n flattenedOptions,\n computedLabel,\n sanitizedAttributes,\n computedOptions,\n computedIcon,\n clickOption,\n nativeSelectChange,\n changeHighlighted,\n onPlacement,\n };\n },\n});\n"],"names":["_sfc_main","defineComponent","NeonDropdown","NeonIcon","NeonSwitch","NeonSize","NeonFunctionalColor","props","emit","attrs","useAttrs","dropdown","ref","open","dropdownPlacement","highlightedKey","highlightedIndex","flattenedOptions","computed","_a","group","isReverse","NeonDropdownPlacement","scrollOnNavigate","element","NeonScrollUtils","navigateBy","offset","$event","newIndex","emitInputEvent","value","clickOption","option","values","index","v","keyboardHandler","reverseOffset","computedOptions","sanitizedAttributes","sanitized","computedLabel","selected","computedIcon","nativeSelectChange","event","selectedKeys","opt","selectedOptions","changeHighlighted","key","onPlacement","placement","onMounted","onUnmounted","watch"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NeonSelect.ts_vue_type_script_src_37fb08e4_lang.es.js","sources":["../../../../src/components/user-input/select/NeonSelect.ts?vue&type=script&src=37fb08e4&lang.ts"],"sourcesContent":["import { computed, defineComponent, onMounted, onUnmounted, ref, useAttrs, watch } from 'vue';\nimport { NeonSize } from '@/common/enums/NeonSize';\nimport type { NeonSelectGroup } from '@/common/models/NeonSelectGroup';\nimport type { NeonSelectOption } from '@/common/models/NeonSelectOption';\nimport { NeonFunctionalColor } from '@/common/enums/NeonFunctionalColor';\nimport NeonDropdown from '@/components/presentation/dropdown/NeonDropdown.vue';\nimport NeonIcon from '@/components/presentation/icon/NeonIcon.vue';\nimport NeonSwitch from '@/components/user-input/switch/NeonSwitch.vue';\nimport { NeonDropdownPlacement } from '@/common/enums/NeonDropdownPlacement';\nimport { NeonScrollUtils } from '@/common/utils/NeonScrollUtils';\n\n/**\n * <p>The <strong>NeonSelect</strong> is the equivalent of an HTML &lt;select&gt; form control. On touch devices\n * NeonSelect will use the native select for input. <strong>NeonSelect</strong> supports grouping and multiselect.</p>\n * <p><strong>Note:</strong> As well as the options described below, pass through attributes supported by\n * <a href=\"/presentation/dropdown\">NeonDropdown</a> to change the style of the dropdown button.</p>\n */\nexport default defineComponent({\n name: 'NeonSelect',\n components: {\n NeonDropdown,\n NeonIcon,\n NeonSwitch,\n },\n props: {\n /**\n * Id for the dropdown button\n */\n id: { type: String },\n /**\n * Placeholder to display as button label when there is no option selected.\n */\n placeholder: { type: String, required: true },\n /**\n * Display the placeholder as the first option in the select, this is useful as an alternative to a label.\n */\n placeholderAsOption: { type: Boolean, default: false },\n /**\n * Optional placeholder icon.\n */\n placeholderIcon: { type: String, required: false },\n /**\n * A list of options to render in the select.\n */\n options: { type: Array as () => Array<NeonSelectOption>, required: false },\n /**\n * A list of grouped options to render in the select.\n */\n groupedOptions: { type: Array as () => Array<NeonSelectGroup>, required: false },\n /**\n * Either a single string, indicating the key of the selected option or an array of selected keys in the case\n * multiple = true.\n */\n modelValue: { type: [String, Array as () => Array<string>], required: true },\n /**\n * Allow multi-select.\n */\n multiple: { type: Boolean, default: false },\n /**\n * Placeholder when multiple values are selected.\n */\n multiselectPlaceholder: { type: String, required: false },\n /**\n * Disable the select\n */\n disabled: { type: Boolean, default: false },\n /**\n * The size of the dropdown - Small, Medium or Large.\n */\n size: { type: String as () => NeonSize, default: NeonSize.Medium },\n /**\n * The color of the select.\n */\n color: { type: String as () => NeonFunctionalColor, default: NeonFunctionalColor.LowContrast },\n },\n emits: [\n /**\n * emitted when the user changes the selection.\n * @type {string | string[]} either the selected option's key (single select) or an array of the selected keys\n * (multi-select).\n */\n 'update:modelValue',\n ],\n setup(props, { emit }) {\n const attrs = useAttrs();\n\n const dropdown = ref<HTMLElement | null>(null);\n\n const open = ref(false);\n const dropdownPlacement = ref<NeonDropdownPlacement | null>(null);\n const highlightedKey = ref<string | null>(null);\n const highlightedIndex = ref(-1);\n\n const flattenedOptions = computed((): NeonSelectOption[] => {\n return props.options || props.groupedOptions?.flatMap((group) => group.options) || [];\n });\n\n const isReverse = () => {\n if (!props.groupedOptions) {\n switch (dropdownPlacement.value) {\n case NeonDropdownPlacement.TopLeft:\n case NeonDropdownPlacement.TopRight:\n case NeonDropdownPlacement.LeftBottom:\n case NeonDropdownPlacement.RightBottom:\n return true;\n }\n }\n\n return false;\n };\n\n const scrollOnNavigate = () => {\n const element = dropdown.value?.querySelector('.neon-select__option--highlighted') as HTMLElement;\n\n if (element) {\n NeonScrollUtils.scrollIntoView(element);\n }\n };\n\n const navigateBy = (offset: number, $event: KeyboardEvent) => {\n const newIndex = highlightedIndex.value + offset;\n if (newIndex >= 0 && newIndex <= flattenedOptions.value.length - 1) {\n highlightedIndex.value = newIndex;\n highlightedKey.value = flattenedOptions.value[highlightedIndex.value].key;\n $event.preventDefault();\n setTimeout(scrollOnNavigate);\n }\n };\n\n const emitInputEvent = (value: string | string[]) => {\n emit('update:modelValue', value);\n };\n\n const clickOption = (option: NeonSelectOption) => {\n if (props.multiple) {\n const values = [...props.modelValue];\n const index = values.findIndex((v) => v === option.key);\n if (index >= 0) {\n values.splice(index, 1);\n } else {\n values.push(option.key);\n }\n emitInputEvent(values);\n } else if (props.modelValue !== option.key) {\n open.value = false;\n emitInputEvent(option.key);\n }\n };\n\n const keyboardHandler = ($event: KeyboardEvent) => {\n if (open.value) {\n switch ($event.code) {\n case 'ArrowUp':\n case 'ArrowDown': {\n const reverseOffset = isReverse() ? -1 : 1;\n if ($event.code === 'ArrowUp') {\n navigateBy(-1 * reverseOffset, $event);\n } else {\n navigateBy(1 * reverseOffset, $event);\n }\n }\n break;\n case 'Enter':\n case 'Space':\n if (!flattenedOptions.value[highlightedIndex.value].disabled) {\n clickOption(flattenedOptions.value[highlightedIndex.value]);\n $event.preventDefault();\n }\n break;\n case 'Tab':\n if (!$event.ctrlKey && !$event.metaKey && !$event.altKey) {\n open.value = false;\n }\n break;\n }\n }\n };\n\n const computedOptions = computed((): Array<NeonSelectGroup> => {\n return (\n props.groupedOptions || [\n {\n group: '',\n options: props.options || [],\n },\n ]\n );\n });\n\n const sanitizedAttributes = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { ...sanitized } = attrs;\n return sanitized;\n });\n\n const computedLabel = computed(() => {\n if (props.multiple && props.modelValue.length > 0) {\n if (props.multiselectPlaceholder) {\n return props.multiselectPlaceholder;\n } else if (props.modelValue.length > 1) {\n return `${props.modelValue.length} items selected`;\n } else {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue[0]);\n return selected?.label || '';\n }\n } else if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.label;\n }\n }\n\n return props.placeholder;\n });\n\n const computedIcon = computed(() => {\n if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.icon;\n }\n }\n\n return props.placeholderIcon;\n });\n\n const nativeSelectChange = (event: Event) => {\n const selectedKeys = Array.from((event.target as HTMLSelectElement).options)\n .filter((opt) => opt.selected)\n .map((opt) => opt.value);\n const selectedOptions = flattenedOptions.value.filter((v) => selectedKeys.indexOf(v.key) >= 0);\n const value = props.multiple ? selectedOptions.map((value) => value.key) : selectedOptions[0].key;\n emitInputEvent(value);\n };\n\n const changeHighlighted = (key: string) => {\n highlightedKey.value = key;\n highlightedIndex.value = flattenedOptions.value.findIndex((opt) => opt.key === key);\n };\n\n const onPlacement = (placement: NeonDropdownPlacement) => {\n dropdownPlacement.value = placement;\n };\n\n onMounted(() => {\n document.addEventListener('keydown', keyboardHandler);\n });\n\n onUnmounted(() => {\n document.removeEventListener('keydown', keyboardHandler);\n });\n\n watch(\n () => open.value,\n (open: boolean) => {\n if (open) {\n highlightedKey.value = flattenedOptions.value[0].key;\n highlightedIndex.value = 0;\n }\n },\n );\n\n return {\n dropdown,\n open,\n highlightedKey,\n highlightedIndex,\n flattenedOptions,\n computedLabel,\n sanitizedAttributes,\n computedOptions,\n computedIcon,\n clickOption,\n nativeSelectChange,\n changeHighlighted,\n onPlacement,\n };\n },\n});\n"],"names":["value","open"],"mappings":"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"}
1
+ {"version":3,"file":"NeonSelect.ts_vue_type_script_src_37fb08e4_lang.es.js","sources":["../../../../src/components/user-input/select/NeonSelect.ts?vue&type=script&src=37fb08e4&lang.ts"],"sourcesContent":["import { computed, defineComponent, onMounted, onUnmounted, ref, useAttrs, watch } from 'vue';\nimport { NeonSize } from '@/common/enums/NeonSize';\nimport type { NeonSelectGroup } from '@/common/models/NeonSelectGroup';\nimport type { NeonSelectOption } from '@/common/models/NeonSelectOption';\nimport { NeonFunctionalColor } from '@/common/enums/NeonFunctionalColor';\nimport NeonDropdown from '@/components/presentation/dropdown/NeonDropdown.vue';\nimport NeonIcon from '@/components/presentation/icon/NeonIcon.vue';\nimport NeonSwitch from '@/components/user-input/switch/NeonSwitch.vue';\nimport { NeonDropdownPlacement } from '@/common/enums/NeonDropdownPlacement';\nimport { NeonScrollUtils } from '@/common/utils/NeonScrollUtils';\n\n/**\n * <p>The <strong>NeonSelect</strong> is the equivalent of an HTML &lt;select&gt; form control. On touch devices\n * NeonSelect will use the native select for input. <strong>NeonSelect</strong> supports grouping and multiselect.</p>\n * <p><strong>Note:</strong> As well as the options described below, pass through attributes supported by\n * <a href=\"/presentation/dropdown\">NeonDropdown</a> to change the style of the dropdown button.</p>\n */\nexport default defineComponent({\n name: 'NeonSelect',\n components: {\n NeonDropdown,\n NeonIcon,\n NeonSwitch,\n },\n props: {\n /**\n * Id for the dropdown button\n */\n id: { type: String },\n /**\n * Placeholder to display as button label when there is no option selected.\n */\n placeholder: { type: String, required: true },\n /**\n * Display the placeholder as the first option in the select, this is useful as an alternative to a label.\n */\n placeholderAsOption: { type: Boolean, default: false },\n /**\n * Optional placeholder icon.\n */\n placeholderIcon: { type: String, required: false },\n /**\n * A list of options to render in the select.\n */\n options: { type: Array as () => Array<NeonSelectOption>, required: false },\n /**\n * A list of grouped options to render in the select.\n */\n groupedOptions: { type: Array as () => Array<NeonSelectGroup>, required: false },\n /**\n * Either a single string, indicating the key of the selected option or an array of selected keys in the case\n * multiple = true.\n */\n modelValue: { type: [String, Array as () => Array<string>], required: true },\n /**\n * Allow multi-select.\n */\n multiple: { type: Boolean, default: false },\n /**\n * Placeholder when multiple values are selected.\n */\n multiselectPlaceholder: { type: String, required: false },\n /**\n * Disable the select\n */\n disabled: { type: Boolean, default: false },\n /**\n * The size of the dropdown - Small, Medium or Large.\n */\n size: { type: String as () => NeonSize, default: NeonSize.Medium },\n /**\n * The color of the select.\n */\n color: { type: String as () => NeonFunctionalColor, default: NeonFunctionalColor.LowContrast },\n },\n emits: [\n /**\n * emitted when the user changes the selection.\n * @type {string | string[]} either the selected option's key (single select) or an array of the selected keys\n * (multi-select).\n */\n 'update:modelValue',\n ],\n setup(props, { emit }) {\n const attrs = useAttrs();\n\n const dropdown = ref<HTMLElement | null>(null);\n\n const open = ref(false);\n const dropdownPlacement = ref<NeonDropdownPlacement | null>(null);\n const highlightedKey = ref<string | null>(null);\n const highlightedIndex = ref(-1);\n\n const flattenedOptions = computed((): NeonSelectOption[] => {\n return props.options || props.groupedOptions?.flatMap((group) => group.options) || [];\n });\n\n const isReverse = () => {\n if (!props.groupedOptions) {\n switch (dropdownPlacement.value) {\n case NeonDropdownPlacement.TopLeft:\n case NeonDropdownPlacement.TopRight:\n case NeonDropdownPlacement.LeftBottom:\n case NeonDropdownPlacement.RightBottom:\n return true;\n }\n }\n\n return false;\n };\n\n const scrollOnNavigate = () => {\n const element = dropdown.value?.querySelector('.neon-select__option--highlighted') as HTMLElement;\n\n if (element) {\n NeonScrollUtils.scrollIntoView(element);\n }\n };\n\n const navigateBy = (offset: number, $event: KeyboardEvent) => {\n const newIndex = highlightedIndex.value + offset;\n if (newIndex >= 0 && newIndex <= flattenedOptions.value.length - 1) {\n highlightedIndex.value = newIndex;\n highlightedKey.value = flattenedOptions.value[highlightedIndex.value].key;\n $event.preventDefault();\n setTimeout(scrollOnNavigate);\n }\n };\n\n const emitInputEvent = (value: string | string[]) => {\n emit('update:modelValue', value);\n };\n\n const clickOption = (option: NeonSelectOption) => {\n if (props.multiple) {\n const values = [...props.modelValue];\n const index = values.findIndex((v) => v === option.key);\n if (index >= 0) {\n values.splice(index, 1);\n } else {\n values.push(option.key);\n }\n emitInputEvent(values);\n } else if (props.modelValue !== option.key) {\n open.value = false;\n emitInputEvent(option.key);\n }\n };\n\n const keyboardHandler = ($event: KeyboardEvent) => {\n if (open.value) {\n switch ($event.code) {\n case 'ArrowUp':\n case 'ArrowDown':\n {\n const reverseOffset = isReverse() ? -1 : 1;\n if ($event.code === 'ArrowUp') {\n navigateBy(-1 * reverseOffset, $event);\n } else {\n navigateBy(1 * reverseOffset, $event);\n }\n }\n break;\n case 'Enter':\n case 'Space':\n if (!flattenedOptions.value[highlightedIndex.value].disabled) {\n clickOption(flattenedOptions.value[highlightedIndex.value]);\n $event.preventDefault();\n }\n break;\n case 'Tab':\n if (!$event.ctrlKey && !$event.metaKey && !$event.altKey) {\n open.value = false;\n }\n break;\n }\n }\n };\n\n const computedOptions = computed((): Array<NeonSelectGroup> => {\n return (\n props.groupedOptions || [\n {\n group: '',\n options: props.options || [],\n },\n ]\n );\n });\n\n const sanitizedAttributes = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { ...sanitized } = attrs;\n return sanitized;\n });\n\n const computedLabel = computed(() => {\n if (props.multiple && props.modelValue.length > 0) {\n if (props.multiselectPlaceholder) {\n return props.multiselectPlaceholder;\n } else if (props.modelValue.length > 1) {\n return `${props.modelValue.length} items selected`;\n } else {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue[0]);\n return selected?.label || '';\n }\n } else if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.label;\n }\n }\n\n return props.placeholder;\n });\n\n const computedIcon = computed(() => {\n if (props.modelValue) {\n const selected = flattenedOptions.value.find((option) => option.key === props.modelValue);\n\n if (selected) {\n return selected.icon;\n }\n }\n\n return props.placeholderIcon;\n });\n\n const nativeSelectChange = (event: Event) => {\n const selectedKeys = Array.from((event.target as HTMLSelectElement).options)\n .filter((opt) => opt.selected)\n .map((opt) => opt.value);\n const selectedOptions = flattenedOptions.value.filter((v) => selectedKeys.indexOf(v.key) >= 0);\n const value = props.multiple ? selectedOptions.map((value) => value.key) : selectedOptions[0].key;\n emitInputEvent(value);\n };\n\n const changeHighlighted = (key: string) => {\n highlightedKey.value = key;\n highlightedIndex.value = flattenedOptions.value.findIndex((opt) => opt.key === key);\n };\n\n const onPlacement = (placement: NeonDropdownPlacement) => {\n dropdownPlacement.value = placement;\n };\n\n onMounted(() => {\n document.addEventListener('keydown', keyboardHandler);\n });\n\n onUnmounted(() => {\n document.removeEventListener('keydown', keyboardHandler);\n });\n\n watch(\n () => open.value,\n (open: boolean) => {\n if (open) {\n highlightedKey.value = flattenedOptions.value[0].key;\n highlightedIndex.value = 0;\n }\n },\n );\n\n return {\n dropdown,\n open,\n highlightedKey,\n highlightedIndex,\n flattenedOptions,\n computedLabel,\n sanitizedAttributes,\n computedOptions,\n computedIcon,\n clickOption,\n nativeSelectChange,\n changeHighlighted,\n onPlacement,\n };\n },\n});\n"],"names":["value","open"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aotearoan/neon",
3
3
  "description": "Neon is a lightweight design library of Vue 3 components with minimal dependencies.",
4
- "version": "9.0.2-beta-1",
4
+ "version": "9.0.4-beta-1",
5
5
  "main": "./dist/neoon.cjs.js",
6
6
  "module": "dist/neon.es.js",
7
7
  "types": "dist/neon.d.ts",
@@ -49,6 +49,10 @@
49
49
  }
50
50
 
51
51
  @mixin switch {
52
+ label.neon-field + label.neon-switch {
53
+ margin-top: calc(var(--neon-font-size-xs) + 4 * var(--neon-base-space));
54
+ }
55
+
52
56
  .neon-switch {
53
57
  display: flex;
54
58
  flex-direction: row;
@@ -160,6 +160,8 @@
160
160
  .neon-note,
161
161
  table,
162
162
  label,
163
+ .neon--horizontal,
164
+ .neon--vertical,
163
165
  p {
164
166
  & + h1,
165
167
  & + .neon-h1,