@tekkare/auriga 0.1.175 → 0.1.177

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.
Files changed (37) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/argAdvancedSearchBar.vue +1 -1
  3. package/dist/runtime/components/argChart.vue +1 -1
  4. package/dist/runtime/components/argExportXLSX.vue +6 -3
  5. package/dist/runtime/components/argMapsEurope.vue +216 -0
  6. package/dist/runtime/components/argMapsEurope.vue.d.ts +57 -0
  7. package/dist/runtime/components/argMapsFrDepartements.vue +1 -1
  8. package/dist/runtime/components/argMapsFrDepartements.vue.d.ts +1 -1
  9. package/dist/runtime/components/argMapsFrRegions.vue +1 -1
  10. package/dist/runtime/components/argMapsFrRegions.vue.d.ts +1 -1
  11. package/dist/runtime/components/argMapsFrRegionsToDepartements.vue +1130 -0
  12. package/dist/runtime/components/argMapsFrRegionsToDepartements.vue.d.ts +95 -0
  13. package/dist/runtime/components/argMapsUs.vue +216 -0
  14. package/dist/runtime/components/argMapsUs.vue.d.ts +57 -0
  15. package/dist/runtime/components/argNumberInput.vue +1 -1
  16. package/dist/runtime/components/argSearchInput.vue +165 -19
  17. package/dist/runtime/components/argSearchInput.vue.d.ts +70 -0
  18. package/dist/runtime/components/argSimpleInput.vue +1 -1
  19. package/dist/runtime/components/maps/countryEuropPath.json +177 -0
  20. package/dist/runtime/components/maps/departementsPath.json +406 -0
  21. package/dist/runtime/components/{mapsFr → maps}/interfaces.d.ts +112 -0
  22. package/dist/runtime/components/{mapsFr → maps}/interfaces.mjs +114 -0
  23. package/dist/runtime/components/maps/regionsPath.json +164 -0
  24. package/dist/runtime/components/maps/usStatesPath.json +152 -0
  25. package/dist/runtime/components/oneCountryEurope.vue +62 -0
  26. package/dist/runtime/components/oneCountryEurope.vue.d.ts +54 -0
  27. package/dist/runtime/components/oneDepartementFr.vue +1 -1
  28. package/dist/runtime/components/oneDepartementFr.vue.d.ts +1 -1
  29. package/dist/runtime/components/oneRegionFr.vue +1 -1
  30. package/dist/runtime/components/oneRegionFr.vue.d.ts +1 -1
  31. package/dist/runtime/components/oneRegionToDepartements.vue +178 -0
  32. package/dist/runtime/components/oneRegionToDepartements.vue.d.ts +111 -0
  33. package/dist/runtime/components/oneStateUs.vue +62 -0
  34. package/dist/runtime/components/oneStateUs.vue.d.ts +54 -0
  35. package/package.json +1 -1
  36. package/dist/runtime/components/mapsFr/departementsPath.json +0 -407
  37. package/dist/runtime/components/mapsFr/regionsPath.json +0 -164
