@arcgis/lumina 4.33.0-next.11 → 4.33.0-next.111

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.
Files changed (53) hide show
  1. package/dist/Controller-CZ8Djohh.js +627 -0
  2. package/dist/LitElement.d.ts +36 -29
  3. package/dist/config.js +13 -6
  4. package/dist/context.d.ts +13 -3
  5. package/dist/controllers/Controller.d.ts +153 -0
  6. package/dist/controllers/ControllerInternals.d.ts +59 -0
  7. package/dist/controllers/ControllerManager.d.ts +83 -0
  8. package/dist/controllers/accessor/index.d.ts +2 -0
  9. package/dist/controllers/accessor/index.js +259 -0
  10. package/dist/controllers/accessor/reEmitEvent.d.ts +10 -0
  11. package/dist/controllers/accessor/useAccessor.d.ts +74 -0
  12. package/dist/controllers/functional.d.ts +19 -0
  13. package/dist/controllers/index.d.ts +24 -0
  14. package/dist/controllers/index.js +267 -0
  15. package/dist/controllers/load.d.ts +6 -0
  16. package/dist/controllers/proxyExports.d.ts +27 -0
  17. package/dist/controllers/tests/autoDestroyMock.d.ts +5 -0
  18. package/dist/controllers/tests/utils.d.ts +1 -0
  19. package/dist/controllers/toFunction.d.ts +8 -0
  20. package/dist/controllers/trackKey.d.ts +8 -0
  21. package/dist/controllers/trackPropKey.d.ts +21 -0
  22. package/dist/controllers/trackPropertyKey.d.ts +29 -0
  23. package/dist/controllers/types.d.ts +152 -0
  24. package/dist/controllers/useDirection.d.ts +11 -0
  25. package/dist/controllers/useMedia.d.ts +8 -0
  26. package/dist/controllers/usePropertyChange.d.ts +12 -0
  27. package/dist/controllers/useT9n.d.ts +48 -0
  28. package/dist/controllers/useWatchAttributes.d.ts +7 -0
  29. package/dist/controllers/utils.d.ts +15 -0
  30. package/dist/createEvent.d.ts +7 -2
  31. package/dist/decorators.d.ts +2 -2
  32. package/dist/devOnlyDetectIncorrectLazyUsages.d.ts +1 -1
  33. package/dist/hmrSupport.d.ts +1 -1
  34. package/dist/hmrSupport.js +1 -7
  35. package/dist/index.d.ts +17 -16
  36. package/dist/index.js +386 -150
  37. package/dist/jsx/baseTypes.d.ts +13 -9
  38. package/dist/jsx/directives.d.ts +25 -7
  39. package/dist/jsx/generatedTypes.d.ts +6 -10
  40. package/dist/jsx/types.d.ts +5 -32
  41. package/dist/lazyLoad.d.ts +18 -18
  42. package/dist/lifecycleSupport.d.ts +1 -1
  43. package/dist/makeRuntime.d.ts +109 -0
  44. package/dist/proxyExports-CK5BLFLO.js +60 -0
  45. package/dist/render.d.ts +5 -0
  46. package/dist/runtime.d.ts +4 -107
  47. package/dist/stencilSsrCompatibility/index.d.ts +2 -6
  48. package/dist/stencilSsrCompatibility/index.js +2 -3
  49. package/dist/typings/importMeta.d.ts +2 -2
  50. package/dist/{chunk-NO7HOBNA.js → utils-CwiifsrO.js} +44 -61
  51. package/package.json +4 -3
  52. package/dist/chunk-PGHUBTOM.js +0 -21
  53. package/dist/wrappersUtils.test.d.ts +0 -1
