UNPKG

@arcgis/map-components

Version:
553 lines (552 loc) • 24.1 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */ import { c as O } from "../../chunks/runtime.js"; import { css as z, html as u } from "lit"; import { GenericController as C, proxyExports as $, useDirection as M } from "@arcgis/lumina/controllers"; import { LitElement as R, createEvent as I, nothing as S } from "@arcgis/lumina"; import { u as G } from "../../chunks/useT9n.js"; import { m as N } from "../../chunks/useViewModel.js"; import { property as d, subclass as B } from "@arcgis/core/core/accessorSupport/decorators.js"; import E from "@arcgis/core/core/Accessor.js"; import w from "@arcgis/core/core/Collection.js"; import { ignoreAbortErrors as T } from "@arcgis/core/core/promiseUtils.js"; import { watch as v, on as D, whenOnce as m } from "@arcgis/core/core/reactiveUtils.js"; import H from "@arcgis/core/Graphic.js"; import V from "@arcgis/core/layers/Layer.js"; import k from "@arcgis/core/graphic/CSVGraphicOrigin.js"; import j from "@arcgis/core/graphic/GeoJSONGraphicOrigin.js"; import W from "@arcgis/core/graphic/SceneGraphicOrigin.js"; import K from "@arcgis/core/graphic/WFSGraphicOrigin.js"; import U from "@arcgis/core/graphic/BuildingGraphicOrigin.js"; import Q from "@arcgis/core/graphic/FeatureGraphicOrigin.js"; import { fetchPopupFeaturesFromGraphics as P } from "@arcgis/core/applications/SceneViewer/sceneViewerUtils.js"; import { s as _ } from "../../chunks/resources.js"; const q = z`:host{width:100%;height:100%;padding:var(--calcite-spacing-none);margin:var(--calcite-spacing-none);display:flex;--internal-attribution-height: 16px;--arcgis-internal-presentation-padding-start: unset;--arcgis-internal-presentation-padding-end: unset;--arcgis-internal-presentation-cover-padding-top: unset;--arcgis-internal-presentation-cover-padding-bottom: unset;--arcgis-internal-presentation-cover-padding-start: unset;--arcgis-internal-presentation-cover-padding-end: unset}p{padding:0;margin:0}.root{display:flex;flex-direction:column;justify-content:space-between;width:100%;height:100%}.presentation-content{display:flex;width:100%;justify-content:flex-end;padding-top:var(--calcite-spacing-lg);padding-inline-start:calc(var(--calcite-spacing-lg) + var(--arcgis-internal-presentation-padding-start));padding-inline-end:calc(var(--calcite-spacing-lg) + var(--arcgis-internal-presentation-padding-end))}.navigation{width:fit-content;pointer-events:auto;display:flex;align-items:center;gap:var(--calcite-spacing-sm);background-color:var(--calcite-color-foreground-1);box-shadow:var(--arcgis-internal-box-shadow);margin-block:auto calc(var(--calcite-spacing-lg) + var(--internal-attribution-height));margin-inline-start:var(--calcite-spacing-lg)}.slide-counter-text{display:flex;align-items:center;justify-content:center;gap:var(--calcite-spacing-base);min-width:64px}.slide-counter-text-element{box-sizing:border-box;max-width:28px;margin:0;padding:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-variant-numeric:tabular-nums}.legend{pointer-events:all;box-shadow:var(--calcite-shadow-sm);max-width:300px;height:auto;max-height:calc(100vh - 136px);overflow:hidden auto}`; var J = Object.defineProperty, X = Object.getOwnPropertyDescriptor, l = (i, e, t, s) => { for (var n = s > 1 ? void 0 : s ? X(e, t) : e, r = i.length - 1, o; r >= 0; r--) (o = i[r]) && (n = (s ? o(e, t, n) : o(n)) || n); return s && n && J(e, t, n), n; }; let a = class extends E { //endregion //#region Lifecycle constructor(i) { super(i), this.transitionActive = !1, this.showLegend = !1, this.keyboardNavigationEnabled = !1, this._subscribeToSlideEvents = (e) => { this._unsubscribeToSlideEvents(e), e.forEach((t) => { const s = t.on("apply-slide-start", () => this._onApplySlideStart(t)), n = t.on("apply-slide-complete", () => this._onApplySlideComplete(t)), r = t.on("apply-slide-cancel", () => this._onApplySlideCancel(t)); this.addHandles(s, t.id), this.addHandles(n, t.id), this.addHandles(r, t.id); }); }, this._unsubscribeToSlideEvents = (e) => { e.forEach((t) => { this.hasHandles(t.id) && this.removeHandles(t.id); }); }; } initialize() { this.addHandles( v( () => this.view?.map, (i, e) => { if (this.hasHandles("sceneLoaded") && this.removeHandles("sceneLoaded"), e) { const t = e.presentation?.slides; t && t.length > 0 && this._unsubscribeToSlideEvents(t); } i && this.addHandles( v( () => i.loaded, (t) => { t && (this.removeHandles("sceneLoaded"), this._startWatchSlides(), this._slideId && this._applySlideById(this._slideId)); }, { initial: !0 } ), "sceneLoaded" ); }, { initial: !0 } ) ); } destroy() { this._unsubscribeToSlideEvents(this.slides); } get slideId() { return this._slideId; } set slideId(i) { i === void 0 || !this.view?.map?.loaded ? this._slideId = i : this._applySlideById(i); } get visibleSlides() { return this.view?.map?.presentation?.slides?.filter((i) => !i.hidden) ?? new w(); } get slides() { return this.view?.map?.presentation?.slides ?? new w(); } get lastSlideSelected() { return this.getSlideIndexBySlideId(this.slideId) === this.visibleSlides.length - 1; } get firstSlideSelected() { return this.getSlideIndexBySlideId(this.slideId) === 0; } get slideSelected() { return this.getSlideIndexBySlideId(this.slideId) > -1; } get hasOnlyOneSlide() { return this.visibleSlides.length === 1; } get slideIndex() { return this.getSlideIndexBySlideId(this.slideId); } getSlideIndexBySlideId(i) { let e = -1; return i && (e = this.visibleSlides.findIndex((t) => t.id === i)), e; } navigateInPresentation(i) { const e = this.slideIndex + i; let t = this._getSlideBySlideIndex(e); t ??= this._getSlideBySlideIndex(0), t && this._applySlide(t); } captureArrowKeysForNavigation(i, e) { const t = ["ArrowLeft", "ArrowRight", "PageUp", "PageDown"]; if (document.activeElement?.nodeName.toLowerCase() === "arcgis-scene" || !t.includes(i.code)) return; const n = e === "rtl" ? "ArrowRight" : "ArrowLeft", o = i.code === n || i.code === "PageUp" ? -1 : 1; this.navigateInPresentation(o); } async setSliceAnalysisInteractive() { if (!this.view?.analyses?.length) return; const i = this.view.analyses.find( (t) => t.type === "slice" && t.origin?.type === "web-scene" ); if (!i) return; const e = await this.view.whenAnalysisView(i); e && (e.interactive = !0); } //#endregion //#region Private Methods _getSlideBySlideIndex(i) { if (i != null && i >= 0 && i < this.visibleSlides.length) return this.visibleSlides.getItemAt(i); } async _applySlideById(i) { const e = i ? this._getSlideBySlideId(i) : void 0; e && await this._applySlide(e); } _getSlideBySlideId(i) { return this.visibleSlides.find((e) => e.id === i); } async _applySlide(i) { this.view && await T(i.applyTo(this.view)); } _startWatchSlides() { this._subscribeToSlideEvents(this.slides), this.addHandles( D( () => this.slides, "change", (i) => { this._subscribeToSlideEvents(new w(i.added)), this._unsubscribeToSlideEvents(new w(i.removed)); }, { onListenerAdd: this._subscribeToSlideEvents, onListenerRemove: this._unsubscribeToSlideEvents } ) ); } _onApplySlideStart(i) { this._slideId = i.id, this.transitionActive = !0, this.showLegend = !1, this.onApplySlideStart?.(i); } _onApplySlideComplete(i) { this.transitionActive = !1, this.showLegend = !!i.elements.legendInfo?.visible, this.onApplySlideComplete?.(i); } _onApplySlideCancel(i) { this.transitionActive = !1, this.showLegend = !!i.elements.legendInfo?.visible, this.onApplySlideCancel?.(i); } //#endregion }; l([ d() ], a.prototype, "_slideId", 2); l([ d() ], a.prototype, "view", 2); l([ d() ], a.prototype, "slideId", 1); l([ d() ], a.prototype, "transitionActive", 2); l([ d() ], a.prototype, "showLegend", 2); l([ d() ], a.prototype, "keyboardNavigationEnabled", 2); l([ d() ], a.prototype, "visibleSlides", 1); l([ d() ], a.prototype, "slides", 1); l([ d() ], a.prototype, "lastSlideSelected", 1); l([ d() ], a.prototype, "firstSlideSelected", 1); l([ d() ], a.prototype, "slideSelected", 1); l([ d() ], a.prototype, "hasOnlyOneSlide", 1); l([ d() ], a.prototype, "onApplySlideStart", 2); l([ d() ], a.prototype, "onApplySlideComplete", 2); l([ d() ], a.prototype, "onApplySlideCancel", 2); l([ d() ], a.prototype, "getSlideIndexBySlideId", 1); a = l([ B("components.presentation.PresentationViewModel") ], a); class Y extends C { constructor(e) { super(e); } hostLoaded() { this.component.manager.onLifecycle(() => { const e = this.component; m(() => e.referenceElement).then((t) => { this._isArcgisScene(t) && (this._sceneRef = t); }); }); } openPopup(e) { this.component.view && this.component.slideId === e.id && e.elements.popupInfo != null && this._preparePopupFeature(this.component.view, e.elements.popupInfo).then( ({ success: t, features: s, popupInfo: n }) => { this.component.slideId === e.id && (t ? this._handlePopupFeatureFound(e, s, n) : this.component.arcgisPopupFeatureNotFound.emit({ slide: e })); } ); } //#region Private Methods _isArcgisScene(e) { return e === void 0 || typeof e == "string" ? !1 : "tagName" in e && e.tagName === "ARCGIS-SCENE"; } closePopup() { this.component.slidePopupDisabled || this._sceneRef?.closePopup(); } async _handlePopupFeatureFound(e, t, s) { const n = s?.location ?? void 0; this.component.arcgisPopupFeaturesRetrieved.emit({ slide: e, features: t, location: n }), this.component.slidePopupDisabled || await this._sceneRef?.openPopup({ features: t, location: n }); } async _preparePopupFeature(e, t) { let s = []; if (!t.features?.length || t.features.length === 0) return { success: !1, features: s }; const n = t.features?.getItemAt(t.selectedFeatureIndex)?.layerReference; if (n?.layerId == null) return { success: !1, features: s }; const { layer: r, sublayer: o } = this._getLayersFromView(e, n.layerId, n?.sublayerId); if (!r) return { success: !1, features: s }; const c = o ?? r; if (!c || !this._layerTypeSupportsCapturePopup(c)) return { success: !1, features: s }; if (s = await this._fetchFeaturesFromQueryable(e, t, r, o, c), s && this._featureHasBeenFilledWithAttributes(s)) { const p = s[0]; return this._setFallbackPopupTemplate(p, o, r), this._setFallbackGeometry(p, t?.location), { success: !0, features: s, popupInfo: t }; } debugger; return { success: !1, features: s }; } _getLayersFromView(e, t, s) { const n = e.map?.findLayerById(t) ?? void 0, r = this._getBuildingSceneLayerSublayer(n, s); return { layer: n, sublayer: r }; } _getBuildingSceneLayerSublayer(e, t) { let s; return e && this._isLayer(e) && this._isBuildingSceneLayer(e) && t != null && (s = e.allSublayers.find( (n) => n.id === t && n.type === "building-component" )), s; } _featureHasBeenFilledWithAttributes(e) { return e && e.length > 0 && e[0].attributes && Object.entries(e[0].attributes)?.length > 1; } async _fetchFeaturesFromQueryable(e, t, s, n, r) { const o = t.features?.getItemAt(t.selectedFeatureIndex); if (o?.id == null) return await Promise.resolve([]); const c = await e.whenLayerView(s); await m(() => !c.updating); const h = this._tryGetBuildingComponentSublayerView(s, n, c) ?? c; await m(() => !h.updating); const f = this._createFeatureGraphic(s, n, r, o.id); let x = await P(h, [f]); return this._featureHasBeenFilledWithAttributes(x) || (await m(() => !e.updating), x = await P(h, [f])), x; } _tryGetBuildingComponentSublayerView(e, t, s) { let n; return this._isLayer(e) && this._isBuildingSceneLayer(e) && t != null && (n = s.sublayerViews.find( (r) => r.sublayer.id === t.id )), n; } _setFallbackPopupTemplate(e, t, s) { e.popupTemplate == null && (e.popupTemplate = t?.popupTemplate ? t.popupTemplate : s.popupTemplate); } /** * If there is no geometry of the feature in the service, * the popup highlights the location point in the scene. * * @param popupFeature * @param location * @private */ _setFallbackGeometry(e, t) { e.geometry == null && t && (e.geometry = t.clone()); } _createFeatureGraphic(e, t, s, n) { const r = this._getGlobalIdFieldNameFromLayer(s), o = n.type === "global-id" && r ? r : s.objectIdField, c = this._getGraphicOrigin(e, t), p = new H({ attributes: {}, layer: e, origin: c }); return p.attributes[o] = n.value, p; } _getGraphicOrigin(e, t) { switch (e.type) { case "csv": return new k(e); case "feature": return new Q(e); case "geojson": return new j(e); case "scene": return new W(e); case "wfs": return new K(e); case "building-scene": return t ? new U(t) : void 0; default: return; } } _layerTypeSupportsCapturePopup(e) { return e != null && ["csv", "feature", "geojson", "wfs", "scene", "building-component"].includes(e.type); } _isLayer(e) { return !!e && e instanceof V; } _isBuildingSceneLayer(e) { return e?.type === "building-scene"; } _getGlobalIdFieldNameFromLayer(e) { return e.fields?.find((t) => t.type === "global-id")?.name; } //#endregion } const Z = (i) => new Y(i), g = Object.freeze({ width: 0, height: 0 }), y = /* @__PURE__ */ new WeakMap(), b = () => ({ topCenter: { ...g }, topLeft: { ...g }, topRight: { ...g }, bottomCenter: { ...g }, bottomLeft: { ...g }, bottomRight: { ...g } }), L = (i) => ({ topCenter: { ...i.topCenter }, topLeft: { ...i.topLeft }, topRight: { ...i.topRight }, bottomCenter: { ...i.bottomCenter }, bottomLeft: { ...i.bottomLeft }, bottomRight: { ...i.bottomRight } }), F = (i) => { let e = y.get(i); return e || (e = { observedGroups: /* @__PURE__ */ new Map(), observedSizes: b(), subscribers: /* @__PURE__ */ new Set() }, y.set(i, e)), e; }, ee = (i) => { const e = i?.topCenter.value, t = i?.topLeft.value, s = i?.topRight.value, n = i?.bottomCenter.value, r = i?.bottomLeft.value, o = i?.bottomRight.value; return e && t && s && n && r && o ? { topCenter: e, topLeft: t, topRight: s, bottomCenter: n, bottomLeft: r, bottomRight: o } : null; }, te = (i, e) => _.every((t) => i.get(t) === e[t]), ie = (i) => { const e = L(i.observedSizes); i.subscribers.forEach((t) => t(e)); }, se = (i, e) => { const t = y.get(i); if (!t) return; let s = !1; e.forEach((n) => { const r = _.find((f) => t.observedGroups.get(f) === n.target); if (!r) return; const { width: o, height: c } = n.contentRect, p = { width: o, height: c }, h = t.observedSizes[r]; h.width === p.width && h.height === p.height || (t.observedSizes[r] = p, s = !0); }), s && ie(t); }, A = (i, e) => { const t = F(i); t.resizeObserver || (t.resizeObserver = new ResizeObserver((n) => { se(i, n); })); const s = ee(e); if (!s) { t.observedGroups.size > 0 && (t.resizeObserver.disconnect(), t.observedGroups.clear()); return; } te(t.observedGroups, s) || (t.resizeObserver.disconnect(), t.observedGroups.clear(), _.forEach((n) => { const r = s[n]; t.observedGroups.set(n, r), t.resizeObserver?.observe(r); })); }, ne = (i, e) => { const t = F(i); return t.subscribers.add(e), e(L(t.observedSizes)), () => { const s = y.get(i); s && (s.subscribers.delete(e), s.subscribers.size === 0 && (s.resizeObserver?.disconnect(), s.observedGroups.clear(), y.delete(i))); }; }; class re extends C { // References to the slot group elements owned by the host component. #t; #e; #i; /** * Creates a controller that measures the host component's slot group containers. * * @param component The host component that owns the slot group elements. */ constructor(e) { super(e), this.exports = b(); } hostDisconnected() { this.#i?.(), this.#i = void 0, this.#e = void 0, this.#t = void 0, this.exports = b(); } hostLifecycle() { return [ v( () => this.#s(), (t) => { if (this.#e !== t) { if (this.#i?.(), this.#i = void 0, this.#e = t, this.#t = t?.slotGroupRefs, !t) { this.exports = b(); return; } this.#i = ne(t, (s) => { this.#n(s) || (this.exports = s); }), A(t, this.#t); } }, { sync: !0, initial: !0 } ), v( () => this.#s()?.slotGroupRefs, (t) => { this.#t = t, this.#e && t && A(this.#e, t); }, { sync: !0, initial: !0 } ) ]; } #s() { const { referenceElement: e } = this.component; return e && typeof e != "string" ? e : void 0; } hostUpdated() { !this.#e || !this.#t || A(this.#e, this.#t); } // Compares the newly measured sizes against the currently exported values. #n(e) { const t = this.exports ?? b(); return _.every((s) => { const n = t[s], r = e[s]; return n.width === r.width && n.height === r.height; }); } } const oe = $(re), ae = N(a); class le extends R { constructor() { super(...arguments), this._messages = G(), this.viewModel = ae(this), this._direction = M(), this._captureArrowKeysForNavigation = (e) => { this.viewModel.captureArrowKeysForNavigation(e, this._direction); }, this._useFeatureRefPopup = Z(this), this._handleApplySlideStart = () => { this._useFeatureRefPopup.closePopup(); }, this._handleApplySlideComplete = (e) => { this._useFeatureRefPopup.openPopup(e), this.sliceAnalysisInteractive && this.viewModel.setSliceAnalysisInteractive(); }, this.autoDestroyDisabled = !1, this.view = this.viewModel.view, this.scale = "m", this.keyboardNavigationEnabled = !1, this.slidePopupDisabled = !1, this.slideCaptionsDisabled = !1, this.slideLegendDisabled = !1, this.sliceAnalysisInteractive = !1, this.arcgisPopupFeatureNotFound = I(), this.arcgisPopupFeaturesRetrieved = I(), this.arcgisReady = I(); } static { this.properties = { _slotSizesController: 16, slideId: 1, autoDestroyDisabled: 5, view: 0, scale: 1, keyboardNavigationEnabled: 5, slidePopupDisabled: 5, slideCaptionsDisabled: 5, slideLegendDisabled: 5, sliceAnalysisInteractive: 5 }; } static { this.styles = q; } get slideId() { return this.viewModel.slideId; } set slideId(e) { this.viewModel.slideId = e; } async destroy() { await this.manager.destroy(); } loaded() { this.manager.onLifecycle(() => { this.viewModel.onApplySlideStart = this._handleApplySlideStart, this.viewModel.onApplySlideComplete = this._handleApplySlideComplete, this._keyboardHandle = v(() => this.keyboardNavigationEnabled, (t) => { document.removeEventListener("keydown", this._captureArrowKeysForNavigation), t && document.addEventListener("keydown", this._captureArrowKeysForNavigation); }, { initial: !0 }); const e = this; m(() => e.referenceElement).then((t) => { this._isArcgisScene(t) && (this._slotSizesController = oe(this), this._watchSceneViewSlotSizes()); }), this.manager.onDisconnected(() => { document.removeEventListener("keydown", this._captureArrowKeysForNavigation), this._keyboardHandle?.remove(); }); }); } _isArcgisScene(e) { return e === void 0 || typeof e == "string" ? !1 : "tagName" in e && e.tagName === "ARCGIS-SCENE"; } _watchSceneViewSlotSizes() { return v(() => this._slotSizesController, (e) => this._updatePresentationCaptionsPadding(e?.topLeft, e?.topRight, e?.bottomLeft, e?.bottomRight), { initial: !0 }); } _updatePresentationCaptionsPadding(e, t, s, n) { const r = this._direction === "ltr" ? e?.width ?? 0 : t?.width ?? 0, o = this._direction === "ltr" ? t?.width ?? 0 : e?.width ?? 0, c = Math.max(e?.height ?? 0, t?.height ?? 0), p = Math.max(s?.height ?? 0, n?.height ?? 0); r > 0 ? this.el.style.setProperty("--arcgis-internal-presentation-padding-start", `calc(var(--calcite-spacing-lg) + ${r.toString()}px)`) : this.el.style.setProperty("--arcgis-internal-presentation-padding-start", "0px"), o > 0 ? this.el.style.setProperty("--arcgis-internal-presentation-padding-end", `calc(var(--calcite-spacing-lg) + ${o.toString()}px)`) : this.el.style.setProperty("--arcgis-internal-presentation-padding-end", "0px"); const h = r <= Math.max(c, p) && o <= Math.max(c, p); this.el.style.setProperty("--arcgis-internal-presentation-cover-padding-top", h ? "0" : `${c}px`), this.el.style.setProperty("--arcgis-internal-presentation-cover-padding-bottom", h ? "0" : `${p}px`), this.el.style.setProperty("--arcgis-internal-presentation-cover-padding-start", h ? `${r}px` : "0"), this.el.style.setProperty("--arcgis-internal-presentation-cover-padding-end", h ? `${o}px` : "0"); } render() { if (this.viewModel.visibleSlides.length === 0) return u`<div></div>`; const e = this.viewModel.visibleSlides.find((r) => r.id === this.slideId), t = this._renderNavigation(), s = this._renderCaptions(e), n = this._renderLegend(); return u`<div class="root"><div class="presentation-content">${s}${n}</div>${t}</div>`; } _renderNavigation() { const e = this.viewModel.lastSlideSelected && !this.viewModel.hasOnlyOneSlide, t = this._direction === "rtl", s = t ? "chevron-right" : "chevron-left", n = t ? "chevron-left" : "chevron-right"; return u`<div class="navigation"><calcite-button appearance=transparent icon-start=${s ?? S} kind=neutral .scale=${this.scale} .disabled=${this.viewModel.firstSlideSelected || !this.viewModel.slideSelected} .label=${this._messages.previous} title=${this._messages.previous ?? S} @click=${() => this.viewModel.navigateInPresentation(-1)}></calcite-button><div class="slide-counter-text">${this._renderSlideCounter()}</div><calcite-button appearance=transparent icon-start=${(e ? "reset" : n) ?? S} kind=neutral .scale=${this.scale} .label=${e ? this._messages.restart : this._messages.next} title=${(e ? this._messages.restart : this._messages.next) ?? S} @click=${() => this.viewModel.navigateInPresentation(1)}></calcite-button></div>`; } _renderSlideCounter() { const e = this.viewModel.slideIndex + 1, t = this._messages?.slideNavAriaText?.replace("${index}", e.toString()).replace("${numberOfSlides}", this.viewModel.visibleSlides.length.toString()); return this.viewModel.slideSelected ? u`<p role=banner aria-label=${t ?? S} aria-live=polite><div class="slide-counter-text-element" data-testId=arcgis-map-presentation-slideIndex>${e}</div><div class="slide-counter-text-element">/</div><p class="slide-counter-text-element" data-testId=arcgis-map-presentation-numberOfSlides>${this.viewModel.visibleSlides.length}</p></p>` : u`<p role=banner data-testId=arcgis-map-presentation-numberOfSlides>${this.viewModel.visibleSlides?.length} ${this._messages?.slides}</p>`; } _renderCaptions(e) { return this.slideCaptionsDisabled ? null : u`<arcgis-presentation-captions .slide=${e} .transitionActive=${this.viewModel.transitionActive}></arcgis-presentation-captions>`; } _renderLegend() { return this.slideLegendDisabled || !this.viewModel.showLegend ? null : u`<calcite-panel data-testid=presentation-legend class="legend" .heading=${this._messages.legend} closable @calcitePanelClose=${() => this.viewModel.showLegend = !1}><arcgis-legend .view=${this.view} @arcgisReady=${(e) => e.stopPropagation()}></arcgis-legend></calcite-panel>`; } } O("arcgis-presentation", le); export { le as ArcgisPresentation };