@@ -0,0 +1,95 @@
1
+ import type { PropType } from "vue";
2
+ import { Departements, Regions } from "./maps/interfaces";
3
+ type Data = {
4
+ name: Departements;
5
+ value: number;
6
+ };
7
+ declare const _default: import("vue").DefineComponent<{
8
+ data: {
9
+ type: PropType<Data[]>;
10
+ default: null;
11
+ required: true;
12
+ };
13
+ title: {
14
+ type: StringConstructor;
15
+ default: null;
16
+ required: false;
17
+ };
18
+ source: {
19
+ type: StringConstructor;
20
+ default: null;
21
+ required: false;
22
+ };
23
+ withDynamicTitle: {
24
+ type: BooleanConstructor;
25
+ default: boolean;
26
+ };
27
+ lang: {
28
+ type: StringConstructor;
29
+ default: string;
30
+ required: false;
31
+ };
32
+ }, {
33
+ dptScale: import("vue").Ref<number[]>;
34
+ scale: import("vue").Ref<number[]>;
35
+ tooltipPosition: import("vue").Ref<{
36
+ x: number;
37
+ y: number;
38
+ width: number;
39
+ }>;
40
+ handleBackClick: () => void;
41
+ openSource: () => void;
42
+ setTooltipPosition: (x: number, y: number, width: number) => Promise<void>;
43
+ RegionsData: import("vue").ComputedRef<never[]>;
44
+ hoveredRegion: import("vue").Ref<Regions | null>;
45
+ hoveredDepartement: import("vue").Ref<Departements | null>;
46
+ clickedRegion: import("vue").Ref<Regions | null>;
47
+ handleClick: (region: Regions) => void;
48
+ handleHover: (region: Regions) => void;
49
+ handleDepartementHover: (departement: Departements) => void;
50
+ handleMouseLeave: () => void;
51
+ handleDepartementMouseLeave: (departement: Departements) => void;
52
+ handleSVGClick: () => void;
53
+ mapPosition: import("vue").Ref<{
54
+ x: number;
55
+ y: number;
56
+ }>;
57
+ componentKey: import("vue").Ref<number>;
58
+ Regions: typeof Regions;
59
+ getColor: (value?: number) => "var(--lightest)" | "#3F1151" | "#432974" | "#404A85" | "#3F668A" | "#43808C" | "#4C9C8A" | "#5FB57E" | "#85CB68" | "#BDDD51" | "#F9E855" | undefined;
60
+ regionsPath: any;
61
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "openSource"[], "openSource", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
62
+ data: {
63
+ type: PropType<Data[]>;
64
+ default: null;
65
+ required: true;
66
+ };
67
+ title: {
68
+ type: StringConstructor;
69
+ default: null;
70
+ required: false;
71
+ };
72
+ source: {
73
+ type: StringConstructor;
74
+ default: null;
75
+ required: false;
76
+ };
77
+ withDynamicTitle: {
78
+ type: BooleanConstructor;
79
+ default: boolean;
80
+ };
81
+ lang: {
82
+ type: StringConstructor;
83
+ default: string;
84
+ required: false;
85
+ };
86
+ }>> & {
87
+ onOpenSource?: ((...args: any[]) => any) | undefined;
88
+ }, {
89
+ lang: string;
90
+ data: Data[];
91
+ title: string;
92
+ source: string;
93
+ withDynamicTitle: boolean;
94
+ }, {}>;
95
+ export default _default;
@@ -0,0 +1,216 @@
1
+ <template>
2
+ <div class="oip_table_card map_card-container" :id="`container_map-${title}`">
3
+ <div class="p-24">
4
+ <div class="oip_subtitle">
5
+ {{ title ? title : "Your map title" }}
6
+ </div>
7
+ <ArgSourceContainer @click="openSource">
8
+ {{ source ? source : "Your source" }}
9
+ </ArgSourceContainer>
10
+ </div>
11
+ <div
12
+ v-if="hoveredState !== null"
13
+ :id="`tooltip_map-${title}`"
14
+ class="tooltip_container"
15
+ :style="{
16
+ top: tooltipPosition.y + 'px',
17
+ left: tooltipPosition.x + 'px',
18
+ width: tooltipPosition.width + 'px',
19
+ }"
20
+ >
21
+ <div class="tooltip">
22
+ <p class="card_title">{{ hoveredState }}</p>
23
+ <div class="card_text">
24
+ <slot
25
+ name="Tooltip"
26
+ v-bind:value="{
27
+ name: hoveredState,
28
+ value: data.find((x) => x.name == hoveredState)?.value,
29
+ }"
30
+ />
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="p24">
35
+ <svg
36
+ class="map"
37
+ width="auto"
38
+ height="500"
39
+ viewBox="0 0 1856 1264"
40
+ fill="none"
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ >
43
+ <OneStateUs
44
+ v-for="state in UsStates"
45
+ :key="state"
46
+ :data="{
47
+ color: getColor(data.find((x) => x.name == state)?.value),
48
+ value: data.find((x) => x.name == state)?.value,
49
+ }"
50
+ :currentState="state"
51
+ :title="title"
52
+ :hoveredState="hoveredState"
53
+ @hover="handleHover(state)"
54
+ @mouseleave="handleMouseLeave"
55
+ />
56
+ </svg>
57
+ <div class="legend">
58
+ <div class="scale" />
59
+ <div class="legend-text">
60
+ <p v-for="value in scale" :key="value">
61
+ {{ Math.ceil(value) }}
62
+ </p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <slot name="Subcontent" />
67
+ </div>
68
+ </template>
69
+
70
+ <script>
71
+ import { onMounted, ref, watch, defineComponent, nextTick } from "vue";
72
+ import { UsStates } from "./maps/interfaces";
73
+ import ArgSourceContainer from "./argSourceContainer.vue";
74
+ import OneStateUs from "./oneStateUs.vue";
75
+ export default defineComponent({
76
+ name: "argMapsUs",
77
+ components: { OneStateUs, ArgSourceContainer },
78
+ props: {
79
+ data: {
80
+ type: Array,
81
+ default: null,
82
+ required: true
83
+ },
84
+ title: {
85
+ type: [String, null],
86
+ default: null,
87
+ required: false
88
+ },
89
+ source: {
90
+ type: [String, null],
91
+ default: null
92
+ }
93
+ },
94
+ emits: ["openSource"],
95
+ setup(props, { emit }) {
96
+ const minimalValue = ref(null);
97
+ const maximalValue = ref(null);
98
+ const hoveredState = ref(null);
99
+ const tooltipPosition = ref({ x: 0, y: 0, width: 0 });
100
+ const scale = ref([]);
101
+ function getColor(value) {
102
+ if (!value)
103
+ return "var(--lightest)";
104
+ if (value >= scale.value[9]) {
105
+ return "#3F1151";
106
+ } else if (value >= scale.value[8]) {
107
+ return "#432974";
108
+ } else if (value >= scale.value[7]) {
109
+ return "#404A85";
110
+ } else if (value >= scale.value[6]) {
111
+ return "#3F668A";
112
+ } else if (value >= scale.value[5]) {
113
+ return "#43808C";
114
+ } else if (value >= scale.value[4]) {
115
+ return "#4C9C8A";
116
+ } else if (value >= scale.value[3]) {
117
+ return "#5FB57E";
118
+ } else if (value >= scale.value[2]) {
119
+ return "#85CB68";
120
+ } else if (value >= scale.value[1]) {
121
+ return "#BDDD51";
122
+ } else if (value >= scale.value[0]) {
123
+ return "#F9E855";
124
+ }
125
+ }
126
+ function handleHover(state) {
127
+ hoveredState.value = state;
128
+ }
129
+ function handleMouseLeave() {
130
+ hoveredState.value = null;
131
+ }
132
+ function openSource() {
133
+ emit("openSource");
134
+ }
135
+ function setupScale() {
136
+ minimalValue.value = Math.floor(
137
+ Math.min(...props.data.map((x) => x.value))
138
+ );
139
+ maximalValue.value = Math.ceil(
140
+ Math.max(...props.data.map((x) => x.value))
141
+ );
142
+ const step = (maximalValue.value - minimalValue.value) / 10;
143
+ if (minimalValue.value !== null) {
144
+ scale.value = Array.from(
145
+ { length: 10 },
146
+ (_, i) => (minimalValue.value !== null ? minimalValue.value : 0) + i * step
147
+ );
148
+ }
149
+ }
150
+ onMounted(() => {
151
+ setupScale();
152
+ });
153
+ watch(
154
+ () => props.data,
155
+ () => {
156
+ setupScale();
157
+ }
158
+ );
159
+ watch(
160
+ () => hoveredState.value,
161
+ () => {
162
+ if (hoveredState.value) {
163
+ const selectedState = document.getElementById(
164
+ `interactiveMap-${props.title}-${hoveredState.value}`
165
+ )?.getBoundingClientRect();
166
+ const containerPosition = document.getElementById(`container_map-${props.title}`)?.getBoundingClientRect();
167
+ if (!selectedState || !containerPosition)
168
+ return;
169
+ tooltipPosition.value = {
170
+ x: selectedState?.x - containerPosition?.x,
171
+ y: selectedState?.top - containerPosition?.top - 60,
172
+ width: selectedState?.width
173
+ };
174
+ }
175
+ }
176
+ );
177
+ watch(
178
+ () => hoveredState.value,
179
+ async () => {
180
+ if (hoveredState.value) {
181
+ await nextTick();
182
+ const selectedRegion = document.getElementById(
183
+ `interactiveMap-${props.title}-${hoveredState.value}`
184
+ )?.getBoundingClientRect();
185
+ const containerPosition = document.getElementById(`container_map-${props.title}`)?.getBoundingClientRect();
186
+ const tooltipElement = document.getElementById(
187
+ `tooltip_map-${props.title}`
188
+ );
189
+ const tooltipHeight = tooltipElement ? tooltipElement.getBoundingClientRect().height : 60;
190
+ if (!selectedRegion || !containerPosition)
191
+ return;
192
+ tooltipPosition.value = {
193
+ x: selectedRegion?.x - containerPosition?.x,
194
+ y: selectedRegion?.top - containerPosition?.top - tooltipHeight,
195
+ width: selectedRegion?.width
196
+ };
197
+ }
198
+ }
199
+ );
200
+ return {
201
+ getColor,
202
+ handleHover,
203
+ handleMouseLeave,
204
+ UsStates,
205
+ hoveredState,
206
+ tooltipPosition,
207
+ scale,
208
+ openSource
209
+ };
210
+ }
211
+ });
212
+ </script>
213
+
214
+ <style scoped>
215
+ .map{margin-top:24px}.p24{padding:24px}.map path{stroke-width:2px;stroke:rgba(0,0,0,.2);max-height:400px;position:relative}.map path:hover{transition:all .2s}.map_card-container{display:flex;flex-direction:column;gap:8px;min-width:400px;position:relative;width:100%}.test{margin-bottom:200px}.tooltip_container{align-items:center;display:flex;flex-direction:column;justify-content:center;left:0;min-width:-moz-fit-content;min-width:fit-content;position:absolute;top:0;z-index:96}.tooltip{background:#fff;border:1px solid var(--light);border-radius:4px;box-shadow:var(--medium-shadow);color:var(--darkest);font-size:12px}.card_title{background-color:var(--light);border-radius:4px 4px 0 0;font-size:14px;font-weight:600;padding:2px 8px;width:calc(100% - 15px)}.card_text{color:var(--dark);font-size:12px;font-weight:400;line-height:160%;padding:8px;width:100%}.legend{display:flex;flex-direction:column;gap:8px;margin:8px auto auto;width:50%}.scale{background:linear-gradient(45deg,#3f1151,#432974,#404a85,#3f668a,#43808c,#4c9c8a,#5fb57e,#85cb68,#bddd51,#f9e855);height:10px;transform:rotate(180deg)}.legend-text{align-items:center;color:var(--dark);display:flex;font-size:12px;font-weight:400;justify-content:space-between;line-height:160%}.p-24{padding:0 24px}
216
+ </style>
@@ -0,0 +1,57 @@
1
+ import type { PropType } from "vue";
2
+ import { UsStates } from "./maps/interfaces";
3
+ type Data = {
4
+ name: UsStates;
5
+ value: number;
6
+ };
7
+ declare const _default: import("vue").DefineComponent<{
8
+ data: {
9
+ type: PropType<Data[]>;
10
+ default: null;
11
+ required: true;
12
+ };
13
+ title: {
14
+ type: PropType<string | null>;
15
+ default: null;
16
+ required: false;
17
+ };
18
+ source: {
19
+ type: PropType<string | null>;
20
+ default: null;
21
+ };
22
+ }, {
23
+ getColor: (value?: number) => "var(--lightest)" | "#3F1151" | "#432974" | "#404A85" | "#3F668A" | "#43808C" | "#4C9C8A" | "#5FB57E" | "#85CB68" | "#BDDD51" | "#F9E855" | undefined;
24
+ handleHover: (state: UsStates) => void;
25
+ handleMouseLeave: () => void;
26
+ UsStates: typeof UsStates;
27
+ hoveredState: import("vue").Ref<UsStates | null>;
28
+ tooltipPosition: import("vue").Ref<{
29
+ x: number;
30
+ y: number;
31
+ width: number;
32
+ }>;
33
+ scale: import("vue").Ref<number[]>;
34
+ openSource: () => void;
35
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "openSource"[], "openSource", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
36
+ data: {
37
+ type: PropType<Data[]>;
38
+ default: null;
39
+ required: true;
40
+ };
41
+ title: {
42
+ type: PropType<string | null>;
43
+ default: null;
44
+ required: false;
45
+ };
46
+ source: {
47
+ type: PropType<string | null>;
48
+ default: null;
49
+ };
50
+ }>> & {
51
+ onOpenSource?: ((...args: any[]) => any) | undefined;
52
+ }, {
53
+ data: Data[];
54
+ title: string | null;
55
+ source: string | null;
56
+ }, {}>;
57
+ export default _default;
@@ -106,5 +106,5 @@ export default defineComponent({
106
106
  </script>
107
107
 
108
108
  <style scoped>
109
- .input_number_box .input_number_action.action_left:hover,.input_number_box .input_number_action.action_right:hover{border:1.5px solid rgba(33,118,255,.2)!important}.input_number_box .input_number_action.action_left:hover svg,.input_number_box .input_number_action.action_right:hover svg{color:var(--primary)!important}.input_number_box:focus-within{border:1.5px solid var(--primary)!important;box-shadow:0 0 0 4px rgba(33,118,255,.1)!important}.input_number_box:focus-within .input_number_action.action_left{left:0!important;top:0!important}.input_number_box:focus-within .input_number_action.action_right{right:0!important;top:0!important}.input_number_box:focus-within{z-index:9999!important}.input_number_box:focus-within .input_number_action.action_left,.input_number_box:focus-within .input_number_box .input_number_action.action_left:hover{border-bottom:1.5px transparent!important;border-left:1.5px transparent!important;border-top:1.5px transparent!important}.input_number_box:focus-within .input_number_action.action_right,.input_number_box:focus-within .input_number_box .input_number_action.action_right:hover{border-bottom:1.5px transparent!important;border-right:1.5px transparent!important;border-top:1.5px transparent!important}.input_number_section{align-items:flex-start;display:flex;flex-direction:column;gap:4px;padding:0}.input_number_box{padding:12px 48px;position:relative;z-index:1}.input_number_action,.input_number_box{align-items:center;background:var(--white);border:1.5px solid var(--light);border-radius:8px;display:flex;flex-direction:row;gap:8px}.input_number_action{cursor:pointer;justify-content:center;padding:12px;position:absolute;z-index:2}.action_right{right:-1.5px;top:-1.5px}.action_left{left:-1.5px;top:-1.5px}.number_input_style{border:none;color:var(--darkest);font-size:14px;font-weight:500;height:16px;line-height:16px;max-width:127.5px;padding:0!important;text-align:center}.number_input_style:focus-visible{border:none;outline:none}input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none}input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}
109
+ .input_number_box .input_number_action.action_left:hover,.input_number_box .input_number_action.action_right:hover{border:1.5px solid rgba(33,118,255,.2)!important}.input_number_box .input_number_action.action_left:hover svg,.input_number_box .input_number_action.action_right:hover svg{color:var(--primary)!important}.input_number_box:focus-within{border:1.5px solid var(--primary)!important;filter:drop-shadow(0 0 4px rgba(33,118,255,.3))!important}.input_number_box:focus-within .input_number_action.action_left{left:0!important;top:0!important}.input_number_box:focus-within .input_number_action.action_right{right:0!important;top:0!important}.input_number_box:focus-within{z-index:9999!important}.input_number_box:focus-within .input_number_action.action_left,.input_number_box:focus-within .input_number_box .input_number_action.action_left:hover{border-bottom:1.5px transparent!important;border-left:1.5px transparent!important;border-top:1.5px transparent!important}.input_number_box:focus-within .input_number_action.action_right,.input_number_box:focus-within .input_number_box .input_number_action.action_right:hover{border-bottom:1.5px transparent!important;border-right:1.5px transparent!important;border-top:1.5px transparent!important}.input_number_section{align-items:flex-start;display:flex;flex-direction:column;gap:4px;padding:0}.input_number_box{padding:12px 48px;position:relative;z-index:1}.input_number_action,.input_number_box{align-items:center;background:var(--white);border:1.5px solid var(--light);border-radius:8px;display:flex;flex-direction:row;gap:8px}.input_number_action{cursor:pointer;justify-content:center;padding:12px;position:absolute;z-index:2}.action_right{right:-1.5px;top:-1.5px}.action_left{left:-1.5px;top:-1.5px}.number_input_style{border:none;color:var(--darkest);font-size:14px;font-weight:500;height:16px;line-height:16px;max-width:127.5px;padding:0!important;text-align:center}.number_input_style:focus-visible{border:none;outline:none}input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none}input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}
110
110
  </style>
