@vcmap/ui 6.0.11 → 6.1.0-rc.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.
Files changed (69) hide show
  1. package/config/base.config.json +25 -3
  2. package/config/dev.config.json +17 -3
  3. package/config/splashscreen.config.json +13 -0
  4. package/dist/assets/cesium.js +1 -1
  5. package/dist/assets/{core-d78889f9.js → core-9d0cfec3.js} +6949 -5868
  6. package/dist/assets/core.js +1 -1
  7. package/dist/assets/ol.js +1 -1
  8. package/dist/assets/ui-08446666.css +1 -0
  9. package/dist/assets/{ui-f56287eb.js → ui-08446666.js} +17374 -19067
  10. package/dist/assets/ui.js +1 -1
  11. package/dist/assets/vue.js +1 -1
  12. package/dist/assets/{vuetify-03bc5f58.js → vuetify-67025c41.js} +1 -1
  13. package/dist/assets/vuetify.js +1 -1
  14. package/index.d.ts +11 -1
  15. package/index.js +6 -0
  16. package/package.json +2 -2
  17. package/plugins/@vcmap-show-case/dev-tools/package.json +5 -0
  18. package/plugins/@vcmap-show-case/dev-tools/src/eventLogger.js +35 -0
  19. package/plugins/@vcmap-show-case/dev-tools/src/index.js +59 -0
  20. package/plugins/@vcmap-show-case/search-example/src/searchImpl.js +10 -0
  21. package/src/application/VcsApp.vue.d.ts +22 -0
  22. package/src/application/VcsContainer.vue.d.ts +15 -0
  23. package/src/application/VcsSplashScreen.vue +35 -28
  24. package/src/application/VcsSplashScreen.vue.d.ts +1 -0
  25. package/src/callback/addModuleCallback.d.ts +29 -0
  26. package/src/callback/addModuleCallback.js +61 -0
  27. package/src/callback/removeModuleCallback.d.ts +29 -0
  28. package/src/callback/removeModuleCallback.js +53 -0
  29. package/src/callback/startRotationCallback.d.ts +37 -0
  30. package/src/callback/startRotationCallback.js +67 -0
  31. package/src/callback/stopRotationCallback.d.ts +8 -0
  32. package/src/callback/stopRotationCallback.js +37 -0
  33. package/src/components/icons/+all.js +4 -0
  34. package/src/components/icons/View360Icon.vue +55 -0
  35. package/src/components/icons/View360Icon.vue.d.ts +2 -0
  36. package/src/components/lists/VcsTreeNode.vue +237 -0
  37. package/src/components/lists/VcsTreeNode.vue.d.ts +31 -0
  38. package/src/components/lists/VcsTreeview.vue +103 -173
  39. package/src/components/lists/VcsTreeview.vue.d.ts +41 -4
  40. package/src/components/lists/VcsTreeviewTitle.vue +10 -3
  41. package/src/components/lists/VcsTreeviewTitle.vue.d.ts +2 -0
  42. package/src/featureInfo/BalloonComponent.vue +18 -47
  43. package/src/featureInfo/BalloonComponent.vue.d.ts +0 -1
  44. package/src/featureInfo/IframeComponent.vue +1 -32
  45. package/src/featureInfo/IframeComponent.vue.d.ts +1 -4
  46. package/src/i18n/de.d.ts +1 -0
  47. package/src/i18n/de.js +1 -0
  48. package/src/i18n/en.d.ts +1 -0
  49. package/src/i18n/en.js +1 -0
  50. package/src/init.d.ts +6 -0
  51. package/src/init.js +26 -14
  52. package/src/manager/window/WindowComponent.vue +1 -1
  53. package/src/navigation/MapNavigation.vue +83 -1
  54. package/src/navigation/MapNavigation.vue.d.ts +2 -0
  55. package/src/search/ResultItem.vue +1 -10
  56. package/src/search/ResultsComponent.vue +11 -1
  57. package/src/search/ResultsComponent.vue.d.ts +9 -0
  58. package/src/search/SearchComponent.vue +88 -11
  59. package/src/search/SearchComponent.vue.d.ts +7 -0
  60. package/src/search/search.d.ts +3 -0
  61. package/src/search/search.js +3 -2
  62. package/src/uiConfig.d.ts +31 -0
  63. package/src/uiConfig.js +5 -0
  64. package/src/vuePlugins/vuetify.js +2 -0
  65. package/dist/assets/ui-f56287eb.css +0 -1
  66. /package/dist/assets/{cesium-5a0d7ac6.js → cesium-11e5bbc6.js} +0 -0
  67. /package/dist/assets/{ol-27d44222.js → ol-0d0ebb27.js} +0 -0
  68. /package/dist/assets/{vue-41556557.js → vue-2f81c7f8.js} +0 -0
  69. /package/dist/assets/{vuetify-03bc5f58.css → vuetify-67025c41.css} +0 -0
