@kiva/kv-components 3.36.0 → 3.38.0
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.
- package/CHANGELOG.md +22 -0
- package/package.json +3 -2
- package/vue/.storybook/preview.js +4 -0
- package/vue/KvImpactDashboardHeader.vue +40 -0
- package/vue/KvMap.vue +370 -0
- package/vue/stories/KvImpactDashboardHeader.stories.js +22 -0
- package/vue/stories/KvMap.stories.js +69 -0
- package/vue/KvKivaPartnerHeader.vue +0 -44
- package/vue/stories/KvKivaPartnerHeader.stories.js +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.38.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.37.0...@kiva/kv-components@3.38.0) (2023-08-29)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* kvmap ported to kv components library ([#286](https://github.com/kiva/kv-ui-elements/issues/286)) ([373e53f](https://github.com/kiva/kv-ui-elements/commit/373e53fd407d161e79033826a6063fbd5ca5b2ce))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [3.37.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.36.0...@kiva/kv-components@3.37.0) (2023-08-18)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* update header icon ([a593f2c](https://github.com/kiva/kv-ui-elements/commit/a593f2c4ba2285a1917622db55a88ff68097fe89))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [3.36.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.35.1...@kiva/kv-components@3.36.0) (2023-08-14)
|
|
7
29
|
|
|
8
30
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.38.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"tailwindcss": "^3.0.18",
|
|
43
43
|
"vue": "^2.6.14",
|
|
44
44
|
"vue-loader": "^15.9.6",
|
|
45
|
+
"vue-meta": "^2.4.0",
|
|
45
46
|
"vue-router": "^3.5.2",
|
|
46
47
|
"vue-template-compiler": "^2.6.12"
|
|
47
48
|
},
|
|
@@ -75,5 +76,5 @@
|
|
|
75
76
|
"optional": true
|
|
76
77
|
}
|
|
77
78
|
},
|
|
78
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "00704fdebcb089c0ad690f58a3d9790c76d69e3f"
|
|
79
80
|
}
|
|
@@ -3,6 +3,7 @@ import addons from '@storybook/addons';
|
|
|
3
3
|
import KvThemeProvider from '../KvThemeProvider.vue';
|
|
4
4
|
import { defaultTheme, darkTheme } from '@kiva/kv-tokens/configs/kivaColors.cjs';
|
|
5
5
|
import Vue from 'vue';
|
|
6
|
+
import Meta from 'vue-meta';
|
|
6
7
|
import VueCompositionApi from '@vue/composition-api';
|
|
7
8
|
import VueRouter from 'vue-router';
|
|
8
9
|
|
|
@@ -11,6 +12,9 @@ Vue.use(VueCompositionApi);
|
|
|
11
12
|
|
|
12
13
|
Vue.use(VueRouter);
|
|
13
14
|
|
|
15
|
+
// initialize vue-meta
|
|
16
|
+
Vue.use(Meta);
|
|
17
|
+
|
|
14
18
|
export const parameters = {
|
|
15
19
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
|
16
20
|
controls: {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!-- eslint-disable max-len -->
|
|
2
|
+
<template>
|
|
3
|
+
<nav class="tw-bg-primary">
|
|
4
|
+
<div
|
|
5
|
+
class="header__full tw-h-9 tw-grid xl:tw-gap-x-4 tw-items-center tw-mx-auto tw-px-2.5 md:tw-px-4 lg:tw-px-8"
|
|
6
|
+
style="max-width: 1200px;"
|
|
7
|
+
>
|
|
8
|
+
<div class="header__full__logo tw-w-6 tw-text-brand">
|
|
9
|
+
<svg
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
viewBox="0 0 57 23"
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
d="M4.695.391H0v22.141h4.695V.391zm12.899 22.141h4.695V7.011h-4.695v15.521zm12.159 0h5.413l5.413-15.521h-4.662s-2.544 8.445-3.293 11.119h-.066c-.75-2.674-3.326-11.119-3.326-11.119h-4.956l5.477 15.521zm-23.537-8.31c7.37 0 9.092-6.158 9.092-7.21h-.637c-7.372 0-9.094 6.157-9.094 7.21h.639zm-.639.969c0 1.117 1.276 7.403 9.222 7.403h.638c0-1.119-1.277-7.403-9.221-7.403h-.639zM22.746 2.739C22.746 1.272 21.671 0 19.941 0c-1.727 0-2.804 1.272-2.804 2.739 0 1.468 1.077 2.739 2.804 2.739 1.73 0 2.805-1.271 2.805-2.739M57 7.011h-4.532V9.13c-.783-1.631-2.608-2.543-4.729-2.543-3.848 0-6.88 3.129-6.88 8.184 0 5.087 2.935 8.185 6.652 8.185 2.608 0 4.173-1.272 4.956-2.675v2.25H57V7.011zm-4.663 8.151c0 2.871-1.76 4.208-3.522 4.208-1.924 0-3.163-1.956-3.163-4.598 0-2.608 1.305-4.598 3.326-4.598 1.663 0 3.359 1.37 3.359 4.206v.782z"
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="header__full__right">
|
|
21
|
+
<slot></slot>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</nav>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<style scoped>
|
|
28
|
+
.header__full {
|
|
29
|
+
grid-template-areas: 'logo right';
|
|
30
|
+
grid-template-columns: 1fr auto;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.header__full__logo {
|
|
34
|
+
grid-area: logo;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.header__full__right {
|
|
38
|
+
grid-area: right;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
package/vue/KvMap.vue
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="tw-relative tw-block tw-w-full"
|
|
4
|
+
:style="mapDimensions"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
:id="`kv-map-holder-${mapId}`"
|
|
8
|
+
:ref="refString"
|
|
9
|
+
class="tw-w-full tw-h-full tw-bg-black"
|
|
10
|
+
:style="{ position: 'absolute' }"
|
|
11
|
+
></div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
name: 'KvMap',
|
|
18
|
+
metaInfo() {
|
|
19
|
+
return {
|
|
20
|
+
script: [].concat(!this.hasWebGL ? [
|
|
21
|
+
// leaflet - uses raster tiles for additional browser coverage
|
|
22
|
+
{
|
|
23
|
+
vmid: `leafletjs${this.mapId}`,
|
|
24
|
+
src: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js',
|
|
25
|
+
async: true,
|
|
26
|
+
defer: true,
|
|
27
|
+
},
|
|
28
|
+
] : []).concat(this.hasWebGL ? [
|
|
29
|
+
// maplibregl - uses vector tiles and webgl for rendering
|
|
30
|
+
{
|
|
31
|
+
vmid: `maplibregljs${this.mapId}`,
|
|
32
|
+
src: 'https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js',
|
|
33
|
+
async: true,
|
|
34
|
+
defer: true,
|
|
35
|
+
},
|
|
36
|
+
] : []),
|
|
37
|
+
link: [
|
|
38
|
+
].concat(!this.hasWebGL ? [
|
|
39
|
+
// leaflet - uses raster tiles for additional browser coverage
|
|
40
|
+
{
|
|
41
|
+
vmid: `leafletcss${this.mapId}`,
|
|
42
|
+
rel: 'stylesheet',
|
|
43
|
+
href: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css',
|
|
44
|
+
},
|
|
45
|
+
] : []).concat(this.hasWebGL ? [
|
|
46
|
+
// maplibregl - uses vector tiles and webgl for rendering
|
|
47
|
+
{
|
|
48
|
+
vmid: `maplibreglcss${this.mapId}`,
|
|
49
|
+
rel: 'stylesheet',
|
|
50
|
+
href: 'https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css',
|
|
51
|
+
},
|
|
52
|
+
] : []),
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
props: {
|
|
56
|
+
/**
|
|
57
|
+
* Aspect Ration for computed map dimensions
|
|
58
|
+
* We'll divide the container width by this to determine the height
|
|
59
|
+
*/
|
|
60
|
+
aspectRatio: {
|
|
61
|
+
type: Number,
|
|
62
|
+
default: 1,
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Control how quickly the autoZoom occurs
|
|
66
|
+
*/
|
|
67
|
+
autoZoomDelay: {
|
|
68
|
+
type: Number,
|
|
69
|
+
default: 1500,
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Set the height to override aspect ratio driven and/or default dimensions
|
|
73
|
+
*/
|
|
74
|
+
height: {
|
|
75
|
+
type: Number,
|
|
76
|
+
default: null,
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Setting this initialZoom will zoom the map from initialZoom to zoom when the map enters the viewport
|
|
80
|
+
*/
|
|
81
|
+
initialZoom: {
|
|
82
|
+
type: Number,
|
|
83
|
+
default: null,
|
|
84
|
+
},
|
|
85
|
+
/**
|
|
86
|
+
* Set the center point latitude
|
|
87
|
+
*/
|
|
88
|
+
lat: {
|
|
89
|
+
type: Number,
|
|
90
|
+
default: null,
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Set the center point longitude
|
|
94
|
+
*/
|
|
95
|
+
long: {
|
|
96
|
+
type: Number,
|
|
97
|
+
default: null,
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Set this if there are more than one map on the page
|
|
101
|
+
*/
|
|
102
|
+
mapId: {
|
|
103
|
+
type: Number,
|
|
104
|
+
default: 0,
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* Force use of Leaflet
|
|
108
|
+
*/
|
|
109
|
+
useLeaflet: {
|
|
110
|
+
type: Boolean,
|
|
111
|
+
default: false,
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* Set the width to override aspect ratio driven and/or default dimensions
|
|
115
|
+
*/
|
|
116
|
+
width: {
|
|
117
|
+
type: Number,
|
|
118
|
+
default: null,
|
|
119
|
+
},
|
|
120
|
+
/**
|
|
121
|
+
* Default zoom level
|
|
122
|
+
*/
|
|
123
|
+
zoomLevel: {
|
|
124
|
+
type: Number,
|
|
125
|
+
default: 4,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
data() {
|
|
129
|
+
return {
|
|
130
|
+
hasWebGL: false,
|
|
131
|
+
leafletReady: false,
|
|
132
|
+
mapInstance: null,
|
|
133
|
+
mapLibreReady: false,
|
|
134
|
+
mapLoaded: false,
|
|
135
|
+
zoomActive: false,
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
computed: {
|
|
139
|
+
mapDimensions() {
|
|
140
|
+
// Use container to derive height based on aspect ration + width
|
|
141
|
+
const container = this.$el?.getBoundingClientRect();
|
|
142
|
+
const height = container ? `${container.width / this.aspectRatio}px` : '300px';
|
|
143
|
+
const width = container ? `${container.width}px` : '100%';
|
|
144
|
+
// Override values if deliberate height or width are provided
|
|
145
|
+
return {
|
|
146
|
+
height: this.height ? `${this.height}px` : height,
|
|
147
|
+
width: this.width ? `${this.width}px` : width,
|
|
148
|
+
paddingBottom: this.height ? `${this.height}px` : `${100 / this.aspectRatio}%`,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
refString() {
|
|
152
|
+
return `mapholder${this.mapId}`;
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
watch: {
|
|
156
|
+
lat(next, prev) {
|
|
157
|
+
if (prev === null && this.long && !this.mapLibreReady && !this.leafletReady) {
|
|
158
|
+
this.initializeMap();
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
long(next, prev) {
|
|
162
|
+
if (prev === null && this.lat && !this.mapLibreReady && !this.leafletReady) {
|
|
163
|
+
this.initializeMap();
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
mounted() {
|
|
168
|
+
if (!this.mapLibreReady && !this.leafletReady) {
|
|
169
|
+
this.initializeMap();
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
beforeDestroy() {
|
|
173
|
+
if (this.mapInstance) {
|
|
174
|
+
if (!this.hasWebGL && !this.leafletReady) {
|
|
175
|
+
// turn off the leaflet instance
|
|
176
|
+
this.mapInstance.off();
|
|
177
|
+
}
|
|
178
|
+
// remove either leaflet or maplibregl
|
|
179
|
+
this.mapInstance.remove();
|
|
180
|
+
}
|
|
181
|
+
this.destroyWrapperObserver();
|
|
182
|
+
},
|
|
183
|
+
methods: {
|
|
184
|
+
activateZoom(zoomOut = false) {
|
|
185
|
+
const { mapInstance, hasWebGL, mapLibreReady } = this;
|
|
186
|
+
const currentZoomLevel = mapInstance.getZoom();
|
|
187
|
+
// exit if already zoomed in (getZoom() works for both leaflet + maplibregl)
|
|
188
|
+
if ((!zoomOut && currentZoomLevel === this.zoomLevel)
|
|
189
|
+
|| (zoomOut && currentZoomLevel === this.initialZoom)) return false;
|
|
190
|
+
|
|
191
|
+
this.zoomActive = true;
|
|
192
|
+
// establish delayed zoom duration
|
|
193
|
+
const timedZoom = window.setTimeout(() => {
|
|
194
|
+
if (hasWebGL && mapLibreReady) {
|
|
195
|
+
// maplibregl specific zoom method
|
|
196
|
+
mapInstance.zoomTo(
|
|
197
|
+
zoomOut ? this.initialZoom : this.zoomLevel,
|
|
198
|
+
{ duration: 1200 },
|
|
199
|
+
);
|
|
200
|
+
} else {
|
|
201
|
+
// leaflet specific zoom method
|
|
202
|
+
mapInstance.setZoom(zoomOut ? this.initialZoom : this.zoomLevel);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
clearTimeout(timedZoom);
|
|
206
|
+
this.zoomActive = false;
|
|
207
|
+
}, this.autoZoomDelay);
|
|
208
|
+
},
|
|
209
|
+
createWrapperObserver() {
|
|
210
|
+
// Watch for the wrapper element moving in and out of the viewport
|
|
211
|
+
this.wrapperObserver = this.createIntersectionObserver({
|
|
212
|
+
targets: [this.$refs?.[this.refString]],
|
|
213
|
+
callback: (entries) => {
|
|
214
|
+
entries.forEach((entry) => {
|
|
215
|
+
if (entry.target === this.$refs?.[this.refString] && !this.zoomActive) {
|
|
216
|
+
if (entry.intersectionRatio > 0) {
|
|
217
|
+
this.activateZoom();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
destroyWrapperObserver() {
|
|
225
|
+
if (this.wrapperObserver) {
|
|
226
|
+
this.wrapperObserver.disconnect();
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
checkWebGL() {
|
|
230
|
+
// exit and use leaflet if specified or document isn't present
|
|
231
|
+
if (this.useLeaflet || typeof document === 'undefined') return false;
|
|
232
|
+
// via. https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL
|
|
233
|
+
// Create canvas element. The canvas is not added to the document itself,
|
|
234
|
+
// so it is never displayed in the browser window.
|
|
235
|
+
const canvas = document.createElement('canvas');
|
|
236
|
+
// Get WebGLRenderingContext from canvas element.
|
|
237
|
+
const gl = canvas.getContext('webgl')
|
|
238
|
+
|| canvas.getContext('experimental-webgl');
|
|
239
|
+
// Report the result.
|
|
240
|
+
if (gl && gl instanceof WebGLRenderingContext) {
|
|
241
|
+
this.hasWebGL = true;
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
},
|
|
246
|
+
initializeMap() {
|
|
247
|
+
/**
|
|
248
|
+
* This initial checkWebGL() call kicks off the vue-meta asset inclusion
|
|
249
|
+
* We then start polling for the readiness of our selected map library and initialize it once ready
|
|
250
|
+
*/
|
|
251
|
+
if (this.checkWebGL()) {
|
|
252
|
+
this.testDelayedGlobalLibrary('maplibregl').then((response) => {
|
|
253
|
+
if (response.loaded && !this.mapLoaded && !this.useLeaflet && this.lat && this.long) {
|
|
254
|
+
this.initializeMapLibre();
|
|
255
|
+
this.mapLibreReady = true;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
} else {
|
|
259
|
+
this.testDelayedGlobalLibrary('L').then((leafletTest) => {
|
|
260
|
+
if (leafletTest.loaded && !this.mapLoaded && this.lat && this.long) {
|
|
261
|
+
this.initializeLeaflet();
|
|
262
|
+
this.leafletReady = true;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
initializeLeaflet() {
|
|
268
|
+
/* eslint-disable no-undef, max-len */
|
|
269
|
+
// Initialize primary mapInstance
|
|
270
|
+
this.mapInstance = L.map(`kv-map-holder-${this.mapId}`, {
|
|
271
|
+
center: [this.lat, this.long],
|
|
272
|
+
zoom: this.initialZoom || this.zoomLevel,
|
|
273
|
+
// todo make props for the following options
|
|
274
|
+
dragging: false,
|
|
275
|
+
zoomControl: false,
|
|
276
|
+
animate: true,
|
|
277
|
+
scrollWheelZoom: false,
|
|
278
|
+
doubleClickZoom: false,
|
|
279
|
+
attributionControl: false,
|
|
280
|
+
});
|
|
281
|
+
/* eslint-disable quotes */
|
|
282
|
+
// Add our tileset to the mapInstance
|
|
283
|
+
L.tileLayer('https://api.maptiler.com/maps/bright/{z}/{x}/{y}.png?key=n1Mz5ziX3k6JfdjFe7mx', {
|
|
284
|
+
tileSize: 512,
|
|
285
|
+
zoomOffset: -1,
|
|
286
|
+
minZoom: 1,
|
|
287
|
+
crossOrigin: true,
|
|
288
|
+
}).addTo(this.mapInstance);
|
|
289
|
+
/* eslint-enable quotes */
|
|
290
|
+
/* eslint-enable no-undef, max-len */
|
|
291
|
+
|
|
292
|
+
// signify map has loaded
|
|
293
|
+
this.mapLoaded = true;
|
|
294
|
+
// only activate autoZoom if we have an initialZoom set
|
|
295
|
+
if (this.initialZoom !== null) {
|
|
296
|
+
this.createWrapperObserver();
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
initializeMapLibre() {
|
|
300
|
+
// Initialize primary mapInstance
|
|
301
|
+
// eslint-disable-next-line no-undef
|
|
302
|
+
this.mapInstance = new maplibregl.Map({
|
|
303
|
+
container: `kv-map-holder-${this.mapId}`,
|
|
304
|
+
style: 'https://api.maptiler.com/maps/bright/style.json?key=n1Mz5ziX3k6JfdjFe7mx',
|
|
305
|
+
center: [this.long, this.lat],
|
|
306
|
+
zoom: this.initialZoom || this.zoomLevel,
|
|
307
|
+
attributionControl: false,
|
|
308
|
+
dragPan: false,
|
|
309
|
+
scrollZoom: false,
|
|
310
|
+
doubleClickZoom: false,
|
|
311
|
+
dragRotate: false,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// signify map has loaded
|
|
315
|
+
this.mapLoaded = true;
|
|
316
|
+
|
|
317
|
+
// only activate autoZoom if we have an initialZoom set
|
|
318
|
+
if (this.initialZoom !== null) {
|
|
319
|
+
this.createWrapperObserver();
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
checkIntersectionObserverSupport() {
|
|
323
|
+
if (typeof window === 'undefined'
|
|
324
|
+
|| !('IntersectionObserver' in window)
|
|
325
|
+
|| !('IntersectionObserverEntry' in window)
|
|
326
|
+
|| !('intersectionRatio' in window.IntersectionObserverEntry.prototype)) {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
return true;
|
|
330
|
+
},
|
|
331
|
+
createIntersectionObserver({ callback, options, targets } = {}) {
|
|
332
|
+
if (this.checkIntersectionObserverSupport()) {
|
|
333
|
+
const observer = new IntersectionObserver(callback, options);
|
|
334
|
+
targets.forEach((target) => observer.observe(target));
|
|
335
|
+
return observer;
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
testDelayedGlobalLibrary(library, timeout = 3000) {
|
|
339
|
+
// return a promise
|
|
340
|
+
return new Promise((resolve, reject) => {
|
|
341
|
+
if (typeof window === 'undefined') {
|
|
342
|
+
reject(new Error('window object not available'));
|
|
343
|
+
}
|
|
344
|
+
// establish timeout to limit time until promise resolution
|
|
345
|
+
let readyStateTimeout;
|
|
346
|
+
// establish interval to check for library presence
|
|
347
|
+
const readyStateInterval = window.setInterval(() => {
|
|
348
|
+
// determine if library is present on window
|
|
349
|
+
if (typeof window[library] !== 'undefined') {
|
|
350
|
+
// cleanup timers
|
|
351
|
+
clearInterval(readyStateInterval);
|
|
352
|
+
clearTimeout(readyStateTimeout);
|
|
353
|
+
// resolve the promise
|
|
354
|
+
resolve({ loaded: true });
|
|
355
|
+
}
|
|
356
|
+
}, 100);
|
|
357
|
+
|
|
358
|
+
// activate timeout
|
|
359
|
+
readyStateTimeout = window.setTimeout(() => {
|
|
360
|
+
// clean up interval and timeout
|
|
361
|
+
clearInterval(readyStateInterval);
|
|
362
|
+
clearTimeout(readyStateTimeout);
|
|
363
|
+
// resolve the promise
|
|
364
|
+
resolve({ loaded: false });
|
|
365
|
+
}, timeout);
|
|
366
|
+
});
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
</script>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import KvImpactDashboardHeader from '../KvImpactDashboardHeader.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'KvImpactDashboardHeader',
|
|
5
|
+
component: KvImpactDashboardHeader,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const story = (args) => {
|
|
9
|
+
const template = (_args, { argTypes }) => ({
|
|
10
|
+
props: Object.keys(argTypes),
|
|
11
|
+
components: { KvImpactDashboardHeader },
|
|
12
|
+
template: `
|
|
13
|
+
<div class="tw-bg-secondary tw-pb-7">
|
|
14
|
+
<kv-impact-dashboard-header />
|
|
15
|
+
</div>
|
|
16
|
+
`,
|
|
17
|
+
});
|
|
18
|
+
template.args = args;
|
|
19
|
+
return template;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const Default = story();
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import KvMap from '../KvMap.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'KvMap',
|
|
5
|
+
component: KvMap,
|
|
6
|
+
args: {
|
|
7
|
+
autoZoomDelay: 1000,
|
|
8
|
+
height: null,
|
|
9
|
+
initialZoom: null,
|
|
10
|
+
lat: 37.700091,
|
|
11
|
+
long: -123.013243,
|
|
12
|
+
mapId: 0,
|
|
13
|
+
useLeaflet: false,
|
|
14
|
+
width: null,
|
|
15
|
+
zoomLevel: 4,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const Template = (args, { argTypes }) => ({
|
|
20
|
+
props: Object.keys(argTypes),
|
|
21
|
+
components: { KvMap },
|
|
22
|
+
template: `<kv-map
|
|
23
|
+
class="tw-rounded tw-overflow-hidden"
|
|
24
|
+
:auto-zoom-delay="autoZoomDelay"
|
|
25
|
+
:height="height"
|
|
26
|
+
:lat="lat"
|
|
27
|
+
:long="long"
|
|
28
|
+
:initial-zoom="initialZoom"
|
|
29
|
+
:map-id="mapId"
|
|
30
|
+
:use-leaflet="useLeaflet"
|
|
31
|
+
:width="width"
|
|
32
|
+
:zoom-level="zoomLevel"
|
|
33
|
+
/>`,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const Default = Template.bind({});
|
|
37
|
+
Default.args = {
|
|
38
|
+
initialZoom: null,
|
|
39
|
+
mapId: 1,
|
|
40
|
+
zoomLevel: 14,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const AutoZoom = Template.bind({});
|
|
44
|
+
AutoZoom.args = {
|
|
45
|
+
initialZoom: 1,
|
|
46
|
+
lat: -0.023559,
|
|
47
|
+
long: 37.906193,
|
|
48
|
+
mapId: 2,
|
|
49
|
+
zoomLevel: 4,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const FixedDimensions = Template.bind({});
|
|
53
|
+
FixedDimensions.args = {
|
|
54
|
+
initialZoom: null,
|
|
55
|
+
height: 250,
|
|
56
|
+
mapId: 3,
|
|
57
|
+
width: 250,
|
|
58
|
+
zoomLevel: 14,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const Leaflet = Template.bind({});
|
|
62
|
+
Leaflet.args = {
|
|
63
|
+
initialZoom: null,
|
|
64
|
+
lat: -0.023559,
|
|
65
|
+
long: 37.906193,
|
|
66
|
+
mapId: 4,
|
|
67
|
+
useLeaflet: true,
|
|
68
|
+
zoomLevel: 6,
|
|
69
|
+
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
<!-- eslint-disable max-len -->
|
|
2
|
-
<template>
|
|
3
|
-
<nav class="tw-bg-primary">
|
|
4
|
-
<div
|
|
5
|
-
class="header__full tw-grid xl:tw-gap-x-4 tw-items-center tw-mx-auto tw-px-2.5 md:tw-px-4 lg:tw-px-8"
|
|
6
|
-
style="height: 96px; max-width: 1200px;"
|
|
7
|
-
>
|
|
8
|
-
<div class="header__full__logo">
|
|
9
|
-
<!-- kivaPartner logo SVG -->
|
|
10
|
-
<svg
|
|
11
|
-
width="163"
|
|
12
|
-
height="48"
|
|
13
|
-
viewBox="0 0 55 24"
|
|
14
|
-
fill="none"
|
|
15
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
16
|
-
>
|
|
17
|
-
<path
|
|
18
|
-
d="M4.56965 0.399536H0V23.1675H4.57195V0.399536H4.56965ZM16.5793 23.1675H21.1513V7.69252H16.5793V23.1675ZM28.2721 23.1675H33.533L38.7938 7.69252H34.2219C34.2219 7.69252 31.7786 16.083 31.0346 18.7523H30.9818C30.2378 16.083 27.7394 7.69252 27.7394 7.69252H22.9034L28.2721 23.1675ZM54.7371 7.69252H50.3259V9.81649C49.5819 8.18284 47.8367 7.25719 45.7539 7.25719C42.0362 7.25719 39.0579 10.3618 39.0579 15.43C39.0579 20.4982 41.9283 23.6005 45.5404 23.6005C48.0938 23.6005 49.5796 22.3472 50.3764 20.9312V23.1675H54.7876L54.7371 7.69252ZM50.2202 15.8103C50.2202 18.6446 48.521 20.0056 46.8194 20.0056C44.9594 20.0056 43.7378 18.0443 43.7378 15.4231C43.7378 12.802 45.0122 10.8407 46.9801 10.8407C48.5738 10.8407 50.2202 12.2017 50.2202 15.0359V15.8103ZM5.73847 15.0474C13.0729 15.0474 14.7744 8.78314 14.7744 7.69252H14.1361C6.80166 7.69252 5.10239 13.959 5.10239 15.0474H5.73847ZM5.10239 15.595C5.10239 16.7406 6.37684 23.1148 14.2417 23.1148H14.8801C14.8801 21.9692 13.6056 15.595 5.73847 15.595H5.10239ZM21.6358 3.45145C21.6358 1.97819 20.5198 0.727182 19.0846 0.727182H18.9239C18.2242 0.7087 17.5458 0.968118 17.0377 1.44844C16.5296 1.92875 16.2334 2.59068 16.2142 3.28878V3.45145C16.2142 4.92471 17.3302 6.17572 18.7654 6.17572H18.9239C19.6239 6.19482 20.3029 5.93568 20.8115 5.4553C21.3201 4.97492 21.6166 4.31264 21.6358 3.61413V3.45145Z"
|
|
19
|
-
fill="#2AA967"
|
|
20
|
-
/>
|
|
21
|
-
</svg>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div class="header__full__right">
|
|
25
|
-
<slot></slot>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</nav>
|
|
29
|
-
</template>
|
|
30
|
-
|
|
31
|
-
<style scoped>
|
|
32
|
-
.header__full {
|
|
33
|
-
grid-template-areas: 'logo right';
|
|
34
|
-
grid-template-columns: 1fr auto;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.header__full__logo {
|
|
38
|
-
grid-area: logo;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.header__full__right {
|
|
42
|
-
grid-area: right;
|
|
43
|
-
}
|
|
44
|
-
</style>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import KvKivaPartnerHeader from '../KvKivaPartnerHeader.vue';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
title: 'KvKivaPartnerHeader',
|
|
5
|
-
component: KvKivaPartnerHeader,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const story = (args) => {
|
|
9
|
-
const template = (_args, { argTypes }) => ({
|
|
10
|
-
props: Object.keys(argTypes),
|
|
11
|
-
components: { KvKivaPartnerHeader },
|
|
12
|
-
template: `
|
|
13
|
-
<kv-kiva-partner-header />
|
|
14
|
-
`,
|
|
15
|
-
});
|
|
16
|
-
template.args = args;
|
|
17
|
-
return template;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const Default = story();
|