@@ -1,30 +1,72 @@
1
1
  <template>
2
- <div class="filters_input_search">
3
- <div class="search-section">
4
- <arg-icon
5
- name="MagnifyingGlass"
6
- color="var(--medium)"
7
- size="20"
8
- class="search-icon"
9
- />
10
- <input
11
- :value="searchValue"
12
- class="filters_input_style"
13
- :placeholder="placeHolderValue"
14
- @input="changeInput"
15
- @keydown.enter="submitSearch"
16
- />
2
+ <div class="relative" @click.stop>
3
+ <div
4
+ class="filters_input_search"
5
+ :class="suggOpen ? 'no_bottom' : ''"
6
+ @click.stop="openSugg"
7
+ >
8
+ <div class="search-section">
9
+ <arg-icon
10
+ name="MagnifyingGlass"
11
+ color="var(--medium)"
12
+ size="20"
13
+ class="search-icon"
14
+ />
15
+ <input
16
+ :value="searchValue"
17
+ class="filters_input_style"
18
+ :placeholder="placeHolderValue"
19
+ @input="changeInput"
20
+ @keydown.enter="submitSearch"
21
+ @keydown.down="selectOption(true)"
22
+ @keydown.up="selectOption(false)"
23
+ />
24
+ </div>
25
+ <div
26
+ v-if="searchValue.length > 0"
27
+ class="close-icon"
28
+ @click="clearValue()"
29
+ >
30
+ <arg-icon name="X" size="14" color="var(--dark)" thickness="32" />
31
+ </div>
17
32
  </div>