package/src/init.d.ts CHANGED
@@ -11,6 +11,12 @@ export default function initApp(mountTarget: string): Promise<import("@src/vcsUi
11
11
  * @returns {Promise<import("@src/vcsUiApp.js").default>}
12
12
  */
13
13
  export function initAppFromModule(mountTarget: string, configUrl?: string | undefined): Promise<import("@src/vcsUiApp.js").default>;
14
+ /**
15
+ * Creates a module from a config object or a url
16
+ * @param {import("@vcmap/core").VcsModuleConfig|string} c
17
+ * @returns {Promise<import("@vcmap/core").VcsModule|null>}
18
+ */
19
+ export function createModuleFromObjectOrUrl(c: import("@vcmap/core").VcsModuleConfig | string): Promise<import("@vcmap/core").VcsModule | null>;
14
20
  /**
15
21
  * Initializes app with a map config containing a set of config urls
16
22
  * @param {string} mountTarget
package/src/init.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createApp } from 'vue';
2
2
  import { check, is, maybe, oneOf, optional } from '@vcsuite/check';
3
3
  import { VcsModule } from '@vcmap/core';
4
+ import { getLogger } from '@vcsuite/logger';
4
5
  import VcsAppComponentWrapper from './application/VcsAppWrapper.vue';
5
6
  import VcsUiApp from './vcsUiApp.js';
6
7
  import { createSafeI18n } from './vuePlugins/i18n.js';
@@ -76,6 +77,30 @@ export async function initAppFromModule(mountTarget, configUrl) {
76
77
  return app;
77
78
  }
78
79
 
80
+ /**
81
+ * Creates a module from a config object or a url
82
+ * @param {import("@vcmap/core").VcsModuleConfig|string} c
83
+ * @returns {Promise<import("@vcmap/core").VcsModule|null>}
84
+ */
85
+ export async function createModuleFromObjectOrUrl(c) {
86
+ if (is(c, Object)) {
87
+ if (!is(c, VcsUiAppConfigPattern)) {
88
+ getLogger('init').warning(
89
+ 'Provided object is no valid VcsUiAppConfig',
90
+ c,
91
+ );
92
+ }
93
+ return new VcsModule(/** @type{import("@vcmap/core").VcsModuleConfig} */ c);
94
+ } else if (is(c, String)) {
95
+ const response = await fetch(c);
96
+ if (response.ok) {
97
+ const config = await response.json();
98
+ return new VcsModule(config);
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+
79
104
  /**
80
105
  * Initializes app with a map config containing a set of config urls
81
106
  * @param {string} mountTarget
@@ -95,20 +120,7 @@ export async function initAppFromAppConfig(mountTarget, appUrl) {
95
120
  check(appConfig.modules, [oneOf(String, Object)]);
96
121
 
97
122
  const modules = await Promise.all(
98
- appConfig.modules.map(async (c) => {
99
- if (is(c, VcsUiAppConfigPattern)) {
100
- return new VcsModule(
101
- /** @type{import("@vcmap/core").VcsModuleConfig} */ c,
102
- );
103
- } else if (is(c, String)) {
104
- const response = await fetch(c);
105
- if (response.ok) {
106
- const config = await response.json();
107
- return new VcsModule(config);
108
- }
109
- }
110
- return null;
111
- }),
123
+ appConfig.modules.map(createModuleFromObjectOrUrl),
112
124
  );
