@cdc/markup-include 4.22.10 → 4.22.11
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 +2 -1
- package/examples/gallery/button-and-text.json +30 -30
- package/examples/gallery/icon-no-text.json +30 -30
- package/examples/gallery/image-with-text.json +30 -30
- package/examples/test.html +26 -1
- package/package.json +3 -3
- package/src/CdcMarkupInclude.jsx +48 -66
- package/src/ConfigContext.js +3 -3
- package/src/components/EditorPanel.js +60 -66
- package/src/data/initial-state.js +12 -12
- package/src/index.html +25 -26
- package/src/index.js +2 -2
- package/src/scss/main.scss +3 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@cdc/markup-include)
|
|
4
4
|
|
|
5
|
-
`<CdcMarkupInclude />` is a React component produced by the CDC for importing HTML markup data from a separate source link.
|
|
5
|
+
`<CdcMarkupInclude />` is a React component produced by the CDC for importing HTML markup data from a separate source link.
|
|
6
6
|
|
|
7
7
|
This package is part of the larger [CDC Open Visualization](https://github.com/CDCgov/cdc-open-viz) project.
|
|
8
8
|
|
|
@@ -10,6 +10,7 @@ This package is part of the larger [CDC Open Visualization](https://github.com/C
|
|
|
10
10
|
|
|
11
11
|
1. Install the package in your React project `npm install @cdc/markup-include`
|
|
12
12
|
2. Import the component and begin using in your code.
|
|
13
|
+
|
|
13
14
|
```JSX
|
|
14
15
|
import CdcMarkupInclude from '@cdc/markup-include'
|
|
15
16
|
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
2
|
+
"title": "",
|
|
3
|
+
"showHeader": false,
|
|
4
|
+
"type": "markup-include",
|
|
5
|
+
"srcUrl": "https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Markup-Include-Button-and-Text.html",
|
|
6
|
+
"theme": "theme-blue",
|
|
7
|
+
"data": [
|
|
8
|
+
{
|
|
9
|
+
"Race": "Hispanic or Latino",
|
|
10
|
+
"Age-adjusted rate": "644.2"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"Race": "Non-Hispanic American Indian",
|
|
14
|
+
"Age-adjusted rate": "636.1"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"Race": "Non-Hispanic Black",
|
|
18
|
+
"Age-adjusted rate": "563.7"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"Race": "Non-Hispanic Asian or Pacific Islander",
|
|
22
|
+
"Age-adjusted rate": "202.5"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"Race": "Non-Hispanic White",
|
|
26
|
+
"Age-adjusted rate": "183.6"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"dataFileName": "valid-data-chart.csv",
|
|
30
|
+
"dataFileSourceType": "file"
|
|
31
|
+
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
2
|
+
"title": "",
|
|
3
|
+
"showHeader": false,
|
|
4
|
+
"type": "markup-include",
|
|
5
|
+
"srcUrl": "https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/SSI-Example-Markup-Include.html",
|
|
6
|
+
"theme": "theme-blue",
|
|
7
|
+
"data": [
|
|
8
|
+
{
|
|
9
|
+
"Race": "Hispanic or Latino",
|
|
10
|
+
"Age-adjusted rate": "644.2"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"Race": "Non-Hispanic American Indian",
|
|
14
|
+
"Age-adjusted rate": "636.1"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"Race": "Non-Hispanic Black",
|
|
18
|
+
"Age-adjusted rate": "563.7"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"Race": "Non-Hispanic Asian or Pacific Islander",
|
|
22
|
+
"Age-adjusted rate": "202.5"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"Race": "Non-Hispanic White",
|
|
26
|
+
"Age-adjusted rate": "183.6"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"dataFileName": "valid-data-chart.csv",
|
|
30
|
+
"dataFileSourceType": "file"
|
|
31
|
+
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
2
|
+
"title": "<strong>Markup Include</strong> - Image with Text",
|
|
3
|
+
"showHeader": false,
|
|
4
|
+
"type": "markup-include",
|
|
5
|
+
"srcUrl": "/wcms/4.0/cdc-wp/data-presentation/examples/SSI-Image-With-Text.html",
|
|
6
|
+
"theme": "theme-slate",
|
|
7
|
+
"data": [
|
|
8
|
+
{
|
|
9
|
+
"Race": "Hispanic or Latino",
|
|
10
|
+
"Age-adjusted rate": "644.2"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"Race": "Non-Hispanic American Indian",
|
|
14
|
+
"Age-adjusted rate": "636.1"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"Race": "Non-Hispanic Black",
|
|
18
|
+
"Age-adjusted rate": "563.7"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"Race": "Non-Hispanic Asian or Pacific Islander",
|
|
22
|
+
"Age-adjusted rate": "202.5"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"Race": "Non-Hispanic White",
|
|
26
|
+
"Age-adjusted rate": "183.6"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"dataFileName": "valid-data-chart.csv",
|
|
30
|
+
"dataFileSourceType": "file"
|
|
31
|
+
}
|
package/examples/test.html
CHANGED
|
@@ -1 +1,26 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
7
|
+
<title>Document</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<h1>Header</h1>
|
|
11
|
+
<p>
|
|
12
|
+
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the
|
|
13
|
+
necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
|
|
14
|
+
</p>
|
|
15
|
+
<br />
|
|
16
|
+
<p>
|
|
17
|
+
Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar. The Big Oxmox advised her not to do so, because there were thousands of
|
|
18
|
+
bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn’t listen.
|
|
19
|
+
</p>
|
|
20
|
+
<br />
|
|
21
|
+
<p>
|
|
22
|
+
She packed her seven versalia, put her initial into the belt and made herself on the way. When she reached the first hills of the Italic Mountains, she had a last view back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet Village and the subline of her own road, the Line
|
|
23
|
+
Lane. Pityful a rethoric question ran over her cheek.
|
|
24
|
+
</p>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/markup-include",
|
|
3
|
-
"version": "4.22.
|
|
3
|
+
"version": "4.22.11",
|
|
4
4
|
"description": "React component for displaying HTML content from an outside link",
|
|
5
5
|
"main": "dist/cdcmarkupinclude",
|
|
6
6
|
"scripts": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@cdc/core": "^4.22.
|
|
23
|
+
"@cdc/core": "^4.22.11",
|
|
24
24
|
"axios": "^0.26.1",
|
|
25
25
|
"chroma": "0.0.1",
|
|
26
26
|
"chroma-js": "^2.1.0",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"resolutions": {
|
|
36
36
|
"@types/react": "17.x"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "9768d1ea0e2383044977d988e33531bcdfe33ea6"
|
|
39
39
|
}
|
package/src/CdcMarkupInclude.jsx
CHANGED
|
@@ -12,39 +12,28 @@ import defaults from './data/initial-state'
|
|
|
12
12
|
|
|
13
13
|
import './scss/main.scss'
|
|
14
14
|
|
|
15
|
-
import { publish } from '@cdc/core/helpers/events'
|
|
15
|
+
import { publish } from '@cdc/core/helpers/events'
|
|
16
16
|
|
|
17
|
-
import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
|
|
18
|
-
|
|
19
|
-
const CdcMarkupInclude = (
|
|
20
|
-
{
|
|
21
|
-
configUrl,
|
|
22
|
-
config: configObj,
|
|
23
|
-
isDashboard = false,
|
|
24
|
-
isEditor = false,
|
|
25
|
-
setConfig: setParentConfig
|
|
26
|
-
}
|
|
27
|
-
) => {
|
|
17
|
+
import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
|
|
28
18
|
|
|
19
|
+
const CdcMarkupInclude = ({ configUrl, config: configObj, isDashboard = false, isEditor = false, setConfig: setParentConfig }) => {
|
|
29
20
|
// Default States
|
|
30
|
-
const [
|
|
31
|
-
const [
|
|
21
|
+
const [config, setConfig] = useState({ ...defaults })
|
|
22
|
+
const [loading, setLoading] = useState(true)
|
|
32
23
|
|
|
33
24
|
// Custom States
|
|
34
|
-
const [
|
|
35
|
-
const [
|
|
36
|
-
const [
|
|
37
|
-
const [
|
|
38
|
-
const container = useRef()
|
|
25
|
+
const [urlMarkup, setUrlMarkup] = useState('')
|
|
26
|
+
const [markupError, setMarkupError] = useState(null)
|
|
27
|
+
const [errorMessage, setErrorMessage] = useState(null)
|
|
28
|
+
const [coveLoadedHasRan, setCoveLoadedHasRan] = useState(false)
|
|
29
|
+
const container = useRef()
|
|
39
30
|
|
|
40
|
-
const {innerContainerClasses, contentClasses} = useDataVizClasses(config)
|
|
31
|
+
const { innerContainerClasses, contentClasses } = useDataVizClasses(config)
|
|
41
32
|
|
|
42
|
-
let {
|
|
43
|
-
title
|
|
44
|
-
} = config
|
|
33
|
+
let { title } = config
|
|
45
34
|
|
|
46
35
|
// Default Functions
|
|
47
|
-
const updateConfig =
|
|
36
|
+
const updateConfig = newConfig => {
|
|
48
37
|
Object.keys(defaults).forEach(key => {
|
|
49
38
|
if (newConfig[key] && 'object' === typeof newConfig[key] && !Array.isArray(newConfig[key])) {
|
|
50
39
|
newConfig[key] = { ...defaults[key], ...newConfig[key] }
|
|
@@ -59,7 +48,7 @@ const CdcMarkupInclude = (
|
|
|
59
48
|
}
|
|
60
49
|
|
|
61
50
|
const loadConfig = useCallback(async () => {
|
|
62
|
-
let response = configObj || await (await fetch(configUrl)).json()
|
|
51
|
+
let response = configObj || (await (await fetch(configUrl)).json())
|
|
63
52
|
let responseData = response.data ?? {}
|
|
64
53
|
|
|
65
54
|
if (response.dataUrl) {
|
|
@@ -87,7 +76,7 @@ const CdcMarkupInclude = (
|
|
|
87
76
|
let errorList = {
|
|
88
77
|
200: 'This is likely due to a CORS restriction policy from the remote origin address.',
|
|
89
78
|
404: 'The requested source URL cannot be found. Please verify the link address provided.',
|
|
90
|
-
|
|
79
|
+
proto: 'Provided source URL must include https:// or http:// before the address (depending on the source content type).'
|
|
91
80
|
}
|
|
92
81
|
|
|
93
82
|
message += errorList[errorCode]
|
|
@@ -95,23 +84,23 @@ const CdcMarkupInclude = (
|
|
|
95
84
|
} else {
|
|
96
85
|
setErrorMessage(null)
|
|
97
86
|
}
|
|
98
|
-
}, [
|
|
87
|
+
}, [markupError])
|
|
99
88
|
|
|
100
89
|
const loadConfigMarkupData = useCallback(async () => {
|
|
101
90
|
setMarkupError(null)
|
|
102
91
|
|
|
103
92
|
if (config.srcUrl) {
|
|
104
93
|
if (config.srcUrl === '#example') {
|
|
105
|
-
setUrlMarkup(
|
|
94
|
+
setUrlMarkup(
|
|
95
|
+
'<!doctype html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>Header</h1> <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p> <br> <p>Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar. The Big Oxmox advised her not to do so, because there were thousands of bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn’t listen. </p><br><p>She packed her seven versalia, put her initial into the belt and made herself on the way. When she reached the first hills of the Italic Mountains, she had a last view back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet Village and the subline of her own road, the Line Lane. Pityful a rethoric question ran over her cheek.</p></body></html>'
|
|
96
|
+
)
|
|
106
97
|
} else {
|
|
107
98
|
try {
|
|
108
|
-
await axios
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
})
|
|
99
|
+
await axios.get(config.srcUrl).then(res => {
|
|
100
|
+
if (res.data) {
|
|
101
|
+
setUrlMarkup(res.data)
|
|
102
|
+
}
|
|
103
|
+
})
|
|
115
104
|
} catch (err) {
|
|
116
105
|
if (err.response) {
|
|
117
106
|
// Response with error
|
|
@@ -127,9 +116,9 @@ const CdcMarkupInclude = (
|
|
|
127
116
|
} else {
|
|
128
117
|
setUrlMarkup('')
|
|
129
118
|
}
|
|
130
|
-
}, [
|
|
119
|
+
}, [config.srcUrl])
|
|
131
120
|
|
|
132
|
-
const parseBodyMarkup =
|
|
121
|
+
const parseBodyMarkup = markup => {
|
|
133
122
|
let parse
|
|
134
123
|
let hasBody = false
|
|
135
124
|
if (markup && markup !== '' && markup !== null) {
|
|
@@ -146,7 +135,7 @@ const CdcMarkupInclude = (
|
|
|
146
135
|
|
|
147
136
|
//Load initial config
|
|
148
137
|
useEffect(() => {
|
|
149
|
-
loadConfig().catch(
|
|
138
|
+
loadConfig().catch(err => console.log(err))
|
|
150
139
|
publish('cove_loaded', { loadConfigHasRun: true })
|
|
151
140
|
}, [])
|
|
152
141
|
|
|
@@ -155,43 +144,39 @@ const CdcMarkupInclude = (
|
|
|
155
144
|
publish('cove_loaded', { config: config })
|
|
156
145
|
setCoveLoadedHasRan(true)
|
|
157
146
|
}
|
|
158
|
-
}, [config, container])
|
|
147
|
+
}, [config, container])
|
|
159
148
|
|
|
160
149
|
//Reload config if config object provided/updated
|
|
161
150
|
useEffect(() => {
|
|
162
|
-
loadConfig().catch(
|
|
163
|
-
}, [
|
|
151
|
+
loadConfig().catch(err => console.log(err))
|
|
152
|
+
}, [configObj?.data])
|
|
164
153
|
|
|
165
154
|
//Reload any functions when config is updated
|
|
166
155
|
useEffect(() => {
|
|
167
|
-
loadConfigMarkupData().catch(
|
|
168
|
-
}, [
|
|
156
|
+
loadConfigMarkupData().catch(err => console.log(err))
|
|
157
|
+
}, [loadConfigMarkupData])
|
|
169
158
|
|
|
170
|
-
let content =
|
|
159
|
+
let content = <Loading />
|
|
171
160
|
|
|
172
|
-
let bodyClasses = [
|
|
173
|
-
'markup-include',
|
|
174
|
-
]
|
|
161
|
+
let bodyClasses = ['markup-include']
|
|
175
162
|
|
|
176
163
|
if (loading === false) {
|
|
177
164
|
let body = (
|
|
178
|
-
<div className={
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
<div className=
|
|
187
|
-
{!markupError && urlMarkup &&
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
{markupError && config.srcUrl && <div className="warning">{errorMessage}</div>}
|
|
165
|
+
<div className={bodyClasses.join(' ')} ref={container}>
|
|
166
|
+
{title && (
|
|
167
|
+
<header className={`cove-component__header ${config.theme}`} aria-hidden='true'>
|
|
168
|
+
{parse(title)} {isDashboard}
|
|
169
|
+
</header>
|
|
170
|
+
)}
|
|
171
|
+
<div className={`cove-component__content ${contentClasses.join(' ')}`}>
|
|
172
|
+
<div className={`${innerContainerClasses.join(' ')}`}>
|
|
173
|
+
<div className='cove-component__content-wrap'>
|
|
174
|
+
{!markupError && urlMarkup && <Markup content={parseBodyMarkup(urlMarkup)} />}
|
|
175
|
+
{markupError && config.srcUrl && <div className='warning'>{errorMessage}</div>}
|
|
191
176
|
</div>
|
|
192
177
|
</div>
|
|
178
|
+
</div>
|
|
193
179
|
</div>
|
|
194
|
-
</div>
|
|
195
180
|
)
|
|
196
181
|
|
|
197
182
|
content = (
|
|
@@ -203,11 +188,8 @@ const CdcMarkupInclude = (
|
|
|
203
188
|
}
|
|
204
189
|
|
|
205
190
|
return (
|
|
206
|
-
<ErrorBoundary component=
|
|
207
|
-
<ConfigContext.Provider
|
|
208
|
-
value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard }}>
|
|
209
|
-
{content}
|
|
210
|
-
</ConfigContext.Provider>
|
|
191
|
+
<ErrorBoundary component='CdcMarkupInclude'>
|
|
192
|
+
<ConfigContext.Provider value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard }}>{content}</ConfigContext.Provider>
|
|
211
193
|
</ErrorBoundary>
|
|
212
194
|
)
|
|
213
195
|
}
|
package/src/ConfigContext.js
CHANGED
|
@@ -9,21 +9,13 @@ import InputText from '@cdc/core/components/inputs/InputText'
|
|
|
9
9
|
|
|
10
10
|
import '@cdc/core/styles/v2/components/editor.scss'
|
|
11
11
|
|
|
12
|
-
const headerColors = [
|
|
12
|
+
const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
|
|
13
13
|
|
|
14
|
-
const EditorPanel = memo(
|
|
15
|
-
const {
|
|
16
|
-
config,
|
|
17
|
-
updateConfig,
|
|
18
|
-
loading,
|
|
19
|
-
data,
|
|
20
|
-
setParentConfig,
|
|
21
|
-
isDashboard
|
|
22
|
-
} = useContext(ConfigContext)
|
|
23
|
-
|
|
24
|
-
const [ displayPanel, setDisplayPanel ] = useState(true)
|
|
25
|
-
const [ showConfigConfirm, setShowConfigConfirm ] = useState(false)
|
|
14
|
+
const EditorPanel = memo(props => {
|
|
15
|
+
const { config, updateConfig, loading, data, setParentConfig, isDashboard } = useContext(ConfigContext)
|
|
26
16
|
|
|
17
|
+
const [displayPanel, setDisplayPanel] = useState(true)
|
|
18
|
+
const [showConfigConfirm, setShowConfigConfirm] = useState(false)
|
|
27
19
|
|
|
28
20
|
const updateField = (section, subsection, fieldName, newValue) => {
|
|
29
21
|
// Top level
|
|
@@ -40,11 +32,11 @@ const EditorPanel = memo((props) => {
|
|
|
40
32
|
|
|
41
33
|
const isArray = Array.isArray(config[section])
|
|
42
34
|
|
|
43
|
-
let sectionValue = isArray ? [
|
|
35
|
+
let sectionValue = isArray ? [...config[section], newValue] : { ...config[section], [fieldName]: newValue }
|
|
44
36
|
|
|
45
37
|
if (null !== subsection) {
|
|
46
38
|
if (isArray) {
|
|
47
|
-
sectionValue = [
|
|
39
|
+
sectionValue = [...config[section]]
|
|
48
40
|
sectionValue[subsection] = { ...sectionValue[subsection], [fieldName]: newValue }
|
|
49
41
|
} else if (typeof newValue === 'string') {
|
|
50
42
|
sectionValue[subsection] = newValue
|
|
@@ -69,9 +61,9 @@ const EditorPanel = memo((props) => {
|
|
|
69
61
|
|
|
70
62
|
setParentConfig(newConfig)
|
|
71
63
|
}
|
|
72
|
-
}, [
|
|
64
|
+
}, [config])
|
|
73
65
|
|
|
74
|
-
useEffect(()=> {
|
|
66
|
+
useEffect(() => {
|
|
75
67
|
if (!showConfigConfirm) {
|
|
76
68
|
let newConfig = { ...config }
|
|
77
69
|
delete newConfig.newViz
|
|
@@ -91,8 +83,8 @@ const EditorPanel = memo((props) => {
|
|
|
91
83
|
|
|
92
84
|
const Error = () => {
|
|
93
85
|
return (
|
|
94
|
-
<section className=
|
|
95
|
-
<section className=
|
|
86
|
+
<section className='waiting'>
|
|
87
|
+
<section className='waiting-container'>
|
|
96
88
|
<h3>Error With Configuration</h3>
|
|
97
89
|
<p>{config.runtime.editorErrorMessage}</p>
|
|
98
90
|
</section>
|
|
@@ -101,7 +93,7 @@ const EditorPanel = memo((props) => {
|
|
|
101
93
|
}
|
|
102
94
|
|
|
103
95
|
const Confirm = () => {
|
|
104
|
-
const confirmDone =
|
|
96
|
+
const confirmDone = e => {
|
|
105
97
|
e.preventDefault()
|
|
106
98
|
let newConfig = { ...config }
|
|
107
99
|
delete newConfig.newViz
|
|
@@ -109,12 +101,12 @@ const EditorPanel = memo((props) => {
|
|
|
109
101
|
}
|
|
110
102
|
|
|
111
103
|
return (
|
|
112
|
-
<section className=
|
|
113
|
-
<section className=
|
|
104
|
+
<section className='waiting'>
|
|
105
|
+
<section className='waiting-container'>
|
|
114
106
|
<h3>Finish Configuring</h3>
|
|
115
107
|
<p>Set all required options to the left and confirm below to display a preview of the markup.</p>
|
|
116
|
-
<button className=
|
|
117
|
-
|
|
108
|
+
<button className='btn' style={{ margin: '1em auto' }} onClick={confirmDone}>
|
|
109
|
+
I'm Done
|
|
118
110
|
</button>
|
|
119
111
|
</section>
|
|
120
112
|
</section>
|
|
@@ -130,45 +122,52 @@ const EditorPanel = memo((props) => {
|
|
|
130
122
|
}
|
|
131
123
|
|
|
132
124
|
const CheckBox = memo(({ label, value, fieldName, section = null, subsection = null, tooltip, updateField, ...attributes }) => (
|
|
133
|
-
<label className=
|
|
134
|
-
<input
|
|
135
|
-
|
|
125
|
+
<label className='checkbox'>
|
|
126
|
+
<input
|
|
127
|
+
type='checkbox'
|
|
128
|
+
name={fieldName}
|
|
129
|
+
checked={value}
|
|
130
|
+
onChange={() => {
|
|
131
|
+
updateField(section, subsection, fieldName, !value)
|
|
132
|
+
}}
|
|
133
|
+
{...attributes}
|
|
134
|
+
/>
|
|
135
|
+
<span className='edit-label column-heading'>{label}</span>
|
|
136
|
+
<span className='cove-icon'>{tooltip}</span>
|
|
136
137
|
</label>
|
|
137
138
|
))
|
|
138
139
|
|
|
139
140
|
const editorContent = (
|
|
140
141
|
<Accordion>
|
|
141
|
-
<Accordion.Section title=
|
|
142
|
-
<InputText value={config.title || ''} fieldName=
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
<InputText
|
|
147
|
-
value={config.srcUrl || ''} fieldName="srcUrl" label="Source URL"
|
|
148
|
-
placeholder="https://www.example.com/file.html" updateField={updateField}
|
|
149
|
-
/>
|
|
142
|
+
<Accordion.Section title='General'>
|
|
143
|
+
<InputText value={config.title || ''} fieldName='title' label='Title' placeholder='Markup Include Title' updateField={updateField} />
|
|
144
|
+
|
|
145
|
+
<InputText value={config.srcUrl || ''} fieldName='srcUrl' label='Source URL' placeholder='https://www.example.com/file.html' updateField={updateField} />
|
|
150
146
|
</Accordion.Section>
|
|
151
|
-
<Accordion.Section title=
|
|
152
|
-
<div className=
|
|
147
|
+
<Accordion.Section title='Visual'>
|
|
148
|
+
<div className='input-group'>
|
|
153
149
|
<label>Theme</label>
|
|
154
|
-
<ul className=
|
|
155
|
-
{headerColors.map(
|
|
156
|
-
<li
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
<ul className='color-palette'>
|
|
151
|
+
{headerColors.map(palette => (
|
|
152
|
+
<li
|
|
153
|
+
title={palette}
|
|
154
|
+
key={palette}
|
|
155
|
+
onClick={() => {
|
|
156
|
+
updateConfig({ ...config, theme: palette })
|
|
157
|
+
}}
|
|
158
|
+
className={config.theme === palette ? 'selected ' + palette : palette}
|
|
159
|
+
></li>
|
|
160
160
|
))}
|
|
161
161
|
</ul>
|
|
162
162
|
</div>
|
|
163
163
|
|
|
164
|
-
<div className=
|
|
165
|
-
<CheckBox value={config.visual.border} section=
|
|
166
|
-
<CheckBox value={config.visual.borderColorTheme} section=
|
|
167
|
-
<CheckBox value={config.visual.accent} section=
|
|
168
|
-
<CheckBox value={config.visual.background} section=
|
|
169
|
-
<CheckBox value={config.visual.hideBackgroundColor} section=
|
|
164
|
+
<div className='cove-accordion__panel-section checkbox-group'>
|
|
165
|
+
<CheckBox value={config.visual.border} section='visual' fieldName='border' label='Display Border' updateField={updateField} />
|
|
166
|
+
<CheckBox value={config.visual.borderColorTheme} section='visual' fieldName='borderColorTheme' label='Use Border Color Theme' updateField={updateField} />
|
|
167
|
+
<CheckBox value={config.visual.accent} section='visual' fieldName='accent' label='Use Accent Style' updateField={updateField} />
|
|
168
|
+
<CheckBox value={config.visual.background} section='visual' fieldName='background' label='Use Theme Background Color' updateField={updateField} />
|
|
169
|
+
<CheckBox value={config.visual.hideBackgroundColor} section='visual' fieldName='hideBackgroundColor' label='Hide Background Color' updateField={updateField} />
|
|
170
170
|
</div>
|
|
171
|
-
|
|
172
171
|
</Accordion.Section>
|
|
173
172
|
</Accordion>
|
|
174
173
|
)
|
|
@@ -176,24 +175,19 @@ const EditorPanel = memo((props) => {
|
|
|
176
175
|
if (loading) return null
|
|
177
176
|
|
|
178
177
|
return (
|
|
179
|
-
<ErrorBoundary component=
|
|
180
|
-
<div className=
|
|
181
|
-
{!config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error/>}
|
|
182
|
-
{config.newViz && showConfigConfirm && <Confirm/>}
|
|
183
|
-
<button className={`cove-editor--toggle` + (!displayPanel ? ` collapsed` : ``)}
|
|
184
|
-
title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick}/>
|
|
178
|
+
<ErrorBoundary component='EditorPanel'>
|
|
179
|
+
<div className='cove-editor'>
|
|
180
|
+
{!config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error />}
|
|
181
|
+
{config.newViz && showConfigConfirm && <Confirm />}
|
|
182
|
+
<button className={`cove-editor--toggle` + (!displayPanel ? ` collapsed` : ``)} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick} />
|
|
185
183
|
<section className={`cove-editor__panel` + (displayPanel ? `` : ' hidden')}>
|
|
186
|
-
<div className=
|
|
187
|
-
<h2 className=
|
|
188
|
-
<section className=
|
|
189
|
-
{editorContent}
|
|
190
|
-
</section>
|
|
184
|
+
<div className='cove-editor__panel-container'>
|
|
185
|
+
<h2 className='cove-editor__heading'>Configure Markup Include</h2>
|
|
186
|
+
<section className='cove-editor__content'>{editorContent}</section>
|
|
191
187
|
</div>
|
|
192
188
|
</section>
|
|
193
|
-
<div className=
|
|
194
|
-
<div className=
|
|
195
|
-
{props.children}
|
|
196
|
-
</div>
|
|
189
|
+
<div className='cove-editor__content'>
|
|
190
|
+
<div className='cove-editor__content-wrap'>{props.children}</div>
|
|
197
191
|
</div>
|
|
198
192
|
</div>
|
|
199
193
|
</ErrorBoundary>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
2
|
+
title: 'Markup Include',
|
|
3
|
+
showHeader: false,
|
|
4
|
+
type: 'markup-include',
|
|
5
|
+
srcUrl: '#example',
|
|
6
|
+
theme: 'theme-blue',
|
|
7
|
+
visual: {
|
|
8
|
+
border: false,
|
|
9
|
+
accent: false,
|
|
10
|
+
background: false,
|
|
11
|
+
hideBackgroundColor: false,
|
|
12
|
+
borderColorTheme: false
|
|
13
|
+
}
|
|
14
14
|
}
|
package/src/index.html
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.react-container+.react-container {
|
|
16
|
-
margin-top: 3rem;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
6
|
+
<style>
|
|
7
|
+
body {
|
|
8
|
+
/* max-width: 1000px; */
|
|
9
|
+
margin: 0 auto !important;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
}
|
|
21
14
|
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
.react-container + .react-container {
|
|
16
|
+
margin-top: 3rem;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<!-- Original -->
|
|
22
|
+
<div class="react-container" data-config="/examples/example-config.json"></div>
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
<!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/Markup-Include.html#examples -->
|
|
25
|
+
<!-- <div class="react-container" data-config="/examples/gallery/icon-no-text.json"></div> -->
|
|
26
|
+
<!-- <div class="react-container" data-config="/examples/gallery/image-with-text.json"></div> -->
|
|
27
|
+
<!-- <div class="react-container" data-config="/examples/gallery/button-and-text.json"></div> -->
|
|
28
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
29
|
+
</body>
|
|
31
30
|
</html>
|
package/src/index.js
CHANGED
|
@@ -8,11 +8,11 @@ const domContainers = document.querySelectorAll('.react-container')
|
|
|
8
8
|
|
|
9
9
|
let isEditor = window.location.href.includes('editor=true')
|
|
10
10
|
|
|
11
|
-
domContainers.forEach(
|
|
11
|
+
domContainers.forEach(domContainer => {
|
|
12
12
|
render(
|
|
13
13
|
<React.StrictMode>
|
|
14
14
|
<GlobalContextProvider>
|
|
15
|
-
<CdcMarkupInclude configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor}/>
|
|
15
|
+
<CdcMarkupInclude configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
|
|
16
16
|
</GlobalContextProvider>
|
|
17
17
|
</React.StrictMode>,
|
|
18
18
|
domContainer
|
package/src/scss/main.scss
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
@import '~@cdc/core/styles/v2/main';
|
|
2
2
|
|
|
3
3
|
.markup-include {
|
|
4
|
-
|
|
5
4
|
.checkbox-group {
|
|
6
5
|
padding: 16px;
|
|
7
6
|
border: 1px solid #c4c4c4;
|
|
8
7
|
border-radius: 8px;
|
|
9
8
|
margin-top: 8px;
|
|
10
|
-
margin-bottom: 24px;
|
|
9
|
+
margin-bottom: 24px;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
.cove-component__header {
|
|
12
|
+
.cove-component__header {
|
|
14
13
|
font-size: unset;
|
|
15
14
|
}
|
|
16
|
-
|
|
15
|
+
|
|
17
16
|
.cove-component__content {
|
|
18
17
|
background-color: #f2f2f2;
|
|
19
18
|
font-size: 14px;
|