18
- <div v-if="searchValue.length > 0" class="close-icon" @click="clearValue()">
19
- <arg-icon name="X" size="14" color="var(--dark)" thickness="32" />
33
+ <div
34
+ v-if="suggestions !== null && suggOpen"
35
+ class="search_suggestions"
36
+ :class="suggOpen ? 'sugg_open' : ''"
37
+ @click.stop
38
+ >
39
+ <div v-if="filterSuggestions.length > 0" class="sugg_container">
40
+ <p
41
+ v-for="(sugg, index) in filterSuggestions"
42
+ :key="index"
43
+ class="oip_body"
44
+ :class="optionIndex === index + 1 ? 'selected' : ''"
45
+ @click="selectSugg(sugg)"
46
+ @mouseover="optionIndex = 0"
47
+ >
48
+ <arg-icon
49
+ v-if="sugg.icon"
50
+ :name="sugg.icon"
51
+ size="14"
52
+ color="var(--medium)"
53
+ />
54
+ {{ sugg.text }}
55
+ </p>
56
+ </div>
57
+ <div v-else class="sugg_container">
58
+ <p class="not-found oip_body">{{ notFound[lang] }}</p>
59
+ </div>
20
60
  </div>
21
61
  </div>
22
62
  </template>
23
63
  <script>