113
125
  // eslint-disable-next-line no-restricted-syntax
114
126
  for await (const module of modules) {
@@ -27,7 +27,7 @@
27
27
  </div>
28
28
  <v-divider v-if="!windowState.hideHeader" />
29
29
  <div
30
- class="overflow-x-hidden mb-1"
30
+ class="overflow-x-hidden overflow-y-auto mb-1 d-flex flex-grow-1 flex-column"
31
31
  :class="{
32
32
  rounded: !isDocked,
33
33
  }"
@@ -36,6 +36,15 @@
36
36
  <v-row justify="center" v-if="is3D && mdAndUp">
37
37
  <TiltSlider v-model="tilt" :disabled="movementApiCallsDisabled" />
38
38
  </v-row>
39
+ <v-row v-if="!hideRotationButton && is3D" justify="center">
40
+ <OrientationToolsButton
41
+ :icon="rotationAction.icon"
42
+ :tooltip="rotationAction.title"
43
+ :color="rotationAction.active ? 'primary' : undefined"
44
+ @click.stop="rotationAction.callback($event)"
45
+ :disabled="rotationAction.disabled"
46
+ />
47
+ </v-row>
39
48
  <v-row justify="center">
40
49
  <OrientationToolsButton
41
50
  v-if="homeAction.icon"
@@ -60,7 +69,13 @@
60
69
 
61
70
  <script>
62
71
  import { computed, inject, ref, reactive, onUnmounted } from 'vue';
63
- import { ObliqueMap, CesiumMap, ObliqueViewDirection } from '@vcmap/core';
72
+ import {
73
+ ObliqueMap,
74
+ CesiumMap,
75
+ ObliqueViewDirection,
76
+ startRotation,
77
+ rotationMapControlSymbol,
78
+ } from '@vcmap/core';
64
79
  import { VContainer, VRow } from 'vuetify/components';
65
80
  import { useDisplay } from 'vuetify';
66
81
  import { Math as CesiumMath } from '@vcmap-cesium/engine';
@@ -125,6 +140,59 @@
125
140
  return { action, destroy: () => listener?.() };
126
141
  }
127
142
 
143
+ /**
144
+ * @description Creates a rotate-around-center action to continuously rotate the viewpoint around the current map center at a specified speed. The action can be toggled on or off.
145
+ * @param {import("@src/vcsUiApp.js").default} app - The app instance containing the active map.
146
+ * @param {import("vue").ComputedRef<number>} defaultTimePerRotation - A computed property representing the time it takes to complete one rotation. The value should be a number representing seconds per rotation. Default is 60 seconds per rotation.
147
+ * @returns {{ action: import("vue").Reactive<VcsAction>, destroy: function():void }} - Returns the rotation action and a destroy method to stop the rotation listener if active.
148
+ */
149
+ function setupRotationButton(app, defaultTimePerRotation) {
150
+ let stopRotation;
151
+ const action = reactive({
152
+ name: 'rotate-action',
153
+ title: 'navigation.rotateButton',
154
+ icon: '$vcsView360',
155
+ active: false,
156
+ callback: async () => {
157
+ if (action.active) {
158
+ if (stopRotation) {
159
+ stopRotation();
160
+ } else {
161
+ app.maps.resetExclusiveMapControls();
162
+ }
163
+ } else {
164
+ stopRotation = await startRotation(
165
+ app,
166
+ undefined,
167
+ defaultTimePerRotation.value,
168
+ );
169
+ }
170
+ },
171
+ });
172
+
173
+ const rotationListener =
174
+ app.maps.exclusiveMapControlsChanged.addEventListener((eventData) => {
175
+ const { options, id } = eventData;
176
+ action.active =
177
+ id === rotationMapControlSymbol &&
178
+ options.keyEvents === true &&
179
+ options.apiCalls === true &&
180
+ options.pointerEvents === true;
181
+ action.disabled =
182
+ id !== rotationMapControlSymbol &&
183
+ options.keyEvents === true &&
184
+ options.apiCalls === true &&
185
+ options.pointerEvents === true;
186
+ });
187
+ return {
188
+ action,
189
+ destroy: () => {
190
+ stopRotation();
191
+ rotationListener();
192
+ },
193
+ };
194
+ }
195
+
128
196
  /**
129
197
  * @enum {string}
130
198
  */
