@icij/murmur-next 4.0.1 → 4.0.4
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/lib/components/AccordionStep.vue +53 -42
- package/lib/components/AccordionWrapper.vue +25 -24
- package/lib/components/ActiveTextTruncate.vue +44 -22
- package/lib/components/AdvancedLinkForm.vue +96 -46
- package/lib/components/Brand.vue +30 -23
- package/lib/components/BrandExpansion.vue +12 -3
- package/lib/components/ConfirmButton.vue +30 -26
- package/lib/components/ContentPlaceholder.vue +11 -7
- package/lib/components/CustomPagination.vue +50 -32
- package/lib/components/DigitsInput.vue +64 -60
- package/lib/components/DonateForm.vue +112 -83
- package/lib/components/EmbedForm.vue +37 -21
- package/lib/components/EmbeddableFooter.vue +14 -10
- package/lib/components/FollowUsPopover.vue +42 -40
- package/lib/components/GenericFooter.vue +98 -23
- package/lib/components/GenericHeader.vue +66 -29
- package/lib/components/HapticCopy.vue +41 -29
- package/lib/components/ImddbHeader.vue +113 -92
- package/lib/components/OrdinalLegend.vue +43 -20
- package/lib/components/RangePicker.vue +63 -42
- package/lib/components/ResponsiveIframe.vue +9 -2
- package/lib/components/ScaleLegend.vue +56 -18
- package/lib/components/SecretInput.vue +7 -8
- package/lib/components/SelectableDropdown.vue +120 -74
- package/lib/components/SharingOptions.vue +93 -36
- package/lib/components/SharingOptionsLink.vue +11 -5
- package/lib/components/SignUpForm.vue +44 -23
- package/lib/components/SlideUpDown.vue +7 -2
- package/lib/components/TexturedDeck.vue +24 -14
- package/lib/components/TinyPagination.vue +35 -22
- package/lib/composables/chart.ts +174 -157
- package/lib/composables/resizeObserver.ts +29 -29
- package/lib/composables/sendEmail.ts +53 -42
- package/lib/config.default.ts +17 -10
- package/lib/config.ts +34 -27
- package/lib/datavisualisations/BarChart.vue +48 -42
- package/lib/datavisualisations/ColumnChart.vue +133 -89
- package/lib/datavisualisations/LineChart.vue +79 -57
- package/lib/datavisualisations/StackedBarChart.vue +116 -68
- package/lib/datavisualisations/StackedColumnChart.vue +196 -115
- package/lib/enums.ts +25 -15
- package/lib/i18n.ts +3 -3
- package/lib/keys.ts +2 -2
- package/lib/main.ts +14 -10
- package/lib/maps/ChoroplethMap.vue +299 -160
- package/lib/maps/ChoroplethMapAnnotation.vue +29 -18
- package/lib/maps/SymbolMap.vue +194 -123
- package/lib/shims-bootstrap-vue.d.ts +1 -1
- package/lib/shims-vue.d.ts +3 -3
- package/lib/styles/functions.scss +10 -6
- package/lib/styles/lib.scss +2 -4
- package/lib/styles/mixins.scss +8 -8
- package/lib/styles/utilities.scss +1 -1
- package/lib/styles/variables.scss +24 -18
- package/lib/types.ts +26 -10
- package/lib/utils/animation.ts +4 -4
- package/lib/utils/assets.ts +31 -28
- package/lib/utils/clipboard.ts +16 -10
- package/lib/utils/iframe-resizer.ts +18 -13
- package/lib/utils/placeholder.ts +54 -23
- package/lib/utils/placeholderTypes.ts +3 -3
- package/package.json +7 -2
|
@@ -1,55 +1,46 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
<component
|
|
3
|
+
:is="rootElement"
|
|
4
|
+
id="imddb-header"
|
|
5
|
+
data-turbolinks-permanent
|
|
6
|
+
class="navbar navbar-expand-lg imddb-header"
|
|
7
|
+
:offset="100"
|
|
8
|
+
:z-index="1020"
|
|
9
|
+
:on-unpin="closeFollowUsPopover"
|
|
10
|
+
:class="{ 'headroom--frozen': !collapseNavbar }"
|
|
11
|
+
:style="{ position: position }"
|
|
12
|
+
>
|
|
13
|
+
<!-- @slot Redefines brand -->
|
|
14
|
+
<slot name="brand">
|
|
15
|
+
<a :href="homeUrl" class="navbar-brand imddb-header__brand">
|
|
16
|
+
<img
|
|
17
|
+
alt="ICIJ logo"
|
|
18
|
+
class="me-3"
|
|
19
|
+
height="25"
|
|
20
|
+
src="../assets/images/icij@2x.png"
|
|
21
|
+
/>
|
|
22
|
+
{{ project }}
|
|
23
|
+
</a>
|
|
24
|
+
</slot>
|
|
25
|
+
<button
|
|
26
|
+
class="navbar-toggler"
|
|
27
|
+
type="button"
|
|
28
|
+
aria-label="Toggle navigation"
|
|
29
|
+
@click="toggleNavbar"
|
|
12
30
|
>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<button class="navbar-toggler" type="button" aria-label="Toggle navigation" @click="toggleNavbar">
|
|
21
|
-
<span class="navbar-toggler-icon" />
|
|
22
|
-
</button>
|
|
23
|
-
<div class="navbar-collapse" :class="{ collapse: collapseNavbar }">
|
|
24
|
-
<div class="imddb-header__site-switch me-auto">
|
|
25
|
-
<!-- @slot Redefines the main navbar block (containing the dropdown) -->
|
|
26
|
-
<slot name="navbar">
|
|
27
|
-
<ul class="navbar-nav">
|
|
28
|
-
<b-nav-item-dropdown @show="hidePopover">
|
|
29
|
-
<template v-slot:button-content>
|
|
30
|
-
{{ title }}
|
|
31
|
-
</template>
|
|
32
|
-
<b-dropdown-item
|
|
33
|
-
v-for="(item, $index) in dropdownItems"
|
|
34
|
-
v-bind="{ active: !!item.active }"
|
|
35
|
-
:key="$index"
|
|
36
|
-
:href="item.href"
|
|
37
|
-
>
|
|
38
|
-
{{ item.label }}
|
|
39
|
-
</b-dropdown-item>
|
|
40
|
-
</b-nav-item-dropdown>
|
|
41
|
-
</ul>
|
|
42
|
-
</slot>
|
|
43
|
-
</div>
|
|
44
|
-
<ul class="navbar-nav">
|
|
45
|
-
<li v-if="hasLanguagesDropdown" class="nav-item">
|
|
31
|
+
<span class="navbar-toggler-icon" />
|
|
32
|
+
</button>
|
|
33
|
+
<div class="navbar-collapse" :class="{ collapse: collapseNavbar }">
|
|
34
|
+
<div class="imddb-header__site-switch me-auto">
|
|
35
|
+
<!-- @slot Redefines the main navbar block (containing the dropdown) -->
|
|
36
|
+
<slot name="navbar">
|
|
37
|
+
<ul class="navbar-nav">
|
|
46
38
|
<b-nav-item-dropdown @show="hidePopover">
|
|
47
39
|
<template v-slot:button-content>
|
|
48
|
-
|
|
49
|
-
{{ currentLanguage }}
|
|
40
|
+
{{ title }}
|
|
50
41
|
</template>
|
|
51
42
|
<b-dropdown-item
|
|
52
|
-
v-for="(item, $index) in
|
|
43
|
+
v-for="(item, $index) in dropdownItems"
|
|
53
44
|
v-bind="{ active: !!item.active }"
|
|
54
45
|
:key="$index"
|
|
55
46
|
:href="item.href"
|
|
@@ -57,37 +48,62 @@
|
|
|
57
48
|
{{ item.label }}
|
|
58
49
|
</b-dropdown-item>
|
|
59
50
|
</b-nav-item-dropdown>
|
|
60
|
-
</
|
|
61
|
-
|
|
62
|
-
<a href="https://www.icij.org/leak/" target="_blank" class="nav-link">
|
|
63
|
-
{{ t('imddb-header.navbar.leak') }}
|
|
64
|
-
</a>
|
|
65
|
-
</li>
|
|
66
|
-
<li class="nav-item me-lg-3">
|
|
67
|
-
<slot name="donate-link">
|
|
68
|
-
<a target="_blank" :href="donateUrl" class="nav-link">
|
|
69
|
-
{{ t('imddb-header.navbar.support') }}
|
|
70
|
-
</a>
|
|
71
|
-
</slot>
|
|
72
|
-
</li>
|
|
73
|
-
<li class="nav-item">
|
|
74
|
-
<button id="follow-icij" class="btn btn-primary btn-block fw-bold" @mouseenter="showFollowUsPopover=true">
|
|
75
|
-
{{ t('imddb-header.navbar.follow') }}
|
|
76
|
-
</button>
|
|
77
|
-
<b-popover
|
|
78
|
-
v-model="showFollowUsPopover"
|
|
79
|
-
target="follow-icij"
|
|
80
|
-
ref="followUsPopover"
|
|
81
|
-
placement="bottom-start"
|
|
82
|
-
click
|
|
83
|
-
|
|
84
|
-
>
|
|
85
|
-
<follow-us-popover @update:close="closeFollowUsPopover" @keydown.esc="closeFollowUsPopover" />
|
|
86
|
-
</b-popover>
|
|
87
|
-
</li>
|
|
88
|
-
</ul>
|
|
51
|
+
</ul>
|
|
52
|
+
</slot>
|
|
89
53
|
</div>
|
|
90
|
-
|
|
54
|
+
<ul class="navbar-nav">
|
|
55
|
+
<li v-if="hasLanguagesDropdown" class="nav-item">
|
|
56
|
+
<b-nav-item-dropdown @show="hidePopover">
|
|
57
|
+
<template v-slot:button-content>
|
|
58
|
+
<fa icon="globe" />
|
|
59
|
+
{{ currentLanguage }}
|
|
60
|
+
</template>
|
|
61
|
+
<b-dropdown-item
|
|
62
|
+
v-for="(item, $index) in languages"
|
|
63
|
+
v-bind="{ active: !!item.active }"
|
|
64
|
+
:key="$index"
|
|
65
|
+
:href="item.href"
|
|
66
|
+
>
|
|
67
|
+
{{ item.label }}
|
|
68
|
+
</b-dropdown-item>
|
|
69
|
+
</b-nav-item-dropdown>
|
|
70
|
+
</li>
|
|
71
|
+
<li class="nav-item">
|
|
72
|
+
<a href="https://www.icij.org/leak/" target="_blank" class="nav-link">
|
|
73
|
+
{{ t('imddb-header.navbar.leak') }}
|
|
74
|
+
</a>
|
|
75
|
+
</li>
|
|
76
|
+
<li class="nav-item me-lg-3">
|
|
77
|
+
<slot name="donate-link">
|
|
78
|
+
<a target="_blank" :href="donateUrl" class="nav-link">
|
|
79
|
+
{{ t('imddb-header.navbar.support') }}
|
|
80
|
+
</a>
|
|
81
|
+
</slot>
|
|
82
|
+
</li>
|
|
83
|
+
<li class="nav-item">
|
|
84
|
+
<button
|
|
85
|
+
id="follow-icij"
|
|
86
|
+
class="btn btn-primary btn-block fw-bold"
|
|
87
|
+
@mouseenter="showFollowUsPopover = true"
|
|
88
|
+
>
|
|
89
|
+
{{ t('imddb-header.navbar.follow') }}
|
|
90
|
+
</button>
|
|
91
|
+
<b-popover
|
|
92
|
+
v-model="showFollowUsPopover"
|
|
93
|
+
target="follow-icij"
|
|
94
|
+
ref="followUsPopover"
|
|
95
|
+
placement="bottom-start"
|
|
96
|
+
click
|
|
97
|
+
>
|
|
98
|
+
<follow-us-popover
|
|
99
|
+
@update:close="closeFollowUsPopover"
|
|
100
|
+
@keydown.esc="closeFollowUsPopover"
|
|
101
|
+
/>
|
|
102
|
+
</b-popover>
|
|
103
|
+
</li>
|
|
104
|
+
</ul>
|
|
105
|
+
</div>
|
|
106
|
+
</component>
|
|
91
107
|
</template>
|
|
92
108
|
|
|
93
109
|
<script lang="ts">
|
|
@@ -109,8 +125,12 @@ import {
|
|
|
109
125
|
onBeforeMount
|
|
110
126
|
} from 'vue'
|
|
111
127
|
import { useI18n } from 'vue-i18n'
|
|
112
|
-
import {
|
|
113
|
-
|
|
128
|
+
import {
|
|
129
|
+
BDropdownItem,
|
|
130
|
+
BModal,
|
|
131
|
+
BNavItemDropdown,
|
|
132
|
+
BPopover
|
|
133
|
+
} from 'bootstrap-vue-next'
|
|
114
134
|
|
|
115
135
|
type CssPosition = 'absolute' | 'relative' | 'fixed' | 'static'
|
|
116
136
|
type ImddHeaderItem = { label: string; href: string; active: boolean }
|
|
@@ -183,39 +203,41 @@ export default defineComponent({
|
|
|
183
203
|
default: () => config.get('app.donate-url')
|
|
184
204
|
}
|
|
185
205
|
},
|
|
186
|
-
setup(props){
|
|
187
|
-
const { t }= useI18n()
|
|
188
|
-
const followUsPopover = ref<ComponentPublicInstance<
|
|
206
|
+
setup(props) {
|
|
207
|
+
const { t } = useI18n()
|
|
208
|
+
const followUsPopover = ref<ComponentPublicInstance<
|
|
209
|
+
typeof BPopover
|
|
210
|
+
> | null>(null)
|
|
189
211
|
const showFollowUsPopover = ref(false)
|
|
190
212
|
const collapseNavbar = ref(true)
|
|
191
213
|
const languages = ref<ImddHeaderItem[]>([])
|
|
192
|
-
const root = ref<ComponentPublicInstance|null>(null)
|
|
193
|
-
const rootElement = computed((): string=> {
|
|
214
|
+
const root = ref<ComponentPublicInstance | null>(null)
|
|
215
|
+
const rootElement = computed((): string => {
|
|
194
216
|
return props.noHeadroom ? 'div' : 'headroom'
|
|
195
217
|
})
|
|
196
|
-
const hasLanguagesDropdown = computed((): boolean=> {
|
|
218
|
+
const hasLanguagesDropdown = computed((): boolean => {
|
|
197
219
|
return !!languages.value?.length
|
|
198
220
|
})
|
|
199
|
-
const currentLanguage = computed((): string=> {
|
|
221
|
+
const currentLanguage = computed((): string => {
|
|
200
222
|
return get(find(languages.value, { active: true }), 'label', 'Language')
|
|
201
223
|
})
|
|
202
|
-
onBeforeMount(()=>{
|
|
224
|
+
onBeforeMount(() => {
|
|
203
225
|
library.add(faGlobe)
|
|
204
226
|
})
|
|
205
|
-
onMounted(()=>{
|
|
227
|
+
onMounted(() => {
|
|
206
228
|
languages.value = config.get('imddb-header.languages.items')
|
|
207
229
|
})
|
|
208
230
|
function closeFollowUsPopover() {
|
|
209
|
-
if(followUsPopover.value?.hide){
|
|
231
|
+
if (followUsPopover.value?.hide) {
|
|
210
232
|
followUsPopover.value?.hide(new Event('forceHide'))
|
|
211
233
|
}
|
|
212
|
-
showFollowUsPopover.value=false
|
|
234
|
+
showFollowUsPopover.value = false
|
|
213
235
|
}
|
|
214
|
-
function hidePopover(){
|
|
236
|
+
function hidePopover() {
|
|
215
237
|
root.value?.$emit('bv::hide::popover')
|
|
216
238
|
closeFollowUsPopover()
|
|
217
239
|
}
|
|
218
|
-
function hideDropdown(){
|
|
240
|
+
function hideDropdown() {
|
|
219
241
|
root.value?.$emit('bv::hide::dropdown')
|
|
220
242
|
}
|
|
221
243
|
function toggleNavbar(): void {
|
|
@@ -255,7 +277,6 @@ export default defineComponent({
|
|
|
255
277
|
display: flex;
|
|
256
278
|
padding: 0px;
|
|
257
279
|
|
|
258
|
-
|
|
259
280
|
.popover {
|
|
260
281
|
width: 100%;
|
|
261
282
|
}
|
|
@@ -33,34 +33,40 @@ export default defineComponent({
|
|
|
33
33
|
default: null
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
-
emits:['update','update:highlight'],
|
|
37
|
-
setup(props,{emit}){
|
|
38
|
-
const markerBoundingClientRect = computed((): DOMRect | undefined=> {
|
|
39
|
-
const svg = d3
|
|
36
|
+
emits: ['update', 'update:highlight'],
|
|
37
|
+
setup(props, { emit }) {
|
|
38
|
+
const markerBoundingClientRect = computed((): DOMRect | undefined => {
|
|
39
|
+
const svg = d3
|
|
40
|
+
.select('body')
|
|
41
|
+
.append('svg')
|
|
42
|
+
.attr('width', 2046)
|
|
43
|
+
.attr('height', 2046)
|
|
40
44
|
const marker = svg.append('path').attr('d', markerPathFunction())
|
|
41
45
|
const rect: DOMRect | undefined = marker.node()?.getBoundingClientRect()
|
|
42
46
|
svg.remove()
|
|
43
47
|
return rect
|
|
44
48
|
})
|
|
45
49
|
|
|
46
|
-
const markerViewbox = computed(()=> {
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
const markerViewbox = computed(() => {
|
|
51
|
+
const { width, height } = markerBoundingClientRect.value ?? {
|
|
52
|
+
width: 0,
|
|
53
|
+
height: 0
|
|
54
|
+
}
|
|
55
|
+
return `0 0 ${width} ${height}`
|
|
49
56
|
})
|
|
50
|
-
const classList = computed(()=> {
|
|
57
|
+
const classList = computed(() => {
|
|
51
58
|
return {
|
|
52
59
|
'ordinal-legend--horizontal': props.horizontal,
|
|
53
60
|
'ordinal-legend--has-highlight': props.highlight !== null,
|
|
54
61
|
'ordinal-legend--has-value': props.value !== null
|
|
55
62
|
}
|
|
56
63
|
})
|
|
57
|
-
const dataWithIds = computed(()=> {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
64
|
+
const dataWithIds = computed(() => {
|
|
65
|
+
return props.data.map((d: any): { [key: string]: string } => {
|
|
66
|
+
const id = uniqueId()
|
|
67
|
+
return { [props.categoryObjectsPath]: id, ...d }
|
|
68
|
+
})
|
|
69
|
+
})
|
|
64
70
|
function itemClassList(d: { [key: string]: string }) {
|
|
65
71
|
const id = d[props.categoryObjectsPath]
|
|
66
72
|
return {
|
|
@@ -70,7 +76,9 @@ export default defineComponent({
|
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
function markerPathFunction(d?: Datum): string {
|
|
73
|
-
return isFunction(props.markerPath) && d
|
|
79
|
+
return isFunction(props.markerPath) && d
|
|
80
|
+
? props.markerPath(d)
|
|
81
|
+
: props.markerPath
|
|
74
82
|
}
|
|
75
83
|
function update(d: Datum) {
|
|
76
84
|
/**
|
|
@@ -102,12 +110,25 @@ export default defineComponent({
|
|
|
102
110
|
|
|
103
111
|
<template>
|
|
104
112
|
<ul class="ordinal-legend list-unstyled" :class="classList">
|
|
105
|
-
<li
|
|
106
|
-
|
|
113
|
+
<li
|
|
114
|
+
v-for="d in data"
|
|
115
|
+
:key="d[categoryObjectsPath]"
|
|
116
|
+
class="ordinal-legend__item"
|
|
117
|
+
:class="itemClassList(d)"
|
|
118
|
+
>
|
|
119
|
+
<a
|
|
120
|
+
@click="update(d)"
|
|
121
|
+
@mouseover="updateHighlight(d)"
|
|
122
|
+
@mouseleave="updateHighlight()"
|
|
123
|
+
>
|
|
107
124
|
<span class="ordinal-legend__item__marker me-1">
|
|
108
125
|
<slot name="marker" :marker="{ path: d.path, color: d.color }">
|
|
109
126
|
<svg :viewBox="markerViewbox">
|
|
110
|
-
<path
|
|
127
|
+
<path
|
|
128
|
+
:d="markerPathFunction(d)"
|
|
129
|
+
:fill="d.color"
|
|
130
|
+
class="ordinal-legend__item__marker__path"
|
|
131
|
+
/>
|
|
111
132
|
</svg>
|
|
112
133
|
</slot>
|
|
113
134
|
</span>
|
|
@@ -127,7 +148,9 @@ export default defineComponent({
|
|
|
127
148
|
.ordinal-legend {
|
|
128
149
|
$muted-item-opacity: 0.2;
|
|
129
150
|
$muted-item-filter: grayscale(30%) brightness(10%);
|
|
130
|
-
$muted-item-transition:
|
|
151
|
+
$muted-item-transition:
|
|
152
|
+
opacity 0.2s,
|
|
153
|
+
filter 0.2s;
|
|
131
154
|
|
|
132
155
|
font-size: $font-size-sm;
|
|
133
156
|
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
defineComponent,
|
|
4
|
+
VNode,
|
|
5
|
+
DirectiveBinding,
|
|
6
|
+
PropType,
|
|
7
|
+
ref,
|
|
8
|
+
watch,
|
|
9
|
+
computed,
|
|
10
|
+
onBeforeMount,
|
|
11
|
+
toRef
|
|
12
|
+
} from 'vue'
|
|
3
13
|
import { faGripLinesVertical } from '@fortawesome/free-solid-svg-icons/faGripLinesVertical'
|
|
4
14
|
import { clamp, get, has, invoke, round } from 'lodash'
|
|
5
15
|
|
|
@@ -17,14 +27,19 @@ export default defineComponent({
|
|
|
17
27
|
},
|
|
18
28
|
directives: {
|
|
19
29
|
draggable: {
|
|
20
|
-
|
|
21
30
|
mounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void {
|
|
22
31
|
let startX: number, initialClientX: number
|
|
23
32
|
const relative = binding.modifiers?.relative ?? false
|
|
24
33
|
|
|
25
34
|
// Emit an event to the parent component
|
|
26
|
-
function emitEvent({
|
|
27
|
-
|
|
35
|
+
function emitEvent({
|
|
36
|
+
name,
|
|
37
|
+
data = null
|
|
38
|
+
}: {
|
|
39
|
+
name: string
|
|
40
|
+
data?: any
|
|
41
|
+
}) {
|
|
42
|
+
vnode.el.dispatchEvent(new CustomEvent(name, { detail: data }))
|
|
28
43
|
//const handlers = get(vnode, 'data.on') ?? get(vnode, 'componentOptions.listeners')
|
|
29
44
|
/*if (has(handlers, name)) {
|
|
30
45
|
invoke(handlers, `${name}.fns`, data)
|
|
@@ -33,7 +48,10 @@ export default defineComponent({
|
|
|
33
48
|
|
|
34
49
|
// Handle the dragging of the element
|
|
35
50
|
function move(event: MouseEvent | TouchEvent) {
|
|
36
|
-
const clientX =
|
|
51
|
+
const clientX =
|
|
52
|
+
event instanceof MouseEvent
|
|
53
|
+
? event.clientX
|
|
54
|
+
: event.touches[0].clientX
|
|
37
55
|
const offset = relative ? el.offsetWidth : 0
|
|
38
56
|
const maxX = binding.instance?.rangeWidth() - offset
|
|
39
57
|
const data = clamp(startX + clientX - initialClientX, 0, maxX)
|
|
@@ -81,7 +99,7 @@ export default defineComponent({
|
|
|
81
99
|
* indicating the start and end of the range.
|
|
82
100
|
*/
|
|
83
101
|
range: {
|
|
84
|
-
type: Array as unknown as PropType<[number,number]>,
|
|
102
|
+
type: Array as unknown as PropType<[number, number]>,
|
|
85
103
|
required: true
|
|
86
104
|
},
|
|
87
105
|
/**
|
|
@@ -89,14 +107,14 @@ export default defineComponent({
|
|
|
89
107
|
*/
|
|
90
108
|
hover: {
|
|
91
109
|
type: Boolean as PropType<boolean>,
|
|
92
|
-
default:false
|
|
110
|
+
default: false
|
|
93
111
|
},
|
|
94
112
|
/**
|
|
95
113
|
* Offset from the left side of the component
|
|
96
114
|
* where the dragging for the start value begins.
|
|
97
115
|
*/
|
|
98
116
|
startOffset: {
|
|
99
|
-
type: [Number,String] as PropType<number|string>,
|
|
117
|
+
type: [Number, String] as PropType<number | string>,
|
|
100
118
|
default: 0
|
|
101
119
|
},
|
|
102
120
|
/**
|
|
@@ -104,7 +122,7 @@ export default defineComponent({
|
|
|
104
122
|
* the dragging for the end value ends.
|
|
105
123
|
*/
|
|
106
124
|
endOffset: {
|
|
107
|
-
type: [Number,String] as PropType<number|string>,
|
|
125
|
+
type: [Number, String] as PropType<number | string>,
|
|
108
126
|
default: 0
|
|
109
127
|
},
|
|
110
128
|
/**
|
|
@@ -147,19 +165,19 @@ export default defineComponent({
|
|
|
147
165
|
default: false
|
|
148
166
|
}
|
|
149
167
|
},
|
|
150
|
-
emits:['update:range'],
|
|
151
|
-
setup(props, {emit}){
|
|
152
|
-
onBeforeMount(()=>{
|
|
168
|
+
emits: ['update:range'],
|
|
169
|
+
setup(props, { emit }) {
|
|
170
|
+
onBeforeMount(() => {
|
|
153
171
|
library.add(faGripLinesVertical)
|
|
154
172
|
})
|
|
155
|
-
const rangePickerBounds = ref<HTMLElement|null>(null)
|
|
173
|
+
const rangePickerBounds = ref<HTMLElement | null>(null)
|
|
156
174
|
const start = toRef(props.range[0] ?? 0)
|
|
157
|
-
const end =
|
|
158
|
-
const moving =
|
|
159
|
-
const resizing =
|
|
175
|
+
const end = toRef(props.range[1] ?? 0)
|
|
176
|
+
const moving = ref(false)
|
|
177
|
+
const resizing = ref(false)
|
|
160
178
|
const disabled = computed(() => {
|
|
161
|
-
|
|
162
|
-
|
|
179
|
+
return props.range.length < 2
|
|
180
|
+
})
|
|
163
181
|
const overlayStyle = computed((): { left: string; right: string } => {
|
|
164
182
|
return {
|
|
165
183
|
left: `${start.value * 100}%`,
|
|
@@ -167,17 +185,17 @@ export default defineComponent({
|
|
|
167
185
|
}
|
|
168
186
|
})
|
|
169
187
|
const boundsStyle = computed((): { left: string; right: string } => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
188
|
+
return {
|
|
189
|
+
left: startOffsetWithUnit.value,
|
|
190
|
+
right: endOffsetWithUnit.value
|
|
191
|
+
}
|
|
192
|
+
})
|
|
175
193
|
|
|
176
194
|
const startOffsetWithUnit = computed((): string => {
|
|
177
195
|
return valueWithUnit(props.startOffset)
|
|
178
196
|
})
|
|
179
197
|
const endOffsetWithUnit = computed((): string => {
|
|
180
|
-
|
|
198
|
+
return valueWithUnit(props.endOffset)
|
|
181
199
|
})
|
|
182
200
|
|
|
183
201
|
const startBoundStyle = computed((): { left: string } => {
|
|
@@ -185,21 +203,20 @@ export default defineComponent({
|
|
|
185
203
|
})
|
|
186
204
|
|
|
187
205
|
const endBoundStyle = computed((): { left: string } => {
|
|
188
|
-
|
|
206
|
+
return { left: `${end.value * 100}%` }
|
|
189
207
|
})
|
|
190
208
|
const classList = computed((): { [key: string]: boolean } => {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
)
|
|
209
|
+
return {
|
|
210
|
+
[`range-picker--${props.variant}`]: !!props.variant,
|
|
211
|
+
'range-picker--hover': props.hover,
|
|
212
|
+
'range-picker--disabled': disabled.value,
|
|
213
|
+
'range-picker--rounded': props.rounded,
|
|
214
|
+
'range-picker--resizing': resizing.value,
|
|
215
|
+
'range-picker--moving': moving.value
|
|
216
|
+
}
|
|
217
|
+
})
|
|
201
218
|
|
|
202
|
-
function toggleMoving(value){
|
|
219
|
+
function toggleMoving(value) {
|
|
203
220
|
moving.value = value ?? !moving.value
|
|
204
221
|
}
|
|
205
222
|
function toggleResizing(value) {
|
|
@@ -211,8 +228,7 @@ export default defineComponent({
|
|
|
211
228
|
function rangeWidth(): number {
|
|
212
229
|
return rangePickerBounds.value?.getBoundingClientRect().width ?? 0
|
|
213
230
|
}
|
|
214
|
-
function dragStartBound({detail: dx}) {
|
|
215
|
-
|
|
231
|
+
function dragStartBound({ detail: dx }) {
|
|
216
232
|
const newValue = snapValue(dx / rangeWidth())
|
|
217
233
|
// Ensure start value doesn't get too close to end value
|
|
218
234
|
if (newValue < end.value - props.minDistance) {
|
|
@@ -225,7 +241,7 @@ export default defineComponent({
|
|
|
225
241
|
emit('update:range', [start.value, end.value])
|
|
226
242
|
}
|
|
227
243
|
}
|
|
228
|
-
function dragEndBound({detail: dx}) {
|
|
244
|
+
function dragEndBound({ detail: dx }) {
|
|
229
245
|
const newValue = snapValue(dx / rangeWidth())
|
|
230
246
|
// Ensure end value doesn't get too close to start value
|
|
231
247
|
if (newValue > start.value + props.minDistance) {
|
|
@@ -238,7 +254,7 @@ export default defineComponent({
|
|
|
238
254
|
emit('update:range', [start.value, end.value])
|
|
239
255
|
}
|
|
240
256
|
}
|
|
241
|
-
function dragBounds({detail:dx}) {
|
|
257
|
+
function dragBounds({ detail: dx }) {
|
|
242
258
|
const diff = snapValue(end.value - start.value)
|
|
243
259
|
const newValue = snapValue(dx / rangeWidth())
|
|
244
260
|
start.value = round(newValue, props.precision)
|
|
@@ -279,7 +295,12 @@ export default defineComponent({
|
|
|
279
295
|
<div class="range-picker__wrapper">
|
|
280
296
|
<slot />
|
|
281
297
|
</div>
|
|
282
|
-
<div
|
|
298
|
+
<div
|
|
299
|
+
v-show="!disabled"
|
|
300
|
+
ref="rangePickerBounds"
|
|
301
|
+
class="range-picker__bounds"
|
|
302
|
+
:style="boundsStyle"
|
|
303
|
+
>
|
|
283
304
|
<div
|
|
284
305
|
v-draggable.relative
|
|
285
306
|
class="range-picker__bounds__overlay"
|
|
@@ -346,7 +367,7 @@ export default defineComponent({
|
|
|
346
367
|
}
|
|
347
368
|
|
|
348
369
|
&--moving &__wrapper,
|
|
349
|
-
&--resizing &__wrapper{
|
|
370
|
+
&--resizing &__wrapper {
|
|
350
371
|
&,
|
|
351
372
|
* {
|
|
352
373
|
pointer-events: none;
|
|
@@ -10,7 +10,10 @@ import { injectAssets } from '@/utils/assets'
|
|
|
10
10
|
|
|
11
11
|
let iframeUniqueIdCounter = 0
|
|
12
12
|
type StartsWithIcijIframe = `icij-iframe-${string}`
|
|
13
|
-
type ResponsiveIframeData = {
|
|
13
|
+
type ResponsiveIframeData = {
|
|
14
|
+
iframeId: StartsWithIcijIframe
|
|
15
|
+
pymParent: null | Parent
|
|
16
|
+
}
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* ResponsiveIframe
|
|
@@ -42,7 +45,11 @@ export default defineComponent({
|
|
|
42
45
|
async mounted(): Promise<void> {
|
|
43
46
|
await injectAssets('https://pym.nprapps.org/pym.v1.min.js')
|
|
44
47
|
//@ts-ignore
|
|
45
|
-
this.pymParent = new window.pym.Parent(
|
|
48
|
+
this.pymParent = new window.pym.Parent(
|
|
49
|
+
this.iframeId,
|
|
50
|
+
this.url,
|
|
51
|
+
this.options
|
|
52
|
+
)
|
|
46
53
|
}
|
|
47
54
|
})
|
|
48
55
|
</script>
|