24
64
  import argIcon from "./argIcon.vue";
65
+ import { useFuse } from "@vueuse/integrations/useFuse";
25
66
  import {
26
67
  onMounted,
27
68
  ref,
69
+ computed,
28
70
  watch,
29
71
  defineComponent
30
72
  } from "vue";
@@ -39,11 +81,98 @@ export default defineComponent({
39
81
  defaultValue: {
40
82
  type: String,
41
83
  default: ""
84
+ },
85
+ suggestions: {
86
+ type: Array,
87
+ default: null
88
+ },
89
+ fuzzyThreshold: {
90
+ type: Number,
91
+ default: 0.5
92
+ },
93
+ lang: {
94
+ type: String,
95
+ default: "en",
96
+ validator: (value) => {
97
+ return ["en", "fr", "es"].includes(value);
98
+ }
42
99
  }
43
100
  },
44
101
  emits: ["update:Value", "submitSearch"],
45
102
  setup(props, { emit }) {
46
103
  const searchValue = ref("");
104
+ const suggOpen = ref(false);
105
+ const notFound = {
106
+ fr: "Aucune suggestion n'a \xE9t\xE9 trouv\xE9e",
107
+ en: "No suggestions were found",
108
+ es: "No se encontraron sugerencias"
109
+ };
110
+ const closeOnEnter = ref(false);
111
+ const optionIndex = ref(0);
112
+ function selectOption(isDown) {
113
+ if (isDown) {
114
+ optionIndex.value = optionIndex.value === filterSuggestions.value.length ? 0 : optionIndex.value + 1;
115
+ } else {
116
+ optionIndex.value = optionIndex.value === 0 ? filterSuggestions.value.length : optionIndex.value - 1;
117
+ }
118
+ }
119
+ watch(
120
+ () => searchValue.value,
121
+ () => {
122
+ if (searchValue.value.length > 0 && props.suggestions !== null) {
123
+ if (!closeOnEnter.value) {
124
+ suggOpen.value = true;
125
+ setTimeout(() => {
126
+ document.addEventListener("click", closeSugg);
127
+ });
128
+ } else {
129
+ suggOpen.value = false;
130
+ document.removeEventListener("click", closeSugg);
131
+ closeOnEnter.value = false;
132
+ }
133
+ } else {
134
+ suggOpen.value = false;
135
+ document.removeEventListener("click", closeSugg);
136
+ }
137
+ }
138
+ );
139
+ watch(
140
+ () => suggOpen.value,
141
+ () => {
142
+ if (!suggOpen.value) {
143
+ optionIndex.value = 0;
144
+ }
145
+ }
146
+ );
147
+ const options = computed(() => ({
148
+ fuseOptions: {
149
+ includeScore: true,
150
+ threshold: props.fuzzyThreshold
151
+ }
152
+ }));
153
+ const filterSuggestions = computed(() => {
154
+ return props.suggestions.filter(
155
+ (f) => useFuse(
156
+ searchValue,
157
+ props.suggestions.map((a) => a.text),
158
+ options.value
159
+ ).results.value.map((a) => a.item).includes(f.text)
160
+ );
161
+ });
162
+ const selectSugg = (sugg) => {
163
+ searchValue.value = sugg.text;
164
+ emit("update:Value", searchValue.value);
165
+ document.removeEventListener("click", closeSugg);
166
+ suggOpen.value = false;
167
+ };
168
+ function closeSugg() {
169
+ suggOpen.value = false;
170
+ }
171
+ function openSugg() {
172
+ if (searchValue.value.length > 0) {
173
+ suggOpen.value = true;
174
+ }
175
+ }
47
176
  onMounted(() => {
48
177
  searchValue.value = props.defaultValue;
49
178
  });
@@ -58,16 +187,33 @@ export default defineComponent({
58
187
  emit("update:Value", searchValue.value);
59
188
  }
60
189
  function submitSearch() {
190
+ if (optionIndex.value > 0) {
191
+ closeOnEnter.value = true;
192
+ searchValue.value = filterSuggestions.value[optionIndex.value - 1].text;
193
+ emit("update:Value", searchValue.value);
194
+ }
61
195
  emit("submitSearch");
62
196
  }
63
197
  function clearValue() {
64
198
  searchValue.value = "";
65
199
  emit("update:Value", searchValue.value);
66
200
  }
67
- return { searchValue, changeInput, submitSearch, clearValue };
201
+ return {
202
+ searchValue,
203
+ changeInput,
204
+ submitSearch,
205
+ clearValue,
206
+ suggOpen,
207
+ openSugg,
208
+ filterSuggestions,
209
+ selectSugg,
210
+ selectOption,
211
+ optionIndex,
212
+ notFound
213
+ };
68
214
  }
69
215
  });