@@ -0,0 +1,259 @@
1
+ import { p as devOnlySetPersistentControllerData, q as devOnlyGetPersistentControllerData, G as GenericController, n as trackPropKey, h as bypassGetter, l as bypassReadOnly, t as trackKey, r as retrieveComponent, g as createEventFactory } from "../../Controller-CZ8Djohh.js";
2
+ import { p as proxyExports } from "../../proxyExports-CK5BLFLO.js";
3
+ import { isEsriInternalEnv } from "@arcgis/components-utils";
4
+ import { watch, on } from "@arcgis/core/core/reactiveUtils.js";
5
+ const makeAccessorController = (loadAccessor, _options) => (component, options) => proxy(component, loadAccessor, options);
6
+ class AccessorController extends GenericController {
7
+ constructor(component, _loadAccessor, _options) {
8
+ super(component);
9
+ this._loadAccessor = _loadAccessor;
10
+ this._options = _options;
11
+ this._watchedProperties = /* @__PURE__ */ new Map();
12
+ this._isBinding = { value: true };
13
+ this.setProvisionalExports(
14
+ accessorSupport.makeGetterProxy(
15
+ component,
16
+ this._watchedProperties,
17
+ this._isBinding,
18
+ this.constructor.allowedPropNameMismatches
19
+ )
20
+ );
21
+ trackPropKey(
22
+ component,
23
+ (resolved) => {
24
+ if (resolved) {
25
+ this._instancePropName = resolved;
26
+ }
27
+ },
28
+ this.exports
29
+ );
30
+ }
31
+ hostConnected() {
32
+ this._isBinding.value = false;
33
+ }
34
+ async hostLoad() {
35
+ const component = this.component;
36
+ const parameters = this._gatherParameters();
37
+ const finalParameters = this._options?.editConstructorProperties?.call(component, parameters) ?? parameters;
38
+ const awaitedParameters = finalParameters instanceof Promise ? await finalParameters : finalParameters;
39
+ const genericComponent = component;
40
+ const existingInstance = typeof this._instancePropName === "string" ? genericComponent[this._instancePropName] : void 0;
41
+ const hasInstance = existingInstance != null && existingInstance !== this.exports;
42
+ if (hasInstance) {
43
+ this._instance = existingInstance;
44
+ existingInstance.set(awaitedParameters);
45
+ } else {
46
+ this._instance = await this._createInstance(awaitedParameters);
47
+ }
48
+ if (component.manager.destroyed) {
49
+ return;
50
+ }
51
+ accessorSupport.watchComponentUpdates(this, this._instance, this._watchedProperties);
52
+ accessorSupport.watchAccessorUpdates(this, this._instance, this._watchedProperties);
53
+ this.exports = this._instance;
54
+ }
55
+ _gatherParameters() {
56
+ const data = Object.fromEntries(
57
+ Array.from(
58
+ this._watchedProperties,
59
+ ([prop, property]) => [property, this.component[prop]]
60
+ ).filter(([, value]) => value !== void 0)
61
+ );
62
+ const props = process.env.NODE_ENV !== "production" && isEsriInternalEnv() ? filterWatchedProperties?.(this, data) ?? data : data;
63
+ return props;
64
+ }
65
+ async _createInstance(parameters) {
66
+ if (this._isAccessorConstructor(this._loadAccessor)) {
67
+ return new this._loadAccessor(parameters);
68
+ } else {
69
+ return await this._loadAccessor(parameters);
70
+ }
71
+ }
72
+ _isAccessorConstructor(loader) {
73
+ return "prototype" in loader && "declaredClass" in loader.prototype;
74
+ }
75
+ hostDestroy() {
76
+ if (this._instance) {
77
+ this._instance.destroy();
78
+ }
79
+ }
80
+ async reCreate() {
81
+ this.hostDestroy();
82
+ await this.hostLoad();
83
+ }
84
+ }
85
+ const proxy = proxyExports(AccessorController);
86
+ const accessorSupport = {
87
+ makeGetterProxy: (component, watchedProperties, isBinding, allowedPropNameMismatches) => new Proxy(
88
+ {},
89
+ {
90
+ /*
91
+ * Without this, makeProvisionalValue() will throw on accessing
92
+ * non-existent prop
93
+ */
94
+ has: (target, prop) => typeof prop === "string" || prop in target,
95
+ get: (target, prop) => {
96
+ const value = Reflect.get(target, prop);
97
+ if (typeof prop === "symbol" || prop in Promise.prototype) {
98
+ return value;
99
+ }
100
+ const hasProp = prop in target;
101
+ const doBinding = isBinding?.value ?? true;
102
+ if (hasProp || !doBinding) {
103
+ return value;
104
+ }
105
+ if (watchedProperties.has(prop)) {
106
+ return;
107
+ }
108
+ return trackKey(
109
+ component,
110
+ (resolved) => {
111
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
112
+ if (resolved === void 0) {
113
+ return;
114
+ }
115
+ const isFlippingBoolean = resolved.key.toLowerCase().includes("disable");
116
+ const collidesWithNativeProp = prop in HTMLElement.prototype;
117
+ const collidesWithCustomProp = allowedPropNameMismatches?.has(prop) === true;
118
+ if (resolved.key !== prop && !collidesWithNativeProp && !collidesWithCustomProp && !isFlippingBoolean) {
119
+ throw new Error(
120
+ `Tried to bind "${resolved?.key}" property to "${prop.toString()}" - property names must match`
121
+ );
122
+ }
123
+ if (!resolved.isReactive) {
124
+ throw new Error(
125
+ `For two-way binding with Accessor to work, the property on your component must have @property() or @state() decorator. "${prop.toString()}" has neither`
126
+ );
127
+ }
128
+ }
129
+ if (resolved !== void 0) {
130
+ watchedProperties.set(resolved.key, prop);
131
+ }
132
+ },
133
+ value
134
+ );
135
+ }
136
+ }
137
+ ),
138
+ // Update Accessor on component prop change
139
+ watchComponentUpdates(controller, instance, watchedProperties) {
140
+ function getter(_value, propName) {
141
+ const propertyName = watchedProperties.get(propName);
142
+ const value = instance[propertyName];
143
+ const flipBoolean = typeof value === "boolean" && propertyName !== propName && propName.toLowerCase().includes("disable");
144
+ return flipBoolean ? !value : value;
145
+ }
146
+ const setter = (newValue, _oldValue, propName) => {
147
+ const propertyName = watchedProperties.get(propName);
148
+ const value = instance[propertyName];
149
+ const flipBoolean = typeof value === "boolean" && propertyName !== propName && propName.toLowerCase().includes("disable");
150
+ const currentValue = flipBoolean ? !value : value ?? void 0;
151
+ if (currentValue === newValue) {
152
+ return newValue;
153
+ }
154
+ instance[propertyName] = flipBoolean ? !newValue : newValue;
155
+ const finalValue = instance[propertyName];
156
+ return flipBoolean ? !finalValue : finalValue;
157
+ };
158
+ const manager = controller.component.manager;
159
+ watchedProperties.forEach((_propName, propertyName) => {
160
+ manager._accessorGetter[propertyName] = getter;
161
+ manager._accessorSetter[propertyName] = setter;
162
+ });
163
+ },
164
+ // Update component on Accessor prop change
165
+ watchAccessorUpdates(controller, instance, watchedProperties) {
166
+ const { component } = controller;
167
+ const genericComponent = component;
168
+ const genericInstance = instance;
169
+ const readonlyProps = findReadOnlyAccessorProps(instance);
170
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
171
+ setReadonlyProps?.(controller, readonlyProps);
172
+ }
173
+ bypassGetter(
174
+ () => (
175
+ // Careful: Map's forEach callback arguments are (value, key), not (key, value)
176
+ watchedProperties.forEach((propertyName, propName) => {
177
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv() && !(propertyName in instance)) {
178
+ throw new Error(`"${propertyName}" does not exist on the accessor instance`);
179
+ }
180
+ if (readonlyProps.has(propertyName)) {
181
+ return;
182
+ }
183
+ const domValue = genericComponent[propName];
184
+ const modelValue = genericInstance[propertyName] ?? void 0;
185
+ const flipBoolean = typeof domValue === "boolean" && propertyName !== propName && propName.toLowerCase().includes("disable");
186
+ const resolvedDomValue = flipBoolean ? !domValue : domValue;
187
+ if (resolvedDomValue != null && modelValue !== resolvedDomValue) {
188
+ genericInstance[propertyName] = resolvedDomValue;
189
+ }
190
+ })
191
+ )
192
+ );
193
+ controller.onLifecycle(() => {
194
+ if (instance.destroyed) {
195
+ return;
196
+ }
197
+ return Array.from(
198
+ watchedProperties,
199
+ ([propName, propertyName]) => watch(
200
+ () => genericInstance[propertyName],
201
+ () => {
202
+ const newValue = genericInstance[propertyName];
203
+ const flipBoolean = typeof newValue === "boolean" && propertyName !== propName && propName.toLowerCase().includes("disable");
204
+ const resolvedNewValue = flipBoolean ? !newValue : newValue;
205
+ bypassReadOnly(() => {
206
+ genericComponent[propName] = resolvedNewValue;
207
+ });
208
+ },
209
+ { initial: true }
210
+ )
211
+ );
212
+ });
213
+ },
214
+ async reCreate(instance, component) {
215
+ const accessorController = component.manager.useRefSync(instance);
216
+ if (accessorController === void 0) {
217
+ if (process.env.NODE_ENV !== "production") {
218
+ console.error("Unable to resolve the useAccessor controller from the provided value");
219
+ }
220
+ return;
221
+ }
222
+ await accessorController.reCreate();
223
+ }
224
+ };
225
+ function findReadOnlyAccessorProps(instance) {
226
+ const accessor = instance;
227
+ const properties = Object.entries(accessor.__accessor__?.metadata ?? {});
228
+ return new Set(
229
+ properties.filter(([_property, descriptor]) => descriptor?.readOnly === true).map(([property]) => property)
230
+ );
231
+ }
232
+ const setReadonlyProps = process.env.NODE_ENV !== "production" && isEsriInternalEnv() ? (controller, properties) => {
233
+ devOnlySetPersistentControllerData?.(controller, properties);
234
+ } : void 0;
235
+ const filterWatchedProperties = process.env.NODE_ENV !== "production" && isEsriInternalEnv() ? (controller, data) => {
236
+ const readonlyProperties = devOnlyGetPersistentControllerData?.(controller);
237
+ if (readonlyProperties instanceof Set) {
238
+ return Object.fromEntries(Object.entries(data).filter(([key]) => !readonlyProperties.has(key)));
239
+ }
240
+ return data;
241
+ } : void 0;
242
+ function reEmitEvent(getEventedAccessor, eventName) {
243
+ const component = retrieveComponent();
244
+ const manager = component.manager;
245
+ manager.onLoaded(() => manager.onLifecycle(() => on(getEventedAccessor, eventName, emitter.emit)));
246
+ const emitter = createEventFactory();
247
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
248
+ if (typeof emitter !== "object" || emitter === null || !("emit" in emitter) || typeof emitter.emit !== "function") {
249
+ throw new Error(`Expected to find $createEvent static property on Lumina's LitElement`);
250
+ }
251
+ }
252
+ return emitter;
253
+ }
254
+ export {
255
+ AccessorController,
256
+ accessorSupport,
257
+ makeAccessorController,
258
+ reEmitEvent
259
+ };
@@ -0,0 +1,10 @@
1
+ import { EventEmitter } from '../../createEvent';
2
+ /**
3
+ * Re-emit an event from the accessor instance on the component
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * arcgisGo = reEmitEvent<__esri.HomeViewModelGoEvent>(() => this.viewModel, "go");
8
+ * ```
9
+ */
10
+ export declare function reEmitEvent<T>(getEventedAccessor: () => __esri.Evented, eventName: string): EventEmitter<T>;
@@ -0,0 +1,74 @@
1
+ import { Controller, GenericController } from '../Controller';
2
+ import { LitElement } from '../../LitElement';
3
+ type Requires<Props, Accessor extends __esri.Accessor> = LitElement & Pick<Accessor, keyof Accessor & keyof Props> & {
4
+ autoDestroyDisabled: boolean;
5
+ destroy: () => Promise<void>;
6
+ };
7
+ /**
8
+ * Given an Accessor class, create a controller that will do two-way binding of
9
+ * props between the component and the Accessor
10
+ *
11
+ * See 4.accessor.tsx for documentation & examples
12
+ */
13
+ export declare const makeAccessorController: <Props, Accessor extends __esri.Accessor, OmitProps extends string = never>(loadAccessor: ((props: Props) => Accessor | Promise<Accessor>) | (new (props: Props) => Accessor), _options?: {
14
+ /**
15
+ * By default, to ensure that you didn't accidentally forget to bind any
16
+ * of the Accessor's properties on your component, every property that
17
+ * is accepted by the Accessor's constructor will be required to be bound
18
+ * on your component. If you do not wish to bind certain properties
19
+ * (or you wish to bind them but with a different type), you can omit
20
+ * them using this option.
21
+ *
22
+ * You can also bind the property to \@state rather than \@property if you
23
+ * wish to use it internally only:
24
+ * @example
25
+ * ```tsx
26
+ * \@State() timeZone = this.viewModel.timeZone;
27
+ * ```
28
+ *
29
+ * @remarks
30
+ * This option affects the TypeScript error checking only - it has
31
+ * no runtime impact. Thus, if you wish to save a few bytes in the
32
+ * bundle, rather than simply setting this property like
33
+ * `makeAccessorController(..., { omitProps: ["propName"] })`, you can
34
+ * set it like this:
35
+ * `makeAccessorController(..., {} as { omitProps: ["propName"] })`
36
+ */
37
+ omitProps: OmitProps[];
38
+ }) => (component: Requires<Omit<Props, OmitProps>, Accessor>, options?: {
39
+ editConstructorProperties(props: Props): Promise<Props> | Props;
40
+ }) => Accessor;
41
+ export declare class AccessorController<Props, Accessor extends __esri.Accessor, ExtraRequires = Record<never, never>> extends GenericController<Accessor, ExtraRequires & Requires<Props, Accessor>> {
42
+ private _loadAccessor;
43
+ private _options?;
44
+ protected _instance: Accessor;
45
+ protected _watchedProperties: Map<string, string & keyof Props>;
46
+ private _instancePropName;
47
+ private _isBinding;
48
+ /**
49
+ * (development only) Allow these props to mismatch the name of the Accessor's property
50
+ * to avoid collisions
51
+ *
52
+ * @private
53
+ */
54
+ static allowedPropNameMismatches?: Set<string>;
55
+ constructor(component: ExtraRequires & Requires<Props, Accessor>, _loadAccessor: ((props: Props) => Accessor | Promise<Accessor>) | (new (props: Props) => Accessor), _options?: {
56
+ editConstructorProperties?(props: Props): Promise<Props> | Props;
57
+ } | undefined);
58
+ hostConnected(): void;
59
+ hostLoad(): Promise<void>;
60
+ private _gatherParameters;
61
+ private _createInstance;
62
+ private _isAccessorConstructor;
63
+ hostDestroy(): void;
64
+ reCreate(): Promise<void>;
65
+ }
66
+ export declare const accessorSupport: {
67
+ makeGetterProxy: (component: LitElement, watchedProperties: Map<string, string>, isBinding?: {
68
+ value: boolean;
69
+ }, allowedPropNameMismatches?: Set<string>) => unknown;
70
+ watchComponentUpdates<T>(controller: Controller<T>, instance: __esri.Accessor, watchedProperties: Map<string, string>): void;
71
+ watchAccessorUpdates<T>(controller: Controller<T>, instance: __esri.Accessor, watchedProperties: Map<string, string>): void;
72
+ reCreate(instance: __esri.Accessor, component: LitElement): Promise<void>;
73
+ };
74
+ export {};
@@ -0,0 +1,19 @@
1
+ import { LitElement } from '../LitElement';
2
+ import { GenericControllerType, Controller } from './Controller';
3
+ /**
4
+ * Controller is a function that takes a component instance and then can
5
+ * export some values to the component, or hook into component's lifecycle
6
+ *
7
+ * See controllers documentation for many example controllers and their usages
8
+ */
9
+ export declare const makeController: <Exports>(constructor: (component: LitElement, controller: Controller<Exports>) => Exports | Promise<Exports>) => Exports;
10
+ /**
11
+ * If your controller requires some specific properties to be present on the
12
+ * component, besides what's included in the LitElement, use
13
+ * makeGenericController
14
+ *
15
+ * When using a controller created using makeGenericController(), consumer must
16
+ * pass in "this" explicitly for proper type-checking. If controller was
17
+ * created using makeController(), that is not necessary
18
+ */
19
+ export declare const makeGenericController: <Exports, Component = LitElement>(constructor: (component: Component & LitElement, controller: GenericControllerType<Exports, Component>) => Exports | Promise<Exports>) => (component: Component & LitElement) => Exports;
@@ -0,0 +1,24 @@
1
+ import { EventEmitter as _EventEmitter } from '../createEvent';
2
+ export type { GenericControllerType } from './Controller';
3
+ export { Controller, GenericController } from './Controller';
4
+ export type { ControllerManager } from './ControllerManager';
5
+ export { retrieveComponent, bypassGetter, bypassSetter, bypassReadOnly } from './ControllerInternals';
6
+ export { trackPropertyKey, keyTrackResolve } from './trackPropertyKey';
7
+ export { trackPropKey } from './trackPropKey';
8
+ export { trackKey } from './trackKey';
9
+ export { makeController, makeGenericController } from './functional';
10
+ export { useWatchAttributes } from './useWatchAttributes';
11
+ export { load } from './load';
12
+ export { proxyExports } from './proxyExports';
13
+ export { toFunction } from './toFunction';
14
+ export * from './types';
15
+ export { useMedia } from './useMedia';
16
+ export { useDirection } from './useDirection';
17
+ export type { UseT9n, T9nMeta } from './useT9n';
18
+ export { makeT9nController } from './useT9n';
19
+ export { usePropertyChange } from './usePropertyChange';
20
+ export { isController } from './utils';
21
+ /**
22
+ * @deprecated import from "@arcgis/lumina" instead
23
+ */
24
+ export type EventEmitter<T = undefined> = _EventEmitter<T>;
@@ -0,0 +1,267 @@
1
+ import { C as Controller, s as setAmbientComponent, i as isPromise, e as setParentController, f as retrieveParentControllers, t as trackKey, r as retrieveComponent, g as createEventFactory } from "../Controller-CZ8Djohh.js";
2
+ import { G, h, l, j, c, o, k, n, m } from "../Controller-CZ8Djohh.js";
3
+ import { p as proxyExports } from "../proxyExports-CK5BLFLO.js";
4
+ import { isServer } from "lit";
5
+ import { observeAncestorsMutation, isEsriInternalEnv, getElementAttribute, getElementLocales, startLocaleObserver } from "@arcgis/components-utils";
6
+ const makeController = (constructor) => proxy(void 0, constructor);
7
+ const makeGenericController = (constructor) => (component) => proxy(
8
+ component,
9
+ /**
10
+ * GenericController is identical to Controller, in all except for typing.
11
+ * So dying a type-cast here so as not to needlessly add one more object
12
+ * to the prototype chain
13
+ */
14
+ constructor
15
+ );
16
+ class FunctionalController extends Controller {
17
+ constructor(component, constructor) {
18
+ super(component);
19
+ const originalExports = this.exports;
20
+ try {
21
+ setAmbientComponent(this.component);
22
+ const value = constructor(this.component, this);
23
+ const constructorChangedExports = this.exports !== originalExports;
24
+ if (isPromise(value)) {
25
+ if (!constructorChangedExports) {
26
+ this.setProvisionalExports(value);
27
+ }
28
+ const resolved = value.then((result) => {
29
+ this.exports = result;
30
+ super.catchUpLifecycle();
31
+ }).catch((error) => {
32
+ this._ready.reject(error);
33
+ console.error(error);
34
+ });
35
+ this.onLoad(async () => await resolved);
36
+ } else {
37
+ if (!constructorChangedExports || value !== void 0) {
38
+ this.exports = value;
39
+ }
40
+ queueMicrotask(() => super.catchUpLifecycle());
41
+ }
42
+ } catch (error) {
43
+ this._ready.reject(error);
44
+ console.error(error);
45
+ }
46
+ }
47
+ /** Noop - will be called in the constructor instead */
48
+ catchUpLifecycle() {
49
+ return;
50
+ }
51
+ }
52
+ const proxy = proxyExports(FunctionalController);
53
+ const useWatchAttributes = (attributes, callback) => new AttributeWatchController(attributes, callback);
54
+ class AttributeWatchController extends Controller {
55
+ constructor(_attributes, _callback) {
56
+ super();
57
+ this._attributes = _attributes;
58
+ this._callback = _callback;
59
+ if (isServer) {
60
+ return;
61
+ }
62
+ this._observer = new MutationObserver((mutations) => {
63
+ mutations.forEach((mutation) => {
64
+ if (_attributes.includes(mutation.attributeName)) {
65
+ _callback.call(
66
+ this.component,
67
+ this.component.el.getAttribute(mutation.attributeName),
68
+ mutation.oldValue,
69
+ mutation.attributeName
70
+ );
71
+ }
72
+ });
73
+ });
74
+ }
75
+ hostConnected() {
76
+ this._attributes.forEach((attribute) => {
77
+ if (this.component.el.hasAttribute(attribute)) {
78
+ this._callback.call(this.component, null, this.component.el.getAttribute(attribute), attribute);
79
+ }
80
+ });
81
+ this._observer.observe(this.component.el, {
82
+ attributes: true,
83
+ attributeOldValue: true,
84
+ attributeFilter: this._attributes
85
+ });
86
+ }
87
+ hostDisconnected() {
88
+ this._observer.disconnect();
89
+ }
90
+ }
91
+ const load = makeController;
92
+ const toFunction = (Class) => (...args) => {
93
+ const ambientControllers = retrieveParentControllers();
94
+ const instance = new Class(...args);
95
+ setParentController(ambientControllers.at(-1));
96
+ return instance;
97
+ };
98
+ const useMedia = (query) => makeController((_component, controller) => {
99
+ const media = globalThis.matchMedia(query);
100
+ function changed() {
101
+ controller.exports = media.matches;
102
+ }
103
+ changed();
104
+ controller.onLifecycle(() => {
105
+ media.addEventListener("change", changed);
106
+ return () => media.removeEventListener("change", changed);
107
+ });
108
+ return void 0;
109
+ });
110
+ const defaultDirection = "ltr";
111
+ const useDirection = () => makeController((component, controller) => {
112
+ controller.exports = defaultDirection;
113
+ controller.onLifecycle(() => {
114
+ function callback() {
115
+ const dir = getElementAttribute(component.el, "dir", defaultDirection);
116
+ controller.exports = dir === "rtl" ? "rtl" : "ltr";
117
+ }
118
+ callback();
119
+ return observeAncestorsMutation(component.el, ["dir"], callback);
120
+ });
121
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
122
+ trackKey(
123
+ component,
124
+ (resolved) => {
125
+ if (resolved?.key === "dir") {
126
+ throw new Error(
127
+ `Do not assign this controller to a prop called \`dir\` as that will overwrite the \`dir\` attribute on the host element - component should not be setting the \`dir\` attribute on itself. Instead, assign this controller to a property called \`direction\`.`
128
+ );
129
+ }
130
+ },
131
+ controller.exports
132
+ );
133
+ }
134
+ return void 0;
135
+ });
136
+ const makeT9nController = (getAssetPath) => (options = {}) => (
137
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
138
+ makeController((component, controller) => {
139
+ const locale = getElementLocales(component.el);
140
+ const pending = { _lang: locale.lang, _t9nLocale: locale.t9nLocale, _loading: true };
141
+ const componentWithOverrides = component;
142
+ controller.onLifecycle(
143
+ () => startLocaleObserver(
144
+ component.el,
145
+ () => getAssetPath("./assets"),
146
+ ({ t9nLocale, t9nStrings, lang }) => {
147
+ const withoutOverrides = {
148
+ ...t9nStrings,
149
+ _lang: lang,
150
+ _t9nLocale: t9nLocale,
151
+ _loading: false
152
+ };
153
+ controller.exports = withoutOverrides;
154
+ const label = t9nStrings.componentLabel;
155
+ if (typeof label === "string" && "label" in component && component.label == null) {
156
+ component.label ??= label;
157
+ }
158
+ applyOverrides(componentWithOverrides.messageOverrides);
159
+ },
160
+ options.name
161
+ )
162
+ );
163
+ function applyOverrides(messageOverrides) {
164
+ const currentValue = controller.exports;
165
+ const rawMessages = currentValue._original ?? currentValue;
166
+ const updated = deepMerge(rawMessages, messageOverrides);
167
+ if (messageOverrides) {
168
+ updated._original = rawMessages;
169
+ }
170
+ controller.exports = updated;
171
+ }
172
+ if ("messageOverrides" in componentWithOverrides) {
173
+ controller.onUpdate((changes) => {
174
+ if (changes.has("messageOverrides")) {
175
+ applyOverrides(componentWithOverrides.messageOverrides);
176
+ }
177
+ });
178
+ }
179
+ if (options.blocking) {
180
+ controller.setProvisionalExports(pending, false);
181
+ return controller.ready;
182
+ } else {
183
+ return pending;
184
+ }
185
+ })
186
+ );
187
+ function deepMerge(original, overwrites) {
188
+ if (!overwrites) {
189
+ return original;
190
+ }
191
+ const merged = { ...original };
192
+ Object.entries(overwrites).forEach(([key, value]) => {
193
+ if (typeof value === "object") {
194
+ merged[key] = deepMerge(original[key], value);
195
+ } else {
196
+ merged[key] = value ?? original[key];
197
+ }
198
+ });
199
+ return merged;
200
+ }
201
+ const usePropertyChange = (_component) => propertyChangeController;
202
+ const eventName = "arcgisPropertyChange";
203
+ function propertyChangeController(...toWatch) {
204
+ const component = retrieveComponent();
205
+ const eventEmitter = createEventFactory(eventName, void 0, component);
206
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
207
+ toWatch.forEach((prop) => {
208
+ const descriptor = component.constructor.elementProperties.get(prop);
209
+ const isProp = descriptor !== void 0 && descriptor.state !== true;
210
+ if (!isProp) {
211
+ throw new Error(
212
+ `For usePropertyChange to emit event on "${prop}" property change, you should add @property() to ${prop} in ${component.el.localName}`
213
+ );
214
+ }
215
+ });
216
+ }
217
+ let isFirst = true;
218
+ component.manager.onUpdated((changes) => {
219
+ if (isFirst || !component.el.isConnected) {
220
+ isFirst = false;
221
+ return;
222
+ }
223
+ for (const name of toWatch) {
224
+ if (changes.has(name)) {
225
+ eventEmitter.emit({ name });
226
+ }
227
+ }
228
+ });
229
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
230
+ trackKey(
231
+ component,
232
+ (resolution) => {
233
+ if (resolution === void 0 || resolution.isReactive || resolution.key !== eventName) {
234
+ throw new Error(
235
+ `For consistency, usePropertyChange must be assigned to an arcgisPropertyChange property and that property should not have @property() or @state() decorators: arcgisPropertyChange = usePropertyChange<this>()("prop1", "prop2");`
236
+ );
237
+ }
238
+ },
239
+ eventEmitter
240
+ );
241
+ }
242
+ return eventEmitter;
243
+ }
244
+ export {
245
+ Controller,
246
+ G as GenericController,
247
+ h as bypassGetter,
248
+ l as bypassReadOnly,
249
+ j as bypassSetter,
250
+ c as controllerSymbol,
251
+ o as isController,
252
+ k as keyTrackResolve,
253
+ load,
254
+ makeController,
255
+ makeGenericController,
256
+ makeT9nController,
257
+ proxyExports,
258
+ retrieveComponent,
259
+ toFunction,
260
+ trackKey,
261
+ n as trackPropKey,
262
+ m as trackPropertyKey,
263
+ useDirection,
264
+ useMedia,
265
+ usePropertyChange,
266
+ useWatchAttributes
267
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Load a value from a promise and provide it to the component
3
+ *
4
+ * Documentation: https://qawebgis.esri.com/components/lumina/controllers/load
5
+ */
6
+ export declare const load: <T>(loader: () => Promise<T>) => T;