@@ -306,6 +374,17 @@
306
374
 
307
375
  const { action: homeAction, destroy: homeDestroy } = setupHomeButton(app);
308
376
 
377
+ const defaultTimePerRotation = computed(() => {
378
+ return app.uiConfig.config?.timePerRotation;
379
+ });
380
+
381
+ const { action: rotationAction, destroy: rotationDestroy } =
382
+ setupRotationButton(app, defaultTimePerRotation);
383
+
384
+ const hideRotationButton = computed(() => {
385
+ return app.uiConfig.config?.hideRotationButton;
386
+ });
387
+
309
388
  onUnmounted(() => {
310
389
  if (overviewDestroy) {
311
390
  overviewDestroy();
@@ -316,6 +395,7 @@
316
395
  if (homeDestroy) {
317
396
  homeDestroy();
318
397
  }
398
+ rotationDestroy();
319
399
  postRenderHandler();
320
400
  overviewMapListeners.forEach((cb) => cb());
321
401
  removeMovementDisabledListener();
@@ -346,7 +426,9 @@
346
426
  locatorAction: reactive(locatorAction),
347
427
  showOverviewButton,
348
428
  showLocatorButton,
429
+ hideRotationButton,
349
430
  homeAction,
431
+ rotationAction,
350
432
  movementApiCallsDisabled,
351
433
  };
352
434
  },
@@ -79,7 +79,9 @@ declare const _default: import("vue").DefineComponent<{}, {
79
79
  };
80
80
  showOverviewButton: import("vue").Ref<boolean>;
81
81
  showLocatorButton: import("vue").Ref<boolean>;
82
+ hideRotationButton: import("vue").ComputedRef<boolean | undefined>;
82
83
  homeAction: any;
84
+ rotationAction: any;
83
85
  movementApiCallsDisabled: import("vue").Ref<boolean>;
84
86
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
85
87
  export default _default;
@@ -10,9 +10,6 @@
10
10
  <span v-html="marked" />
11
11
  </v-list-item-title>
12
12
  </template>
13
- <v-tooltip activator="parent">
14
- {{ $st('search.select') }}
15
- </v-tooltip>
16
13
  <template #append>
17
14
  <VcsActionButtonList
18
15
  v-if="hasActions"
@@ -26,12 +23,7 @@
26
23
 
27
24
  <script>
28
25
  import { computed } from 'vue';
29
- import {
30
- VIcon,
31
- VListItem,
32
- VListItemTitle,
33
- VTooltip,
34
- } from 'vuetify/components';
26
+ import { VIcon, VListItem, VListItemTitle } from 'vuetify/components';
35
27
  import DOMPurify from 'dompurify';
36
28
  import VcsActionButtonList from '../components/buttons/VcsActionButtonList.vue';
37
29
  import { markText } from './markText.js';
@@ -50,7 +42,6 @@
50
42
  VIcon,
51
43
  VListItem,
52
44
  VListItemTitle,
53
- VTooltip,
54
45
  },
55
46
  props: {
56
47
  query: {
@@ -7,7 +7,10 @@
7
7
  :item="item"
8
8
  :query="query"
9
9
  class="cursor-pointer"
10
- :class="{ 'vcs-search-result-border': index < items.length - 1 }"
10
+ :class="{
11
+ 'vcs-search-result-border': index < items.length - 1,
12
+ selected: index === selectedIndex,
13
+ }"
11
14
  v-for="(item, index) in items"
12
15
  :key="index"
13
16
  :value="item.value"
@@ -41,6 +44,10 @@
41
44
  type: Array,
42
45
  required: true,
43
46
  },
