UNPKG

@arcgis/map-components

Version:
394 lines (393 loc) • 20.4 kB
/// <reference path="../../index.d.ts" /> import type { PublicLitElement as LitElement } from "@arcgis/lumina"; import type { ArcgisReferenceElement, IconName } from "../types.js"; import type { AnimateEvent, ArcgisValuePickerSubcomponent, Layout } from "./types.js"; import type { T9nMeta } from "@arcgis/lumina/controllers"; /** * The Value Picker component allows users to step or play through an iterable set of data. The component alone acts as a shell, consisting * of a play/pause button, a next button, a previous button, and a slot for adding a component to Value Picker. Value Picker is not associated with a * [View](https://developers.arcgis.com/javascript/latest/references/core/views/View/) nor does it require that the dataset adheres to a specific structure * for it to function. The [arcgis-value-picker-label](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-label/), [arcgis-value-picker-slider](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/), * [arcgis-value-picker-combobox](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-combobox/), and [arcgis-value-picker-collection](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-collection/) components provide the user with a few different options * for placing their data into a Value Picker with minimal configuration. Value Picker handles the different shapes of these components automatically by asserting * that all slotted components will extend the * [ArcgisValuePickerSubcomponent](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/types/#ArcgisValuePickerSubcomponent) * interface, which allows Value picker to send and receive generic sets of instructions that are interpreted by the slotted component. * * ### Configuring Value Picker * * #### Configuring Value Picker without slotted components * * ![value-picker-nodata](https://developers.arcgis.com/javascript/latest/assets/references/components/value-picker/value-picker-nodata.avif) * * ```html * <arcgis-map itemId="462c629e8e604c15baf45627c4f337d6"> * <arcgis-value-picker slot="top-right"></arcgis-value-picker> * </arcgis-map> * ``` * * If a user wishes to use Value Picker with a component or dataset that can't be accurately represented by the slottable components, the component may be placed * adjacent to the empty Value Picker, and events fired by Value Picker can be used to orchestrate the behavior of the adjacent component. * For example, when the user clicks the play button, Value Picker will emit [@arcgisAnimate](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#event-arcgisAnimate) each time * [playRate](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#playRate) ms have elapsed since the button was clicked, which the user could listen to and iterate the index of * their dataset on an interval as a result. * * ```js * const valuePicker = document.querySelector("arcgis-value-picker"); * const basemapGallery = document.querySelector("arcgis-basemap-gallery"); * * const basemaps = new Collection([ * Basemap.fromId("topo-vector"), * Basemap.fromId("hybrid"), * Basemap.fromId("streets"), * Basemap.fromId("satellite"), * Basemap.fromId("oceans"), * ]); * * basemapGallery.source = new LocalBasemapsSource({ basemaps }); * basemapGallery.activeBasemap = basemaps.getItemAt(0); * * valuePicker.addEventListener("arcgisAnimate", () => { * const currentIndex = basemaps.indexOf(basemapGallery.activeBasemap); * basemapGallery.activeBasemap = basemaps.getItemAt(currentIndex + 1); * }); * ``` * * #### Configuring Value Picker with slotted components * * A single component may be placed into the Value Picker slot by placing one element inside of the other: * * ```html * <arcgis-value-picker> * <arcgis-value-picker-slider></arcgis-value-picker-slider> * </arcgis-value-picker> * ``` * * #### 1. Using a label component to step through a list of items * * Consider using the [arcgis-value-picker-label](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-label/) component to step through a small, fixed list of predefined values. This component provides a strict * interface that steps back and forth, so it's a good option for temporal data, or data that shows progression dependent on the element's position in the list. * * ![value-picker-label](https://developers.arcgis.com/javascript/latest/assets/references/components/value-picker/value-picker-label.avif) * * ```js * const mapElement = document.querySelector("arcgis-map"); * const valuePickerLabel = document.querySelector("arcgis-value-picker-label"); * * const labelItems = [ * { value: "2017", label: "Tree cover in 2017" }, * { value: "2018", label: "Tree cover in 2018" }, * { value: "2019", label: "Tree cover in 2019" }, * { value: "2020", label: "Tree cover in 2020" }, * { value: "2021", label: "Tree cover in 2021" } * ]; * * valuePickerLabel.items = labelItems; * * valuePickerLabel.currentValue = labelItems[0]; * ``` * * The user's interaction can be handled by monitoring the [arcgis-value-picker-label.currentValue](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-label/#currentValue) property. * * ```js * valuePickerLabel.addEventListener("arcgisPropertyChange", () => { * const year = Number(valuePickerLabel.currentValue.value); * mapElement.view.timeExtent = { * start: new Date(year, 0, 1), * end: new Date(year + 1, 0, 1), * }; * console.log("The current year is: ", valuePickerLabel.currentValue.value); * }); * ``` * * #### 2. Using a slider component to traverse a list of items * * Consider using the [arcgis-value-picker-slider](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/) component to quickly traverse through a set of data * that can be represented along a fixed numeric range. This is a good option for sets of elements spaced along an interval, or mutating * a continuous parameter such as layer opacity. * * ![value-picker-slider](https://developers.arcgis.com/javascript/latest/assets/references/components/value-picker/value-picker-slider.avif) * * ```js * const valuePickerSlider = document.querySelector("arcgis-value-picker-slider"); * * valuePickerSlider.steps = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]; * valuePickerSlider.labels = [0, 20, 40, 60, 80, 100]; * valuePickerSlider.majorTicks = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]; * valuePickerSlider.minorTicks = [5, 15, 25, 35, 45, 55, 65, 75, 85, 95]; * valuePickerSlider.currentValue = 100; * valuePickerSlider.labelFormatter = (value) => `${value}%`; * ``` * * The user's interaction can be handled by monitoring the [arcgis-value-picker-slider.currentValue](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/#currentValue) property. * * ```js * valuePickerSlider.addEventListener("arcgisPropertyChange", () => { * layer.opacity = valuePickerSlider.currentValue / 100; * console.log("The current layer opacity is: ", valuePickerSlider.currentValue / 100); * }); * ``` * * Note that [arcgis-value-picker-slider.labels](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/#labels), [arcgis-value-picker-slider.majorTicks](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/#majorTicks), and [arcgis-value-picker-slider.minorTicks](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-slider/#minorTicks) * are all independent of each other and optional. * * #### 3. Using a combobox component to select from a list of items * * Consider using the [arcgis-value-picker-combobox](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-combobox/) component to step through a longer list of items that cannot be clicked through * one by one. The combobox component allows the user to open the list as a dropdown and make a selection, or narrow the size of the list by searching for an element or keyword. * * ![value-picker-combobox](https://developers.arcgis.com/javascript/latest/assets/references/components/value-picker/value-picker-combobox.avif) * * ```js * const valuePickerCombobox = document.querySelector("arcgis-value-picker-combobox"); * * const comboboxItems = [ * { value: "Bare", label: "Isolate Bare Ground Areas" }, * { value: "Built", label: "Isolate Built Areas" }, * { value: "Trees", label: "Isolate Trees" }, * { value: "Water", label: "Isolate Water Areas" }, * { value: "Crops", label: "Isolate Crop Areas" }, * ]; * * valuePickerCombobox.items = comboboxItems; * * valuePickerCombobox.currentValue = comboboxItems[0]; * ``` * * The user's interaction can be handled by monitoring the [arcgis-value-picker-combobox.currentValue](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-combobox/#currentValue) property. * * ```js * valuePickerCombobox.addEventListener("arcgisPropertyChange", () => { * layer.rasterFunction = { * functionName: valuePickerCombobox.currentValue.value, * }; * console.log("The current land cover category is: ", valuePickerCombobox.currentValue.value); * }); * ``` * * #### 4. Using a collection component to step through an arbitrary set of data * * Consider using the [arcgis-value-picker-collection](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-collection/) component when a visual representation for the dataset is not necessary. * This is also a good option for datasets already in the form of a [Collection](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/). * * ![value-picker-collection](https://developers.arcgis.com/javascript/latest/assets/references/components/value-picker/value-picker-collection.avif) * * ```js * const Collection = (await import("@arcgis/core/core/Collection.js")).default; * * const mapElement = document.querySelector("arcgis-map"); * const valuePickerCollection = document.querySelector("arcgis-value-picker-collection"); * * const basemapCollection = new Collection(["topo-vector", "streets", "osm"]); * * valuePickerCollection.items = basemapCollection; * * valuePickerCollection.currentValue = "topo-vector"; * ``` * * The user's interaction can be handled by monitoring the [arcgis-value-picker-collection.currentValue](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker-collection/#currentValue) property. * * ```js * valuePickerCollection.addEventListener("arcgisPropertyChange", () => { * mapElement.basemap = valuePickerCollection.currentValue; * console.log("The current basemap is: ", valuePickerCollection.currentValue); * }); * ``` * * @slot - Default slot for adding a component to value-picker. User is responsible for positioning the content via CSS. * @internal * @since 5.1 */ export abstract class ArcgisValuePicker extends LitElement { /** * If true, the component will not be destroyed automatically when it is * disconnected from the document. This is useful when you want to move the * component to a different place on the page, or temporarily hide it. If this * is set, make sure to call the [destroy()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#destroy) method when you are done to * prevent memory leaks. * * @default false */ accessor autoDestroyDisabled: boolean; /** * An optional caption that renders under the Value Picker component to give context for the user. This is particularly * useful when an application is using more than one Value Picker instance. * * @default "" */ accessor caption: string | undefined; /** * When true, the component is visually withdrawn and cannot be interacted with. If the slotted component also has a `disabled` property, * it will be kept in sync with this property. * * @default false */ accessor disabled: boolean; /** * When set to `true`, the next button is not displayed. * * @default false */ accessor hideNextButton: boolean; /** * When set to `true`, the play/pause button is not displayed. * * @default false */ accessor hidePlayButton: boolean; /** * When set to `true`, the previous button is not displayed. * * @default false */ accessor hidePreviousButton: boolean; /** * Icon which represents the component. * Typically used when the component is controlled by another component (e.g. by the Expand component). * * @default "list-rectangle" * @see [Calcite Icons](https://developers.arcgis.com/calcite-design-system/icons/) */ accessor icon: IconName; /** * The component's default label. * * @default "" */ accessor label: string | undefined; /** * Indicates the axis that the Value Picker buttons should be oriented along. * * Horizontal layouts are best for wider components that don't require a lot of vertical space, * or components that iterate from left to right over a dataset. Some examples of these are * horizontal sliders, collapsable dropdowns, or label components. * * Vertical layouts are best for taller components or components that should iterate vertically. * Some examples include vertical sliders or list components that require a larger space to allow the user to scroll through the list. * * @default "horizontal" */ accessor layout: Layout; /** * When set to `true`, playback will restart from the first element of the slotted component's dataset * once it reaches the end. Note that this will not allow the Value Picker buttons to be used to manually loop back to the first element. * * @default false */ accessor loop: boolean; /** @internal */ protected messages: { componentLabel: string; next: string; previous: string; play: string; pause: string; } & T9nMeta<{ componentLabel: string; next: string; previous: string; play: string; pause: string; }>; /** * Specifies the interval, in milliseconds, on which the component will call `step("next")` on the slotted component. * * @default 1000 */ accessor playRate: number; /** * By assigning the `id` attribute of the Map or Scene component to this property, you can position a child component anywhere in the DOM while still maintaining a connection to the Map or Scene. * * @see [Associate components with a Map or Scene component](https://developers.arcgis.com/javascript/latest/programming-patterns/#associate-components-with-a-map-or-scene-component) */ accessor referenceElement: ArcgisReferenceElement | string | undefined; /** The current state of the component. */ get state(): "playing" | "ready"; /** Permanently destroy the component. */ destroy(): Promise<void>; /** * Selects the next index from the slotted component's dataset. * * @example * ```js * const valuePicker = document.querySelector("arcgis-value-picker"); * const valuePickerSlider = document.querySelector("arcgis-value-picker-slider"); * * valuePickerSlider.steps = [1, 2, 3, 4, 5]; * valuePickerSlider.currentValue = 1; * * console.log(`Current value: ${valuePickerSlider.currentValue}`); // "Current value: 1" * valuePicker.next(); * console.log(`Current value: ${valuePickerSlider.currentValue}`); // "Current value: 2" * ``` */ next(): void; /** Stops the component from playing. */ pause(): void; /** * Start playing. Value Picker will call `step("next")` on the slotted component at an interval defined by [playRate](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#playRate). * * @example * ```js * // Start a continuously looping ValuePicker. * const valuePicker = document.querySelector("arcgis-value-picker"); * const valuePickerSlider = document.querySelector("arcgis-value-picker-slider"); * * valuePickerSlider.steps = [1, 2, 3]; * valuePickerSlider.currentValue = 1; * valuePicker.loop = true; * * valuePickerSlider.addEventListener("arcgisPropertyChange", () => { * console.log(valuePickerSlider.currentValue); * }); * * valuePicker.play(); * // output: 1, 2, 3, 1, 2, 3, 1... * ``` */ play(): void; /** * Selects the previous index from the slotted component's dataset. * * @example * ```js * const valuePicker = document.querySelector("arcgis-value-picker"); * const valuePickerSlider = document.querySelector("arcgis-value-picker-slider"); * * valuePickerSlider.steps = [1, 2, 3, 4, 5]; * valuePickerSlider.currentValue = 3; * * console.log(`Current value: ${valuePickerSlider.currentValue}`); // "Current value: 3" * valuePicker.previous(); * console.log(`Current value: ${valuePickerSlider.currentValue}`); // "Current value: 2" * ``` */ previous(): void; /** * Fires on each playback tick after the user presses the play button. The event payload contains `{ first: boolean }` and fires for * the first time after [playRate](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#playRate) ms have elapsed since the user pressed the play button. Users should * listen to this event to manually iterate an external dataset on an interval. */ readonly arcgisAnimate: import("@arcgis/lumina").TargetedEvent<this, AnimateEvent>; /** Fires when the Value Picker's next button is pressed or when the [next()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#next) method is invoked. */ readonly arcgisNext: import("@arcgis/lumina").TargetedEvent<this, void>; /** Fires when the Value Picker's pause button is pressed or when the [pause()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#pause) method is invoked. */ readonly arcgisPause: import("@arcgis/lumina").TargetedEvent<this, void>; /** Fires when the Value Picker's play button is pressed or when the [play()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#play) method is invoked. */ readonly arcgisPlay: import("@arcgis/lumina").TargetedEvent<this, void>; /** Fires when the Value Picker's previous button is pressed or when the [previous()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-value-picker/#previous) method is invoked. */ readonly arcgisPrevious: import("@arcgis/lumina").TargetedEvent<this, void>; /** Emitted when the value of a property is changed. Use this to listen to changes to properties. */ readonly arcgisPropertyChange: import("@arcgis/lumina").TargetedEvent<this, { name: "layout" | "loop" | "playRate" | "state"; }>; /** Fires when the contents of Value Picker's slot changes. */ readonly arcgisSlottedElementChange: import("@arcgis/lumina").TargetedEvent<this, { slottedElement: ArcgisValuePickerSubcomponent | undefined; }>; readonly "@eventTypes": { arcgisAnimate: ArcgisValuePicker["arcgisAnimate"]["detail"]; arcgisNext: ArcgisValuePicker["arcgisNext"]["detail"]; arcgisPause: ArcgisValuePicker["arcgisPause"]["detail"]; arcgisPlay: ArcgisValuePicker["arcgisPlay"]["detail"]; arcgisPrevious: ArcgisValuePicker["arcgisPrevious"]["detail"]; arcgisPropertyChange: ArcgisValuePicker["arcgisPropertyChange"]["detail"]; arcgisSlottedElementChange: ArcgisValuePicker["arcgisSlottedElementChange"]["detail"]; }; }