@abcnews/components-builder 0.0.13 → 0.0.15
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/README.md
CHANGED
|
@@ -136,6 +136,11 @@ You can provide your own footer elements to make either an okay/cancel alert, or
|
|
|
136
136
|
|
|
137
137
|
This uses the native dialogue element, so focus will always be inside the modal. Take care not to show more than one at a time.
|
|
138
138
|
|
|
139
|
+
Use the `position` prop to control where the modal appears:
|
|
140
|
+
|
|
141
|
+
- `centre` (default): Centred in the screen with a full dark backdrop.
|
|
142
|
+
- `right`: Aligned to the right, with a gradient backdrop that leaves your viz visible. Especially useful when the modal changes the viz reactively, so you can see the results.
|
|
143
|
+
|
|
139
144
|
```svelte
|
|
140
145
|
{#snippet children()}
|
|
141
146
|
Hello this is the modal content
|
|
@@ -144,7 +149,7 @@ This uses the native dialogue element, so focus will always be inside the modal.
|
|
|
144
149
|
<button onclick={() => (isOpen = false)}>Ok!</button>
|
|
145
150
|
{/snippet}
|
|
146
151
|
|
|
147
|
-
<Modal title="Example modal" {children} {footerChildren} />
|
|
152
|
+
<Modal title="Example modal" {children} {footerChildren} position="right" />
|
|
148
153
|
```
|
|
149
154
|
|
|
150
155
|
## Google Doc Scrollyteller
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
let hasLoaded = $state(false);
|
|
26
26
|
let markers = $state<Marker[]>([]);
|
|
27
|
-
let mode = $state(Object.keys(prefixes)?.[0]);
|
|
27
|
+
let mode = $state(untrack(() => Object.keys(prefixes)?.[0]));
|
|
28
28
|
|
|
29
29
|
/** which button should show the success indicator */
|
|
30
30
|
let successIndicator = $state("");
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
window.location.pathname
|
|
34
34
|
.match(/\/news-projects\/[^/]+\/(\d+\.\d+\.\d+)/)
|
|
35
35
|
?.slice(1) || [];
|
|
36
|
-
const localStorageKey =
|
|
36
|
+
const localStorageKey = $derived(
|
|
37
|
+
`ABC_NEWS_BUILDER_${projectName.toUpperCase().replace(/-/g, "_")}`,
|
|
38
|
+
);
|
|
37
39
|
|
|
38
40
|
/** Load & sanitise markers from localStorage on initial load */
|
|
39
41
|
$effect(() => {
|
|
@@ -76,7 +78,7 @@
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
interval = setInterval(() => {
|
|
79
|
-
const goodMarkers = (marker) =>
|
|
81
|
+
const goodMarkers = (marker: Marker) =>
|
|
80
82
|
!marker.deleted || marker.deleted > Date.now() - 5000;
|
|
81
83
|
if (!_markers.every(goodMarkers)) {
|
|
82
84
|
markers = _markers.filter(goodMarkers);
|
|
@@ -240,7 +242,7 @@
|
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
let sanitisedMarker = text;
|
|
243
|
-
Object.
|
|
245
|
+
Object.values(prefixes).forEach(
|
|
244
246
|
(prefix) => (sanitisedMarker = sanitisedMarker.replace(prefix, "")),
|
|
245
247
|
);
|
|
246
248
|
|
package/dist/Modal/Modal.svelte
CHANGED
|
@@ -1,116 +1,138 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { X } from "svelte-bootstrap-icons";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
let {
|
|
6
|
+
children,
|
|
7
|
+
footerChildren,
|
|
8
|
+
title = "",
|
|
9
|
+
onClose = () => {},
|
|
10
|
+
position = "centre",
|
|
11
|
+
} = $props<{
|
|
12
|
+
children?: any;
|
|
13
|
+
footerChildren?: any;
|
|
14
|
+
title?: string;
|
|
15
|
+
onClose?: () => void;
|
|
16
|
+
position?: string;
|
|
17
|
+
}>();
|
|
18
|
+
let dialogEl = $state<HTMLDialogElement | undefined>();
|
|
19
|
+
let rect = $state<DOMRect>();
|
|
20
|
+
$effect(() => {
|
|
21
|
+
if (dialogEl) {
|
|
22
|
+
rect = dialogEl.getBoundingClientRect();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
onMount(() => {
|
|
26
|
+
dialogEl?.showModal();
|
|
27
|
+
return () => {
|
|
28
|
+
dialogEl?.close();
|
|
29
|
+
};
|
|
30
|
+
});
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
function onCloseBackdrop(e) {
|
|
33
|
+
if (e.target === dialogEl) {
|
|
34
|
+
onClose();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
24
37
|
</script>
|
|
25
38
|
|
|
26
39
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
27
40
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
41
|
+
<!-- We must track clicks on the modal so clicking the backdrop can close it. This is not an accessibility issue. -->
|
|
28
42
|
<dialog
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
bind:this={dialogEl}
|
|
44
|
+
class="modal modal--{position}"
|
|
45
|
+
onclick={onCloseBackdrop}
|
|
46
|
+
onclose={onCloseBackdrop}
|
|
33
47
|
>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
49
|
+
<div onclick={(e) => e.stopPropagation()}>
|
|
50
|
+
{#if title}
|
|
51
|
+
<div class="modal-title">
|
|
52
|
+
<h1>
|
|
53
|
+
{title}
|
|
54
|
+
</h1>
|
|
55
|
+
<button class="modal-close" onclick={() => onClose()}>
|
|
56
|
+
<X />
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
{/if}
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
<div class="modal-content">
|
|
62
|
+
{@render children?.()}
|
|
63
|
+
</div>
|
|
64
|
+
{#if footerChildren}
|
|
65
|
+
<div class="modal-footer">
|
|
66
|
+
{@render footerChildren?.()}
|
|
67
|
+
</div>
|
|
68
|
+
{/if}
|
|
69
|
+
</div>
|
|
56
70
|
</dialog>
|
|
57
71
|
|
|
58
72
|
<style>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
.modal {
|
|
74
|
+
left: 50%;
|
|
75
|
+
top: 50%;
|
|
76
|
+
transform: translate(-50%, -50%);
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 0;
|
|
79
|
+
background: var(--background);
|
|
80
|
+
color: var(--text);
|
|
81
|
+
border: 1px solid var(--border);
|
|
82
|
+
border-radius: 0.5rem;
|
|
83
|
+
animation: fadein 0.2s;
|
|
84
|
+
&::backdrop {
|
|
85
|
+
animation: fadein 0.2s;
|
|
86
|
+
background: rgba(0, 0, 0, 0.8);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
.modal--right {
|
|
90
|
+
left: 100%;
|
|
91
|
+
transform: translate(calc(-100% - 2rem), -50%);
|
|
92
|
+
&::backdrop {
|
|
93
|
+
animation: fadein 0.2s;
|
|
94
|
+
background: linear-gradient(to left, rgba(0, 0, 0, 0.8), transparent 50%);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
98
|
+
.modal-title {
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
|
103
|
+
gap: 1rem;
|
|
104
|
+
border-bottom: 1px solid var(--border);
|
|
105
|
+
}
|
|
106
|
+
.modal-title h1 {
|
|
107
|
+
font-size: 1rem;
|
|
108
|
+
margin: 0;
|
|
109
|
+
padding: 0;
|
|
110
|
+
flex: 1;
|
|
111
|
+
}
|
|
112
|
+
button.modal-close {
|
|
113
|
+
width: 2rem;
|
|
114
|
+
border: none;
|
|
115
|
+
height: 2rem;
|
|
116
|
+
display: flex;
|
|
117
|
+
justify-content: center;
|
|
118
|
+
align-items: center;
|
|
119
|
+
}
|
|
120
|
+
.modal-content {
|
|
121
|
+
padding: 0.5rem 1rem;
|
|
122
|
+
max-height: 50vh;
|
|
123
|
+
overflow: hidden auto;
|
|
124
|
+
}
|
|
125
|
+
.modal-footer {
|
|
126
|
+
text-align: right;
|
|
127
|
+
border-top: 1px solid var(--border);
|
|
128
|
+
padding: 0.5rem 1rem;
|
|
129
|
+
}
|
|
130
|
+
@keyframes fadein {
|
|
131
|
+
from {
|
|
132
|
+
opacity: 0;
|
|
133
|
+
}
|
|
134
|
+
to {
|
|
135
|
+
opacity: 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
116
138
|
</style>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
children
|
|
3
|
-
footerChildren
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
children?: any;
|
|
3
|
+
footerChildren?: any;
|
|
4
4
|
title?: string;
|
|
5
|
-
onClose?:
|
|
6
|
-
|
|
5
|
+
onClose?: () => void;
|
|
6
|
+
position?: string;
|
|
7
|
+
};
|
|
8
|
+
declare const Modal: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
9
|
type Modal = ReturnType<typeof Modal>;
|
|
8
10
|
export default Modal;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
} = $props();
|
|
18
18
|
|
|
19
19
|
const uniqueId = "list" + (Math.random() * 10e15).toString(16);
|
|
20
|
-
let selectedValues = $state<string[]>(value);
|
|
20
|
+
let selectedValues = $state<string[]>(untrack(() => value));
|
|
21
21
|
let isFocused = $state(false);
|
|
22
22
|
let inputElement = $state<HTMLInputElement>();
|
|
23
23
|
let inputValue = $state("");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Modal from "../Modal/Modal.svelte";
|
|
3
|
-
import { onMount } from "svelte";
|
|
3
|
+
import { onMount, untrack } from "svelte";
|
|
4
4
|
|
|
5
5
|
type NewVersion = {
|
|
6
6
|
newVersion: string;
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
buttonText = "Open new builder",
|
|
13
13
|
}: { overrideNewVersion?: NewVersion; buttonText?: string } = $props();
|
|
14
14
|
|
|
15
|
-
let newVersion = $state<NewVersion | undefined>(
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
let newVersion = $state<NewVersion | undefined>(
|
|
16
|
+
untrack(() => overrideNewVersion),
|
|
17
|
+
);
|
|
18
|
+
let isOpen = $state(untrack(() => !!newVersion));
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Check for a new version of the given project
|