@studiometa/js-toolkit 3.0.0-alpha.9 → 3.0.0-beta.1
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/Base/Base.js +2 -2
- package/Base/Base.js.map +2 -2
- package/Base/features.d.ts +1 -0
- package/Base/features.js +1 -0
- package/Base/features.js.map +2 -2
- package/Base/managers/EventsManager.js +2 -4
- package/Base/managers/EventsManager.js.map +2 -2
- package/Base/managers/OptionsManager.d.ts +2 -2
- package/Base/managers/OptionsManager.js +8 -8
- package/Base/managers/OptionsManager.js.map +2 -2
- package/Base/managers/RefsManager.js.map +2 -2
- package/Base/utils.d.ts +4 -0
- package/Base/utils.js +7 -3
- package/Base/utils.js.map +2 -2
- package/decorators/withBreakpointObserver.js +14 -9
- package/decorators/withBreakpointObserver.js.map +2 -2
- package/decorators/withDrag.d.ts +1 -1
- package/decorators/withDrag.js.map +1 -1
- package/decorators/withRelativePointer.d.ts +1 -1
- package/decorators/withRelativePointer.js.map +1 -1
- package/decorators/withResponsiveOptions.d.ts +3 -1
- package/decorators/withResponsiveOptions.js +22 -2
- package/decorators/withResponsiveOptions.js.map +2 -2
- package/helpers/createApp.js +5 -1
- package/helpers/createApp.js.map +2 -2
- package/package.json +1 -1
- package/services/AbstractService.d.ts +98 -0
- package/services/AbstractService.js +114 -0
- package/services/AbstractService.js.map +7 -0
- package/services/DragService.d.ts +124 -0
- package/services/DragService.js +217 -0
- package/services/DragService.js.map +7 -0
- package/services/KeyService.d.ts +29 -0
- package/services/KeyService.js +48 -0
- package/services/KeyService.js.map +7 -0
- package/services/LoadService.d.ts +15 -0
- package/services/LoadService.js +19 -0
- package/services/LoadService.js.map +7 -0
- package/services/PointerService.d.ts +56 -0
- package/services/PointerService.js +129 -0
- package/services/PointerService.js.map +7 -0
- package/services/RafService.d.ts +19 -0
- package/services/RafService.js +45 -0
- package/services/RafService.js.map +7 -0
- package/services/ResizeService.d.ts +29 -0
- package/services/ResizeService.js +66 -0
- package/services/ResizeService.js.map +7 -0
- package/services/{scroll.d.ts → ScrollService.d.ts} +14 -3
- package/services/ScrollService.js +90 -0
- package/services/ScrollService.js.map +7 -0
- package/services/index.d.ts +8 -41
- package/services/index.js +8 -18
- package/services/index.js.map +3 -3
- package/services/utils.d.ts +14 -0
- package/services/utils.js +11 -0
- package/services/utils.js.map +7 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/index.js.map +2 -2
- package/utils/loadElement.d.ts +42 -0
- package/utils/loadElement.js +33 -0
- package/utils/loadElement.js.map +7 -0
- package/utils/tween.js +1 -1
- package/utils/tween.js.map +2 -2
- package/services/drag.d.ts +0 -75
- package/services/drag.js +0 -199
- package/services/drag.js.map +0 -7
- package/services/key.d.ts +0 -21
- package/services/key.js +0 -65
- package/services/key.js.map +0 -7
- package/services/load.d.ts +0 -11
- package/services/load.js +0 -38
- package/services/load.js.map +0 -7
- package/services/pointer.d.ts +0 -32
- package/services/pointer.js +0 -123
- package/services/pointer.js.map +0 -7
- package/services/raf.d.ts +0 -9
- package/services/raf.js +0 -56
- package/services/raf.js.map +0 -7
- package/services/resize.d.ts +0 -15
- package/services/resize.js +0 -67
- package/services/resize.js.map +0 -7
- package/services/scroll.js +0 -105
- package/services/scroll.js.map +0 -7
- package/services/service.d.ts +0 -16
- package/services/service.js +0 -47
- package/services/service.js.map +0 -7
package/Base/Base.js
CHANGED
|
@@ -116,13 +116,13 @@ class Base {
|
|
|
116
116
|
* Small helper to log stuff.
|
|
117
117
|
*/
|
|
118
118
|
get $log() {
|
|
119
|
-
return this.__options.log ? window.console.log.bind(window, `[${this
|
|
119
|
+
return this.__options.log ? window.console.log.bind(window, `[${this.$id}]`) : noop;
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
122
|
* Small helper to make warning easier.
|
|
123
123
|
*/
|
|
124
124
|
get $warn() {
|
|
125
|
-
return this.__options.log ? window.console.warn.bind(window, `[${this
|
|
125
|
+
return this.__options.log ? window.console.warn.bind(window, `[${this.$id}]`) : noop;
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Small helper to debug information.
|
package/Base/Base.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/Base/Base.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: WeakMap<BaseConstructor, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n */\nexport class Base<T extends BaseProps = BaseProps> {\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Store the event handlers.\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager & T['$refs'] & BaseRefs;\n\n get $refs(): RefsManager & T['$refs'] & BaseRefs {\n return this.__refs;\n }\n\n __options: OptionsManager & T['$options'] & BaseOptions;\n\n get $options(): OptionsManager & T['$options'] & BaseOptions {\n return this.__options;\n }\n\n __children: ChildrenManager & T['$children'] & BaseChildren;\n\n get $children(): ChildrenManager & T['$children'] & BaseChildren {\n return this.__children;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.log.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.warn.bind(window, `[${this.__config.name}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.__options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @returns {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { __config } = this;\n\n if (__config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${__config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new WeakMap();\n }\n\n this.$el.__base__.set(this.__ctor, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted) {\n return this;\n }\n\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.$services.enableAll()),\n addToQueue(() => this.$children.mountAll()),\n addToQueue(() => (this.$isMounted = true)),\n addToQueue(() => this.__callMethod('mounted')),\n ]);\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n // Redo\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.$services.enableAll()),\n // Update\n addToQueue(() => this.$children.updateAll()),\n addToQueue(() => this.__callMethod('updated')),\n ]);\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n await Promise.all([\n addToQueue(() => (this.$isMounted = false)),\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n addToQueue(() => this.$children.destroyAll()),\n addToQueue(() => this.__callMethod('destroyed')),\n ]);\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.__ctor, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __addEmits(event: string): void {\n const ctor = this.__ctor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.__ctor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Get the instance constructor.\n */\n get __ctor(): BaseConstructor {\n return this.constructor as BaseConstructor;\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.addEventListener(event, listener, options);\n\n if (isDev) {\n if (!target) {\n console.warn(\n `[${this.$id}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${this.$el.constructor.name}\\`.`,\n );\n }\n }\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @returns {void}\n */\n $emit(event: string | Event, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.$el.dispatchEvent(event instanceof Event ? event : new CustomEvent(event, { detail: args }));\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register(nameOrSelector?: string): Array<Promise<Base>> {\n return getComponentElements(nameOrSelector ?? this.config.name).map((el) =>\n new this(el).$mount(),\n );\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,OAAO,YAAY,eAAe;AAEjD,IAAI,KAAK;AA+CF,MAAM,KAAsC;AAAA;AAAA;AAAA;AAAA,EAIjD,OAAgB,UAAU;AAAA;AAAA;AAAA;AAAA,EAK1B,UAA+B;AAAA;AAAA;AAAA;AAAA,EAK/B;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA;AAAA;AAAA;AAAA,EAKb,kBAAwE,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAKhF,IAAI,QAAc;AAChB,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,KAAK;AAClB,QAAI,OAAO,KAAK;AAEhB,WAAO,QAAQ;AACb,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO;AAAA,MACT;AAEA,eAAS,OAAO;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAuB;AACzB,QAAI,QAAQ,OAAO,eAAe,IAAI;AACtC,QAAI,EAAE,OAAO,IAAI,MAAM;AAEvB,WAAO,MAAM,YAAY,UAAU,MAAM,YAAY,SAAS;AAC5D,eAAS,EAAE,GAAG,MAAM,YAAY,QAAQ,GAAG,OAAO;AAElD,UAAI,MAAM,YAAY,OAAO,SAAS;AACpC,eAAO,UAAU,EAAE,GAAG,MAAM,YAAY,OAAO,SAAS,GAAG,OAAO,QAAQ;AAAA,MAC5E;AAEA,UAAI,MAAM,YAAY,OAAO,SAAS,OAAO,OAAO;AAClD,eAAO,QAAQ,CAAC,GAAG,MAAM,YAAY,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,MACpE;AAEA,cAAQ,OAAO,eAAe,KAAK;AAAA,IACrC;AAEA,WAAO,UAAU,OAAO,WAAW,CAAC;AACpC,WAAO,OAAO,OAAO,QAAQ,CAAC;AAC9B,WAAO,aAAa,OAAO,cAAc,CAAC;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,MAEL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,QAA6C;AAC/C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,WAAyD;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6D;AAC/D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAqC;AACvC,WAAO,KAAK,UAAU,MAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: WeakMap<BaseConstructor, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n */\nexport class Base<T extends BaseProps = BaseProps> {\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Store the event handlers.\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager & T['$refs'] & BaseRefs;\n\n get $refs(): RefsManager & T['$refs'] & BaseRefs {\n return this.__refs;\n }\n\n __options: OptionsManager & T['$options'] & BaseOptions;\n\n get $options(): OptionsManager & T['$options'] & BaseOptions {\n return this.__options;\n }\n\n __children: ChildrenManager & T['$children'] & BaseChildren;\n\n get $children(): ChildrenManager & T['$children'] & BaseChildren {\n return this.__children;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.log.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.__options.log ? window.console.warn.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.__options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @returns {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { __config } = this;\n\n if (__config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${__config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new WeakMap();\n }\n\n this.$el.__base__.set(this.__ctor, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted) {\n return this;\n }\n\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.$services.enableAll()),\n addToQueue(() => this.$children.mountAll()),\n addToQueue(() => (this.$isMounted = true)),\n addToQueue(() => this.__callMethod('mounted')),\n ]);\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n // Redo\n addToQueue(() => this.$children.registerAll()),\n addToQueue(() => this.$refs.registerAll()),\n addToQueue(() => this.$services.enableAll()),\n // Update\n addToQueue(() => this.$children.updateAll()),\n addToQueue(() => this.__callMethod('updated')),\n ]);\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n await Promise.all([\n addToQueue(() => (this.$isMounted = false)),\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.$refs.unregisterAll()),\n addToQueue(() => this.$services.disableAll()),\n addToQueue(() => this.$children.destroyAll()),\n addToQueue(() => this.__callMethod('destroyed')),\n ]);\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.__ctor, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __addEmits(event: string): void {\n const ctor = this.__ctor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.__ctor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Get the instance constructor.\n */\n get __ctor(): BaseConstructor {\n return this.constructor as BaseConstructor;\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.addEventListener(event, listener, options);\n\n if (isDev) {\n if (!target) {\n console.warn(\n `[${this.$id}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${this.$el.constructor.name}\\`.`,\n );\n }\n }\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @returns {void}\n */\n $emit(event: string | Event, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.$el.dispatchEvent(event instanceof Event ? event : new CustomEvent(event, { detail: args }));\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register(nameOrSelector?: string): Array<Promise<Base>> {\n return getComponentElements(nameOrSelector ?? this.config.name).map((el) =>\n new this(el).$mount(),\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/Base/features.d.ts
CHANGED
package/Base/features.js
CHANGED
package/Base/features.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/Base/features.ts"],
|
|
4
|
-
"sourcesContent": ["export type Features = {\n blocking: boolean;\n breakpoints: Record<string, string>;\n attributes: {\n component: string;\n option: string;\n ref: string;\n }
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["export type Features = {\n blocking: boolean;\n breakpoints: Record<string, string>;\n prefix: string;\n attributes: {\n component: string;\n option: string;\n ref: string;\n };\n};\n\ninterface FeaturesMap extends Map<keyof Features, Features[keyof Features]> {\n get<T extends keyof Features>(key: T): Features[T];\n set<T extends keyof Features>(key: T, value: Features[T]): this;\n}\n\nexport const features = new Map<keyof Features, Features[keyof Features]>([\n ['blocking', false],\n [\n 'breakpoints',\n {\n xxs: '0rem',\n xs: '30rem', // 480px\n s: '48rem', // 768px\n m: '64rem', // 1024px\n l: '80rem', // 1280px\n xl: '90rem', // 1440px\n xxl: '120rem', // 1920px\n xxxl: '160rem', // 2560px\n },\n ],\n ['prefix', 'tk'],\n [\n 'attributes',\n {\n component: 'data-component',\n option: 'data-option',\n ref: 'data-ref',\n },\n ],\n]) as FeaturesMap;\n"],
|
|
5
|
+
"mappings": "AAgBO,MAAM,WAAW,oBAAI,IAA8C;AAAA,EACxE,CAAC,YAAY,KAAK;AAAA,EAClB;AAAA,IACE;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,IAAI;AAAA;AAAA,MACJ,GAAG;AAAA;AAAA,MACH,GAAG;AAAA;AAAA,MACH,GAAG;AAAA;AAAA,MACH,IAAI;AAAA;AAAA,MACJ,KAAK;AAAA;AAAA,MACL,MAAM;AAAA;AAAA,IACR;AAAA,EACF;AAAA,EACA,CAAC,UAAU,IAAI;AAAA,EACf;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,KAAK;AAAA,IACP;AAAA,EACF;AACF,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -37,9 +37,7 @@ function manageRef(that, name, elements, mode = "add") {
|
|
|
37
37
|
for (const method of methods) {
|
|
38
38
|
const event = getEventNameByMethod(method, name);
|
|
39
39
|
for (const element of elements) {
|
|
40
|
-
|
|
41
|
-
element[action](event, that.__refsHandler);
|
|
42
|
-
}
|
|
40
|
+
element?.[action](event, that.__refsHandler);
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
}
|
|
@@ -167,7 +165,7 @@ class EventsManager extends AbstractManager {
|
|
|
167
165
|
let index = -1;
|
|
168
166
|
for (const child of childrenManager[childName]) {
|
|
169
167
|
index++;
|
|
170
|
-
if (child.$el === event.
|
|
168
|
+
if (child.$el === event.currentTarget && (eventIsNative(event.type, child.$el) || eventIsDefinedInConfig(event.type, child.__config))) {
|
|
171
169
|
const normalizedEventName = pascalCase(event.type);
|
|
172
170
|
const normalizedChildName = pascalCase(childName);
|
|
173
171
|
const method = `on${normalizedChildName}${normalizedEventName}`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/Base/managers/EventsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Base, BaseProps } from '../index.js';\nimport getAllProperties from '../../utils/object/getAllProperties.js';\nimport { dashCase, isArray, pascalCase } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @returns {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @returns {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return dashCase(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @returns {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n if (element instanceof EventTarget) {\n element[action](event, that.__refsHandler);\n }\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n const config = instance.__config;\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n if (getEventTarget(instance, event, config)) {\n instance[action](event, that.__childrenHandler);\n }\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @returns {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n } else {\n const target = getEventTarget(base, event, config);\n target?.[modeMethod](event, that.__rootElementHandler);\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? (event.detail ?? []) : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = pascalCase(refName);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const childrenManager = this.__base.$children;\n\n for (const childName of childrenManager.registeredNames) {\n let index = -1;\n\n for (const child of childrenManager[childName] as Base<BaseProps>[]) {\n index++;\n\n if (\n child.$el === event.target &&\n (eventIsNative(event.type, child.$el) ||\n eventIsDefinedInConfig(event.type, child.__config))\n ) {\n const normalizedEventName = pascalCase(event.type);\n const normalizedChildName = pascalCase(childName);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: child }));\n }\n }\n }\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties([\n '__methodsCache',\n '__rootElementHandler',\n '__refsHandler',\n '__childrenHandler',\n '__documentHandler',\n '__windowHandler',\n ]);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @returns {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @returns {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,OAAO,sBAAsB;AAC7B,SAAS,UAAU,SAAS,kBAAkB;AAC9C,SAAS,gBAAgB,eAAe,8BAA8B;AACtE,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,gBAAgB;AAEzB,MAAM,UAAU,oBAAI,IAAI;AAQxB,SAAS,SAAS,OAAuB;AACvC,MAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,YAAQ,IAAI,OAAO,IAAI,OAAO,KAAK,CAAC;AAAA,EACtC;AAEA,SAAO,QAAQ,IAAI,KAAK;AAC1B;AAUA,SAAS,qBAAqB,QAAgB,OAAO,IAAY;AAC/D,QAAM,QAAQ,SAAS,MAAM,WAAW,IAAI,CAAC,YAAY;AACzD,QAAM,CAAC,EAAE,KAAK,IAAI,OAAO,MAAM,KAAK;AACpC,SAAO,SAAS,KAAK;AACvB;AAWA,SAAS,sBAAsB,MAAqB,OAAO,IAAc;AACvE,QAAM,QAAQ,SAAS,MAAM,WAAW,IAAI,CAAC,UAAU;AACvD,QAAM,MAAM,MAAM,SAAS;AAE3B,MAAI,UAAU,KAAK,eAAe,IAAI,GAAG;AAEzC,MAAI,CAAC,SAAS;AACZ,cAAU,MAAM;AAAA,MACd,iBAAiB,KAAK,QAAQ,CAAC,GAAG,CAAC,WAAW,MAAM,KAAK,MAAM,CAAC,EAAE;AAAA,QAChE,CAAC,KAAK,CAAC,MAAM,MAAM,IAAI,IAAI,MAAM;AAAA,QACjC,oBAAI,IAAI;AAAA,MACV;AAAA,IACF;AACA,SAAK,eAAe,IAAI,KAAK,OAAO;AAAA,EACtC;AAEA,SAAO;AACT;AAeA,SAAS,UAEP,MACA,MACA,UACA,OAAyB,OACzB;AACA,QAAM,SAAS,GAAG,IAAI;AACtB,QAAM,UAAU,sBAAsB,MAAM,IAAI;AAChD,aAAW,UAAU,SAAS;AAC5B,UAAM,QAAQ,qBAAqB,QAAQ,IAAI;AAC/C,eAAW,WAAW,UAAU;AAC9B,
|
|
4
|
+
"sourcesContent": ["import type { Base, BaseProps } from '../index.js';\nimport getAllProperties from '../../utils/object/getAllProperties.js';\nimport { dashCase, isArray, pascalCase } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @returns {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @returns {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return dashCase(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @returns {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n element?.[action](event, that.__refsHandler);\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n const config = instance.__config;\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n if (getEventTarget(instance, event, config)) {\n instance[action](event, that.__childrenHandler);\n }\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @returns {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n } else {\n const target = getEventTarget(base, event, config);\n target?.[modeMethod](event, that.__rootElementHandler);\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? (event.detail ?? []) : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = pascalCase(refName);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const childrenManager = this.__base.$children;\n\n for (const childName of childrenManager.registeredNames) {\n let index = -1;\n\n for (const child of childrenManager[childName] as Base<BaseProps>[]) {\n index++;\n\n if (\n child.$el === event.currentTarget &&\n (eventIsNative(event.type, child.$el) ||\n eventIsDefinedInConfig(event.type, child.__config))\n ) {\n const normalizedEventName = pascalCase(event.type);\n const normalizedChildName = pascalCase(childName);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: child }));\n }\n }\n }\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties([\n '__methodsCache',\n '__rootElementHandler',\n '__refsHandler',\n '__childrenHandler',\n '__documentHandler',\n '__windowHandler',\n ]);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @returns {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @returns {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Options as DeepmergeOptions } from 'deepmerge';
|
|
2
2
|
import { AbstractManager } from './AbstractManager.js';
|
|
3
3
|
import type { Base } from '../index.js';
|
|
4
|
-
type OptionType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;
|
|
4
|
+
export type OptionType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;
|
|
5
5
|
type ArrayOption = {
|
|
6
6
|
type: ArrayConstructor;
|
|
7
7
|
default?: (instance: Base) => unknown[];
|
|
@@ -34,7 +34,7 @@ export type OptionsInterface = {
|
|
|
34
34
|
/**
|
|
35
35
|
* Get a property name.
|
|
36
36
|
*/
|
|
37
|
-
export declare const __getPropertyName: (name: string, prefix?: unknown) => string;
|
|
37
|
+
export declare const __getPropertyName: (name: string, prefix?: unknown, optionAttribute?: unknown) => string;
|
|
38
38
|
/**
|
|
39
39
|
* Class options to manage options as data attributes on an HTML element.
|
|
40
40
|
*
|
|
@@ -19,10 +19,8 @@ const __defaultValues = {
|
|
|
19
19
|
Object: () => ({})
|
|
20
20
|
};
|
|
21
21
|
const UPPERCASE_REGEX = /([A-Z])/g;
|
|
22
|
-
const __getPropertyName = memo(function __getPropertyName2(name, prefix = "") {
|
|
23
|
-
|
|
24
|
-
const propertyName = `${attributes.option}${prefix ? `-${prefix}` : ""}-${name.replaceAll(UPPERCASE_REGEX, "-$1")}`;
|
|
25
|
-
return propertyName;
|
|
22
|
+
const __getPropertyName = memo(function __getPropertyName2(name, prefix = "", optionAttribute = features.get("attributes").option) {
|
|
23
|
+
return `${optionAttribute}${prefix ? `-${prefix}` : ""}-${name.replaceAll(UPPERCASE_REGEX, "-$1")}`;
|
|
26
24
|
});
|
|
27
25
|
function __register(that, name, config) {
|
|
28
26
|
if (!types.has(config.type)) {
|
|
@@ -99,11 +97,12 @@ class OptionsManager extends AbstractManager {
|
|
|
99
97
|
get(name, config) {
|
|
100
98
|
const { type } = config;
|
|
101
99
|
const defaultValue = isFunction(config.default) ? config.default(this.__base) : config.default;
|
|
102
|
-
const
|
|
100
|
+
const attributes = features.get("attributes");
|
|
101
|
+
const propertyName = __getPropertyName(name, "", attributes.option);
|
|
103
102
|
const hasProperty = this.__element.hasAttribute(propertyName);
|
|
104
103
|
if (type === Boolean) {
|
|
105
104
|
if (defaultValue) {
|
|
106
|
-
const negatedPropertyName = __getPropertyName(name, "no");
|
|
105
|
+
const negatedPropertyName = __getPropertyName(name, "no", attributes.option);
|
|
107
106
|
const hasNegatedProperty = this.__element.hasAttribute(negatedPropertyName);
|
|
108
107
|
return !hasNegatedProperty;
|
|
109
108
|
}
|
|
@@ -131,7 +130,8 @@ class OptionsManager extends AbstractManager {
|
|
|
131
130
|
*/
|
|
132
131
|
set(name, value, config) {
|
|
133
132
|
const { type, default: defaultValue } = config;
|
|
134
|
-
const
|
|
133
|
+
const attributes = features.get("attributes");
|
|
134
|
+
const propertyName = __getPropertyName(name, "", attributes.option);
|
|
135
135
|
if (value.constructor.name !== type.name) {
|
|
136
136
|
if (isDev) {
|
|
137
137
|
const val = isArray(value) || isObject(value) ? JSON.stringify(value) : value;
|
|
@@ -144,7 +144,7 @@ class OptionsManager extends AbstractManager {
|
|
|
144
144
|
switch (type) {
|
|
145
145
|
case Boolean:
|
|
146
146
|
if (defaultValue) {
|
|
147
|
-
const negatedPropertyName = __getPropertyName(name, "no");
|
|
147
|
+
const negatedPropertyName = __getPropertyName(name, "no", attributes.option);
|
|
148
148
|
if (value) {
|
|
149
149
|
this.__element.removeAttribute(negatedPropertyName);
|
|
150
150
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/Base/managers/OptionsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import deepmerge from 'deepmerge';\nimport type { Options as DeepmergeOptions } from 'deepmerge';\nimport { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isFunction,\n isDefined,\n isBoolean,\n isArray,\n isObject,\n memo,\n} from '../../utils/index.js';\nimport type { Base } from '../index.js';\nimport { features } from '../features.js';\n\
|
|
5
|
-
"mappings": "AAAA,OAAO,eAAe;AAEtB,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,gBAAgB;AA2CzB,MAAM,QAAyB,oBAAI,IAAI,CAAC,QAAQ,QAAQ,SAAS,OAAO,MAAM,CAAC;AAK/E,MAAM,kBAAkB;AAAA,EACtB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO,MAAM,CAAC;AAAA,EACd,QAAQ,OAAO,CAAC;AAClB;AAEA,MAAM,kBAAkB;AAKjB,MAAM,oBAAoB,KAAK,SAASA,mBAAkB,MAAc,SAAS,IAAI
|
|
4
|
+
"sourcesContent": ["import deepmerge from 'deepmerge';\nimport type { Options as DeepmergeOptions } from 'deepmerge';\nimport { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isFunction,\n isDefined,\n isBoolean,\n isArray,\n isObject,\n memo,\n} from '../../utils/index.js';\nimport type { Base } from '../index.js';\nimport { features } from '../features.js';\n\nexport type OptionType =\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | ArrayConstructor\n | ObjectConstructor;\n\ntype ArrayOption = {\n type: ArrayConstructor;\n default?: (instance: Base) => unknown[];\n merge?: boolean | DeepmergeOptions;\n};\n\ntype ObjectOption = {\n type: ObjectConstructor;\n default?: (instance: Base) => unknown;\n merge?: boolean | DeepmergeOptions;\n};\n\ntype StringOption = {\n type: StringConstructor;\n default?: string | ((instance: Base) => string);\n};\n\ntype NumberOption = {\n type: NumberConstructor;\n default?: number | ((instance: Base) => number);\n};\n\ntype BooleanOption = {\n type: BooleanConstructor;\n default?: boolean | ((instance: Base) => boolean);\n};\n\nexport type OptionObject = ArrayOption | ObjectOption | StringOption | NumberOption | BooleanOption;\nexport type OptionsSchema = { [name: string]: OptionType | OptionObject };\nexport type OptionsInterface = { [optionName: string]: unknown };\n\n/**\n * List of allowed types.\n */\nconst types: Set<OptionType> = new Set([String, Number, Boolean, Array, Object]);\n\n/**\n * The default values to return for each available type.\n */\nconst __defaultValues = {\n String: '',\n Number: 0,\n Boolean: false,\n Array: () => [],\n Object: () => ({}),\n};\n\nconst UPPERCASE_REGEX = /([A-Z])/g;\n\n/**\n * Get a property name.\n */\nexport const __getPropertyName = memo(function __getPropertyName(name: string, prefix = '', optionAttribute = features.get('attributes').option) {\n return `${optionAttribute}${prefix ? `-${prefix}` : ''}-${name.replaceAll(UPPERCASE_REGEX, '-$1')}`;\n});\n\n/**\n * Register an option.\n *\n * @param {OptionsManager} that\n * @param {string} name\n * @param {OptionObject} config\n * @returns {void}\n * @private\n */\nfunction __register(that: OptionsManager, name: string, config: OptionObject) {\n if (!types.has(config.type)) {\n if (isDev) {\n throw new Error(\n `The \"${name}\" option has an invalid type. The allowed types are: String, Number, Boolean, Array and Object.`,\n );\n }\n return;\n }\n\n config.default = config.default ?? __defaultValues[config.type.name];\n\n if ((config.type === Array || config.type === Object) && !isFunction(config.default)) {\n if (isDev) {\n throw new Error(\n `The default value for options of type \"${config.type.name}\" must be returned by a function.`,\n );\n }\n return;\n }\n\n Object.defineProperty(that, name, {\n get: () => that.get(name, config),\n set: (value) => {\n that.set(name, value, config);\n },\n enumerable: true,\n });\n}\n\n/**\n * Class options to manage options as data attributes on an HTML element.\n *\n * @todo Use `MutationObserver` to update values? Might be more performant.\n */\nexport class OptionsManager extends AbstractManager {\n /**\n * An object to store Array and Object values for reference.\n *\n * @private\n */\n __values = {};\n\n /**\n * Default value for the name property.\n */\n name = 'Base';\n\n /**\n * Default value for the debug property.\n */\n debug = false;\n\n /**\n * Default value for the log property.\n */\n log = false;\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n\n this.__hideProperties(['__values', '__defaultValues']);\n const schema: OptionsSchema = this.__config.options || {};\n this.name = this.__config.name;\n\n schema.debug = {\n type: Boolean,\n default: this.__config.debug ?? false,\n };\n\n schema.log = {\n type: Boolean,\n default: this.__config.log ?? false,\n };\n\n for (const [name, config] of Object.entries(schema)) {\n __register(\n this,\n name,\n types.has(config as OptionType)\n ? ({ type: config as OptionType } as OptionObject)\n : (config as OptionObject),\n );\n }\n }\n\n /**\n * Get an option value.\n */\n get(name: string, config: OptionObject) {\n const { type } = config;\n const defaultValue = isFunction(config.default) ? config.default(this.__base) : config.default;\n const attributes = features.get('attributes');\n const propertyName = __getPropertyName(name, '', attributes.option);\n const hasProperty = this.__element.hasAttribute(propertyName);\n\n if (type === Boolean) {\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no', attributes.option);\n const hasNegatedProperty = this.__element.hasAttribute(negatedPropertyName);\n\n return !hasNegatedProperty;\n }\n\n return hasProperty || defaultValue;\n }\n\n const value = this.__element.getAttribute(propertyName);\n\n if (type === Number) {\n return hasProperty ? Number(value) : defaultValue;\n }\n\n if (type === Array || type === Object) {\n // eslint-disable-next-line no-param-reassign\n config = type === Array ? (config as ArrayOption) : (config as ObjectOption);\n\n if (!this.__values[name]) {\n let val = hasProperty ? JSON.parse(value) : defaultValue;\n\n if (isDefined(config.merge)) {\n val = isBoolean(config.merge)\n ? deepmerge(defaultValue, val)\n : deepmerge(defaultValue, val, config.merge);\n }\n\n this.__values[name] = val;\n }\n\n return this.__values[name];\n }\n\n return hasProperty ? value : defaultValue;\n }\n\n /**\n * Set an option value.\n */\n set(name: string, value: unknown, config: OptionObject) {\n const { type, default: defaultValue } = config;\n const attributes = features.get('attributes');\n const propertyName = __getPropertyName(name, '', attributes.option);\n\n if (value.constructor.name !== type.name) {\n if (isDev) {\n const val = isArray(value) || isObject(value) ? JSON.stringify(value) : value;\n throw new TypeError(\n `The \"${val}\" value for the \"${name}\" option must be of type \"${type.name}\"`,\n );\n }\n return;\n }\n\n switch (type) {\n case Boolean:\n if (defaultValue) {\n const negatedPropertyName = __getPropertyName(name, 'no', attributes.option);\n\n if (value) {\n this.__element.removeAttribute(negatedPropertyName);\n } else {\n this.__element.setAttribute(negatedPropertyName, '');\n }\n } else if (value) {\n this.__element.setAttribute(propertyName, '');\n } else {\n this.__element.removeAttribute(propertyName);\n }\n break;\n case Array:\n case Object:\n this.__values[name] = value;\n break;\n default:\n this.__element.setAttribute(propertyName, value as string);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["__getPropertyName"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/Base/managers/RefsManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isArray,\n
|
|
5
|
-
"mappings": "AAAA,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { AbstractManager } from './AbstractManager.js';\nimport {\n isDev,\n isArray,\n getAncestorWhereUntil,\n endsWith,\n startsWith,\n memo,\n camelCase,\n} from '../../utils/index.js';\nimport { features } from '../features.js';\n\nconst NORMALIZE_REF_NAME_REGEX = /\\[\\]$/;\nconst NAMESPACED_REF_REGEX = /^(.*\\.)/;\n\n/**\n * Normalize the name of ref.\n */\nexport const normalizeRefName = memo(function normalizeRefName(name: string) {\n let normalizedName = name;\n\n if (endsWith(name, '[]')) {\n normalizedName = normalizedName.replace(NORMALIZE_REF_NAME_REGEX, '');\n }\n\n if (normalizedName.includes('.')) {\n return normalizedName.replace(NAMESPACED_REF_REGEX, '');\n }\n\n return normalizedName;\n});\n\n/**\n * Filter refs belonging to the related Base instance.\n */\nfunction refBelongToInstance(ref: HTMLElement, rootElement: HTMLElement, name: string) {\n const attributes = features.get('attributes');\n const isPrefixed = startsWith(ref.getAttribute(attributes.ref), name);\n const firstComponentAncestor = getAncestorWhereUntil(\n ref,\n (el) =>\n el &&\n (isPrefixed\n ? el.getAttribute(attributes.component) === name && el\n : el.getAttribute(attributes.component)) &&\n el !== rootElement,\n (el) => el === rootElement,\n );\n\n return firstComponentAncestor === rootElement;\n}\n\n/**\n * Register one ref.\n *\n * @param {RefsManager} that\n * @param {string} refName The ref name.\n * @private\n */\nfunction __register(that: RefsManager, refName: string) {\n const isMultiple = endsWith(refName, '[]');\n const propName = normalizeRefName(refName);\n const { name } = that.__base.$options;\n const attributes = features.get('attributes');\n const refs = [] as HTMLElement[];\n const selector = `[${attributes.ref}=\"${refName}\"],[${attributes.ref}=\"${name}.${refName}\"]`;\n\n for (const ref of that.__element.querySelectorAll<HTMLElement>(selector)) {\n if (refBelongToInstance(ref, that.__element, name)) {\n refs.push(ref);\n }\n }\n\n /* v8 ignore next 7 */\n if (isDev && !isMultiple && refs.length > 1) {\n console.warn(\n `[${that.__base.$id}]`,\n `The \"${refName}\" ref has been found multiple times.`,\n 'Did you forgot to add the `[]` suffix to its name?',\n );\n }\n\n if (refs.length) {\n that.__eventsManager.bindRef(refName, refs);\n }\n\n Object.defineProperty(that, camelCase(propName), {\n // @todo remove usage of non-multiple refs as array\n value: isMultiple || refs.length > 1 ? refs : refs[0],\n enumerable: true,\n configurable: true,\n });\n}\n\n/**\n * Unregister one ref.\n */\nfunction __unregister(that: RefsManager, refName: string) {\n const propName = normalizeRefName(refName);\n const refs = isArray(that[propName]) ? that[propName] : [that[propName]];\n that.__eventsManager.unbindRef(refName, refs);\n}\n\n/**\n * Refs Manager\n *\n * @todo Use `MutationObserver` to automatically update refs?\n */\nexport class RefsManager extends AbstractManager {\n /**\n * Get refs configuration.\n */\n get __refs() {\n return this.__config.refs ?? [];\n }\n\n /**\n * Register all refs.\n */\n registerAll() {\n for (const refName of this.__refs) __register(this, refName);\n }\n\n /**\n * Unregister all refs.\n */\n unregisterAll() {\n for (const refName of this.__refs) __unregister(this, refName);\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AAEzB,MAAM,2BAA2B;AACjC,MAAM,uBAAuB;AAKtB,MAAM,mBAAmB,KAAK,SAASA,kBAAiB,MAAc;AAC3E,MAAI,iBAAiB;AAErB,MAAI,SAAS,MAAM,IAAI,GAAG;AACxB,qBAAiB,eAAe,QAAQ,0BAA0B,EAAE;AAAA,EACtE;AAEA,MAAI,eAAe,SAAS,GAAG,GAAG;AAChC,WAAO,eAAe,QAAQ,sBAAsB,EAAE;AAAA,EACxD;AAEA,SAAO;AACT,CAAC;AAKD,SAAS,oBAAoB,KAAkB,aAA0B,MAAc;AACrF,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,aAAa,WAAW,IAAI,aAAa,WAAW,GAAG,GAAG,IAAI;AACpE,QAAM,yBAAyB;AAAA,IAC7B;AAAA,IACA,CAAC,OACC,OACC,aACG,GAAG,aAAa,WAAW,SAAS,MAAM,QAAQ,KAClD,GAAG,aAAa,WAAW,SAAS,MACxC,OAAO;AAAA,IACT,CAAC,OAAO,OAAO;AAAA,EACjB;AAEA,SAAO,2BAA2B;AACpC;AASA,SAAS,WAAW,MAAmB,SAAiB;AACtD,QAAM,aAAa,SAAS,SAAS,IAAI;AACzC,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,EAAE,KAAK,IAAI,KAAK,OAAO;AAC7B,QAAM,aAAa,SAAS,IAAI,YAAY;AAC5C,QAAM,OAAO,CAAC;AACd,QAAM,WAAW,IAAI,WAAW,GAAG,KAAK,OAAO,OAAO,WAAW,GAAG,KAAK,IAAI,IAAI,OAAO;AAExF,aAAW,OAAO,KAAK,UAAU,iBAA8B,QAAQ,GAAG;AACxE,QAAI,oBAAoB,KAAK,KAAK,WAAW,IAAI,GAAG;AAClD,WAAK,KAAK,GAAG;AAAA,IACf;AAAA,EACF;AAGA,MAAI,SAAS,CAAC,cAAc,KAAK,SAAS,GAAG;AAC3C,YAAQ;AAAA,MACN,IAAI,KAAK,OAAO,GAAG;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,QAAQ;AACf,SAAK,gBAAgB,QAAQ,SAAS,IAAI;AAAA,EAC5C;AAEA,SAAO,eAAe,MAAM,UAAU,QAAQ,GAAG;AAAA;AAAA,IAE/C,OAAO,cAAc,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC;AAAA,IACpD,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB,CAAC;AACH;AAKA,SAAS,aAAa,MAAmB,SAAiB;AACxD,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,OAAO,QAAQ,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,CAAC;AACvE,OAAK,gBAAgB,UAAU,SAAS,IAAI;AAC9C;AAOO,MAAM,oBAAoB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAI/C,IAAI,SAAS;AACX,WAAO,KAAK,SAAS,QAAQ,CAAC;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACZ,eAAW,WAAW,KAAK,OAAQ,YAAW,MAAM,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACd,eAAW,WAAW,KAAK,OAAQ,cAAa,MAAM,OAAO;AAAA,EAC/D;AACF;",
|
|
6
6
|
"names": ["normalizeRefName"]
|
|
7
7
|
}
|
package/Base/utils.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { Base, BaseConfig, BaseConstructor } from './index.js';
|
|
|
3
3
|
* Add a task to the main queue.
|
|
4
4
|
*/
|
|
5
5
|
export declare function addToQueue(fn: () => unknown): Promise<unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* Get the selector for a given component.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getSelector(nameOrSelector: string): string;
|
|
6
10
|
/**
|
|
7
11
|
* Get a list of elements based on the name of a component.
|
|
8
12
|
*
|
package/Base/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isArray, isDefined, SmartQueue } from "../utils/index.js";
|
|
1
|
+
import { isArray, isDefined, SmartQueue, dashCase } from "../utils/index.js";
|
|
2
2
|
import { features } from "./features.js";
|
|
3
3
|
let queue;
|
|
4
4
|
function addToQueue(fn) {
|
|
@@ -15,9 +15,12 @@ const selectors = /* @__PURE__ */ new Map();
|
|
|
15
15
|
const separator = " ";
|
|
16
16
|
function getSelector(nameOrSelector) {
|
|
17
17
|
const { component } = features.get("attributes");
|
|
18
|
-
const
|
|
18
|
+
const prefix = features.get("prefix");
|
|
19
|
+
const key = prefix + component + nameOrSelector;
|
|
19
20
|
if (!selectors.has(key)) {
|
|
20
21
|
const parts = [
|
|
22
|
+
// Tag select
|
|
23
|
+
`${prefix}-${dashCase(nameOrSelector)}`,
|
|
21
24
|
// Single selector
|
|
22
25
|
`[${component}="${nameOrSelector}"]`,
|
|
23
26
|
// Selector in the middle of a list of selectors
|
|
@@ -82,6 +85,7 @@ export {
|
|
|
82
85
|
eventIsNative,
|
|
83
86
|
getComponentElements,
|
|
84
87
|
getEventTarget,
|
|
85
|
-
getInstances
|
|
88
|
+
getInstances,
|
|
89
|
+
getSelector
|
|
86
90
|
};
|
|
87
91
|
//# sourceMappingURL=utils.js.map
|
package/Base/utils.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/Base/utils.ts"],
|
|
4
|
-
"sourcesContent": ["import { isArray, isDefined,
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS,
|
|
4
|
+
"sourcesContent": ["import { isArray, isDefined, SmartQueue, dashCase } from '../utils/index.js';\nimport type { Base, BaseConfig, BaseConstructor } from './index.js';\nimport { features } from './features.js';\n\nlet queue: SmartQueue;\n\n/**\n * Add a task to the main queue.\n */\nexport function addToQueue(fn: () => unknown) {\n if (features.get('blocking')) {\n fn();\n return;\n }\n\n if (!queue) {\n queue = new SmartQueue();\n }\n\n return queue.add(fn);\n}\n\nconst selectors = new Map();\n\n// Separator used for multi-component declaration in `data-component` attributeS.\nconst separator = ' ';\n\n/**\n * Get the selector for a given component.\n */\nexport function getSelector(nameOrSelector: string): string {\n const { component } = features.get('attributes');\n const prefix = features.get('prefix');\n const key = prefix + component + nameOrSelector;\n\n if (!selectors.has(key)) {\n const parts = [\n // Tag select\n `${prefix}-${dashCase(nameOrSelector)}`,\n // Single selector\n `[${component}=\"${nameOrSelector}\"]`,\n // Selector in the middle of a list of selectors\n `[${component}*=\"${separator}${nameOrSelector}${separator}\"]`,\n // Selector at the end of a list of selectors\n `[${component}$=\"${separator}${nameOrSelector}\"]`,\n // Selector at the beginning of a list of selectors\n `[${component}^=\"${nameOrSelector}${separator}\"]`,\n ];\n selectors.set(key, parts.join(','));\n }\n\n return selectors.get(key);\n}\n\n/**\n * Get a list of elements based on the name of a component.\n *\n * @param {string} nameOrSelector\n * The name or selector to used for this component.\n * @param {HTMLElement|Document} element\n * The root element on which to query the selector, defaults to `document`.\n * @returns {Array<HTMLElement>}\n * A list of elements on which the component should be mounted.\n */\nexport function getComponentElements(\n nameOrSelector: string,\n element: HTMLElement | Document = document,\n): HTMLElement[] {\n const selector = getSelector(nameOrSelector);\n let elements = [];\n\n try {\n elements = Array.from(element.querySelectorAll(selector));\n // eslint-disable-next-line no-empty\n } catch {}\n\n // If no child component found with the default selector, and if the selector does not\n // start with an uppercase letter, matching a component's name, try a classic DOM selector.\n if (elements.length === 0 && nameOrSelector[0] === nameOrSelector[0].toLowerCase()) {\n elements = Array.from(element.querySelectorAll(nameOrSelector));\n }\n\n return elements;\n}\n\n/**\n * Test if an event is defined in the given config.\n */\nexport function eventIsDefinedInConfig(event: string, config: BaseConfig): boolean {\n return isArray(config.emits) && config.emits.includes(event);\n}\n\n/**\n * Test if an event can be used on the given element.\n */\nexport function eventIsNative(event: string, element: HTMLElement): boolean {\n return isDefined(element[`on${event}`]);\n}\n\n/**\n * Get the target of a given event.\n */\nexport function getEventTarget(\n instance: Base,\n event: string,\n config: BaseConfig,\n): Base['$el'] {\n if (eventIsDefinedInConfig(event, config) || eventIsNative(event, instance.$el)) {\n return instance.$el;\n }\n}\n\nconst instances = new Set<Base>();\n\n/**\n * Get all mounted instances or the ones from a given component.\n */\nexport function getInstances(): Set<Base>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor: T,\n): Set<InstanceType<T>>;\nexport function getInstances<T extends BaseConstructor = BaseConstructor>(\n ctor?: T,\n): Set<InstanceType<T>> | Set<Base> {\n if (isDefined(ctor)) {\n const filteredInstances = new Set<InstanceType<T>>();\n for (const instance of instances) {\n if (instance instanceof ctor) {\n filteredInstances.add(instance as InstanceType<T>);\n }\n }\n return filteredInstances;\n } else {\n return new Set(instances);\n }\n}\n\nexport function addInstance(instance: Base) {\n instances.add(instance);\n}\n\nexport function deleteInstance(instance: Base) {\n instances.delete(instance);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS,WAAW,YAAY,gBAAgB;AAEzD,SAAS,gBAAgB;AAEzB,IAAI;AAKG,SAAS,WAAW,IAAmB;AAC5C,MAAI,SAAS,IAAI,UAAU,GAAG;AAC5B,OAAG;AACH;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,WAAW;AAAA,EACzB;AAEA,SAAO,MAAM,IAAI,EAAE;AACrB;AAEA,MAAM,YAAY,oBAAI,IAAI;AAG1B,MAAM,YAAY;AAKX,SAAS,YAAY,gBAAgC;AAC1D,QAAM,EAAE,UAAU,IAAI,SAAS,IAAI,YAAY;AAC/C,QAAM,SAAS,SAAS,IAAI,QAAQ;AACpC,QAAM,MAAM,SAAS,YAAY;AAEjC,MAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,UAAM,QAAQ;AAAA;AAAA,MAEZ,GAAG,MAAM,IAAI,SAAS,cAAc,CAAC;AAAA;AAAA,MAErC,IAAI,SAAS,KAAK,cAAc;AAAA;AAAA,MAEhC,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS;AAAA;AAAA,MAEzD,IAAI,SAAS,MAAM,SAAS,GAAG,cAAc;AAAA;AAAA,MAE7C,IAAI,SAAS,MAAM,cAAc,GAAG,SAAS;AAAA,IAC/C;AACA,cAAU,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,EACpC;AAEA,SAAO,UAAU,IAAI,GAAG;AAC1B;AAYO,SAAS,qBACd,gBACA,UAAkC,UACnB;AACf,QAAM,WAAW,YAAY,cAAc;AAC3C,MAAI,WAAW,CAAC;AAEhB,MAAI;AACF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,QAAQ,CAAC;AAAA,EAE1D,QAAQ;AAAA,EAAC;AAIT,MAAI,SAAS,WAAW,KAAK,eAAe,CAAC,MAAM,eAAe,CAAC,EAAE,YAAY,GAAG;AAClF,eAAW,MAAM,KAAK,QAAQ,iBAAiB,cAAc,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;AAKO,SAAS,uBAAuB,OAAe,QAA6B;AACjF,SAAO,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,KAAK;AAC7D;AAKO,SAAS,cAAc,OAAe,SAA+B;AAC1E,SAAO,UAAU,QAAQ,KAAK,KAAK,EAAE,CAAC;AACxC;AAKO,SAAS,eACd,UACA,OACA,QACa;AACb,MAAI,uBAAuB,OAAO,MAAM,KAAK,cAAc,OAAO,SAAS,GAAG,GAAG;AAC/E,WAAO,SAAS;AAAA,EAClB;AACF;AAEA,MAAM,YAAY,oBAAI,IAAU;AASzB,SAAS,aACd,MACkC;AAClC,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,oBAAoB,oBAAI,IAAqB;AACnD,eAAW,YAAY,WAAW;AAChC,UAAI,oBAAoB,MAAM;AAC5B,0BAAkB,IAAI,QAA2B;AAAA,MACnD;AAAA,IACF;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO,IAAI,IAAI,SAAS;AAAA,EAC1B;AACF;AAEO,SAAS,YAAY,UAAgB;AAC1C,YAAU,IAAI,QAAQ;AACxB;AAEO,SAAS,eAAe,UAAgB;AAC7C,YAAU,OAAO,QAAQ;AAC3B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -22,20 +22,25 @@ function testConflictingBreakpointConfiguration(instance) {
|
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
function createResizeCallback(instance) {
|
|
26
|
+
return ({ breakpoint }) => {
|
|
27
|
+
const action = testBreakpoints(instance, breakpoint);
|
|
28
|
+
if (action === "$destroy" && instance.$isMounted) {
|
|
29
|
+
instance[action]();
|
|
30
|
+
} else if (action === "$mount" && !instance.$isMounted) {
|
|
31
|
+
setTimeout(() => instance[action](), 0);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
25
35
|
function addToResize(key, instance) {
|
|
26
36
|
if (isDev) {
|
|
27
37
|
testConflictingBreakpointConfiguration(instance);
|
|
28
38
|
}
|
|
29
|
-
const { add, has } = useResize();
|
|
39
|
+
const { add, has, props } = useResize();
|
|
30
40
|
if (!has(key)) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
instance[action]();
|
|
35
|
-
} else if (action === "$mount" && !instance.$isMounted) {
|
|
36
|
-
setTimeout(() => instance[action](), 0);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
41
|
+
const callback = createResizeCallback(instance);
|
|
42
|
+
add(key, callback);
|
|
43
|
+
callback(props());
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
function withBreakpointObserver(BaseClass) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/decorators/withBreakpointObserver.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BaseDecorator, BaseInterface } from '../Base/types.js';\nimport type { Base, BaseProps, BaseConfig } from '../Base/index.js';\nimport { useResize } from '../services/index.js';\nimport { isDev, startsWith } from '../utils/index.js';\nimport { features } from '../Base/features.js';\n\nexport interface WithBreakpointObserverProps extends BaseProps {\n $options: {\n activeBreakpoints?: string;\n inactiveBreakpoints?: string;\n };\n}\n\nexport interface WithBreakpointObserverInterface extends BaseInterface {}\n\n/**\n * Test the breakpoins of the given Base instance and return the hook to call.\n *\n * @param {Base<WithBreakpointObserverProps>} instance The component's instance.\n * @param {string} [breakpoint] The breakpoint to test.\n * @returns {string} The action to trigger.\n */\nfunction testBreakpoints(\n instance: Base<WithBreakpointObserverProps>,\n breakpoint: string = useResize().props().breakpoint,\n): string {\n const { activeBreakpoints, inactiveBreakpoints } = instance.$options;\n const isInActiveBreakpoint =\n activeBreakpoints && activeBreakpoints.split(' ').includes(breakpoint);\n const isInInactiveBreakpoint =\n inactiveBreakpoints && inactiveBreakpoints.split(' ').includes(breakpoint);\n\n if (\n (activeBreakpoints && isInActiveBreakpoint) ||\n (inactiveBreakpoints && !isInInactiveBreakpoint)\n ) {\n return '$mount';\n }\n\n return '$destroy';\n}\n\n/**\n * Test if the given instance is configured for breakpoints.\n *\n * @param {Base<WithBreakpointObserverProps>} instance A Base class instance.\n * @returns {boolean} True if configured correctly, false otherwise.\n */\nfunction hasBreakpointConfiguration(instance: Base<WithBreakpointObserverProps>): boolean {\n const { activeBreakpoints, inactiveBreakpoints } = instance.$options;\n return Boolean(activeBreakpoints || inactiveBreakpoints);\n}\n\n/**\n * Test if the given instance has a conflicting configuration for breakpoints.\n *\n * @param {Base<WithBreakpointObserverProps>} instance A Base class instance.\n * @returns {void}\n */\nfunction testConflictingBreakpointConfiguration(instance: Base<WithBreakpointObserverProps>): void {\n const { activeBreakpoints, inactiveBreakpoints, name } = instance.$options;\n if (activeBreakpoints && inactiveBreakpoints) {\n throw new Error(\n `[${name}] Incorrect configuration: the \\`activeBreakpoints\\` and \\`inactiveBreakpoints\\` are not compatible.`,\n );\n }\n}\n\n/**\n * Add the current instance to the resize service.\n *\n * @param {string} key The key for the resize service callback.\n * @param {Base} instance The instance to observe.\n */\nfunction addToResize(key, instance) {\n if (isDev) {\n testConflictingBreakpointConfiguration(instance);\n }\n\n const { add, has } = useResize();\n\n if (!has(key)) {\n
|
|
5
|
-
"mappings": "AAEA,SAAS,iBAAiB;
|
|
4
|
+
"sourcesContent": ["import type { BaseDecorator, BaseInterface } from '../Base/types.js';\nimport type { Base, BaseProps, BaseConfig } from '../Base/index.js';\nimport { useResize } from '../services/index.js';\nimport type { ResizeServiceProps } from '../services/index.js';\nimport { isDev, startsWith } from '../utils/index.js';\nimport { features } from '../Base/features.js';\n\nexport interface WithBreakpointObserverProps extends BaseProps {\n $options: {\n activeBreakpoints?: string;\n inactiveBreakpoints?: string;\n };\n}\n\nexport interface WithBreakpointObserverInterface extends BaseInterface {}\n\n/**\n * Test the breakpoins of the given Base instance and return the hook to call.\n *\n * @param {Base<WithBreakpointObserverProps>} instance The component's instance.\n * @param {string} [breakpoint] The breakpoint to test.\n * @returns {string} The action to trigger.\n */\nfunction testBreakpoints(\n instance: Base<WithBreakpointObserverProps>,\n breakpoint: string = useResize().props().breakpoint,\n): string {\n const { activeBreakpoints, inactiveBreakpoints } = instance.$options;\n const isInActiveBreakpoint =\n activeBreakpoints && activeBreakpoints.split(' ').includes(breakpoint);\n const isInInactiveBreakpoint =\n inactiveBreakpoints && inactiveBreakpoints.split(' ').includes(breakpoint);\n\n if (\n (activeBreakpoints && isInActiveBreakpoint) ||\n (inactiveBreakpoints && !isInInactiveBreakpoint)\n ) {\n return '$mount';\n }\n\n return '$destroy';\n}\n\n/**\n * Test if the given instance is configured for breakpoints.\n *\n * @param {Base<WithBreakpointObserverProps>} instance A Base class instance.\n * @returns {boolean} True if configured correctly, false otherwise.\n */\nfunction hasBreakpointConfiguration(instance: Base<WithBreakpointObserverProps>): boolean {\n const { activeBreakpoints, inactiveBreakpoints } = instance.$options;\n return Boolean(activeBreakpoints || inactiveBreakpoints);\n}\n\n/**\n * Test if the given instance has a conflicting configuration for breakpoints.\n *\n * @param {Base<WithBreakpointObserverProps>} instance A Base class instance.\n * @returns {void}\n */\nfunction testConflictingBreakpointConfiguration(instance: Base<WithBreakpointObserverProps>): void {\n const { activeBreakpoints, inactiveBreakpoints, name } = instance.$options;\n if (activeBreakpoints && inactiveBreakpoints) {\n throw new Error(\n `[${name}] Incorrect configuration: the \\`activeBreakpoints\\` and \\`inactiveBreakpoints\\` are not compatible.`,\n );\n }\n}\n\n/**\n * Callback triggered when the window is resized.\n */\nfunction createResizeCallback(\n instance: Base<WithBreakpointObserverProps>,\n): (resizeProps: ResizeServiceProps) => void {\n return ({ breakpoint }) => {\n const action = testBreakpoints(instance, breakpoint);\n\n // Always destroy before mounting\n if (action === '$destroy' && instance.$isMounted) {\n instance[action]();\n } else if (action === '$mount' && !instance.$isMounted) {\n setTimeout(() => instance[action](), 0);\n }\n };\n}\n\n/**\n * Add the current instance to the resize service.\n *\n * @param {string} key The key for the resize service callback.\n * @param {Base} instance The instance to observe.\n */\nfunction addToResize(key, instance) {\n if (isDev) {\n testConflictingBreakpointConfiguration(instance);\n }\n\n const { add, has, props } = useResize();\n\n if (!has(key)) {\n const callback = createResizeCallback(instance);\n add(key, callback);\n callback(props());\n }\n}\n\n/**\n * BreakpointObserver class.\n */\nexport function withBreakpointObserver<S extends Base>(\n BaseClass: typeof Base,\n): BaseDecorator<WithBreakpointObserverInterface, S, WithBreakpointObserverProps> {\n /**\n * Class.\n */\n class WithBreakpointObserver<T extends BaseProps = BaseProps> extends BaseClass<\n T & WithBreakpointObserverProps\n > {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...BaseClass.config,\n name: `${BaseClass.config.name}WithBreakpointObserver`,\n options: {\n ...BaseClass.config?.options,\n activeBreakpoints: String,\n inactiveBreakpoints: String,\n },\n };\n\n /**\n * Watch for the document resize to test the breakpoints.\n */\n constructor(element: HTMLElement) {\n super(element);\n\n const { remove, props } = useResize();\n const { name } = this.$options;\n\n // Do nothing if no breakpoint has been defined.\n // @see https://js-toolkit.meta.fr/services/resize.html#breakpoint\n if (!props().breakpoint) {\n if (isDev) {\n throw new Error(\n `[${name}] The \\`BreakpointObserver\\` class requires breakpoints to be defined.`,\n );\n }\n return;\n }\n\n const key = `BreakpointObserver-${this.$id}`;\n const attributes = features.get('attributes');\n\n // Watch change on the `data-options` attribute to emit the `set:options` event.\n const mutationObserver = new MutationObserver(([mutation]) => {\n if (\n mutation.type === 'attributes' &&\n startsWith(mutation.attributeName, `${attributes.option}-`)\n ) {\n // Stop here silently when no breakpoint configuration given.\n if (!hasBreakpointConfiguration(this)) {\n this.$mount();\n remove(key);\n return;\n }\n\n addToResize(key, this);\n }\n });\n mutationObserver.observe(this.$el, { attributes: true });\n\n // Stop here silently when no breakpoint configuration given.\n if (!hasBreakpointConfiguration(this)) {\n return;\n }\n\n addToResize(key, this);\n }\n\n /**\n * Override the default $mount method to prevent component's from being\n * mounted when they should not.\n */\n async $mount() {\n // Execute normal behavior when no breakpoint configuration given.\n if (!hasBreakpointConfiguration(this)) {\n return super.$mount();\n }\n\n const action = testBreakpoints(this);\n if (action === '$mount') {\n return super.$mount();\n }\n\n return this;\n }\n }\n\n // @ts-ignore\n return WithBreakpointObserver;\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,iBAAiB;AAE1B,SAAS,OAAO,kBAAkB;AAClC,SAAS,gBAAgB;AAkBzB,SAAS,gBACP,UACA,aAAqB,UAAU,EAAE,MAAM,EAAE,YACjC;AACR,QAAM,EAAE,mBAAmB,oBAAoB,IAAI,SAAS;AAC5D,QAAM,uBACJ,qBAAqB,kBAAkB,MAAM,GAAG,EAAE,SAAS,UAAU;AACvE,QAAM,yBACJ,uBAAuB,oBAAoB,MAAM,GAAG,EAAE,SAAS,UAAU;AAE3E,MACG,qBAAqB,wBACrB,uBAAuB,CAAC,wBACzB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQA,SAAS,2BAA2B,UAAsD;AACxF,QAAM,EAAE,mBAAmB,oBAAoB,IAAI,SAAS;AAC5D,SAAO,QAAQ,qBAAqB,mBAAmB;AACzD;AAQA,SAAS,uCAAuC,UAAmD;AACjG,QAAM,EAAE,mBAAmB,qBAAqB,KAAK,IAAI,SAAS;AAClE,MAAI,qBAAqB,qBAAqB;AAC5C,UAAM,IAAI;AAAA,MACR,IAAI,IAAI;AAAA,IACV;AAAA,EACF;AACF;AAKA,SAAS,qBACP,UAC2C;AAC3C,SAAO,CAAC,EAAE,WAAW,MAAM;AACzB,UAAM,SAAS,gBAAgB,UAAU,UAAU;AAGnD,QAAI,WAAW,cAAc,SAAS,YAAY;AAChD,eAAS,MAAM,EAAE;AAAA,IACnB,WAAW,WAAW,YAAY,CAAC,SAAS,YAAY;AACtD,iBAAW,MAAM,SAAS,MAAM,EAAE,GAAG,CAAC;AAAA,IACxC;AAAA,EACF;AACF;AAQA,SAAS,YAAY,KAAK,UAAU;AAClC,MAAI,OAAO;AACT,2CAAuC,QAAQ;AAAA,EACjD;AAEA,QAAM,EAAE,KAAK,KAAK,MAAM,IAAI,UAAU;AAEtC,MAAI,CAAC,IAAI,GAAG,GAAG;AACb,UAAM,WAAW,qBAAqB,QAAQ;AAC9C,QAAI,KAAK,QAAQ;AACjB,aAAS,MAAM,CAAC;AAAA,EAClB;AACF;AAKO,SAAS,uBACd,WACgF;AAAA,EAIhF,MAAM,+BAAgE,UAEpE;AAAA;AAAA;AAAA;AAAA,IAIA,OAAO,SAAqB;AAAA,MAC1B,GAAG,UAAU;AAAA,MACb,MAAM,GAAG,UAAU,OAAO,IAAI;AAAA,MAC9B,SAAS;AAAA,QACP,GAAG,UAAU,QAAQ;AAAA,QACrB,mBAAmB;AAAA,QACnB,qBAAqB;AAAA,MACvB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,YAAY,SAAsB;AAChC,YAAM,OAAO;AAEb,YAAM,EAAE,QAAQ,MAAM,IAAI,UAAU;AACpC,YAAM,EAAE,KAAK,IAAI,KAAK;AAItB,UAAI,CAAC,MAAM,EAAE,YAAY;AACvB,YAAI,OAAO;AACT,gBAAM,IAAI;AAAA,YACR,IAAI,IAAI;AAAA,UACV;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,MAAM,sBAAsB,KAAK,GAAG;AAC1C,YAAM,aAAa,SAAS,IAAI,YAAY;AAG5C,YAAM,mBAAmB,IAAI,iBAAiB,CAAC,CAAC,QAAQ,MAAM;AAC5D,YACE,SAAS,SAAS,gBAClB,WAAW,SAAS,eAAe,GAAG,WAAW,MAAM,GAAG,GAC1D;AAEA,cAAI,CAAC,2BAA2B,IAAI,GAAG;AACrC,iBAAK,OAAO;AACZ,mBAAO,GAAG;AACV;AAAA,UACF;AAEA,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AACD,uBAAiB,QAAQ,KAAK,KAAK,EAAE,YAAY,KAAK,CAAC;AAGvD,UAAI,CAAC,2BAA2B,IAAI,GAAG;AACrC;AAAA,MACF;AAEA,kBAAY,KAAK,IAAI;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAS;AAEb,UAAI,CAAC,2BAA2B,IAAI,GAAG;AACrC,eAAO,MAAM,OAAO;AAAA,MACtB;AAEA,YAAM,SAAS,gBAAgB,IAAI;AACnC,UAAI,WAAW,UAAU;AACvB,eAAO,MAAM,OAAO;AAAA,MACtB;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAGA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/decorators/withDrag.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BaseDecorator, BaseInterface } from '../Base/types.js';
|
|
2
2
|
import type { Base } from '../Base/index.js';
|
|
3
|
-
import type { DragServiceOptions, DragServiceProps } from '../services/
|
|
3
|
+
import type { DragServiceOptions, DragServiceProps } from '../services/index.js';
|
|
4
4
|
export type DragDecoratorOptions = DragServiceOptions & {
|
|
5
5
|
target?: (this: Base, instance: Base) => HTMLElement;
|
|
6
6
|
};
|