@teamimpact/veda-ui-blocks 0.1.0-beta.7 → 0.1.0-beta.9
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 +6 -3
- package/dist/default.css +11280 -10085
- package/dist/default.css.map +1 -1
- package/dist/disasters.css +11278 -10083
- package/dist/disasters.css.map +1 -1
- package/dist/index.d.ts +169 -68
- package/dist/index.js +713 -152
- package/package.json +5 -7
- package/src/styles/components/banner.scss +0 -18
- package/src/styles/components/card-cta.scss +0 -90
- package/src/styles/components/card-detailed.scss +0 -164
- package/src/styles/components/card-mini.scss +0 -81
- package/src/styles/components/card-simple.scss +0 -79
- package/src/styles/components/card.scss +0 -284
- package/src/styles/components/compare-map.scss +0 -15
- package/src/styles/components/footer.scss +0 -256
- package/src/styles/components/header.scss +0 -212
- package/src/styles/components/index.scss +0 -11
- package/src/styles/components/tag.scss +0 -89
- package/src/styles/default/index.scss +0 -10
- package/src/styles/default/theme-tokens.scss +0 -84
- package/src/styles/disasters/card-cta.scss +0 -31
- package/src/styles/disasters/card-mini.scss +0 -4
- package/src/styles/disasters/card-simple.scss +0 -13
- package/src/styles/disasters/card.scss +0 -13
- package/src/styles/disasters/compare-map.scss +0 -3
- package/src/styles/disasters/fonts.scss +0 -29
- package/src/styles/disasters/footer.scss +0 -9
- package/src/styles/disasters/header.scss +0 -10
- package/src/styles/disasters/index.scss +0 -22
- package/src/styles/disasters/tag.scss +0 -6
- package/src/styles/disasters/theme-tokens.scss +0 -150
- package/src/styles/earthgov/footer.scss +0 -15
- package/src/styles/earthgov/index.scss +0 -12
- package/src/styles/earthgov/theme-tokens.scss +0 -104
package/dist/index.js
CHANGED
|
@@ -19,9 +19,13 @@ var isNull = (x) => x === null;
|
|
|
19
19
|
var isUndefined = (x) => x === void 0;
|
|
20
20
|
var isNil = (x) => isNull(x) || isUndefined(x);
|
|
21
21
|
var isDefined = (x) => !isNil(x);
|
|
22
|
+
var isNumber = (x) => typeof x === "number";
|
|
22
23
|
var isObject = (x) => !isNil(x) && typeof x === "object" && x instanceof Object;
|
|
24
|
+
var isEmptyObject = (x) => isObject(x) && isEmptyArray(Object.keys(x));
|
|
23
25
|
var isArray = (as) => Array.isArray(as);
|
|
26
|
+
var isEmptyArray = (as) => isArray(as) && as.length === 0;
|
|
24
27
|
var isNonEmptyArray = (as) => isArray(as) && as.length > 0;
|
|
28
|
+
var getTypedValues = Object.values;
|
|
25
29
|
|
|
26
30
|
// src/utils/component-utils.tsx
|
|
27
31
|
var get_external_anchor_props = (isExternal) => isExternal ? { target: "_blank", rel: "noopener noreferrer" } : {};
|
|
@@ -98,40 +102,8 @@ var DEFAULT_EXPANDED_CONTENT_JSX = /* @__PURE__ */ jsxs("div", { className: "blo
|
|
|
98
102
|
] })
|
|
99
103
|
] });
|
|
100
104
|
|
|
101
|
-
// src/components/Button/Button.tsx
|
|
102
|
-
import { Button as USWDSButton } from "@trussworks/react-uswds";
|
|
103
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
104
|
-
function Button({
|
|
105
|
-
type = "button",
|
|
106
|
-
secondary = false,
|
|
107
|
-
base = false,
|
|
108
|
-
accentStyle,
|
|
109
|
-
outline = false,
|
|
110
|
-
inverse = false,
|
|
111
|
-
size,
|
|
112
|
-
unstyled = false,
|
|
113
|
-
children,
|
|
114
|
-
className,
|
|
115
|
-
...rest
|
|
116
|
-
}) {
|
|
117
|
-
const uswdsButtonProps = {
|
|
118
|
-
secondary,
|
|
119
|
-
base,
|
|
120
|
-
outline,
|
|
121
|
-
inverse,
|
|
122
|
-
unstyled,
|
|
123
|
-
className,
|
|
124
|
-
type,
|
|
125
|
-
// Only add accentStyle and size if defined, to avoid passing undefined
|
|
126
|
-
...accentStyle ? { accentStyle } : {},
|
|
127
|
-
...size ? { size } : {},
|
|
128
|
-
children
|
|
129
|
-
};
|
|
130
|
-
return /* @__PURE__ */ jsx2(USWDSButton, { ...rest, ...uswdsButtonProps });
|
|
131
|
-
}
|
|
132
|
-
|
|
133
105
|
// src/components/Cards/Card/Card.tsx
|
|
134
|
-
import { jsx as
|
|
106
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
135
107
|
function Card({
|
|
136
108
|
tag,
|
|
137
109
|
title,
|
|
@@ -154,26 +126,52 @@ function Card({
|
|
|
154
126
|
]);
|
|
155
127
|
const hasContent = tag || title || subtitle || description || callToAction || callToActionSecondary;
|
|
156
128
|
return /* @__PURE__ */ jsxs2("div", { className: rootClassName, children: [
|
|
157
|
-
imagePosition === "cover" && /* @__PURE__ */
|
|
129
|
+
imagePosition === "cover" && /* @__PURE__ */ jsx2("div", { className: "blocks-card__media", children: image }),
|
|
158
130
|
/* @__PURE__ */ jsxs2("div", { className: "blocks-card__content-container", children: [
|
|
159
|
-
imagePosition !== "cover" && /* @__PURE__ */
|
|
131
|
+
imagePosition !== "cover" && /* @__PURE__ */ jsx2("div", { className: "blocks-card__media", children: image }),
|
|
160
132
|
hasContent && /* @__PURE__ */ jsxs2("div", { className: "blocks-card__content", children: [
|
|
161
|
-
tag && /* @__PURE__ */
|
|
162
|
-
title && (typeof title === "string" ? /* @__PURE__ */
|
|
163
|
-
subtitle && /* @__PURE__ */
|
|
164
|
-
description && /* @__PURE__ */
|
|
133
|
+
tag && /* @__PURE__ */ jsx2("div", { className: "blocks-card__tag", children: tag }),
|
|
134
|
+
title && (typeof title === "string" ? /* @__PURE__ */ jsx2("h2", { className: "blocks-card__title", children: title }) : title),
|
|
135
|
+
subtitle && /* @__PURE__ */ jsx2("div", { className: "blocks-card__subtitle", children: subtitle }),
|
|
136
|
+
description && /* @__PURE__ */ jsx2("p", { className: "blocks-card__description", children: description }),
|
|
165
137
|
(callToAction || callToActionSecondary) && /* @__PURE__ */ jsxs2("div", { className: "blocks-card__actions", children: [
|
|
166
|
-
callToAction && /* @__PURE__ */
|
|
167
|
-
callToActionSecondary && /* @__PURE__ */
|
|
138
|
+
callToAction && /* @__PURE__ */ jsx2("a", { href: callToAction.href, className: "usa-button", children: callToAction.label }),
|
|
139
|
+
callToActionSecondary && /* @__PURE__ */ jsx2("a", { href: callToActionSecondary.href, className: "usa-button usa-button--outline", children: callToActionSecondary.label })
|
|
168
140
|
] })
|
|
169
141
|
] })
|
|
170
142
|
] }),
|
|
171
|
-
children && /* @__PURE__ */
|
|
143
|
+
children && /* @__PURE__ */ jsx2("div", { className: "blocks-card__children", children })
|
|
172
144
|
] });
|
|
173
145
|
}
|
|
174
146
|
|
|
147
|
+
// src/components/icons/ArrowIcon.tsx
|
|
148
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
149
|
+
var ArrowIcon = () => /* @__PURE__ */ jsxs3(
|
|
150
|
+
"svg",
|
|
151
|
+
{
|
|
152
|
+
width: "20",
|
|
153
|
+
height: "20",
|
|
154
|
+
viewBox: "0 0 20 20",
|
|
155
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
156
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
157
|
+
"aria-hidden": "true",
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsx3("circle", { cx: "10", cy: "10", r: "10", fill: "currentColor" }),
|
|
160
|
+
/* @__PURE__ */ jsx3("g", { transform: "translate(5.333, 5.333)", children: /* @__PURE__ */ jsx3(
|
|
161
|
+
"path",
|
|
162
|
+
{
|
|
163
|
+
fillRule: "evenodd",
|
|
164
|
+
clipRule: "evenodd",
|
|
165
|
+
d: "M4.66667 0L3.84417 0.8225L7.09917 4.08333H0V5.25H7.09917L3.84417 8.51083L4.66667 9.33333L9.33333 4.66667L4.66667 0Z",
|
|
166
|
+
fill: "white"
|
|
167
|
+
}
|
|
168
|
+
) })
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
|
|
175
173
|
// src/components/Cards/CardCTA/CardCTA.tsx
|
|
176
|
-
import { jsx as jsx4, jsxs as
|
|
174
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
177
175
|
function CardCTA({
|
|
178
176
|
title,
|
|
179
177
|
url,
|
|
@@ -190,75 +188,54 @@ function CardCTA({
|
|
|
190
188
|
className
|
|
191
189
|
]);
|
|
192
190
|
const accentColorStyle = accentColor ? { "--blocks-card-cta-custom-accent-color": accentColor } : void 0;
|
|
193
|
-
return /* @__PURE__ */ jsx4("a", { href: url, className: rootClassName, style: { ...accentColorStyle, ...style }, ...rest, children: /* @__PURE__ */
|
|
194
|
-
/* @__PURE__ */
|
|
191
|
+
return /* @__PURE__ */ jsx4("a", { href: url, className: rootClassName, style: { ...accentColorStyle, ...style }, ...rest, children: /* @__PURE__ */ jsxs4("div", { className: "blocks-card-cta__body", children: [
|
|
192
|
+
/* @__PURE__ */ jsxs4(TitleTag, { className: "blocks-card-cta__title", title, children: [
|
|
195
193
|
title,
|
|
196
|
-
/* @__PURE__ */ jsx4("span", { className: "blocks-card-cta__icon", "aria-hidden": "true", children: /* @__PURE__ */
|
|
197
|
-
"svg",
|
|
198
|
-
{
|
|
199
|
-
width: "20",
|
|
200
|
-
height: "20",
|
|
201
|
-
viewBox: "0 0 20 20",
|
|
202
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
203
|
-
preserveAspectRatio: "xMidYMid meet",
|
|
204
|
-
"aria-hidden": "true",
|
|
205
|
-
children: [
|
|
206
|
-
/* @__PURE__ */ jsx4("circle", { cx: "10", cy: "10", r: "10", fill: "currentColor" }),
|
|
207
|
-
/* @__PURE__ */ jsx4("g", { transform: "translate(5.333, 5.333)", children: /* @__PURE__ */ jsx4(
|
|
208
|
-
"path",
|
|
209
|
-
{
|
|
210
|
-
fillRule: "evenodd",
|
|
211
|
-
clipRule: "evenodd",
|
|
212
|
-
d: "M4.66667 0L3.84417 0.8225L7.09917 4.08333H0V5.25H7.09917L3.84417 8.51083L4.66667 9.33333L9.33333 4.66667L4.66667 0Z",
|
|
213
|
-
fill: "white"
|
|
214
|
-
}
|
|
215
|
-
) })
|
|
216
|
-
]
|
|
217
|
-
}
|
|
218
|
-
) })
|
|
194
|
+
/* @__PURE__ */ jsx4("span", { className: "blocks-card-cta__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(ArrowIcon, {}) })
|
|
219
195
|
] }),
|
|
220
196
|
description && /* @__PURE__ */ jsx4("p", { className: "blocks-card-cta__description", children: description })
|
|
221
197
|
] }) });
|
|
222
198
|
}
|
|
223
199
|
|
|
224
200
|
// src/components/Cards/CardDetailed/CardDetailed.tsx
|
|
225
|
-
import { jsx as jsx5, jsxs as
|
|
201
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
226
202
|
function CardDetailed({
|
|
227
203
|
intro,
|
|
228
204
|
title,
|
|
229
205
|
description,
|
|
230
206
|
tags = [],
|
|
231
|
-
|
|
207
|
+
callToAction,
|
|
208
|
+
callToActionSecondary,
|
|
209
|
+
tagPrimary,
|
|
232
210
|
image,
|
|
233
|
-
action,
|
|
234
211
|
imagePosition = "top",
|
|
235
|
-
borderAccent = false,
|
|
236
|
-
titleAs = "h2",
|
|
237
212
|
className = ""
|
|
238
213
|
}) {
|
|
239
|
-
const
|
|
240
|
-
const cardClassName = make_class_name("blocks-card-detailed", [
|
|
214
|
+
const rootClassName = make_class_name("blocks-card-detailed", [
|
|
241
215
|
imagePosition !== "top" ? `blocks-card-detailed--image-${imagePosition}` : "",
|
|
242
216
|
className
|
|
243
217
|
]);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
/* @__PURE__ */
|
|
247
|
-
intro && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__intro", children: intro }),
|
|
248
|
-
/* @__PURE__ */ jsx5(TitleTag, { className: "blocks-card-detailed__title", children: title }),
|
|
249
|
-
description && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__description", children: description }),
|
|
250
|
-
isNonEmptyArray(tags) && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__tags", children: tags }),
|
|
251
|
-
action && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__action", children: action })
|
|
252
|
-
] }),
|
|
253
|
-
/* @__PURE__ */ jsxs4("div", { className: "blocks-card-detailed__image-wrapper", children: [
|
|
218
|
+
const hasContent = intro || title || description || tags.length || callToAction || callToActionSecondary;
|
|
219
|
+
return /* @__PURE__ */ jsxs5("div", { className: rootClassName, children: [
|
|
220
|
+
/* @__PURE__ */ jsxs5("div", { className: "blocks-card-detailed__media", children: [
|
|
254
221
|
image,
|
|
255
|
-
|
|
222
|
+
tagPrimary && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__tag-primary", children: tagPrimary })
|
|
223
|
+
] }),
|
|
224
|
+
hasContent && /* @__PURE__ */ jsxs5("div", { className: "blocks-card-detailed__content-container", children: [
|
|
225
|
+
intro && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__intro", title: intro, children: intro }),
|
|
226
|
+
title && (typeof title === "string" ? /* @__PURE__ */ jsx5("h2", { className: "blocks-card-detailed__title", title, children: title }) : title),
|
|
227
|
+
isNonEmptyArray(tags) && /* @__PURE__ */ jsx5("div", { className: "blocks-card-detailed__tags", children: tags }),
|
|
228
|
+
description && /* @__PURE__ */ jsx5("p", { className: "blocks-card-detailed__description", children: description }),
|
|
229
|
+
(callToAction || callToActionSecondary) && /* @__PURE__ */ jsxs5("div", { className: "blocks-card-detailed__actions", children: [
|
|
230
|
+
callToAction && /* @__PURE__ */ jsx5("a", { href: callToAction.href, className: "usa-button", children: callToAction.label }),
|
|
231
|
+
callToActionSecondary && /* @__PURE__ */ jsx5("a", { href: callToActionSecondary.href, className: "usa-button usa-button--outline", children: callToActionSecondary.label })
|
|
232
|
+
] })
|
|
256
233
|
] })
|
|
257
234
|
] });
|
|
258
235
|
}
|
|
259
236
|
|
|
260
237
|
// src/components/Cards/CardMini/CardMini.tsx
|
|
261
|
-
import { jsx as jsx6, jsxs as
|
|
238
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
262
239
|
function CardMini({ image, title, url, tag, titleAs = "h2", className }) {
|
|
263
240
|
const TitleTag = titleAs;
|
|
264
241
|
const hasTag = Boolean(tag);
|
|
@@ -266,9 +243,9 @@ function CardMini({ image, title, url, tag, titleAs = "h2", className }) {
|
|
|
266
243
|
hasTag ? "blocks-card-mini--with-tag" : void 0,
|
|
267
244
|
className
|
|
268
245
|
]);
|
|
269
|
-
return /* @__PURE__ */
|
|
246
|
+
return /* @__PURE__ */ jsxs6("a", { href: url, className: rootClassName, children: [
|
|
270
247
|
/* @__PURE__ */ jsx6("div", { className: "blocks-card-mini__image", children: image }),
|
|
271
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ jsxs6("div", { className: "blocks-card-mini__body", children: [
|
|
272
249
|
/* @__PURE__ */ jsx6(TitleTag, { className: "blocks-card-mini__title", title, children: title }),
|
|
273
250
|
tag && /* @__PURE__ */ jsx6("div", { className: "blocks-card-mini__tag", children: tag })
|
|
274
251
|
] })
|
|
@@ -276,29 +253,27 @@ function CardMini({ image, title, url, tag, titleAs = "h2", className }) {
|
|
|
276
253
|
}
|
|
277
254
|
|
|
278
255
|
// src/components/Cards/CardSimple/CardSimple.tsx
|
|
279
|
-
import { jsx as jsx7, jsxs as
|
|
256
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
280
257
|
function CardSimple({
|
|
281
258
|
title,
|
|
282
259
|
image,
|
|
283
260
|
url,
|
|
284
261
|
tag,
|
|
285
|
-
showOverlay = false,
|
|
286
262
|
size = "default",
|
|
287
263
|
titleAs = "h2",
|
|
288
264
|
className
|
|
289
265
|
}) {
|
|
290
266
|
const TitleTag = titleAs;
|
|
291
267
|
const rootClassName = make_class_name("blocks-card-simple", [
|
|
292
|
-
showOverlay ? "blocks-card-simple--with-overlay" : void 0,
|
|
293
268
|
size === "compact" ? "blocks-card-simple--compact" : void 0,
|
|
294
269
|
className
|
|
295
270
|
]);
|
|
296
|
-
return /* @__PURE__ */
|
|
297
|
-
/* @__PURE__ */
|
|
271
|
+
return /* @__PURE__ */ jsxs7("a", { href: url, className: rootClassName, children: [
|
|
272
|
+
/* @__PURE__ */ jsxs7("div", { className: "blocks-card-simple__media", children: [
|
|
298
273
|
image,
|
|
299
|
-
|
|
274
|
+
/* @__PURE__ */ jsx7("div", { className: "blocks-card-simple__overlay", "aria-hidden": "true" })
|
|
300
275
|
] }),
|
|
301
|
-
/* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ jsxs7("div", { className: "blocks-card-simple__body", children: [
|
|
302
277
|
tag && /* @__PURE__ */ jsx7("div", { className: "blocks-card-simple__tag", children: tag }),
|
|
303
278
|
/* @__PURE__ */ jsx7(TitleTag, { className: "blocks-card-simple__title", children: title })
|
|
304
279
|
] })
|
|
@@ -307,7 +282,7 @@ function CardSimple({
|
|
|
307
282
|
|
|
308
283
|
// src/components/Footer/Footer.tsx
|
|
309
284
|
import { GridContainer, Icon as Icon2, Link, Footer as USWDSFooter } from "@trussworks/react-uswds";
|
|
310
|
-
import { Fragment, jsx as jsx8, jsxs as
|
|
285
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
311
286
|
function Footer({
|
|
312
287
|
portalDetails,
|
|
313
288
|
primaryNavItems,
|
|
@@ -321,25 +296,25 @@ function Footer({
|
|
|
321
296
|
{
|
|
322
297
|
className: footerClassName,
|
|
323
298
|
size: "slim",
|
|
324
|
-
primary: /* @__PURE__ */
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
/* @__PURE__ */
|
|
299
|
+
primary: /* @__PURE__ */ jsx8(GridContainer, { children: /* @__PURE__ */ jsxs8("section", { className: "blocks-footer__primary-section", children: [
|
|
300
|
+
/* @__PURE__ */ jsxs8("div", { className: "blocks-footer__title", children: [
|
|
301
|
+
portalDetails.logo ? /* @__PURE__ */ jsx8("div", { className: "blocks-footer__logo", children: portalDetails.logo }) : null,
|
|
302
|
+
/* @__PURE__ */ jsxs8("div", { className: "blocks-footer__title-text", children: [
|
|
328
303
|
/* @__PURE__ */ jsx8("span", { children: portalDetails.title }),
|
|
329
304
|
portalDetails.tagline ? /* @__PURE__ */ jsx8("p", { children: portalDetails.tagline }) : null
|
|
330
|
-
] })
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
] }),
|
|
342
|
-
secondary: /* @__PURE__ */
|
|
305
|
+
] })
|
|
306
|
+
] }),
|
|
307
|
+
primaryNavItems.length > 0 ? /* @__PURE__ */ jsx8("nav", { className: "blocks-footer__primary-nav", "aria-label": "Footer primary navigation", children: /* @__PURE__ */ jsx8("ul", { children: primaryNavItems.map(({ label, href, isExternal }) => /* @__PURE__ */ jsx8("li", { className: "usa-footer__primary-content", children: /* @__PURE__ */ jsx8(
|
|
308
|
+
Link,
|
|
309
|
+
{
|
|
310
|
+
className: "usa-footer__primary-link",
|
|
311
|
+
href,
|
|
312
|
+
...get_external_anchor_props(isExternal),
|
|
313
|
+
children: label
|
|
314
|
+
}
|
|
315
|
+
) }, href)) }) }) : null
|
|
316
|
+
] }) }),
|
|
317
|
+
secondary: /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
343
318
|
secondaryNavItems.length > 0 ? /* @__PURE__ */ jsx8("section", { className: "blocks-footer__secondary-section-upper", children: /* @__PURE__ */ jsx8(
|
|
344
319
|
"nav",
|
|
345
320
|
{
|
|
@@ -348,19 +323,20 @@ function Footer({
|
|
|
348
323
|
children: /* @__PURE__ */ jsx8("ul", { children: secondaryNavItems.map(({ label, href, isExternal }) => /* @__PURE__ */ jsx8("li", { className: "usa-footer__secondary-link", children: /* @__PURE__ */ jsx8(Link, { href, ...get_external_anchor_props(isExternal), children: label }) }, href)) })
|
|
349
324
|
}
|
|
350
325
|
) }) : null,
|
|
351
|
-
utilityNavItems?.length || portalDetails.updatedDate || portalDetails.contacts?.length ? /* @__PURE__ */
|
|
352
|
-
utilityNavItems?.length ? /* @__PURE__ */ jsx8("nav", { className: "blocks-footer__utility-nav", "aria-label": "Site utilities", children: /* @__PURE__ */ jsx8("ul", { children: utilityNavItems.length ? utilityNavItems.map(({ text, label, href, isExternal }) => /* @__PURE__ */
|
|
326
|
+
utilityNavItems?.length || portalDetails.updatedDate || portalDetails.contacts?.length ? /* @__PURE__ */ jsxs8("section", { className: "blocks-footer__secondary-section-lower", children: [
|
|
327
|
+
utilityNavItems?.length ? /* @__PURE__ */ jsx8("nav", { className: "blocks-footer__utility-nav", "aria-label": "Site utilities", children: /* @__PURE__ */ jsx8("ul", { children: utilityNavItems.length ? utilityNavItems.map(({ text, label, href, isExternal }) => /* @__PURE__ */ jsxs8("li", { children: [
|
|
353
328
|
text,
|
|
329
|
+
" ",
|
|
354
330
|
/* @__PURE__ */ jsx8(Link, { href, ...get_external_anchor_props(isExternal), children: label })
|
|
355
331
|
] }, href)) : null }) }) : null,
|
|
356
|
-
portalDetails.updatedDate || portalDetails.contacts?.length ? /* @__PURE__ */
|
|
357
|
-
portalDetails.updatedDate ? /* @__PURE__ */
|
|
332
|
+
portalDetails.updatedDate || portalDetails.contacts?.length ? /* @__PURE__ */ jsxs8("div", { className: "blocks-footer__secondary-meta", children: [
|
|
333
|
+
portalDetails.updatedDate ? /* @__PURE__ */ jsxs8("p", { children: [
|
|
358
334
|
"Site last updated: ",
|
|
359
335
|
portalDetails.updatedDate
|
|
360
336
|
] }) : null,
|
|
361
|
-
portalDetails.contacts?.length ? /* @__PURE__ */ jsx8("nav", { className: "blocks-footer__contacts-nav", "aria-label": "Site contacts", children: /* @__PURE__ */ jsx8("ul", { children: portalDetails.contacts.map(({ label, name, email }) => /* @__PURE__ */
|
|
337
|
+
portalDetails.contacts?.length ? /* @__PURE__ */ jsx8("nav", { className: "blocks-footer__contacts-nav", "aria-label": "Site contacts", children: /* @__PURE__ */ jsx8("ul", { children: portalDetails.contacts.map(({ label, name, email }) => /* @__PURE__ */ jsxs8("li", { children: [
|
|
362
338
|
/* @__PURE__ */ jsx8("span", { children: label }),
|
|
363
|
-
/* @__PURE__ */
|
|
339
|
+
/* @__PURE__ */ jsxs8(Link, { href: `mailto:${email}`, ...get_external_anchor_props(), children: [
|
|
364
340
|
/* @__PURE__ */ jsx8(Icon2.Mail, { "aria-hidden": "true", focusable: false }),
|
|
365
341
|
/* @__PURE__ */ jsx8("span", { children: name })
|
|
366
342
|
] })
|
|
@@ -420,7 +396,7 @@ function useWindowResize(handleResize) {
|
|
|
420
396
|
|
|
421
397
|
// src/components/Header/Header.helpers.tsx
|
|
422
398
|
import { Link as Link2, Menu, NavDropDownButton } from "@trussworks/react-uswds";
|
|
423
|
-
import { Fragment as Fragment2, jsx as jsx9, jsxs as
|
|
399
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
424
400
|
var make_nav_items_initial_state = (navItems) => {
|
|
425
401
|
const initialState = {};
|
|
426
402
|
const initialProps = navItems.map((item) => {
|
|
@@ -467,7 +443,7 @@ var make_menu_link_jsx = ({ label, href, isExternal, isPrimary }, options) => {
|
|
|
467
443
|
var make_menu_link_with_dropdown_jsx = ({ label, menuId, subItems }, options) => {
|
|
468
444
|
const { navDropDownOpenState, handleToggleDropdown, currentPath } = options;
|
|
469
445
|
const sublinks = subItems.map((item) => make_menu_link_jsx(item, { currentPath }));
|
|
470
|
-
return /* @__PURE__ */
|
|
446
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
471
447
|
/* @__PURE__ */ jsx9(
|
|
472
448
|
NavDropDownButton,
|
|
473
449
|
{
|
|
@@ -493,7 +469,7 @@ var make_custom_nav_item_jsx = (customNavItem) => isNavItem(customNavItem) ? /*
|
|
|
493
469
|
) : customNavItem;
|
|
494
470
|
|
|
495
471
|
// src/components/Header/Header.tsx
|
|
496
|
-
import { jsx as jsx10, jsxs as
|
|
472
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
497
473
|
function Header(props) {
|
|
498
474
|
const {
|
|
499
475
|
portalDetails: { logo, title, url },
|
|
@@ -561,9 +537,9 @@ function Header(props) {
|
|
|
561
537
|
currentPath
|
|
562
538
|
}) : make_menu_link_jsx(item, { currentPath })
|
|
563
539
|
);
|
|
564
|
-
return /* @__PURE__ */ jsx10(USWDSHeader, { className: headerClassName, basic: true, showMobileOverlay: isMobileNavExpanded, children: /* @__PURE__ */
|
|
565
|
-
/* @__PURE__ */
|
|
566
|
-
/* @__PURE__ */
|
|
540
|
+
return /* @__PURE__ */ jsx10(USWDSHeader, { className: headerClassName, basic: true, showMobileOverlay: isMobileNavExpanded, children: /* @__PURE__ */ jsxs10("div", { className: "usa-nav-container", children: [
|
|
541
|
+
/* @__PURE__ */ jsxs10("div", { className: "usa-navbar", children: [
|
|
542
|
+
/* @__PURE__ */ jsxs10("div", { className: "blocks-header__portal-details", children: [
|
|
567
543
|
/* @__PURE__ */ jsx10("a", { className: "blocks-header__portal-logo", href: url ?? "/", children: logo }),
|
|
568
544
|
title ? /* @__PURE__ */ jsx10(Title, { children: /* @__PURE__ */ jsx10("a", { href: url ?? "/", children: title }) }) : null
|
|
569
545
|
] }),
|
|
@@ -582,12 +558,145 @@ function Header(props) {
|
|
|
582
558
|
] }) });
|
|
583
559
|
}
|
|
584
560
|
|
|
561
|
+
// src/components/Link/Link.tsx
|
|
562
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
563
|
+
function Link3({
|
|
564
|
+
variant = "text",
|
|
565
|
+
size = "md",
|
|
566
|
+
isExternal,
|
|
567
|
+
className,
|
|
568
|
+
as,
|
|
569
|
+
children,
|
|
570
|
+
...rest
|
|
571
|
+
}) {
|
|
572
|
+
const Component = isExternal ? "a" : as ?? "a";
|
|
573
|
+
const rootClassName = make_class_name("blocks-link", [
|
|
574
|
+
`blocks-link--${variant}`,
|
|
575
|
+
variant === "button" || variant === "button-outline" ? "usa-button" : void 0,
|
|
576
|
+
variant === "button-outline" ? "usa-button--outline" : void 0,
|
|
577
|
+
variant === "text" ? "usa-button--unstyled" : void 0,
|
|
578
|
+
`blocks-link--${size}`,
|
|
579
|
+
isExternal ? "blocks-link--external usa-link--external" : void 0,
|
|
580
|
+
className
|
|
581
|
+
]);
|
|
582
|
+
return /* @__PURE__ */ jsxs11(Component, { className: rootClassName, ...get_external_anchor_props(isExternal), ...rest, children: [
|
|
583
|
+
children,
|
|
584
|
+
variant === "arrow" && /* @__PURE__ */ jsx11(ArrowIcon, {})
|
|
585
|
+
] });
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// src/foundations/theme-token-bridge.helpers.ts
|
|
589
|
+
var BASE_COLOR_TOKENS = [
|
|
590
|
+
"base-lightest",
|
|
591
|
+
"base-lighter",
|
|
592
|
+
"base-light",
|
|
593
|
+
"base",
|
|
594
|
+
"base-dark",
|
|
595
|
+
"base-darker",
|
|
596
|
+
"base-darkest",
|
|
597
|
+
"ink"
|
|
598
|
+
];
|
|
599
|
+
var PRIMARY_COLOR_TOKENS = [
|
|
600
|
+
"primary-lightest",
|
|
601
|
+
"primary-lighter",
|
|
602
|
+
"primary-light",
|
|
603
|
+
"primary",
|
|
604
|
+
"primary-vivid",
|
|
605
|
+
"primary-dark",
|
|
606
|
+
"primary-darker",
|
|
607
|
+
"primary-darkest"
|
|
608
|
+
];
|
|
609
|
+
var SECONDARY_COLOR_TOKENS = [
|
|
610
|
+
"secondary-lightest",
|
|
611
|
+
"secondary-lighter",
|
|
612
|
+
"secondary-light",
|
|
613
|
+
"secondary",
|
|
614
|
+
"secondary-vivid",
|
|
615
|
+
"secondary-dark",
|
|
616
|
+
"secondary-darker",
|
|
617
|
+
"secondary-darkest"
|
|
618
|
+
];
|
|
619
|
+
var ACCENT_COOL_COLOR_TOKENS = [
|
|
620
|
+
"accent-cool-lightest",
|
|
621
|
+
"accent-cool-lighter",
|
|
622
|
+
"accent-cool-light",
|
|
623
|
+
"accent-cool",
|
|
624
|
+
"accent-cool-dark",
|
|
625
|
+
"accent-cool-darker",
|
|
626
|
+
"accent-cool-darkest"
|
|
627
|
+
];
|
|
628
|
+
var ACCENT_WARM_COLOR_TOKENS = [
|
|
629
|
+
"accent-warm-lightest",
|
|
630
|
+
"accent-warm-lighter",
|
|
631
|
+
"accent-warm-light",
|
|
632
|
+
"accent-warm",
|
|
633
|
+
"accent-warm-dark",
|
|
634
|
+
"accent-warm-darker",
|
|
635
|
+
"accent-warm-darkest"
|
|
636
|
+
];
|
|
637
|
+
var INFO_COLOR_TOKENS = [
|
|
638
|
+
"info-lighter",
|
|
639
|
+
"info-light",
|
|
640
|
+
"info",
|
|
641
|
+
"info-dark",
|
|
642
|
+
"info-darker"
|
|
643
|
+
];
|
|
644
|
+
var WARNING_COLOR_TOKENS = [
|
|
645
|
+
"warning-lighter",
|
|
646
|
+
"warning-light",
|
|
647
|
+
"warning",
|
|
648
|
+
"warning-dark",
|
|
649
|
+
"warning-darker"
|
|
650
|
+
];
|
|
651
|
+
var ERROR_COLOR_TOKENS = [
|
|
652
|
+
"error-lighter",
|
|
653
|
+
"error-light",
|
|
654
|
+
"error",
|
|
655
|
+
"error-dark",
|
|
656
|
+
"error-darker"
|
|
657
|
+
];
|
|
658
|
+
var SUCCESS_COLOR_TOKENS = [
|
|
659
|
+
"success-lighter",
|
|
660
|
+
"success-light",
|
|
661
|
+
"success",
|
|
662
|
+
"success-dark",
|
|
663
|
+
"success-darker"
|
|
664
|
+
];
|
|
665
|
+
var DISABLED_COLOR_TOKENS = [
|
|
666
|
+
"disabled-lighter",
|
|
667
|
+
"disabled-light",
|
|
668
|
+
"disabled",
|
|
669
|
+
"disabled-dark",
|
|
670
|
+
"disabled-darker"
|
|
671
|
+
];
|
|
672
|
+
var EMERGENCY_COLOR_TOKENS = ["emergency", "emergency-dark"];
|
|
673
|
+
var COLOR_TOKENS = [
|
|
674
|
+
...BASE_COLOR_TOKENS,
|
|
675
|
+
...PRIMARY_COLOR_TOKENS,
|
|
676
|
+
...SECONDARY_COLOR_TOKENS,
|
|
677
|
+
...ACCENT_COOL_COLOR_TOKENS,
|
|
678
|
+
...ACCENT_WARM_COLOR_TOKENS,
|
|
679
|
+
...INFO_COLOR_TOKENS,
|
|
680
|
+
...WARNING_COLOR_TOKENS,
|
|
681
|
+
...ERROR_COLOR_TOKENS,
|
|
682
|
+
...SUCCESS_COLOR_TOKENS,
|
|
683
|
+
...EMERGENCY_COLOR_TOKENS,
|
|
684
|
+
...DISABLED_COLOR_TOKENS
|
|
685
|
+
];
|
|
686
|
+
var resolveColorToken = (color) => COLOR_TOKENS.includes(color) ? `var(--color-${color})` : color;
|
|
687
|
+
|
|
688
|
+
// src/components/icons/CloseIcon.tsx
|
|
689
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
690
|
+
var CloseIcon = () => /* @__PURE__ */ jsx12("svg", { height: "24", width: "24", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx12("path", { d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) });
|
|
691
|
+
|
|
585
692
|
// src/components/Tag/Tag.tsx
|
|
586
|
-
import { jsx as
|
|
693
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
587
694
|
function Tag({
|
|
588
695
|
variant = "solid",
|
|
589
696
|
size = "default",
|
|
590
697
|
color,
|
|
698
|
+
bgColor,
|
|
699
|
+
borderColor,
|
|
591
700
|
textColor,
|
|
592
701
|
icon,
|
|
593
702
|
onClose,
|
|
@@ -601,14 +710,16 @@ function Tag({
|
|
|
601
710
|
onClose ? "blocks-tag--x-close" : void 0,
|
|
602
711
|
className
|
|
603
712
|
]);
|
|
604
|
-
const customStyle = color || textColor ? {
|
|
605
|
-
...color ? { "--blocks-tag-custom-color": color } : void 0,
|
|
606
|
-
...textColor ? { "--blocks-tag-custom-text-color": textColor } : void 0
|
|
713
|
+
const customStyle = color || textColor || bgColor || borderColor ? {
|
|
714
|
+
...color ? { "--blocks-tag-custom-color": resolveColorToken(color) } : void 0,
|
|
715
|
+
...textColor ? { "--blocks-tag-custom-text-color": resolveColorToken(textColor) } : void 0,
|
|
716
|
+
...bgColor ? { "--blocks-tag-custom-bg-color": resolveColorToken(bgColor) } : void 0,
|
|
717
|
+
...borderColor ? { "--blocks-tag-custom-border-color": resolveColorToken(borderColor) } : void 0
|
|
607
718
|
} : void 0;
|
|
608
|
-
return /* @__PURE__ */
|
|
609
|
-
icon && /* @__PURE__ */
|
|
719
|
+
return /* @__PURE__ */ jsxs12("span", { className: rootClassName, style: customStyle, children: [
|
|
720
|
+
icon && /* @__PURE__ */ jsx13("span", { className: "blocks-tag__icon", children: icon }),
|
|
610
721
|
children,
|
|
611
|
-
onClose && /* @__PURE__ */
|
|
722
|
+
onClose && /* @__PURE__ */ jsx13(
|
|
612
723
|
"button",
|
|
613
724
|
{
|
|
614
725
|
type: "button",
|
|
@@ -616,14 +727,15 @@ function Tag({
|
|
|
616
727
|
"aria-label": "Remove tag",
|
|
617
728
|
tabIndex: 0,
|
|
618
729
|
onClick: onClose,
|
|
619
|
-
children: /* @__PURE__ */
|
|
730
|
+
children: /* @__PURE__ */ jsx13(CloseIcon, {})
|
|
620
731
|
}
|
|
621
732
|
)
|
|
622
733
|
] });
|
|
623
734
|
}
|
|
624
735
|
|
|
625
|
-
// src/geo/
|
|
626
|
-
import {
|
|
736
|
+
// src/geo/GeoConfigProvider.tsx
|
|
737
|
+
import { StacApiProvider } from "@developmentseed/stac-react";
|
|
738
|
+
import { createContext, useContext } from "react";
|
|
627
739
|
|
|
628
740
|
// src/geo/constants.ts
|
|
629
741
|
var NASA_BLUE_MARBLE_BASEMAP_STYLE = {
|
|
@@ -647,35 +759,484 @@ var NASA_BLUE_MARBLE_BASEMAP_STYLE = {
|
|
|
647
759
|
}
|
|
648
760
|
]
|
|
649
761
|
};
|
|
762
|
+
var STAC_API_URL = "https://openveda.cloud/api/stac";
|
|
763
|
+
var TITILER_BASE_URL = "https://openveda.cloud/api/raster";
|
|
764
|
+
var DEFAULT_RENDER_PARAMS = {
|
|
765
|
+
assets: ["cog_default"],
|
|
766
|
+
rescale: "0,0.0001",
|
|
767
|
+
resampling: "bilinear",
|
|
768
|
+
colormap_name: "viridis",
|
|
769
|
+
bidx: [1]
|
|
770
|
+
};
|
|
771
|
+
var DEFAULT_TILE_MATRIX_SET = "WebMercatorQuad";
|
|
772
|
+
var STAC_COLORSTOP_RGBA_ARG_COUNT = 4;
|
|
650
773
|
|
|
651
|
-
// src/geo/
|
|
652
|
-
import "
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
774
|
+
// src/geo/GeoConfigProvider.tsx
|
|
775
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
776
|
+
var GeoConfigContext = createContext(null);
|
|
777
|
+
function useGeoConfig() {
|
|
778
|
+
const ctx = useContext(GeoConfigContext);
|
|
779
|
+
if (!ctx) throw new Error("Geo components require a GeoConfigProvider ancestor");
|
|
780
|
+
return ctx;
|
|
781
|
+
}
|
|
782
|
+
function GeoConfigProvider({
|
|
783
|
+
stacApiUrl = STAC_API_URL,
|
|
784
|
+
titilerBaseUrl = TITILER_BASE_URL,
|
|
657
785
|
children
|
|
658
786
|
}) {
|
|
659
|
-
return /* @__PURE__ */
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
787
|
+
return /* @__PURE__ */ jsx14(GeoConfigContext.Provider, { value: { titilerBaseUrl }, children: /* @__PURE__ */ jsx14(StacApiProvider, { apiUrl: stacApiUrl, children }) });
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// src/geo/Legend/Legend.tsx
|
|
791
|
+
import { Icon as Icon3 } from "@trussworks/react-uswds";
|
|
792
|
+
import { useState as useState3 } from "react";
|
|
793
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
794
|
+
function Legend({ initialExpanded = false, ...props }) {
|
|
795
|
+
const { title, description, unit, min, max, colorStops, provider, spatialExtent, timeDensity } = props;
|
|
796
|
+
const [isExpanded, setIsExpanded] = useState3(initialExpanded);
|
|
797
|
+
const subtitle = [provider, spatialExtent, timeDensity].some(isDefined) ? [provider, spatialExtent, timeDensity].filter(isDefined).join(" \xB7 ") : void 0;
|
|
798
|
+
return /* @__PURE__ */ jsxs13("div", { className: "blocks-legend", children: [
|
|
799
|
+
/* @__PURE__ */ jsxs13("div", { className: "blocks-legend__header", children: [
|
|
800
|
+
/* @__PURE__ */ jsxs13("div", { className: "blocks-legend__header-text", children: [
|
|
801
|
+
title && /* @__PURE__ */ jsx15("h3", { className: "blocks-legend__title", title, children: title }),
|
|
802
|
+
subtitle && /* @__PURE__ */ jsx15("p", { className: "blocks-legend__subtitle", title: subtitle, children: subtitle })
|
|
803
|
+
] }),
|
|
804
|
+
description && /* @__PURE__ */ jsx15(
|
|
805
|
+
"button",
|
|
806
|
+
{
|
|
807
|
+
type: "button",
|
|
808
|
+
className: "blocks-legend__info-toggle",
|
|
809
|
+
"aria-expanded": isExpanded,
|
|
810
|
+
"aria-label": "Toggle layer description",
|
|
811
|
+
onClick: () => setIsExpanded((v) => !v),
|
|
812
|
+
children: /* @__PURE__ */ jsx15(Icon3.InfoOutline, { "aria-hidden": true, focusable: false, size: 3 })
|
|
813
|
+
}
|
|
814
|
+
)
|
|
815
|
+
] }),
|
|
816
|
+
/* @__PURE__ */ jsx15("div", { className: "blocks-legend__gradient-bar", children: /* @__PURE__ */ jsx15(
|
|
817
|
+
"div",
|
|
818
|
+
{
|
|
819
|
+
className: "blocks-legend__gradient",
|
|
820
|
+
style: {
|
|
821
|
+
background: `linear-gradient(to right, ${colorStops.join(", ")})`
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
) }),
|
|
825
|
+
/* @__PURE__ */ jsxs13("div", { className: "blocks-legend__labels", children: [
|
|
826
|
+
/* @__PURE__ */ jsx15("span", { className: "blocks-legend__min", children: min }),
|
|
827
|
+
/* @__PURE__ */ jsx15("span", { className: "blocks-legend__unit", children: unit }),
|
|
828
|
+
/* @__PURE__ */ jsx15("span", { className: "blocks-legend__max", children: max })
|
|
829
|
+
] }),
|
|
830
|
+
isExpanded && description && /* @__PURE__ */ jsx15("div", { className: "blocks-legend__description", children: /* @__PURE__ */ jsx15("div", { className: "blocks-legend__description-inner", children: description }) })
|
|
831
|
+
] });
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// src/geo/StacCompareMap/StacCompareMap.tsx
|
|
835
|
+
import { useEffect as useEffect3, useId, useRef as useRef3, useState as useState4 } from "react";
|
|
836
|
+
import {
|
|
837
|
+
Layer,
|
|
838
|
+
Map as MapLibreMap,
|
|
839
|
+
NavigationControl,
|
|
840
|
+
Source
|
|
841
|
+
} from "react-map-gl/maplibre";
|
|
842
|
+
|
|
843
|
+
// src/geo/AttributionMapControl.tsx
|
|
844
|
+
import maplibregl from "maplibre-gl";
|
|
845
|
+
import { useControl } from "react-map-gl/maplibre";
|
|
846
|
+
function AttributionMapControl({ position = "top-right" }) {
|
|
847
|
+
useControl(() => new maplibregl.AttributionControl(), { position });
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// src/geo/utils/formatDateRange.ts
|
|
852
|
+
function formatDateRange(dateRange) {
|
|
853
|
+
const from = /* @__PURE__ */ new Date(`${dateRange.from}T00:00:00Z`);
|
|
854
|
+
const to = /* @__PURE__ */ new Date(`${dateRange.to}T00:00:00Z`);
|
|
855
|
+
if (from.getUTCFullYear() === to.getUTCFullYear() && from.getUTCMonth() === to.getUTCMonth()) {
|
|
856
|
+
return from.toLocaleDateString("en-US", {
|
|
857
|
+
month: "short",
|
|
858
|
+
year: "numeric",
|
|
859
|
+
timeZone: "UTC"
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
const fromStr = from.toLocaleDateString("en-US", {
|
|
863
|
+
month: "short",
|
|
864
|
+
day: "numeric",
|
|
865
|
+
year: "numeric",
|
|
866
|
+
timeZone: "UTC"
|
|
867
|
+
});
|
|
868
|
+
const toStr = to.toLocaleDateString("en-US", {
|
|
869
|
+
month: "short",
|
|
870
|
+
day: "numeric",
|
|
871
|
+
year: "numeric",
|
|
872
|
+
timeZone: "UTC"
|
|
873
|
+
});
|
|
874
|
+
return `${fromStr} \u2013 ${toStr}`;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// src/geo/DateChip/DateChip.tsx
|
|
878
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
879
|
+
function DateChip({ left, right }) {
|
|
880
|
+
const label = right === void 0 || left.from === right.from && left.to === right.to ? formatDateRange(left) : `${formatDateRange(left)} vs ${formatDateRange(right)}`;
|
|
881
|
+
return /* @__PURE__ */ jsx16("div", { className: "blocks-date-chip", children: label });
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// src/geo/hooks/useStacRasterLayer.ts
|
|
885
|
+
import { useCollection } from "@developmentseed/stac-react";
|
|
886
|
+
|
|
887
|
+
// src/geo/hooks/useMosaicTiles.ts
|
|
888
|
+
import { useQuery } from "@tanstack/react-query";
|
|
889
|
+
|
|
890
|
+
// src/geo/api/titiler/fetchTilejson.ts
|
|
891
|
+
async function fetchTilejson(tilejsonUrl, queryString) {
|
|
892
|
+
const response = await fetch(`${tilejsonUrl}?${queryString}`);
|
|
893
|
+
if (!response.ok) {
|
|
894
|
+
const error = { detail: `Failed to fetch tilejson: ${response.statusText}` };
|
|
895
|
+
throw error;
|
|
896
|
+
}
|
|
897
|
+
const tilejson = await response.json();
|
|
898
|
+
if (!tilejson.tiles?.[0]) {
|
|
899
|
+
const error = { detail: "No tile URL found in response" };
|
|
900
|
+
throw error;
|
|
901
|
+
}
|
|
902
|
+
return tilejson.tiles[0];
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// src/geo/api/titiler/mosaicLinks.ts
|
|
906
|
+
function findTileLink(links) {
|
|
907
|
+
return links.find((link) => link.rel === "tiles") ?? links.at(1) ?? links.at(0) ?? null;
|
|
908
|
+
}
|
|
909
|
+
function buildTilejsonUrl(tileLinkHref, tileMatrixSet) {
|
|
910
|
+
return tileLinkHref.replace("/{tileMatrixSetId}", `/${tileMatrixSet}`);
|
|
911
|
+
}
|
|
912
|
+
function extractTileUrl(registrationResponse, tileMatrixSet) {
|
|
913
|
+
const tileLink = findTileLink(registrationResponse.links);
|
|
914
|
+
if (!tileLink?.href) {
|
|
915
|
+
const error = { detail: "No tile URL found in registration response" };
|
|
916
|
+
throw error;
|
|
917
|
+
}
|
|
918
|
+
const tilejsonUrl = buildTilejsonUrl(tileLink.href, tileMatrixSet);
|
|
919
|
+
return tilejsonUrl;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// src/geo/api/titiler/registerMosaic.ts
|
|
923
|
+
async function registerMosaic(request) {
|
|
924
|
+
const { rasterApiUrl, collectionId, datetime } = request;
|
|
925
|
+
const response = await fetch(`${rasterApiUrl}/searches/register`, {
|
|
926
|
+
method: "POST",
|
|
927
|
+
headers: { "Content-Type": "application/json" },
|
|
928
|
+
body: JSON.stringify({
|
|
929
|
+
collections: [collectionId],
|
|
930
|
+
datetime
|
|
931
|
+
})
|
|
932
|
+
});
|
|
933
|
+
if (!response.ok) {
|
|
934
|
+
const error = {
|
|
935
|
+
detail: `Failed to register mosaic: ${response.statusText}`,
|
|
936
|
+
status: response.status
|
|
937
|
+
};
|
|
938
|
+
throw error;
|
|
939
|
+
}
|
|
940
|
+
return response.json();
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// src/geo/api/titiler/fetchMosaicTileUrl.ts
|
|
944
|
+
var TILE_PARAMS = {
|
|
945
|
+
ASSETS: "assets",
|
|
946
|
+
RESCALE: "rescale",
|
|
947
|
+
RESAMPLING: "resampling",
|
|
948
|
+
COLORMAP_NAME: "colormap_name",
|
|
949
|
+
BIDX: "bidx"
|
|
950
|
+
};
|
|
951
|
+
function buildQueryParams(sourceParams) {
|
|
952
|
+
const params = new URLSearchParams();
|
|
953
|
+
if (sourceParams.assets) params.append(TILE_PARAMS.ASSETS, sourceParams.assets.join(","));
|
|
954
|
+
if (sourceParams.rescale) params.append(TILE_PARAMS.RESCALE, sourceParams.rescale);
|
|
955
|
+
if (sourceParams.resampling) params.append(TILE_PARAMS.RESAMPLING, sourceParams.resampling);
|
|
956
|
+
if (sourceParams.colormap_name)
|
|
957
|
+
params.append(TILE_PARAMS.COLORMAP_NAME, sourceParams.colormap_name);
|
|
958
|
+
if (sourceParams.bidx) params.append(TILE_PARAMS.BIDX, sourceParams.bidx.join(","));
|
|
959
|
+
return params;
|
|
960
|
+
}
|
|
961
|
+
async function fetchMosaicTileUrl(request) {
|
|
962
|
+
const { sourceParams, tileMatrixSet } = request;
|
|
963
|
+
const queryParams = buildQueryParams(sourceParams);
|
|
964
|
+
const queryString = queryParams.toString();
|
|
965
|
+
const registrationResponse = await registerMosaic(request);
|
|
966
|
+
const tilejsonUrl = extractTileUrl(registrationResponse, tileMatrixSet);
|
|
967
|
+
return fetchTilejson(tilejsonUrl, queryString);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/geo/hooks/useMosaicTiles.ts
|
|
971
|
+
function useMosaicTiles(rasterLayerConfig) {
|
|
972
|
+
const { titilerBaseUrl } = useGeoConfig();
|
|
973
|
+
const { collectionId, dateRange, tileMatrixSet = DEFAULT_TILE_MATRIX_SET } = rasterLayerConfig;
|
|
974
|
+
const datetime = dateRange.from === dateRange.to ? dateRange.from : `${dateRange.from}/${dateRange.to}`;
|
|
975
|
+
const request = {
|
|
976
|
+
rasterApiUrl: titilerBaseUrl,
|
|
977
|
+
collectionId,
|
|
978
|
+
datetime,
|
|
979
|
+
sourceParams: {
|
|
980
|
+
...DEFAULT_RENDER_PARAMS,
|
|
981
|
+
assets: [...DEFAULT_RENDER_PARAMS.assets],
|
|
982
|
+
bidx: [...DEFAULT_RENDER_PARAMS.bidx]
|
|
983
|
+
},
|
|
984
|
+
tileMatrixSet
|
|
985
|
+
};
|
|
986
|
+
return useQuery({
|
|
987
|
+
queryKey: [collectionId, dateRange, titilerBaseUrl],
|
|
988
|
+
queryFn: () => fetchMosaicTileUrl(request),
|
|
989
|
+
staleTime: 30 * 60 * 1e3,
|
|
990
|
+
gcTime: 60 * 60 * 1e3,
|
|
991
|
+
enabled: !!collectionId && !!dateRange?.from && !!dateRange?.to
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// src/geo/hooks/useStacRasterLegend.ts
|
|
996
|
+
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
997
|
+
|
|
998
|
+
// src/geo/utils/stac.formatters.ts
|
|
999
|
+
var formatSpatialExtent = (spatialExtent) => {
|
|
1000
|
+
const [minX, minY, maxX, maxY] = spatialExtent?.bbox?.[0] ?? [];
|
|
1001
|
+
if (minX === void 0 || minY === void 0 || maxX === void 0 || maxY === void 0)
|
|
1002
|
+
return void 0;
|
|
1003
|
+
return maxX - minX >= 359 && maxY - minY >= 179 ? "global" : "regional";
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
// src/geo/utils/stac.typeguards.ts
|
|
1007
|
+
var isRgbaColorStopMap = (value) => {
|
|
1008
|
+
return !isNil(value) && isObject(value) && !isEmptyObject(value) && getTypedValues(value).every(
|
|
1009
|
+
(rgba) => isArray(rgba) && rgba.length === STAC_COLORSTOP_RGBA_ARG_COUNT && rgba.every(isNumber)
|
|
667
1010
|
);
|
|
668
1011
|
};
|
|
1012
|
+
|
|
1013
|
+
// src/geo/utils/extractLegendProps.ts
|
|
1014
|
+
function extractLegendProps(collection, colorStopMap) {
|
|
1015
|
+
const rescale = collection.renders?.dashboard?.rescale?.[0];
|
|
1016
|
+
if (!rescale) return null;
|
|
1017
|
+
if (!isRgbaColorStopMap(colorStopMap)) return null;
|
|
1018
|
+
const colorStops = getTypedValues(colorStopMap).map((rgba) => `rgba(${rgba.join(",")})`);
|
|
1019
|
+
const title = collection.title;
|
|
1020
|
+
const description = collection.description;
|
|
1021
|
+
const provider = collection.providers?.[0]?.name;
|
|
1022
|
+
const timeDensity = collection.properties?.["dashboard:time_density"];
|
|
1023
|
+
const spatialExtent = formatSpatialExtent(collection.extent?.spatial);
|
|
1024
|
+
const unit = collection.item_assets?.cog_default?.["raster:bands"]?.[0]?.unit;
|
|
1025
|
+
return {
|
|
1026
|
+
type: "gradient",
|
|
1027
|
+
...title && { title },
|
|
1028
|
+
...description && { description },
|
|
1029
|
+
min: rescale[0],
|
|
1030
|
+
max: rescale[1],
|
|
1031
|
+
colorStops,
|
|
1032
|
+
...provider && { provider },
|
|
1033
|
+
...timeDensity && { timeDensity },
|
|
1034
|
+
...spatialExtent && { spatialExtent },
|
|
1035
|
+
...unit && { unit }
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// src/geo/hooks/useStacRasterLegend.ts
|
|
1040
|
+
function useStacRasterLegend(collection) {
|
|
1041
|
+
const { titilerBaseUrl } = useGeoConfig();
|
|
1042
|
+
const query = useQuery2({
|
|
1043
|
+
queryKey: ["legend", collection, titilerBaseUrl],
|
|
1044
|
+
queryFn: async () => {
|
|
1045
|
+
if (!collection) return null;
|
|
1046
|
+
const colormapName = collection?.renders?.dashboard?.colormap_name;
|
|
1047
|
+
if (!colormapName) return null;
|
|
1048
|
+
const response = await fetch(`${titilerBaseUrl}/colorMaps/${colormapName}`);
|
|
1049
|
+
if (!response.ok) {
|
|
1050
|
+
const error = {
|
|
1051
|
+
detail: `Colormap "${colormapName}" not found (HTTP ${response.status})`,
|
|
1052
|
+
status: response.status
|
|
1053
|
+
};
|
|
1054
|
+
throw error;
|
|
1055
|
+
}
|
|
1056
|
+
const colorMap = await response.json();
|
|
1057
|
+
return extractLegendProps(collection, colorMap);
|
|
1058
|
+
},
|
|
1059
|
+
enabled: !!collection
|
|
1060
|
+
});
|
|
1061
|
+
return {
|
|
1062
|
+
legend: query.data ?? null,
|
|
1063
|
+
isLoading: query.isLoading,
|
|
1064
|
+
error: query.error || null
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// src/geo/hooks/useStacRasterLayer.ts
|
|
1069
|
+
function useStacRasterLayer(rasterLayerConfig) {
|
|
1070
|
+
const { collectionId } = rasterLayerConfig;
|
|
1071
|
+
const {
|
|
1072
|
+
collection,
|
|
1073
|
+
isLoading: isLoadingCollection,
|
|
1074
|
+
error: collectionError
|
|
1075
|
+
} = useCollection(collectionId);
|
|
1076
|
+
const {
|
|
1077
|
+
data: tiles,
|
|
1078
|
+
isLoading: tilesetLoading,
|
|
1079
|
+
error: tilesetError
|
|
1080
|
+
} = useMosaicTiles(rasterLayerConfig);
|
|
1081
|
+
const {
|
|
1082
|
+
legend,
|
|
1083
|
+
isLoading: isLoadingLegend,
|
|
1084
|
+
error: legendError
|
|
1085
|
+
} = useStacRasterLegend(collection);
|
|
1086
|
+
return {
|
|
1087
|
+
mapSource: {
|
|
1088
|
+
tiles: tiles ?? null
|
|
1089
|
+
},
|
|
1090
|
+
legend,
|
|
1091
|
+
isLoading: isLoadingCollection || tilesetLoading || isLoadingLegend,
|
|
1092
|
+
error: collectionError || tilesetError || legendError || null
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// src/geo/StacCompareMap/StacCompareMap.tsx
|
|
1097
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1098
|
+
var MAP_PANEL_STYLE = {
|
|
1099
|
+
position: "absolute",
|
|
1100
|
+
top: 0,
|
|
1101
|
+
bottom: 0,
|
|
1102
|
+
width: "100%"
|
|
1103
|
+
};
|
|
1104
|
+
function StacCompareMap({
|
|
1105
|
+
baseMapStyle,
|
|
1106
|
+
initialViewState,
|
|
1107
|
+
leftLayerConfig,
|
|
1108
|
+
rightLayerConfig,
|
|
1109
|
+
className
|
|
1110
|
+
}) {
|
|
1111
|
+
const instanceId = useId();
|
|
1112
|
+
const leftMapRef = useRef3(null);
|
|
1113
|
+
const rightMapRef = useRef3(null);
|
|
1114
|
+
const compareRef = useRef3(null);
|
|
1115
|
+
const containerRef = useRef3(null);
|
|
1116
|
+
const [leftMapLoaded, setLeftMapLoaded] = useState4(false);
|
|
1117
|
+
const [rightMapLoaded, setRightMapLoaded] = useState4(false);
|
|
1118
|
+
const containerClassName = make_class_name("blocks-stacmap-compare", [className]);
|
|
1119
|
+
const left = useStacRasterLayer(leftLayerConfig);
|
|
1120
|
+
const right = useStacRasterLayer(rightLayerConfig);
|
|
1121
|
+
const isSameCollection = leftLayerConfig.collectionId === rightLayerConfig.collectionId;
|
|
1122
|
+
const leftSourceId = `${leftLayerConfig.collectionId}-raster-source-left-${instanceId}`;
|
|
1123
|
+
const leftLayerId = `${leftLayerConfig.collectionId}-raster-layer-left-${instanceId}`;
|
|
1124
|
+
const rightSourceId = `${rightLayerConfig.collectionId}-raster-source-right-${instanceId}`;
|
|
1125
|
+
const rightLayerId = `${rightLayerConfig.collectionId}-raster-layer-right-${instanceId}`;
|
|
1126
|
+
useEffect3(() => {
|
|
1127
|
+
if (!leftMapLoaded || !rightMapLoaded) return;
|
|
1128
|
+
if (compareRef.current) return;
|
|
1129
|
+
const leftMap = leftMapRef.current?.getMap();
|
|
1130
|
+
const rightMap = rightMapRef.current?.getMap();
|
|
1131
|
+
const container = containerRef.current;
|
|
1132
|
+
if (!leftMap || !rightMap || !container) return;
|
|
1133
|
+
import("mapbox-gl-compare").then(({ default: MapboxCompare }) => {
|
|
1134
|
+
if (compareRef.current) return;
|
|
1135
|
+
try {
|
|
1136
|
+
compareRef.current = new MapboxCompare(leftMap, rightMap, container, {
|
|
1137
|
+
mousemove: false,
|
|
1138
|
+
orientation: "vertical"
|
|
1139
|
+
});
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
console.error("Failed to initialize mapbox-gl-compare:", error);
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
}, [leftMapLoaded, rightMapLoaded]);
|
|
1145
|
+
useEffect3(() => {
|
|
1146
|
+
return () => {
|
|
1147
|
+
compareRef.current?.remove();
|
|
1148
|
+
compareRef.current = null;
|
|
1149
|
+
};
|
|
1150
|
+
}, []);
|
|
1151
|
+
const mapProps = {
|
|
1152
|
+
...baseMapStyle && { mapStyle: baseMapStyle },
|
|
1153
|
+
...initialViewState && { initialViewState },
|
|
1154
|
+
style: MAP_PANEL_STYLE
|
|
1155
|
+
};
|
|
1156
|
+
return /* @__PURE__ */ jsxs14("div", { ref: containerRef, className: containerClassName, children: [
|
|
1157
|
+
/* @__PURE__ */ jsxs14(
|
|
1158
|
+
MapLibreMap,
|
|
1159
|
+
{
|
|
1160
|
+
ref: leftMapRef,
|
|
1161
|
+
...mapProps,
|
|
1162
|
+
attributionControl: false,
|
|
1163
|
+
onLoad: () => setLeftMapLoaded(true),
|
|
1164
|
+
children: [
|
|
1165
|
+
/* @__PURE__ */ jsx17(AttributionMapControl, {}),
|
|
1166
|
+
/* @__PURE__ */ jsx17(NavigationControl, { position: "top-left", showCompass: false }),
|
|
1167
|
+
left.mapSource.tiles && /* @__PURE__ */ jsx17(Source, { id: leftSourceId, type: "raster", tiles: [left.mapSource.tiles], children: /* @__PURE__ */ jsx17(Layer, { id: leftLayerId, type: "raster" }) })
|
|
1168
|
+
]
|
|
1169
|
+
}
|
|
1170
|
+
),
|
|
1171
|
+
/* @__PURE__ */ jsxs14(
|
|
1172
|
+
MapLibreMap,
|
|
1173
|
+
{
|
|
1174
|
+
ref: rightMapRef,
|
|
1175
|
+
...mapProps,
|
|
1176
|
+
attributionControl: false,
|
|
1177
|
+
onLoad: () => setRightMapLoaded(true),
|
|
1178
|
+
children: [
|
|
1179
|
+
/* @__PURE__ */ jsx17(AttributionMapControl, {}),
|
|
1180
|
+
right.mapSource.tiles && /* @__PURE__ */ jsx17(Source, { id: rightSourceId, type: "raster", tiles: [right.mapSource.tiles], children: /* @__PURE__ */ jsx17(Layer, { id: rightLayerId, type: "raster" }) })
|
|
1181
|
+
]
|
|
1182
|
+
}
|
|
1183
|
+
),
|
|
1184
|
+
/* @__PURE__ */ jsx17("div", { className: "blocks-stacmap-compare__date-chip", children: /* @__PURE__ */ jsx17(DateChip, { left: leftLayerConfig.dateRange, right: rightLayerConfig.dateRange }) }),
|
|
1185
|
+
!isSameCollection && left.legend && /* @__PURE__ */ jsx17("div", { className: "blocks-stacmap-compare__legend-left", children: /* @__PURE__ */ jsx17(Legend, { ...left.legend }) }),
|
|
1186
|
+
right.legend && /* @__PURE__ */ jsx17("div", { className: "blocks-stacmap-compare__legend-right", children: /* @__PURE__ */ jsx17(Legend, { ...right.legend }) })
|
|
1187
|
+
] });
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// src/geo/StacSingleLayerMap/StacSingleLayerMap.tsx
|
|
1191
|
+
import { useId as useId2 } from "react";
|
|
1192
|
+
import {
|
|
1193
|
+
Layer as Layer2,
|
|
1194
|
+
Map as MapLibreMap2,
|
|
1195
|
+
NavigationControl as NavigationControl2,
|
|
1196
|
+
Source as Source2
|
|
1197
|
+
} from "react-map-gl/maplibre";
|
|
1198
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1199
|
+
function StacSingleLayerMap({
|
|
1200
|
+
baseMapStyle = NASA_BLUE_MARBLE_BASEMAP_STYLE,
|
|
1201
|
+
initialViewState,
|
|
1202
|
+
layerConfig
|
|
1203
|
+
}) {
|
|
1204
|
+
const instanceId = useId2();
|
|
1205
|
+
const sourceId = `${layerConfig.collectionId}-raster-source-${instanceId}`;
|
|
1206
|
+
const layerId = `${layerConfig.collectionId}-raster-layer-${instanceId}`;
|
|
1207
|
+
const { mapSource, legend } = useStacRasterLayer(layerConfig);
|
|
1208
|
+
return /* @__PURE__ */ jsxs15("div", { className: "blocks-stacmap-singlelayer", children: [
|
|
1209
|
+
/* @__PURE__ */ jsxs15(
|
|
1210
|
+
MapLibreMap2,
|
|
1211
|
+
{
|
|
1212
|
+
mapStyle: baseMapStyle,
|
|
1213
|
+
...initialViewState && { initialViewState },
|
|
1214
|
+
style: { position: "absolute", inset: 0 },
|
|
1215
|
+
attributionControl: false,
|
|
1216
|
+
children: [
|
|
1217
|
+
/* @__PURE__ */ jsx18(AttributionMapControl, {}),
|
|
1218
|
+
/* @__PURE__ */ jsx18(NavigationControl2, { position: "top-left", showCompass: false }),
|
|
1219
|
+
mapSource.tiles && /* @__PURE__ */ jsx18(Source2, { id: sourceId, type: "raster", tiles: [mapSource.tiles], children: /* @__PURE__ */ jsx18(Layer2, { id: layerId, type: "raster" }) })
|
|
1220
|
+
]
|
|
1221
|
+
}
|
|
1222
|
+
),
|
|
1223
|
+
/* @__PURE__ */ jsx18("div", { className: "blocks-stacmap-singlelayer__legend", children: legend && /* @__PURE__ */ jsx18(Legend, { ...legend }) }),
|
|
1224
|
+
/* @__PURE__ */ jsx18("div", { className: "blocks-stacmap-singlelayer__date-chip", children: /* @__PURE__ */ jsx18(DateChip, { left: layerConfig.dateRange }) })
|
|
1225
|
+
] });
|
|
1226
|
+
}
|
|
669
1227
|
export {
|
|
670
1228
|
Banner,
|
|
671
|
-
Button,
|
|
672
1229
|
Card,
|
|
673
1230
|
CardCTA,
|
|
674
1231
|
CardDetailed,
|
|
675
1232
|
CardMini,
|
|
676
1233
|
CardSimple,
|
|
677
1234
|
Footer,
|
|
1235
|
+
GeoConfigProvider,
|
|
678
1236
|
Header,
|
|
679
|
-
|
|
1237
|
+
Legend,
|
|
1238
|
+
Link3 as Link,
|
|
1239
|
+
StacCompareMap,
|
|
1240
|
+
StacSingleLayerMap,
|
|
680
1241
|
Tag
|
|
681
1242
|
};
|