@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
package/lib/styles/lib.scss
CHANGED
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
@import './utilities';
|
|
6
6
|
@import 'bootstrap/scss/_mixins';
|
|
7
7
|
:root,
|
|
8
|
-
[data-bs-theme=
|
|
9
|
-
|
|
8
|
+
[data-bs-theme='light'] {
|
|
10
9
|
--input-bg: #{$bs-input-bg};
|
|
11
|
-
|
|
12
10
|
}
|
|
13
11
|
@if $enable-dark-mode {
|
|
14
12
|
@include color-mode(dark, true) {
|
|
@@ -16,4 +14,4 @@
|
|
|
16
14
|
--input-bg: #{$bs-input-bg-dark};
|
|
17
15
|
}
|
|
18
16
|
}
|
|
19
|
-
$input-bg:var(--input-bg);
|
|
17
|
+
$input-bg: var(--input-bg);
|
package/lib/styles/mixins.scss
CHANGED
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
@mixin animation($animation) {
|
|
17
|
-
-webkit-animation
|
|
18
|
-
-moz-animation
|
|
19
|
-
-o-animation
|
|
20
|
-
animation
|
|
17
|
+
-webkit-animation: $animation;
|
|
18
|
+
-moz-animation: $animation;
|
|
19
|
+
-o-animation: $animation;
|
|
20
|
+
animation: $animation;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
@mixin animation-delay-loop($from:0, $to:10, $delay: 300ms) {
|
|
23
|
+
@mixin animation-delay-loop($from: 0, $to: 10, $delay: 300ms) {
|
|
24
24
|
@for $i from $from through $to {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
&:nth-child(#{$i}) {
|
|
26
|
+
animation-delay: $i * $delay;
|
|
27
|
+
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$white:
|
|
1
|
+
$white: #fff !default;
|
|
2
2
|
$gray-100: #f8f8f8 !default;
|
|
3
3
|
$gray-200: #e9e9e9 !default;
|
|
4
4
|
$gray-300: #dedede !default;
|
|
@@ -8,30 +8,30 @@ $gray-600: #696969 !default; // Brand color
|
|
|
8
8
|
$gray-700: #494949 !default;
|
|
9
9
|
$gray-800: #3c3c3c !default; // Brand color
|
|
10
10
|
$gray-900: #212121 !default;
|
|
11
|
-
$black:
|
|
11
|
+
$black: #000 !default;
|
|
12
12
|
|
|
13
|
-
$primary: #ff0000 !default;
|
|
13
|
+
$primary: #ff0000 !default; // Brand color
|
|
14
14
|
$secondary: $gray-500 !default;
|
|
15
|
-
$danger: #
|
|
16
|
-
$success: #
|
|
17
|
-
$info: #
|
|
18
|
-
$warning: #
|
|
15
|
+
$danger: #8b0707 !default; // Brand color
|
|
16
|
+
$success: #46ec4e !default;
|
|
17
|
+
$info: #0000ff !default;
|
|
18
|
+
$warning: #ffba00 !default;
|
|
19
19
|
$light: $gray-200 !default;
|
|
20
20
|
$dark: #000 !default;
|
|
21
21
|
|
|
22
22
|
$brand-grays: () !default;
|
|
23
23
|
$brand-grays: map-merge(
|
|
24
24
|
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
'gray-lighter': $gray-400,
|
|
26
|
+
'gray-light': $gray-500,
|
|
27
|
+
'gray-dark': $gray-600,
|
|
28
|
+
'gray-darker': $gray-800
|
|
29
29
|
),
|
|
30
30
|
$brand-grays
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
-
$body-bg: $white !default;
|
|
34
|
-
$body-color: $black !default;
|
|
33
|
+
$body-bg: $white !default; // Brand color
|
|
34
|
+
$body-color: $black !default; // Brand color
|
|
35
35
|
$text-muted: $gray-500 !default;
|
|
36
36
|
|
|
37
37
|
$component-active-bg: $primary !default;
|
|
@@ -44,14 +44,22 @@ $enable-rounded: false !default;
|
|
|
44
44
|
$enable-shadows: true !default;
|
|
45
45
|
$enable-gradients: false !default;
|
|
46
46
|
|
|
47
|
-
$font-family-sans-serif:
|
|
48
|
-
|
|
47
|
+
$font-family-sans-serif:
|
|
48
|
+
'Poppins',
|
|
49
|
+
-apple-system,
|
|
50
|
+
BlinkMacSystemFont,
|
|
51
|
+
'Segoe UI',
|
|
52
|
+
Roboto,
|
|
53
|
+
'Helvetica Neue',
|
|
54
|
+
Arial,
|
|
55
|
+
sans-serif !default;
|
|
56
|
+
$font-family-serif: 'Merriweather', Georgia, 'Times New Roman', Times, serif !default;
|
|
49
57
|
|
|
50
58
|
$headings-font-family: $font-family-sans-serif !default;
|
|
51
59
|
$headings-font-weight: 700 !default;
|
|
52
60
|
|
|
53
61
|
$jumbotron-bg: $gray-200 !default;
|
|
54
|
-
$jumbotron-font-family:
|
|
62
|
+
$jumbotron-font-family: 'Anton', $font-family-sans-serif !default;
|
|
55
63
|
$jumbotron-font-weight: 400 !default;
|
|
56
64
|
|
|
57
65
|
$fade-bg: $gray-400 !default;
|
|
@@ -60,9 +68,7 @@ $list-group-bg: transparent !default;
|
|
|
60
68
|
$input-focus-border-color: $secondary !default;
|
|
61
69
|
$bs-input-bg: $gray-100 !default;
|
|
62
70
|
$input-focus-bg: $white !default;
|
|
63
|
-
$input-box-shadow: none !default;
|
|
64
71
|
|
|
65
|
-
$btn-box-shadow: none !default;
|
|
66
72
|
$btn-font-family: $font-family-sans-serif;
|
|
67
73
|
|
|
68
74
|
$form-check-input-gutter: 1.5rem !default;
|
package/lib/types.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { StyleValue } from 'vue'
|
|
2
2
|
|
|
3
|
-
import {AccordionKey, ParentKey} from '@/keys'
|
|
3
|
+
import { AccordionKey, ParentKey } from '@/keys'
|
|
4
4
|
import { ComputedRef } from 'vue'
|
|
5
5
|
import type { GeoProjection } from 'd3-geo'
|
|
6
6
|
import { Ref } from 'vue'
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
export type Step = symbol | string
|
|
10
9
|
|
|
11
10
|
export type Accordion = {
|
|
@@ -30,16 +29,33 @@ export type BrandStyle = StyleValue & {
|
|
|
30
29
|
width: string
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export type BrandExpansionStyle = Pick<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
export type BrandExpansionStyle = Pick<
|
|
33
|
+
BrandStyle,
|
|
34
|
+
'--monochrome-color' | 'background'
|
|
35
|
+
>
|
|
36
|
+
|
|
37
|
+
export type Variant =
|
|
38
|
+
| 'primary'
|
|
39
|
+
| 'secondary'
|
|
40
|
+
| 'danger'
|
|
41
|
+
| 'info'
|
|
42
|
+
| 'warning'
|
|
43
|
+
| 'success'
|
|
44
|
+
| 'dark'
|
|
45
|
+
| 'light'
|
|
46
|
+
|
|
47
|
+
export type MapTransform = {
|
|
48
|
+
k: number
|
|
49
|
+
x: number
|
|
50
|
+
y: number
|
|
51
|
+
rotateX: number
|
|
52
|
+
rotateY: number
|
|
53
|
+
}
|
|
38
54
|
|
|
39
55
|
export type ParentMap = {
|
|
40
|
-
mapRect:Ref<DOMRect
|
|
41
|
-
mapTransform:Ref<MapTransform
|
|
42
|
-
rotatingMapProjection:ComputedRef<GeoProjection|Function>
|
|
56
|
+
mapRect: Ref<DOMRect>
|
|
57
|
+
mapTransform: Ref<MapTransform>
|
|
58
|
+
rotatingMapProjection: ComputedRef<GeoProjection | Function>
|
|
43
59
|
}
|
|
44
60
|
export type ParentMapProvide = {
|
|
45
61
|
[ParentKey]: ParentMap
|
package/lib/utils/animation.ts
CHANGED
|
@@ -2,20 +2,20 @@ export class RequestAnimationFrameWrapper {
|
|
|
2
2
|
live: boolean
|
|
3
3
|
callback: () => void
|
|
4
4
|
|
|
5
|
-
constructor
|
|
5
|
+
constructor() {
|
|
6
6
|
this.live = false
|
|
7
7
|
this.callback = () => null
|
|
8
8
|
}
|
|
9
|
-
start
|
|
9
|
+
start(callback: () => void) {
|
|
10
10
|
this.live = true
|
|
11
11
|
this.callback = callback
|
|
12
12
|
this.schedule()
|
|
13
13
|
}
|
|
14
|
-
stop
|
|
14
|
+
stop() {
|
|
15
15
|
this.live = false
|
|
16
16
|
this.callback = () => null
|
|
17
17
|
}
|
|
18
|
-
schedule
|
|
18
|
+
schedule() {
|
|
19
19
|
this.callback()
|
|
20
20
|
if (this.live) {
|
|
21
21
|
window.requestAnimationFrame(this.schedule.bind(this))
|
package/lib/utils/assets.ts
CHANGED
|
@@ -1,45 +1,48 @@
|
|
|
1
1
|
import { memoize, flatten } from 'lodash'
|
|
2
2
|
|
|
3
|
-
var assetUniqueIdCounter: number = 0
|
|
3
|
+
var assetUniqueIdCounter: number = 0
|
|
4
4
|
|
|
5
|
-
export const injectAsset = memoize(function(
|
|
6
|
-
|
|
5
|
+
export const injectAsset = memoize(function (
|
|
6
|
+
file: string,
|
|
7
|
+
id: string = `dynamic-asset-${assetUniqueIdCounter++}`
|
|
8
|
+
): Promise<unknown> {
|
|
7
9
|
return new Promise((resolve: (value?: unknown) => void) => {
|
|
8
|
-
const parent: HTMLElement =
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
script.
|
|
10
|
+
const parent: HTMLElement =
|
|
11
|
+
document.querySelector('body') || document.querySelector('head')!
|
|
12
|
+
const parts = file.split('.')
|
|
13
|
+
const ext = parts[parts.length - 1].toLowerCase()
|
|
14
|
+
switch (ext) {
|
|
15
|
+
case 'js':
|
|
16
|
+
var script = document.createElement('script')
|
|
17
|
+
script.setAttribute('type', 'text/javascript')
|
|
15
18
|
script.onload = resolve
|
|
16
|
-
parent.appendChild(script)
|
|
17
|
-
script.setAttribute(
|
|
18
|
-
script.setAttribute(
|
|
19
|
-
|
|
20
|
-
case
|
|
21
|
-
var css = document.createElement('link')
|
|
22
|
-
css.setAttribute(
|
|
23
|
-
css.setAttribute(
|
|
19
|
+
parent.appendChild(script)
|
|
20
|
+
script.setAttribute('src', file)
|
|
21
|
+
script.setAttribute('id', id)
|
|
22
|
+
break
|
|
23
|
+
case 'css':
|
|
24
|
+
var css = document.createElement('link')
|
|
25
|
+
css.setAttribute('rel', 'stylesheet')
|
|
26
|
+
css.setAttribute('type', 'text/css')
|
|
24
27
|
css.onload = resolve
|
|
25
|
-
parent.appendChild(css)
|
|
26
|
-
css.setAttribute(
|
|
27
|
-
css.setAttribute(
|
|
28
|
-
|
|
28
|
+
parent.appendChild(css)
|
|
29
|
+
css.setAttribute('href', file)
|
|
30
|
+
css.setAttribute('id', id)
|
|
31
|
+
break
|
|
29
32
|
}
|
|
30
33
|
})
|
|
31
34
|
})
|
|
32
35
|
|
|
33
|
-
export const injectAssets = function(...args: string[]): Promise<void> {
|
|
36
|
+
export const injectAssets = function (...args: string[]): Promise<void> {
|
|
34
37
|
const files = flatten(args)
|
|
35
38
|
return new Promise((resolve: () => void) => {
|
|
36
|
-
var filesLoaded = 0
|
|
37
|
-
var allFilesLoaded = function() {
|
|
38
|
-
if(++filesLoaded == files.length) {
|
|
39
|
-
resolve()
|
|
39
|
+
var filesLoaded = 0
|
|
40
|
+
var allFilesLoaded = function () {
|
|
41
|
+
if (++filesLoaded == files.length) {
|
|
42
|
+
resolve()
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
|
-
for(var i=0; i < files.length
|
|
45
|
+
for (var i = 0; i < files.length; i++) {
|
|
43
46
|
injectAsset(files[i]).then(allFilesLoaded)
|
|
44
47
|
}
|
|
45
48
|
})
|
package/lib/utils/clipboard.ts
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import Clipboard from 'clipboard'
|
|
2
2
|
|
|
3
|
-
export function copyText
|
|
4
|
-
return new Promise(function (
|
|
3
|
+
export function copyText(text: string, container: Element): Promise<void> {
|
|
4
|
+
return new Promise(function (
|
|
5
|
+
resolve: (value?: undefined) => void,
|
|
6
|
+
reject: (value?: Clipboard.Event) => void
|
|
7
|
+
) {
|
|
5
8
|
const fakeElement = document.createElement('button')
|
|
6
9
|
// Use the document body as container is no valid object is provided
|
|
7
10
|
container = typeof container === 'object' ? container : document.body
|
|
8
11
|
|
|
9
|
-
const clipboard: Clipboard = new Clipboard(fakeElement, {
|
|
12
|
+
const clipboard: Clipboard = new Clipboard(fakeElement, {
|
|
13
|
+
text: () => text,
|
|
14
|
+
container
|
|
15
|
+
})
|
|
10
16
|
|
|
11
17
|
clipboard.on('success', () => {
|
|
12
18
|
clipboard.destroy()
|
|
13
19
|
resolve()
|
|
14
20
|
})
|
|
15
21
|
|
|
16
|
-
clipboard.on('error', error => {
|
|
22
|
+
clipboard.on('error', (error) => {
|
|
17
23
|
clipboard.destroy()
|
|
18
24
|
reject(error)
|
|
19
25
|
})
|
|
@@ -22,7 +28,7 @@ export function copyText (text: string, container: Element): Promise<void> {
|
|
|
22
28
|
})
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
export function copyHtml
|
|
31
|
+
export function copyHtml(html: string, plain: string) {
|
|
26
32
|
interface ClipboardEvent extends Event {
|
|
27
33
|
clipboardData: {
|
|
28
34
|
setData: (attribute: string, value: string) => void
|
|
@@ -30,12 +36,12 @@ export function copyHtml (html: string, plain: string) {
|
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
function listener(event: ClipboardEvent) {
|
|
33
|
-
event.clipboardData.setData(
|
|
34
|
-
event.clipboardData.setData(
|
|
39
|
+
event.clipboardData.setData('text/html', html)
|
|
40
|
+
event.clipboardData.setData('text/plain', plain)
|
|
35
41
|
event.preventDefault()
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
document.addEventListener(
|
|
39
|
-
document.execCommand(
|
|
40
|
-
document.removeEventListener(
|
|
44
|
+
document.addEventListener('copy', listener as EventListener)
|
|
45
|
+
document.execCommand('copy')
|
|
46
|
+
document.removeEventListener('copy', listener as EventListener)
|
|
41
47
|
}
|
|
@@ -12,29 +12,34 @@ const initialHref = window.location.href
|
|
|
12
12
|
export default class IframeResizer {
|
|
13
13
|
initializer: Promise<PymChild>
|
|
14
14
|
|
|
15
|
-
constructor
|
|
16
|
-
this.initializer = injectAssets('//pym.nprapps.org/pym.v1.min.js').then(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
constructor() {
|
|
16
|
+
this.initializer = injectAssets('//pym.nprapps.org/pym.v1.min.js').then(
|
|
17
|
+
() => {
|
|
18
|
+
pymChild = pymChild || new window.pym.Child({ polling: 300 })
|
|
19
|
+
return pymChild
|
|
20
|
+
}
|
|
21
|
+
)
|
|
20
22
|
}
|
|
21
|
-
sendHeight
|
|
22
|
-
return this.initializer.then(pymChild => pymChild.sendHeight())
|
|
23
|
+
sendHeight(): Promise<void> {
|
|
24
|
+
return this.initializer.then((pymChild) => pymChild.sendHeight())
|
|
23
25
|
}
|
|
24
|
-
static create
|
|
26
|
+
static create(): IframeResizer {
|
|
25
27
|
return new IframeResizer()
|
|
26
28
|
}
|
|
27
|
-
static template(
|
|
29
|
+
static template(
|
|
30
|
+
url: string,
|
|
31
|
+
id: string = 'icij-' + Date.now().toString(32)
|
|
32
|
+
): string {
|
|
28
33
|
return [
|
|
29
34
|
`<script type="text/javascript" src="https://pym.nprapps.org/pym.v1.min.js"></script>`,
|
|
30
35
|
`<div id="${id}"></div>`,
|
|
31
36
|
`<script>`,
|
|
32
37
|
`const icijIframe = new pym.Parent("${id}", "${IframeResizer.deletePymParams(url)}", {})`,
|
|
33
|
-
`</script
|
|
38
|
+
`</script>`
|
|
34
39
|
].join('\n')
|
|
35
40
|
}
|
|
36
41
|
static deletePymParams(href: string = initialHref): string {
|
|
37
|
-
const url = new URL(href)
|
|
42
|
+
const url = new URL(href)
|
|
38
43
|
// Remove all unwanted param
|
|
39
44
|
for (const param of pymParams) {
|
|
40
45
|
url.searchParams.delete(param)
|
|
@@ -42,8 +47,8 @@ export default class IframeResizer {
|
|
|
42
47
|
// Rebuild the URL
|
|
43
48
|
return url.href
|
|
44
49
|
}
|
|
45
|
-
static isEmbedded
|
|
50
|
+
static isEmbedded(href: string = initialHref): boolean {
|
|
46
51
|
const url = new URL(href)
|
|
47
|
-
return every(pymParams, param => url.searchParams.has(param))
|
|
52
|
+
return every(pymParams, (param) => url.searchParams.has(param))
|
|
48
53
|
}
|
|
49
54
|
}
|
package/lib/utils/placeholder.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BoxStyle,
|
|
3
|
+
ContentPlaceholderStyledRow,
|
|
4
|
+
ContentPlaceholderRow,
|
|
5
|
+
ContentPlaceholderRowBoxes,
|
|
6
|
+
ContentPlaceholderStyledRows,
|
|
7
|
+
ContentPlaceholderRows
|
|
8
|
+
} from '@/utils/placeholderTypes'
|
|
2
9
|
|
|
3
10
|
export function isFlexBasis(value: string | number): boolean {
|
|
4
11
|
return Number(value).toString() === value.toString()
|
|
@@ -8,24 +15,37 @@ export function isWidth(value: string | number): boolean {
|
|
|
8
15
|
const valueAsStr = String(value)
|
|
9
16
|
const cssSuffix = ['px', '%', 'em', 'rem']
|
|
10
17
|
let checkState = false
|
|
11
|
-
cssSuffix.forEach(suffix => {
|
|
12
|
-
if (
|
|
18
|
+
cssSuffix.forEach((suffix) => {
|
|
19
|
+
if (
|
|
20
|
+
Number(valueAsStr.split(suffix)[0]) &&
|
|
13
21
|
valueAsStr.split(suffix)[1] === '' &&
|
|
14
|
-
valueAsStr.split(suffix).length === 2
|
|
22
|
+
valueAsStr.split(suffix).length === 2
|
|
23
|
+
) {
|
|
15
24
|
checkState = true
|
|
16
25
|
}
|
|
17
26
|
})
|
|
18
27
|
return checkState
|
|
19
28
|
}
|
|
20
29
|
|
|
21
|
-
export function getBoxStyle(
|
|
30
|
+
export function getBoxStyle(
|
|
31
|
+
left: number,
|
|
32
|
+
width: number,
|
|
33
|
+
isLast: boolean,
|
|
34
|
+
subClass: string = 'box'
|
|
35
|
+
): BoxStyle[] {
|
|
22
36
|
const arr: BoxStyle[] = []
|
|
23
37
|
|
|
24
38
|
if (left !== 0) {
|
|
25
39
|
if (isFlexBasis(left)) {
|
|
26
|
-
arr.push({
|
|
40
|
+
arr.push({
|
|
41
|
+
style: `flex-grow: ${left}; flex-shrink: 0; flex-basis: 0;`,
|
|
42
|
+
subClass
|
|
43
|
+
})
|
|
27
44
|
} else if (isWidth(left)) {
|
|
28
|
-
arr.push({
|
|
45
|
+
arr.push({
|
|
46
|
+
style: `flex-grow: 0; flex-shrink: 0; flex-basis: ${left};`,
|
|
47
|
+
subClass
|
|
48
|
+
})
|
|
29
49
|
}
|
|
30
50
|
}
|
|
31
51
|
if (isFlexBasis(width)) {
|
|
@@ -34,26 +54,37 @@ export function getBoxStyle(left: number, width: number, isLast: boolean, subCla
|
|
|
34
54
|
arr.push({ style: `flex-grow: 0; flex-shrink: 0; flex-basis: ${width};` })
|
|
35
55
|
}
|
|
36
56
|
if (isLast) {
|
|
37
|
-
arr.push({
|
|
57
|
+
arr.push({
|
|
58
|
+
style: 'flex-grow: 1; flex-shrink: 0; flex-basis: 0;',
|
|
59
|
+
subClass
|
|
60
|
+
})
|
|
38
61
|
}
|
|
39
62
|
return arr
|
|
40
63
|
}
|
|
41
64
|
|
|
42
|
-
export function formatRows(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
export function formatRows(
|
|
66
|
+
rows: ContentPlaceholderRows,
|
|
67
|
+
subClass: string = 'box'
|
|
68
|
+
): ContentPlaceholderStyledRows {
|
|
69
|
+
const rowArr: ContentPlaceholderStyledRows = rows.map(
|
|
70
|
+
(row: ContentPlaceholderRow) => {
|
|
71
|
+
// Will contain all boxes in
|
|
72
|
+
const rowBoxes: Array<BoxStyle> = []
|
|
73
|
+
// Create placeholder row with initial height
|
|
74
|
+
const rowObj: ContentPlaceholderStyledRow = {
|
|
75
|
+
height: row.height,
|
|
76
|
+
boxes: []
|
|
77
|
+
}
|
|
78
|
+
// Add style
|
|
79
|
+
row.boxes.forEach((box: Array<any>, index: number) => {
|
|
80
|
+
const isLast: boolean = index === row.boxes.length - 1
|
|
81
|
+
// Merge the box styles
|
|
82
|
+
rowBoxes.push(...getBoxStyle(box[0], box[1], isLast, subClass))
|
|
83
|
+
})
|
|
84
|
+
rowObj.boxes = rowBoxes
|
|
85
|
+
return rowObj
|
|
86
|
+
}
|
|
87
|
+
)
|
|
57
88
|
|
|
58
89
|
return rowArr
|
|
59
90
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { StyleValue } from 'vue'
|
|
2
2
|
|
|
3
3
|
export interface BoxStyle {
|
|
4
|
-
style: StyleValue
|
|
4
|
+
style: StyleValue
|
|
5
5
|
subClass?: string
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export type ContentPlaceholderRowBoxes = Array<Array<number | string>>
|
|
9
9
|
|
|
10
10
|
export interface ContentPlaceholderRow {
|
|
11
|
-
height: number | string
|
|
11
|
+
height: number | string
|
|
12
12
|
boxes: ContentPlaceholderRowBoxes
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface ContentPlaceholderStyledRow {
|
|
16
|
-
height: number | string
|
|
16
|
+
height: number | string
|
|
17
17
|
boxes: Array<BoxStyle>
|
|
18
18
|
}
|
|
19
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icij/murmur-next",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Murmur is ICIJ's Design System for Bootstrap 5 and Vue.js",
|
|
6
6
|
"author": "promera@icij.org",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build": "vite build",
|
|
18
18
|
"preview": "vite preview",
|
|
19
19
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
|
20
|
-
"format": "prettier --write lib/",
|
|
20
|
+
"format": "prettier --write lib/ stories/ .storybook/ tests/",
|
|
21
21
|
"storybook": "storybook dev -p 6006",
|
|
22
22
|
"build-storybook": "storybook build",
|
|
23
23
|
"test": "vitest",
|
|
@@ -104,6 +104,11 @@
|
|
|
104
104
|
"peerDependencies": {
|
|
105
105
|
"vue": "^3.4.19"
|
|
106
106
|
},
|
|
107
|
+
"prettier": {
|
|
108
|
+
"singleQuote": true,
|
|
109
|
+
"semi": false,
|
|
110
|
+
"trailingComma": "none"
|
|
111
|
+
},
|
|
107
112
|
"resolutions": {
|
|
108
113
|
"jackspeak": "2.1.1"
|
|
109
114
|
}
|