@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,16 +1,23 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import get from 'lodash/get'
|
|
3
3
|
import reduce from 'lodash/reduce'
|
|
4
|
-
import {faCode} from '@fortawesome/free-solid-svg-icons/faCode'
|
|
5
|
-
import {
|
|
4
|
+
import { faCode } from '@fortawesome/free-solid-svg-icons/faCode'
|
|
5
|
+
import {
|
|
6
|
+
computed,
|
|
7
|
+
CSSProperties,
|
|
8
|
+
defineComponent,
|
|
9
|
+
onBeforeMount,
|
|
10
|
+
PropType,
|
|
11
|
+
ref
|
|
12
|
+
} from 'vue'
|
|
6
13
|
|
|
7
|
-
import {default as Fa, library} from './Fa'
|
|
14
|
+
import { default as Fa, library } from './Fa'
|
|
8
15
|
|
|
9
16
|
import EmbedForm from '@/components/EmbedForm.vue'
|
|
10
17
|
import SharingOptionsLink from '@/components/SharingOptionsLink.vue'
|
|
11
18
|
import config from '@/config'
|
|
12
19
|
import IframeResizer from '@/utils/iframe-resizer'
|
|
13
|
-
import {BModal, useModal} from
|
|
20
|
+
import { BModal, useModal } from 'bootstrap-vue-next'
|
|
14
21
|
|
|
15
22
|
type MetaValuesMap = {
|
|
16
23
|
url: string
|
|
@@ -40,7 +47,9 @@ export default defineComponent({
|
|
|
40
47
|
*/
|
|
41
48
|
url: {
|
|
42
49
|
type: String,
|
|
43
|
-
default: () =>
|
|
50
|
+
default: () =>
|
|
51
|
+
config.get('sharing-options.url', null) ||
|
|
52
|
+
IframeResizer.deletePymParams()
|
|
44
53
|
},
|
|
45
54
|
/**
|
|
46
55
|
* URL to use specifically with the embed form
|
|
@@ -56,7 +65,10 @@ export default defineComponent({
|
|
|
56
65
|
direction: {
|
|
57
66
|
default: 'row',
|
|
58
67
|
validator(value: string) {
|
|
59
|
-
return
|
|
68
|
+
return (
|
|
69
|
+
['row', 'row-reverse', 'column', 'column-reverse'].indexOf(value) !==
|
|
70
|
+
-1
|
|
71
|
+
)
|
|
60
72
|
}
|
|
61
73
|
},
|
|
62
74
|
/**
|
|
@@ -102,13 +114,12 @@ export default defineComponent({
|
|
|
102
114
|
}
|
|
103
115
|
},
|
|
104
116
|
setup(props) {
|
|
105
|
-
|
|
106
117
|
onBeforeMount(() => {
|
|
107
118
|
library.add(faCode)
|
|
108
119
|
})
|
|
109
120
|
|
|
110
121
|
const embedForm = ref(null)
|
|
111
|
-
const {show} = useModal(
|
|
122
|
+
const { show } = useModal('embedForm')
|
|
112
123
|
const style = computed((): CSSProperties => {
|
|
113
124
|
return {
|
|
114
125
|
'flex-direction': props.direction
|
|
@@ -117,26 +128,44 @@ export default defineComponent({
|
|
|
117
128
|
|
|
118
129
|
const metaValues = computed((): MetaValuesMap => {
|
|
119
130
|
return {
|
|
120
|
-
url: props.url ??
|
|
131
|
+
url: props.url ?? '',
|
|
121
132
|
title: defaultValueFor('sharing-options.title'),
|
|
122
|
-
description: defaultValueFor(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
description: defaultValueFor(
|
|
134
|
+
'sharing-options.description',
|
|
135
|
+
'meta[name="description]'
|
|
136
|
+
),
|
|
137
|
+
facebook_title: defaultValueFor(
|
|
138
|
+
'sharing-options.facebook_title',
|
|
139
|
+
'meta[property="og:title"]'
|
|
140
|
+
),
|
|
141
|
+
facebook_description: defaultValueFor(
|
|
142
|
+
'sharing-options.description',
|
|
143
|
+
'meta[property="og:description"]'
|
|
144
|
+
),
|
|
145
|
+
facebook_media: defaultValueFor(
|
|
146
|
+
'sharing-options.media',
|
|
147
|
+
'meta[property="og:image"]'
|
|
148
|
+
),
|
|
149
|
+
twitter_media: defaultValueFor(
|
|
150
|
+
'sharing-options.media',
|
|
151
|
+
'meta[name="twitter:image"]'
|
|
152
|
+
),
|
|
153
|
+
twitter_user: defaultValueFor(
|
|
154
|
+
'sharing-options.twitter-user',
|
|
155
|
+
'meta[name="twitter:site"]'
|
|
156
|
+
)
|
|
128
157
|
}
|
|
129
158
|
})
|
|
130
159
|
|
|
131
160
|
function valuesFor(network: string): { [key: string]: string } {
|
|
132
161
|
const values = Object.assign(metaValues.value, props.values)
|
|
133
162
|
return reduce(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
163
|
+
props.valuesKeys,
|
|
164
|
+
(res: { [name: string]: string }, key) => {
|
|
165
|
+
res[key] = get(values, `${network}_${key}`, values[key])
|
|
166
|
+
return res
|
|
167
|
+
},
|
|
168
|
+
{}
|
|
140
169
|
)
|
|
141
170
|
}
|
|
142
171
|
|
|
@@ -144,7 +173,11 @@ export default defineComponent({
|
|
|
144
173
|
if (props.noMeta || !metaSelector) {
|
|
145
174
|
return config.get(key)
|
|
146
175
|
}
|
|
147
|
-
return get(
|
|
176
|
+
return get(
|
|
177
|
+
document.head.querySelector(metaSelector),
|
|
178
|
+
'content',
|
|
179
|
+
config.get(key)
|
|
180
|
+
)
|
|
148
181
|
}
|
|
149
182
|
|
|
150
183
|
return {
|
|
@@ -153,30 +186,54 @@ export default defineComponent({
|
|
|
153
186
|
embedForm,
|
|
154
187
|
valuesFor
|
|
155
188
|
}
|
|
156
|
-
|
|
157
|
-
},
|
|
189
|
+
}
|
|
158
190
|
})
|
|
159
191
|
</script>
|
|
160
192
|
|
|
161
193
|
<template>
|
|
162
194
|
<div :style="style" class="sharing-options">
|
|
163
|
-
<sharing-options-link
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
195
|
+
<sharing-options-link
|
|
196
|
+
class="sharing-options__link"
|
|
197
|
+
network="facebook"
|
|
198
|
+
v-bind="valuesFor('facebook')"
|
|
199
|
+
/>
|
|
200
|
+
<sharing-options-link
|
|
201
|
+
class="sharing-options__link"
|
|
202
|
+
network="twitter"
|
|
203
|
+
v-bind="valuesFor('twitter')"
|
|
204
|
+
/>
|
|
205
|
+
<sharing-options-link
|
|
206
|
+
class="sharing-options__link"
|
|
207
|
+
network="linkedin"
|
|
208
|
+
v-bind="valuesFor('linkedin')"
|
|
209
|
+
/>
|
|
210
|
+
<sharing-options-link
|
|
211
|
+
class="sharing-options__link"
|
|
212
|
+
network="email"
|
|
213
|
+
v-bind="valuesFor('email')"
|
|
214
|
+
/>
|
|
215
|
+
<div
|
|
216
|
+
v-show="!noEmbed"
|
|
217
|
+
class="sharing-options__link sharing-options__link--embed"
|
|
218
|
+
>
|
|
168
219
|
<a @click="show">
|
|
169
|
-
<fa icon="code"/>
|
|
220
|
+
<fa icon="code" />
|
|
170
221
|
<span class="sr-only">Embed</span>
|
|
171
222
|
</a>
|
|
172
223
|
</div>
|
|
173
|
-
<b-modal
|
|
224
|
+
<b-modal
|
|
225
|
+
id="embedForm"
|
|
226
|
+
ref="embedForm"
|
|
227
|
+
class="text-dark"
|
|
228
|
+
hide-footer
|
|
229
|
+
title="Embed on your website"
|
|
230
|
+
>
|
|
174
231
|
<embed-form
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
232
|
+
:min-height="iframeMinHeight"
|
|
233
|
+
:min-width="iframeMinWidth"
|
|
234
|
+
:url="embedUrl || url"
|
|
235
|
+
no-preview
|
|
236
|
+
no-title
|
|
180
237
|
/>
|
|
181
238
|
</b-modal>
|
|
182
239
|
</div>
|
|
@@ -7,7 +7,7 @@ import { faEnvelope } from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
|
|
7
7
|
import { faTwitter } from '@fortawesome/free-brands-svg-icons/faTwitter'
|
|
8
8
|
import { faFacebook } from '@fortawesome/free-brands-svg-icons/faFacebook'
|
|
9
9
|
import { faLinkedin } from '@fortawesome/free-brands-svg-icons/faLinkedin'
|
|
10
|
-
import { h, defineComponent, PropType, VNode} from 'vue'
|
|
10
|
+
import { h, defineComponent, PropType, VNode } from 'vue'
|
|
11
11
|
import { IconDefinition } from '@fortawesome/fontawesome-svg-core'
|
|
12
12
|
|
|
13
13
|
import Fa from './Fa'
|
|
@@ -221,12 +221,16 @@ export default defineComponent({
|
|
|
221
221
|
renderIcon(): void | VNode | null {
|
|
222
222
|
if (!this.noIcon) {
|
|
223
223
|
//@ts-ignore
|
|
224
|
-
return h(
|
|
224
|
+
return h(Fa, { icon: this.icon })
|
|
225
225
|
}
|
|
226
226
|
},
|
|
227
227
|
openPopup(): void {
|
|
228
228
|
// Create the popup
|
|
229
|
-
$popup.instance = $popup.parent?.open(
|
|
229
|
+
$popup.instance = $popup.parent?.open(
|
|
230
|
+
this.href,
|
|
231
|
+
'sharer',
|
|
232
|
+
this.popupParams
|
|
233
|
+
)
|
|
230
234
|
$popup.instance?.focus()
|
|
231
235
|
// Watch for popup closing
|
|
232
236
|
$popup.interval = setInterval(this.cleanExistingPopupInterval, 500)
|
|
@@ -252,8 +256,10 @@ export default defineComponent({
|
|
|
252
256
|
render(): void | VNode | null {
|
|
253
257
|
const click = this.hasPopup() ? preventDefault(this.click) : noop
|
|
254
258
|
const href = this.href
|
|
255
|
-
const children = this.$slots.default
|
|
256
|
-
|
|
259
|
+
const children = this.$slots.default
|
|
260
|
+
? this.$slots.default()
|
|
261
|
+
: [this.renderIcon(), h('span', { class: 'visually-hidden' }, this.name)]
|
|
262
|
+
return h(this.tag, { attrs: { href }, onClick: click }, children)
|
|
257
263
|
}
|
|
258
264
|
})
|
|
259
265
|
</script>
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<form
|
|
2
|
+
<form
|
|
3
|
+
class="sign-up-form"
|
|
4
|
+
:class="{ 'sign-up-form--horizontal': horizontal }"
|
|
5
|
+
@submit.prevent="subscribe"
|
|
6
|
+
>
|
|
3
7
|
<fieldset :disabled="frozen">
|
|
4
|
-
<label
|
|
8
|
+
<label
|
|
9
|
+
v-if="!noLabel"
|
|
10
|
+
class="text-uppercase text-muted fw-bold"
|
|
11
|
+
for="input-email"
|
|
12
|
+
>
|
|
5
13
|
{{ t('sign-up-form.label') }}
|
|
6
14
|
</label>
|
|
7
|
-
<div
|
|
15
|
+
<div
|
|
16
|
+
class="sign-up-form__fieldset__group"
|
|
17
|
+
:class="{ 'input-group': horizontal }"
|
|
18
|
+
>
|
|
8
19
|
<input
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
id="input-email"
|
|
21
|
+
v-model="email"
|
|
22
|
+
name="EMAIL"
|
|
23
|
+
type="email"
|
|
24
|
+
class="form-control"
|
|
25
|
+
:placeholder="t('sign-up-form.placeholder').toString()"
|
|
15
26
|
/>
|
|
16
|
-
<button
|
|
27
|
+
<button
|
|
28
|
+
class="sign-up-form__fieldset__group__addon btn text-uppercase fw-bold input-group-text"
|
|
29
|
+
:class="{ [variantColorClass]: true }"
|
|
30
|
+
type="submit"
|
|
31
|
+
>
|
|
17
32
|
{{ t('sign-up-form.submit') }}
|
|
18
33
|
</button>
|
|
19
34
|
</div>
|
|
@@ -32,12 +47,11 @@ import jsonp from 'jsonp'
|
|
|
32
47
|
import castArray from 'lodash/castArray'
|
|
33
48
|
import flatten from 'lodash/flatten'
|
|
34
49
|
import last from 'lodash/last'
|
|
35
|
-
import {computed, defineComponent, PropType, ref} from 'vue'
|
|
50
|
+
import { computed, defineComponent, PropType, ref } from 'vue'
|
|
36
51
|
|
|
37
52
|
import config from '../config'
|
|
38
|
-
import {useI18n} from
|
|
39
|
-
import {useSendEmail} from
|
|
40
|
-
|
|
53
|
+
import { useI18n } from 'vue-i18n'
|
|
54
|
+
import { useSendEmail } from '@/composables/sendEmail'
|
|
41
55
|
|
|
42
56
|
type SignUpFormData = {
|
|
43
57
|
email: string
|
|
@@ -51,7 +65,7 @@ type SignUpFormData = {
|
|
|
51
65
|
* SignUpForm
|
|
52
66
|
*/
|
|
53
67
|
export default defineComponent({
|
|
54
|
-
name: 'SignUpForm',
|
|
68
|
+
name: 'SignUpForm',
|
|
55
69
|
props: {
|
|
56
70
|
/**
|
|
57
71
|
* Mailchimp URL to send the data to.
|
|
@@ -108,24 +122,30 @@ name: 'SignUpForm',
|
|
|
108
122
|
default: 'primary'
|
|
109
123
|
}
|
|
110
124
|
},
|
|
111
|
-
setup(props){
|
|
112
|
-
const {t} = useI18n()
|
|
125
|
+
setup(props) {
|
|
126
|
+
const { t } = useI18n()
|
|
113
127
|
const email = ref('')
|
|
114
128
|
const frozen = ref(false)
|
|
115
129
|
const response = ref({})
|
|
116
130
|
const errorMessage = ref(null)
|
|
117
131
|
const successMessage = ref(null)
|
|
118
|
-
const {send} = useSendEmail(
|
|
132
|
+
const { send } = useSendEmail(
|
|
133
|
+
email,
|
|
134
|
+
props.action,
|
|
135
|
+
props.emailField,
|
|
136
|
+
props.tracker,
|
|
137
|
+
props.referrer,
|
|
138
|
+
props.defaultGroups
|
|
139
|
+
)
|
|
119
140
|
|
|
120
|
-
const variantColorClass = computed(()=> {
|
|
141
|
+
const variantColorClass = computed(() => {
|
|
121
142
|
return `btn-${props.variant}`
|
|
122
|
-
}
|
|
143
|
+
})
|
|
123
144
|
async function subscribe() {
|
|
124
145
|
resetMessages()
|
|
125
146
|
freeze()
|
|
126
147
|
// Send the data, catch the result no matter what and unfreeze the form
|
|
127
|
-
await send().then(done,done).finally(unfreeze)
|
|
128
|
-
|
|
148
|
+
await send().then(done, done).finally(unfreeze)
|
|
129
149
|
}
|
|
130
150
|
|
|
131
151
|
function done({ result, msg }: any): void {
|
|
@@ -134,7 +154,8 @@ name: 'SignUpForm',
|
|
|
134
154
|
successMessage.value = msg
|
|
135
155
|
} else {
|
|
136
156
|
// Mailchimp formats errors in list
|
|
137
|
-
errorMessage.value =
|
|
157
|
+
errorMessage.value =
|
|
158
|
+
last((msg || "Something's wrong").split('0 -')) ?? null
|
|
138
159
|
}
|
|
139
160
|
}
|
|
140
161
|
function resetMessages() {
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
import { defineComponent } from 'vue'
|
|
3
3
|
import type { CSSProperties } from 'vue'
|
|
4
4
|
|
|
5
|
-
type StyleTransition = Pick<
|
|
5
|
+
type StyleTransition = Pick<
|
|
6
|
+
CSSProperties,
|
|
7
|
+
'overflow' | 'transition-property' | 'transition-duration' | 'height'
|
|
8
|
+
>
|
|
6
9
|
const STATE = {
|
|
7
10
|
PRE: 'pre',
|
|
8
11
|
ACTIVE: 'active',
|
|
@@ -98,7 +101,9 @@ export default defineComponent({
|
|
|
98
101
|
await this.deferredNextTick()
|
|
99
102
|
this.mounted = true
|
|
100
103
|
await this.cleanLayout(null)
|
|
101
|
-
this.$container?.addEventListener('transitionend', (e) =>
|
|
104
|
+
this.$container?.addEventListener('transitionend', (e) =>
|
|
105
|
+
this.cleanLayout(e)
|
|
106
|
+
)
|
|
102
107
|
},
|
|
103
108
|
methods: {
|
|
104
109
|
async triggerSlide(): Promise<void> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { clamp } from 'lodash'
|
|
3
|
-
import {computed, defineComponent, PropType} from 'vue'
|
|
3
|
+
import { computed, defineComponent, PropType } from 'vue'
|
|
4
4
|
|
|
5
5
|
import { DeckTexture } from '@/enums'
|
|
6
6
|
import config from '@/config'
|
|
@@ -36,45 +36,50 @@ export default defineComponent({
|
|
|
36
36
|
*/
|
|
37
37
|
black: {
|
|
38
38
|
type: Boolean,
|
|
39
|
-
default:false
|
|
39
|
+
default: false
|
|
40
40
|
},
|
|
41
41
|
/**
|
|
42
42
|
* Host where to find the textures (without tailing slash)
|
|
43
43
|
*/
|
|
44
44
|
backgroundBaseUrl: {
|
|
45
45
|
type: String,
|
|
46
|
-
default: () =>
|
|
46
|
+
default: () =>
|
|
47
|
+
config.get('textured-deck.background-base-url', window.location.origin)
|
|
47
48
|
}
|
|
48
49
|
},
|
|
49
|
-
setup(props, {attrs}) {
|
|
50
|
-
const names = computed((): DeckTexture[] =>{
|
|
50
|
+
setup(props, { attrs }) {
|
|
51
|
+
const names = computed((): DeckTexture[] => {
|
|
51
52
|
return Object.values(DeckTexture)
|
|
52
53
|
})
|
|
53
|
-
const textureIndex = computed((): number =>{
|
|
54
|
+
const textureIndex = computed((): number => {
|
|
54
55
|
if (typeof props.modelValue !== 'number') {
|
|
55
|
-
return clamp(
|
|
56
|
+
return clamp(
|
|
57
|
+
names.value.indexOf(props.modelValue),
|
|
58
|
+
0,
|
|
59
|
+
names.value.length - 1
|
|
60
|
+
)
|
|
56
61
|
}
|
|
57
62
|
return props.modelValue
|
|
58
63
|
})
|
|
59
|
-
const textureName = computed((): string =>{
|
|
64
|
+
const textureName = computed((): string => {
|
|
60
65
|
return names.value[textureIndex.value]
|
|
61
66
|
})
|
|
62
|
-
const filename = computed((): string =>{
|
|
67
|
+
const filename = computed((): string => {
|
|
63
68
|
if (props.black) {
|
|
64
69
|
return `texture-${textureName.value}-black.jpg`
|
|
65
70
|
}
|
|
66
71
|
return `texture-${textureName.value}.jpg`
|
|
67
72
|
})
|
|
68
|
-
const backgroundUrl = computed((): string =>{
|
|
73
|
+
const backgroundUrl = computed((): string => {
|
|
69
74
|
return `${props.backgroundBaseUrl}/assets/img/${filename.value}`
|
|
70
75
|
})
|
|
71
|
-
const backgroundSize = computed((): string =>{
|
|
76
|
+
const backgroundSize = computed((): string => {
|
|
72
77
|
return props.size
|
|
73
78
|
})
|
|
74
|
-
const backgroundImage = computed((): string =>{
|
|
79
|
+
const backgroundImage = computed((): string => {
|
|
75
80
|
return `url("${backgroundUrl.value}")`
|
|
76
81
|
})
|
|
77
|
-
const inheritedProps = computed((): object =>{
|
|
82
|
+
const inheritedProps = computed((): object => {
|
|
78
83
|
return { ...attrs, ...props, tag: undefined }
|
|
79
84
|
})
|
|
80
85
|
return {
|
|
@@ -87,7 +92,12 @@ export default defineComponent({
|
|
|
87
92
|
</script>
|
|
88
93
|
|
|
89
94
|
<template>
|
|
90
|
-
<component
|
|
95
|
+
<component
|
|
96
|
+
:is="tag"
|
|
97
|
+
:style="{ backgroundSize, backgroundImage }"
|
|
98
|
+
v-bind="inheritedProps"
|
|
99
|
+
class="textured-deck"
|
|
100
|
+
>
|
|
91
101
|
<slot />
|
|
92
102
|
</component>
|
|
93
103
|
</template>
|
|
@@ -8,12 +8,18 @@
|
|
|
8
8
|
@click="applyPreviousPage"
|
|
9
9
|
>
|
|
10
10
|
<!-- @slot Previous button content -->
|
|
11
|
-
<slot
|
|
11
|
+
<slot
|
|
12
|
+
name="previous"
|
|
13
|
+
v-bind="{ modelValue, numberOfPages, hasPrevious, hasNext }"
|
|
14
|
+
>
|
|
12
15
|
<fa :icon="previousPageIcon" />
|
|
13
16
|
<span class="sr-only">{{ t('tiny-pagination.previous') }}</span>
|
|
14
17
|
</slot>
|
|
15
18
|
</b-button>
|
|
16
|
-
<form
|
|
19
|
+
<form
|
|
20
|
+
class="tiny-pagination__form form-inline"
|
|
21
|
+
@submit.prevent="applyPageForm"
|
|
22
|
+
>
|
|
17
23
|
<label v-show="!compact" class="tiny-pagination__form__label me-1 mb-0">
|
|
18
24
|
<!-- @slot Display page label -->
|
|
19
25
|
<slot name="page" v-bind="{ modelValue, numberOfPages }">
|
|
@@ -43,7 +49,10 @@
|
|
|
43
49
|
@click="applyNextPage"
|
|
44
50
|
>
|
|
45
51
|
<!-- @slot Next button content -->
|
|
46
|
-
<slot
|
|
52
|
+
<slot
|
|
53
|
+
name="next"
|
|
54
|
+
v-bind="{ modelValue, numberOfPages, hasPrevious, hasNext }"
|
|
55
|
+
>
|
|
47
56
|
<fa :icon="nextPageIcon" />
|
|
48
57
|
<span class="sr-only">{{ t('tiny-pagination.next') }}</span>
|
|
49
58
|
</slot>
|
|
@@ -53,8 +62,8 @@
|
|
|
53
62
|
|
|
54
63
|
<script lang="ts">
|
|
55
64
|
import { faAngleLeft, faAngleRight } from '@fortawesome/free-solid-svg-icons'
|
|
56
|
-
import { defineComponent, PropType, ref, computed,
|
|
57
|
-
import {useI18n} from
|
|
65
|
+
import { defineComponent, PropType, ref, computed, onBeforeMount } from 'vue'
|
|
66
|
+
import { useI18n } from 'vue-i18n'
|
|
58
67
|
|
|
59
68
|
import { library, default as Fa } from './Fa'
|
|
60
69
|
|
|
@@ -146,23 +155,22 @@ export default defineComponent({
|
|
|
146
155
|
type: Boolean
|
|
147
156
|
}
|
|
148
157
|
},
|
|
149
|
-
emits:['update:modelValue'],
|
|
150
|
-
setup(props,{emit}) {
|
|
151
|
-
|
|
152
|
-
onBeforeMount(()=> {
|
|
158
|
+
emits: ['update:modelValue'],
|
|
159
|
+
setup(props, { emit }) {
|
|
160
|
+
onBeforeMount(() => {
|
|
153
161
|
library.add(faAngleLeft, faAngleRight)
|
|
154
162
|
})
|
|
155
163
|
|
|
156
164
|
const { t } = useI18n()
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
const numberOfPages = computed((): number =>{
|
|
165
|
+
|
|
166
|
+
const numberOfPages = computed((): number => {
|
|
160
167
|
if (props.pages === null) {
|
|
161
168
|
return Math.ceil(props.totalRows / props.perPage)
|
|
162
169
|
}
|
|
163
170
|
return Number(props.pages)
|
|
164
171
|
})
|
|
165
|
-
|
|
172
|
+
|
|
173
|
+
const paginationClassList = computed((): object => {
|
|
166
174
|
return {
|
|
167
175
|
[`tiny-pagination--${props.size}`]: true,
|
|
168
176
|
[`tiny-pagination--no-nav`]: props.noNav,
|
|
@@ -170,24 +178,29 @@ export default defineComponent({
|
|
|
170
178
|
[`tiny-pagination--compact`]: props.compact
|
|
171
179
|
}
|
|
172
180
|
})
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
|
|
182
|
+
const hasPrevious = computed((): boolean => pageValue.value > 1)
|
|
183
|
+
const hasNext = computed(
|
|
184
|
+
(): boolean => pageValue.value < numberOfPages.value
|
|
185
|
+
)
|
|
186
|
+
const pageValue = computed(() => +props.modelValue)
|
|
187
|
+
|
|
188
|
+
const currentPageInput = ref<number | string>(pageValue.value)
|
|
189
|
+
|
|
179
190
|
function applyPageForm(): void {
|
|
180
191
|
if (!isNaN(currentPageInput.value as number)) {
|
|
181
192
|
emit('update:modelValue', +currentPageInput.value)
|
|
182
193
|
}
|
|
183
194
|
}
|
|
184
195
|
|
|
185
|
-
function
|
|
186
|
-
emit('update:modelValue', pageValue.value
|
|
196
|
+
function applyNextPage(): void {
|
|
197
|
+
emit('update:modelValue', pageValue.value + 1)
|
|
187
198
|
}
|
|
199
|
+
|
|
188
200
|
function applyPreviousPage(): void {
|
|
189
|
-
emit('update:modelValue', pageValue.value
|
|
201
|
+
emit('update:modelValue', pageValue.value - 1)
|
|
190
202
|
}
|
|
203
|
+
|
|
191
204
|
return {
|
|
192
205
|
t,
|
|
193
206
|
currentPageInput,
|