{"version":3,"sources":["webpack://dxa-ui/./src/framework/scripts/use/api.ts","webpack://dxa-ui/./src/framework/scripts/utils/url.ts","webpack://dxa-ui/./src/patterns/02-components/autocomplete/autocomplete.ts","webpack://dxa-ui/./src/framework/scripts/use/debounce.ts","webpack://dxa-ui/./src/patterns/02-components/autocomplete/autocomplete.tpl.html"],"names":["useApiGet","state","reactive","data","error","isLoading","getData","url","fetch","headers","then","response","json","e","toRefs","parametise","params","queryString","skipEmptyString","getQuery","window","location","search","updateUrl","history","pushState","faker","require","Autocomplete","defineComponent","name","template","props","id","type","String","default","apiUrl","static","Boolean","inputClasses","buttonWrapperClasses","buttonClasses","buttonTextClasses","isSearchPage","setup","context","term","showDropdown","root","searchButton","idRandomised","random","uuid","isExpanded","searchInput","query","computed","select","suggestion","focus","showDropdownMenu","hideDropdownMenu","hideOnFocusChange","event","nextTick","target","relatedTarget","document","activeElement","contains","delayedHide","setTimeout","resetForm","submit","emit","preventDefault","useAutocomplete","methods","suggestions","getSuggestions","callback","delay","debounce","useDebounce","containerClasses","module","exports"],"mappings":"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","file":"chunk-autocomplete-4eb4feb69e.mjs","sourcesContent":["import { reactive, ref, toRefs, Ref } from '@framework/vue';\r\n\r\ninterface BaseApi {\r\n\tdata: T | null;\r\n\terror: any;\r\n\tisLoading: boolean;\r\n}\r\n\r\nexport function useApiGet() {\r\n\tconst state = reactive>({\r\n\t\tdata: null,\r\n\t\terror: null,\r\n\t\tisLoading: false,\r\n\t});\r\n\r\n\tconst getData = async (url: string): Promise => {\r\n\t\tstate.isLoading = true;\r\n\t\tstate.error = null;\r\n\r\n\t\tvar options = {\r\n\t\t\theaders: {\r\n\t\t\t\t'Access-Control-Allow-Origin': '*',\r\n\t\t\t},\r\n\t\t};\r\n\r\n\t\ttry {\r\n\t\t\tstate.data = await fetch(url, options).then((response) =>\r\n\t\t\t\tresponse.json()\r\n\t\t\t);\r\n\t\t} catch (e) {\r\n\t\t\tstate.error = e;\r\n\t\t} finally {\r\n\t\t\tstate.isLoading = false;\r\n\t\t}\r\n\t};\r\n\r\n\treturn {\r\n\t\t...toRefs(state),\r\n\t\tgetData,\r\n\t};\r\n}\r\n","/**\r\n * URL Utils\r\n */\r\n\r\nimport queryString from 'query-string';\r\nexport * from 'query-string';\r\n\r\nexport const parametise = (params: {} = {}): string =>\r\n\tqueryString.stringify(params, {\r\n\t\tskipEmptyString: true,\r\n\t});\r\n\r\n// tslint:disable-next-line:no-any - Query string can actually be anything\r\nexport const getQuery = (): { [key: string]: any } =>\r\n\tqueryString.parse(window.location.search);\r\n\r\nexport const updateUrl = (url: string = ''): void =>\r\n\twindow.history.pushState('', '', `?${url}`);\r\n\r\nexport const parseQuery = (uri: string = ''): {} => queryString.parseUrl(uri);\r\n","/**\r\n * Autocomplete\r\n */\r\n\r\n//#region Dependencies\r\nconst faker = require('faker');\r\n\r\nimport {\r\n\ttoRefs,\r\n\treactive,\r\n\tcomputed,\r\n\tnextTick,\r\n\tdefineComponent,\r\n\tSetupContext,\r\n} from '@framework/vue';\r\n\r\nimport { Props, Data } from './interfaces';\r\n\r\nimport { useDebounce } from '@framework/use/debounce';\r\nimport { useApiGet } from '@framework/use/api';\r\nimport { getQuery } from '@framework/utils/url';\r\n\r\nimport { default as template } from './autocomplete.tpl.html';\r\n//#endregion\r\n\r\n/**\r\n * Autocomplete Vue Component\r\n */\r\nexport const Autocomplete = defineComponent({\r\n\t//#region Name\r\n\tname: 'autocomplete',\r\n\t//#endregion\r\n\r\n\t//#region Template\r\n\ttemplate,\r\n\t//#endregion\r\n\r\n\t//#region Props\r\n\tprops: {\r\n\t\tid: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault: '',\r\n\t\t},\r\n\t\tname: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault: '',\r\n\t\t},\r\n\t\tapiUrl: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault: '/api/search/autocomplete',\r\n\t\t},\r\n\t\tstatic: Boolean,\r\n\t\tinputClasses: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault:\r\n\t\t\t\t'w-full bg-light-teal-40 px-4 text-base placeholder-dark-teal-60 border border-dark-teal-40 rounded-l-md lg:rounded focus:ring-2 focus:ring-dark-teal',\r\n\t\t},\r\n\t\tbuttonWrapperClasses: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault: '',\r\n\t\t},\r\n\t\tbuttonClasses: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault:\r\n\t\t\t\t'lg:w-full rounded-full text-dark-teal hover:text-teal mb-1 px-1',\r\n\t\t},\r\n\t\tbuttonTextClasses: {\r\n\t\t\ttype: String,\r\n\t\t\tdefault: 'hidden lg:inline-block mr-2',\r\n\t\t},\r\n\t\tisSearchPage: {\r\n\t\t\ttype: Boolean,\r\n\t\t\tdefault: false,\r\n\t\t},\r\n\t},\r\n\t//#endregion\r\n\r\n\t//#region Setup\r\n\tsetup(props, context) {\r\n\t\t// State\r\n\t\tconst { state, ...methods } = useAutocomplete(props, context);\r\n\r\n\t\t// API Composable\r\n\t\tconst { data: suggestions, isLoading, error, getData } = useApiGet<\r\n\t\t\tstring[]\r\n\t\t>();\r\n\r\n\t\tconst getSuggestions = useDebounce(() => getData(state.query));\r\n\r\n\t\tlet containerClasses =\r\n\t\t\t'flex items-center justify-center z-10 h-9 w-9 lg:h-full w-full p-1 px-3 rounded-full bg-light-teal-40 lg:from-dark-teal-20 to-white border border-white text-dark-teal';\r\n\t\tif (props.isSearchPage) {\r\n\t\t\tcontainerClasses = 'flex flex-col w-full z-10 relative';\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\t// Local\r\n\t\t\t...toRefs(state),\r\n\t\t\t...methods,\r\n\r\n\t\t\t// Composable\r\n\t\t\tsuggestions,\r\n\t\t\terror,\r\n\t\t\tisLoading,\r\n\t\t\tgetSuggestions,\r\n\t\t\tcontainerClasses,\r\n\t\t};\r\n\t},\r\n\t//#endregion\r\n});\r\n\r\n// Local Logic\r\nfunction useAutocomplete(props: Props, context: SetupContext) {\r\n\tconst state = reactive({\r\n\t\tterm: getQuery()[props.name] || '',\r\n\t\tshowDropdown: false,\r\n\r\n\t\t// Refs\r\n\t\troot: null,\r\n\t\tsearchButton: null,\r\n\t\tidRandomised: props.id + faker.random.uuid(),\r\n\t\tisExpanded: false,\r\n\t\tsearchInput: null,\r\n\t\tstatic: props.static,\r\n\r\n\t\t// Computed\r\n\t\tquery: computed(\r\n\t\t\t(): string => `${props.apiUrl}?${props.name}=${state.term}`\r\n\t\t),\r\n\t});\r\n\r\n\t//#region Methods\r\n\tfunction select(suggestion: string): void {\r\n\t\tstate.term = suggestion;\r\n\t\tstate.showDropdown = false;\r\n\t\tstate.searchButton?.focus();\r\n\t\tstate.isExpanded = true;\r\n\t}\r\n\r\n\tfunction showDropdownMenu(): void {\r\n\t\tstate.showDropdown = true;\r\n\t}\r\n\r\n\tfunction hideDropdownMenu(): void {\r\n\t\tstate.showDropdown = false;\r\n\t}\r\n\r\n\tfunction hideOnFocusChange(event: FocusEvent): void {\r\n\t\tnextTick(() => {\r\n\t\t\tconst target = event.relatedTarget || document.activeElement;\r\n\r\n\t\t\tif (!state.root?.contains(target)) {\r\n\t\t\t\tdelayedHide();\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tfunction delayedHide(): void {\r\n\t\tsetTimeout((): void => {\r\n\t\t\tstate.showDropdown = false;\r\n\t\t\tstate.isExpanded = false;\r\n\t\t}, 200);\r\n\t}\r\n\r\n\tfunction resetForm(): void {\r\n\t\tstate.term = '';\r\n\t}\r\n\r\n\tfunction submit(e: Event): void {\r\n\t\tif (!state.isExpanded) {\r\n\t\t\te.preventDefault();\r\n\t\t\tstate.isExpanded = true;\r\n\t\t\tnextTick(() => {\r\n\t\t\t\tstate.searchInput?.focus();\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\thideDropdownMenu();\r\n\t\t\tcontext.emit('autocomplete-search', state.term);\r\n\t\t}\r\n\t}\r\n\t//#endregion\r\n\r\n\treturn {\r\n\t\tstate,\r\n\t\tselect,\r\n\t\tshowDropdownMenu,\r\n\t\thideDropdownMenu,\r\n\t\thideOnFocusChange,\r\n\t\tdelayedHide,\r\n\t\tresetForm,\r\n\t\tsubmit,\r\n\t};\r\n}\r\n","import { reactive } from 'vue';\r\nimport debounce from 'lodash/debounce';\r\n\r\nexport const DEBOUNCE_DELAY = 300;\r\n\r\nexport const useDebounce = (callback: () => unknown, delay = DEBOUNCE_DELAY) =>\r\n\tdebounce(callback, delay);\r\n","// Module\nvar code = \"
  • {{suggestion}}
\";\n// Exports\nmodule.exports = code;"],"sourceRoot":""}