47
+ selectedIndex: {
48
+ type: Number,
49
+ default: -1,
50
+ },
44
51
  },
45
52
  setup(props) {
46
53
  const items = computed(() => {
@@ -100,4 +107,7 @@
100
107
  border-bottom: thin solid;
101
108
  border-color: rgb(var(--v-theme-base-lighten-2));
102
109
  }
110
+ .selected {
111
+ background-color: rgb(var(--v-theme-base-lighten-4));
112
+ }
103
113
  </style>
@@ -7,6 +7,10 @@ declare const _default: import("vue").DefineComponent<{
7
7
  type: ArrayConstructor;
8
8
  required: true;
9
9
  };
10
+ selectedIndex: {
11
+ type: NumberConstructor;
12
+ default: number;
13
+ };
10
14
  }, {
11
15
  items: import("vue").ComputedRef<any[]>;
12
16
  highlighted: import("vue").WritableComputedRef<never[]>;
@@ -19,7 +23,12 @@ declare const _default: import("vue").DefineComponent<{
19
23
  type: ArrayConstructor;
20
24
  required: true;
21
25
  };
26
+ selectedIndex: {
27
+ type: NumberConstructor;
28
+ default: number;
29
+ };
22
30
  }>>, {
23
31
  query: string;
32
+ selectedIndex: number;
24
33
  }, {}>;
25
34
  export default _default;
@@ -10,20 +10,33 @@
10
10
  :loading="searching"
11
11
  clearable
12
12
  :placeholder="$t('search.placeholder')"
13
- v-model.trim="query"
13
+ v-model="query"
14
14
  @keydown.enter="search"
15
- @input="reset"
15
+ @keydown.down.stop.prevent="selectSuggestion(1)"
16
+ @keydown.up.stop.prevent="selectSuggestion(-1)"
17
+ @input="onInput"
16
18
  @click:clear="reset"
17
19
  />
18
20
  </span>
19
- <v-divider class="mt-1 base-darken-1" v-if="!!results.length" />
20
- <ResultsComponent :query="query" :results="results" />
21
- <v-divider v-if="!!results.length" />
22
- <div v-if="!!results.length" class="d-flex px-2 pt-2 pb-1 justify-end">
23
- <VcsFormButton @click="zoomToAll" variant="outlined">
24
- {{ $t('search.zoomToAll') }}
25
- </VcsFormButton>
26
- </div>
21
+ <template v-if="results.length > 0">
22
+ <v-divider class="mt-1 base-darken-1" />
23
+ <ResultsComponent :query="query" :results="results" />
24
+ <v-divider />
25
+ <div class="d-flex px-2 pt-2 pb-1 justify-end">
26
+ <VcsFormButton @click="zoomToAll" variant="outlined">
27
+ {{ $t('search.zoomToAll') }}
28
+ </VcsFormButton>
29
+ </div>
30
+ </template>
31
+ <template v-else-if="suggestions.length > 0">
32
+ <v-divider class="mt-1 base-darken-1" />
33
+ <ResultsComponent
34
+ class="suggestions"
35
+ :results="suggestions"
36
+ :query="query"
37
+ :selected-index="selectedSuggestion"
38
+ />
39
+ </template>
27
40
  </v-sheet>
28
41
  </template>
29
42
 
@@ -31,14 +44,20 @@
31
44
  :deep(.v-field .v-field__outline *) {
32
45
  border-color: transparent !important;
33
46
  }
47
+
34
48
  .user-select-none {
35
49
  user-select: none;
36
50
  }
51
+
52
+ .suggestions {
53
+ font-style: italic;
54
+ }
37
55
  </style>
38
56
 
39
57
  <script>
40
58
  import { inject, onUnmounted, ref, computed } from 'vue';
41
59
  import { getLogger } from '@vcsuite/logger';
60
+ import { v4 as uuid } from 'uuid';
42
61
  import { VSheet, VDivider, VIcon } from 'vuetify/components';
43
62
  import VcsTextField from '../components/form-inputs-controls/VcsTextField.vue';
44
63
  import ResultsComponent from './ResultsComponent.vue';
@@ -62,26 +81,63 @@
62
81
  /** @type {import("@src/vcsUiApp.js").default} */
63
82
  const app = inject('vcsApp');
64
83
  const searching = ref(false);
84
+ const suggesting = ref('');
65
85
  const query = ref(null);
66
86
  const suggestions = ref([]);
87
+ const selectedSuggestion = ref(-1);
67
88
  const results = app.search.currentResults;
89
+ let queryPreSuggestion = '';
90
+
91
+ let suggestionTimeout;
92
+
93
+ const onInput = () => {
94
+ app.search.clearResults();
95
+ const trimmedInput = query.value?.trim() ?? '';
96
+ if (trimmedInput.length > 0) {
97
+ const requestId = uuid();
98
+ if (suggestionTimeout) {
99
+ clearTimeout(suggestionTimeout);
100
+ }
101
+ suggestionTimeout = setTimeout(() => {
102
+ suggesting.value = requestId;
103
+ queryPreSuggestion = trimmedInput;
104
+ selectedSuggestion.value = -1;
105
+ app.search.suggest(trimmedInput).then((s) => {
106
+ if (suggesting.value === requestId) {
107
+ suggestions.value = s;
108
+ suggesting.value = '';
109
+ }
110
+ });
111
+ }, 200);
112
+ } else {
113
+ selectedSuggestion.value = -1;
114
+ suggesting.value = '';
115
+ suggestions.value = [];
116
+ queryPreSuggestion = '';
117
+ }
118
+ };
68
119
 
69
120
  const reset = () => {
70
121
  app.search.clearResults();
122
+ selectedSuggestion.value = -1;
123
+ suggesting.value = '';
71
124
  suggestions.value = [];
125
+ queryPreSuggestion = '';
72
126
  };
73
127
 
74
128
  const clear = () => {
75
129
  reset();
76
130
  searching.value = false;
131
+ suggestions.value = [];
77
132
  query.value = null;
133
+ queryPreSuggestion = '';
78
134
  };
79
135
 
80
136
  const search = async () => {
81
137
  reset();
82
138
  searching.value = true;
83
139
  try {
84
- await app.search.search(query.value);
140
+ await app.search.search(query.value.trim());
85
141
  } catch (e) {
86
142
  getLogger('Search').error(e);
87
143
  }
@@ -109,6 +165,27 @@
109
165
  search,
110
166
  zoomToAll,
111
167
  searchIconSize,
168
+ suggestions: computed(() =>
169
+ suggestions.value.map((s) => ({
170
+ title: s,
171
+ clicked() {
172
+ query.value = s;
173
+ search();
174
+ },
175
+ })),
176
+ ),
177
+ selectedSuggestion,
178
+ onInput,
179
+ selectSuggestion(value) {
180
+ const newSelection = selectedSuggestion.value + value;
181
+ if (newSelection > -1 && newSelection < suggestions.value?.length) {
182
+ selectedSuggestion.value = newSelection;
183
+ query.value = suggestions.value[newSelection];
184
+ } else {
185
+ selectedSuggestion.value = -1;
186
+ query.value = queryPreSuggestion;
187
+ }
188
+ },
112
189
  };
113
190
  },