70
216
  </script>
71
217
  <style scoped>
72
- .filters_input_search{background:var(--white);border:1.5px solid var(--light);border-radius:8px;justify-content:space-between;margin:5px 0;min-height:40px;padding:0 12px;width:calc(100% - 24px)}.filters_input_search,.search-section{align-items:center;display:flex;flex-direction:row;gap:12px}.search-section{width:100%}.filters_input_search:hover{border:1.5px solid rgba(33,118,255,.2)!important}.filters_input_search:focus-within{border:1.5px solid var(--primary)!important;box-shadow:0 0 0 4px rgba(33,118,255,.1)!important}.filters_input_search:focus-within .search-icon,.filters_input_search:hover .search-icon{color:var(--primary)!important}.filters_input_style{width:100%}.filters_input_style,.filters_input_style:focus-visible{border:none;outline:none}.filters_input_style::-moz-placeholder{color:var(--medium)}.filters_input_style::placeholder{color:var(--medium)}.close-icon{align-items:center;background:var(--light);border-radius:100%;cursor:pointer;display:flex;justify-content:center;padding:5px}
218
+ .filters_input_search{align-items:center;background:var(--white);border:1.5px solid var(--light);border-radius:8px;display:flex;flex-direction:row;gap:12px;justify-content:space-between;min-height:40px;padding:0 12px;width:calc(100% - 24px)}.filters_input_search.no_bottom{border:1.5px solid var(--primary)!important;border-bottom:none!important;border-radius:8px 8px 0 0;filter:drop-shadow(0 0 4px rgba(33,118,255,.3))!important}.search-section{align-items:center;display:flex;flex-direction:row;gap:12px;width:100%}.filters_input_search:not(.no_bottom):hover{border:1.5px solid rgba(33,118,255,.2)}.filters_input_search.no_bottom:hover{border-bottom:none!important}.filters_input_search:focus-within{border:1.5px solid var(--primary)!important;filter:drop-shadow(0 0 4px rgba(33,118,255,.3))!important}.filters_input_search.no_bottom:focus-within{border-bottom:none!important;filter:drop-shadow(0 0 4px rgba(33,118,255,.3))!important}.filters_input_search:focus-within .search-icon,.filters_input_search:hover .search-icon{color:var(--primary)!important}.filters_input_style{width:100%}.filters_input_style,.filters_input_style:focus-visible{border:none;outline:none}.filters_input_style::-moz-placeholder{color:var(--medium)}.filters_input_style::placeholder{color:var(--medium)}.close-icon{align-items:center;background:var(--light);border-radius:100%;cursor:pointer;display:flex;justify-content:center;padding:5px}.relative{position:relative;width:100%}.search_suggestions{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background:hsla(0,0%,100%,.8);border:1.5px solid var(--light);border-radius:0 0 8px 8px;left:0;position:absolute;width:100%;z-index:99}.sugg_open{border-top:1.5px solid var(--primary)!important;border:1.5px solid var(--primary)!important;border-top-color:var(--light)!important;box-shadow:2px 2px 3px rgba(33,118,255,.1),-2px 2px 3px rgba(33,118,255,.1)}.sugg_container{cursor:pointer;display:flex;flex-direction:column}.sugg_container p{align-items:center;display:flex;gap:8px;padding:8px 12px}.sugg_container p.selected,.sugg_container p:not(.not-found):hover{background:rgba(93,153,250,.2)}.sugg_container p.selected svg,.sugg_container p:not(.not-found):hover svg{color:var(--primary)!important}.sugg_container p:last-of-type{border-radius:0 0 8px 8px}
73
219
  </style>