114
191
  };
@@ -7,5 +7,12 @@ declare const _default: import("vue").DefineComponent<{}, {
7
7
  search: () => Promise<void>;
8
8
  zoomToAll: () => void;
9
9
  searchIconSize: import("vue").ComputedRef<number>;
10
+ suggestions: import("vue").ComputedRef<{
11
+ title: never;
12
+ clicked(): void;
13
+ }[]>;
14
+ selectedSuggestion: import("vue").Ref<number>;
15
+ onInput: () => void;
16
+ selectSuggestion(value: any): void;
10
17
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
11
18
  export default _default;
@@ -25,6 +25,9 @@ export type SearchImpl = {
25
25
  */
26
26
  name: string;
27
27
  search: (arg0: string) => Promise<Array<ResultItem>>;
28
+ /**
29
+ * - optional, provides suggestions for autocomplete.
30
+ */
28
31
  suggest?: ((arg0: string) => Promise<Array<string>>) | undefined;
29
32
  /**
30
33
  * - should abort any ongoing requests to search or suggest without throwing an error
@@ -35,8 +35,8 @@ import { getViewpointFromFeature } from '../actions/actionHelper.js';
35
35
  * @typedef {Object} SearchImpl
36
36
  * @property {string} name Name of the implementation. Must be unique, best practice is to prefix with your plugin name to ensure uniqueness or use a uuid.
37
37
  * @property {function(string):Promise<Array<ResultItem>>} search
38
- * @property {function(string):Promise<Array<string>>} [suggest] // XXX currently not implemented in UI at Beta state
39
- * @property{function():void} abort - should abort any ongoing requests to search or suggest without throwing an error
38
+ * @property {function(string):Promise<Array<string>>} [suggest] - optional, provides suggestions for autocomplete.
39
+ * @property {function():void} abort - should abort any ongoing requests to search or suggest without throwing an error
40
40
  * @property {function():void} destroy
41
41
  */
42
42
 
@@ -257,6 +257,7 @@ class Search extends IndexedCollection {
257
257
  * @returns {Promise<Array<string>>}
258
258
  */
259
259
  async suggest(q) {
260
+ this.clearResults();
260
261
  const promises = await Promise.allSettled(
261
262
  [...this._array].map((impl) => {
262
263
  if (impl.suggest) {
package/src/uiConfig.d.ts CHANGED
@@ -15,6 +15,9 @@ export type SplashScreen = {
15
15
  name?: string | undefined;
16
16
  checkBoxText?: string | undefined;
17
17
  buttonTitle?: string | undefined;
18
+ secondaryButtonTitle?: string | undefined;
19
+ exitCallbackOptions?: import("./callback/vcsCallback.js").VcsCallbackOptions[] | undefined;
20
+ secondaryCallbackOptions?: import("./callback/vcsCallback.js").VcsCallbackOptions[] | undefined;
18
21
  menuEntry?: boolean | undefined;
19
22
  acceptInput?: boolean | undefined;
20
23
  position?: {
@@ -92,6 +95,14 @@ export type UiConfigObject = {
92
95
  * - an optional flag whether to show the Locator in the map.
93
96
  */
94
97
  showLocator?: boolean | undefined;
98
+ /**
99
+ * - an optional flag to hide the Rotator in the map.
100
+ */
101
+ hideRotationButton?: boolean | undefined;
102
+ /**
103
+ * - an optional flag that describes the time per rotation in seconds.
104
+ */
105
+ timePerRotation?: number | undefined;
95
106
  /**
96
107
  * - can be used to hide the default Header of the map
97
108
  */
@@ -178,6 +189,9 @@ export type UiConfigObject = {
178
189
  * @property {string} [name]
179
190
  * @property {string} [checkBoxText]
180
191
  * @property {string} [buttonTitle]
192
+ * @property {string} [secondaryButtonTitle]
193
+ * @property {Array<import("./callback/vcsCallback.js").VcsCallbackOptions>} [exitCallbackOptions]
194
+ * @property {Array<import("./callback/vcsCallback.js").VcsCallbackOptions>} [secondaryCallbackOptions]
181
195
  * @property {boolean} [menuEntry]
182
196
  * @property {boolean} [acceptInput]
183
197
  * @property {Object} [position]
@@ -211,6 +225,8 @@ export type UiConfigObject = {
211
225
  * @property {string} [favicon] - the favicon to set
212
226
  * @property {string} [headerTitle] - the title to display in the tab of the browser
213
227
  * @property {boolean} [showLocator] - an optional flag whether to show the Locator in the map.
228
+ * @property {boolean} [hideRotationButton] - an optional flag to hide the Rotator in the map.
229
+ * @property {number} [timePerRotation] - an optional flag that describes the time per rotation in seconds.
214
230
  * @property {boolean} [hideHeader] - can be used to hide the default Header of the map
215
231
  * @property {boolean} [hideSearch] - can be used to hide the integrated Search bar
216
232
  * @property {boolean} [hideMapButtons] - can be used to hide the default Map Buttons
@@ -345,6 +361,13 @@ declare class UiConfig extends Collection<UiConfigurationItem<unknown>> {
345
361
  readonly name?: string | undefined;
346
362
  readonly checkBoxText?: string | undefined;
347
363
  readonly buttonTitle?: string | undefined;
364
+ readonly secondaryButtonTitle?: string | undefined;
365
+ readonly exitCallbackOptions?: readonly {
366
+ readonly type: string;
367
+ }[] | undefined;
368
+ readonly secondaryCallbackOptions?: readonly {
369
+ readonly type: string;
370
+ }[] | undefined;
348
371
  readonly menuEntry?: boolean | undefined;
349
372
  readonly acceptInput?: boolean | undefined;
350
373
  readonly position?: {
@@ -417,6 +440,14 @@ declare class UiConfig extends Collection<UiConfigurationItem<unknown>> {
417
440
  * - an optional flag whether to show the Locator in the map.
418
441
  */
419
442
  readonly showLocator?: boolean | undefined;
443
+ /**
444
+ * - an optional flag to hide the Rotator in the map.
445
+ */
446
+ readonly hideRotationButton?: boolean | undefined;
447
+ /**
448
+ * - an optional flag that describes the time per rotation in seconds.
449
+ */
450
+ readonly timePerRotation?: number | undefined;
420
451
  /**
421
452
  * - can be used to hide the default Header of the map
422
453
  */
package/src/uiConfig.js CHANGED
@@ -24,6 +24,9 @@ import { reactive, readonly } from 'vue';
24
24
  * @property {string} [name]
25
25
  * @property {string} [checkBoxText]
26
26
  * @property {string} [buttonTitle]
27
+ * @property {string} [secondaryButtonTitle]
28
+ * @property {Array<import("./callback/vcsCallback.js").VcsCallbackOptions>} [exitCallbackOptions]
29
+ * @property {Array<import("./callback/vcsCallback.js").VcsCallbackOptions>} [secondaryCallbackOptions]
27
30
  * @property {boolean} [menuEntry]
28
31
  * @property {boolean} [acceptInput]
29
32
  * @property {Object} [position]
@@ -59,6 +62,8 @@ import { reactive, readonly } from 'vue';
59
62
  * @property {string} [favicon] - the favicon to set
60
63
  * @property {string} [headerTitle] - the title to display in the tab of the browser
61
64
  * @property {boolean} [showLocator] - an optional flag whether to show the Locator in the map.
65
+ * @property {boolean} [hideRotationButton] - an optional flag to hide the Rotator in the map.
66
+ * @property {number} [timePerRotation] - an optional flag that describes the time per rotation in seconds.
62
67
  * @property {boolean} [hideHeader] - can be used to hide the default Header of the map
63
68
  * @property {boolean} [hideSearch] - can be used to hide the integrated Search bar
64
69
  * @property {boolean} [hideMapButtons] - can be used to hide the default Map Buttons
@@ -89,6 +89,7 @@ export function createVcsThemes(options, primaryColor) {
89
89
  'hover-opacity': 0.16,
90
90
  'high-emphasis-opacity': 1,
91
91
  'medium-emphasis-opacity': 1,
92
+ 'list-item-subtitle-opacity': 0.6,
92
93
  'vcs-font-size': '13px',
93
94
  'vcs-font-family': 'Titillium Web',
94
95
  ...options?.light?.variables,
@@ -119,6 +120,7 @@ export function createVcsThemes(options, primaryColor) {
119
120
  'hover-opacity': 0.16,
120
121
  'high-emphasis-opacity': 1,
121
122
  'medium-emphasis-opacity': 1,
123
+ 'list-item-subtitle-opacity': 0.6,
122
124
  'vcs-font-size': '13px',
123
125
  'vcs-font-family': 'Titillium Web',
124
126
  ...options?.dark?.variables,