@studiometa/ui 1.3.0 → 1.5.0

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/Action/Action.js CHANGED
@@ -30,8 +30,10 @@ class Action extends Base {
30
30
  }
31
31
  if (on) {
32
32
  const { target, effect } = this.$options;
33
- const effectDefinition = target ? `${target}${ActionEvent.effectSeparator}${effect}` : effect;
34
- this.__actionEvents.add(new ActionEvent(this, on, effectDefinition));
33
+ if (effect) {
34
+ const effectDefinition = target ? `${target}${ActionEvent.effectSeparator}${effect}` : effect;
35
+ this.__actionEvents.add(new ActionEvent(this, on, effectDefinition));
36
+ }
35
37
  }
36
38
  return this.__actionEvents;
37
39
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Action/Action.ts"],
4
- "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { ActionEvent } from './ActionEvent.js';\n\nexport interface ActionProps extends BaseProps {\n $options: {\n on: string;\n target: string;\n selector: string;\n effect: string;\n };\n}\n\n/**\n * Action class.\n * @link https://ui.studiometa.dev/-/components/Action/\n */\nexport class Action<T extends BaseProps = BaseProps> extends Base<ActionProps & T> {\n static config: BaseConfig = {\n name: 'Action',\n options: {\n on: {\n type: String,\n default: 'click',\n },\n target: String,\n effect: String,\n },\n };\n\n /**\n * @private\n */\n __actionEvents: Set<ActionEvent<Action>>;\n\n get actionEvents() {\n if (this.__actionEvents) {\n return this.__actionEvents;\n }\n\n const { on } = this.$options;\n this.__actionEvents = new Set();\n\n // @ts-ignore\n for (const attribute of this.$el.attributes) {\n if (attribute.name.includes('on:')) {\n const name = attribute.name.split('on:').pop();\n this.__actionEvents.add(new ActionEvent(this, name, attribute.value));\n }\n }\n\n if (on) {\n const { target, effect } = this.$options;\n const effectDefinition = target ? `${target}${ActionEvent.effectSeparator}${effect}` : effect;\n this.__actionEvents.add(new ActionEvent(this, on, effectDefinition));\n }\n\n return this.__actionEvents;\n }\n\n /**\n * Mounted\n */\n mounted() {\n for (const actionEvent of this.actionEvents) {\n actionEvent.attachEvent();\n }\n }\n\n /**\n * Destroyed\n */\n destroyed() {\n for (const actionEvent of this.actionEvents) {\n actionEvent.detachEvent();\n }\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,YAAY;AAErB,SAAS,mBAAmB;AAerB,MAAM,eAAgD,KAAsB;AAAA,EACjF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,IAAI;AAAA,QACF,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,EAEA,IAAI,eAAe;AACjB,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,EAAE,GAAG,IAAI,KAAK;AACpB,SAAK,iBAAiB,oBAAI,IAAI;AAG9B,eAAW,aAAa,KAAK,IAAI,YAAY;AAC3C,UAAI,UAAU,KAAK,SAAS,KAAK,GAAG;AAClC,cAAM,OAAO,UAAU,KAAK,MAAM,KAAK,EAAE,IAAI;AAC7C,aAAK,eAAe,IAAI,IAAI,YAAY,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,MACtE;AAAA,IACF;AAEA,QAAI,IAAI;AACN,YAAM,EAAE,QAAQ,OAAO,IAAI,KAAK;AAChC,YAAM,mBAAmB,SAAS,GAAG,MAAM,GAAG,YAAY,eAAe,GAAG,MAAM,KAAK;AACvF,WAAK,eAAe,IAAI,IAAI,YAAY,MAAM,IAAI,gBAAgB,CAAC;AAAA,IACrE;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACR,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { ActionEvent } from './ActionEvent.js';\n\nexport interface ActionProps extends BaseProps {\n $options: {\n on: string;\n target: string;\n selector: string;\n effect: string;\n };\n}\n\n/**\n * Action class.\n * @link https://ui.studiometa.dev/-/components/Action/\n */\nexport class Action<T extends BaseProps = BaseProps> extends Base<ActionProps & T> {\n static config: BaseConfig = {\n name: 'Action',\n options: {\n on: {\n type: String,\n default: 'click',\n },\n target: String,\n effect: String,\n },\n };\n\n /**\n * @private\n */\n __actionEvents: Set<ActionEvent<Action>>;\n\n get actionEvents() {\n if (this.__actionEvents) {\n return this.__actionEvents;\n }\n\n const { on } = this.$options;\n this.__actionEvents = new Set();\n\n // @ts-ignore\n for (const attribute of this.$el.attributes) {\n if (attribute.name.includes('on:')) {\n const name = attribute.name.split('on:').pop();\n this.__actionEvents.add(new ActionEvent(this, name, attribute.value));\n }\n }\n\n if (on) {\n const { target, effect } = this.$options;\n if (effect) {\n const effectDefinition = target ? `${target}${ActionEvent.effectSeparator}${effect}` : effect;\n this.__actionEvents.add(new ActionEvent(this, on, effectDefinition));\n }\n }\n\n return this.__actionEvents;\n }\n\n /**\n * Mounted\n */\n mounted() {\n for (const actionEvent of this.actionEvents) {\n actionEvent.attachEvent();\n }\n }\n\n /**\n * Destroyed\n */\n destroyed() {\n for (const actionEvent of this.actionEvents) {\n actionEvent.detachEvent();\n }\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AAErB,SAAS,mBAAmB;AAerB,MAAM,eAAgD,KAAsB;AAAA,EACjF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,IAAI;AAAA,QACF,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,EAEA,IAAI,eAAe;AACjB,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,EAAE,GAAG,IAAI,KAAK;AACpB,SAAK,iBAAiB,oBAAI,IAAI;AAG9B,eAAW,aAAa,KAAK,IAAI,YAAY;AAC3C,UAAI,UAAU,KAAK,SAAS,KAAK,GAAG;AAClC,cAAM,OAAO,UAAU,KAAK,MAAM,KAAK,EAAE,IAAI;AAC7C,aAAK,eAAe,IAAI,IAAI,YAAY,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,MACtE;AAAA,IACF;AAEA,QAAI,IAAI;AACN,YAAM,EAAE,QAAQ,OAAO,IAAI,KAAK;AAChC,UAAI,QAAQ;AACV,cAAM,mBAAmB,SAAS,GAAG,MAAM,GAAG,YAAY,eAAe,GAAG,MAAM,KAAK;AACvF,aAAK,eAAe,IAAI,IAAI,YAAY,MAAM,IAAI,gBAAgB,CAAC;AAAA,MACrE;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACR,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,eAAW,eAAe,KAAK,cAAc;AAC3C,kBAAY,YAAY;AAAA,IAC1B;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -48,6 +48,11 @@ export declare class ActionEvent<T extends Base> {
48
48
  * Get the targets object for the defined targets string.
49
49
  */
50
50
  get targets(): Record<string, Base<import("@studiometa/js-toolkit").BaseProps>>[];
51
+ /**
52
+ * Get instances mounted on the action element.
53
+ * @internal
54
+ */
55
+ get instances(): Map<string, Base<import("@studiometa/js-toolkit").BaseProps>>;
51
56
  /**
52
57
  * Handle the defined event and trigger the effect for each defined target.
53
58
  */
@@ -55,7 +60,7 @@ export declare class ActionEvent<T extends Base> {
55
60
  /**
56
61
  * Execute the effect for all targets.
57
62
  */
58
- private executeEffect;
63
+ executeEffect(targets: Array<Record<string, Base>>, effect: Function, event: Event): void;
59
64
  /**
60
65
  * Bind the defined event to the given Action instance root element.
61
66
  */
@@ -68,13 +68,22 @@ class ActionEvent {
68
68
  */
69
69
  get effect() {
70
70
  const { effectDefinition } = this;
71
- if (!effectCache.has(effectDefinition)) {
72
- effectCache.set(
73
- effectDefinition,
74
- new Function("ctx", "event", "target", "action", "self", `return ${effectDefinition}`)
75
- );
71
+ const keys = Array.from(this.instances.keys());
72
+ const cacheKey = effectDefinition + keys.join("");
73
+ if (!effectCache.has(cacheKey)) {
74
+ const args = [
75
+ "ctx",
76
+ "event",
77
+ "target",
78
+ "action",
79
+ "self",
80
+ "$el",
81
+ ...keys,
82
+ `return ${effectDefinition}`
83
+ ];
84
+ effectCache.set(cacheKey, new Function(...args));
76
85
  }
77
- return effectCache.get(effectDefinition);
86
+ return effectCache.get(cacheKey);
78
87
  }
79
88
  /**
80
89
  * Get the targets object for the defined targets string.
@@ -100,6 +109,20 @@ class ActionEvent {
100
109
  }
101
110
  return targets;
102
111
  }
112
+ /**
113
+ * Get instances mounted on the action element.
114
+ * @internal
115
+ */
116
+ get instances() {
117
+ const { $el } = this.action;
118
+ const instances = /* @__PURE__ */ new Map();
119
+ for (const instance of getInstances()) {
120
+ if (instance.$el === $el) {
121
+ instances.set(instance.$config.name, instance);
122
+ }
123
+ }
124
+ return instances;
125
+ }
103
126
  /**
104
127
  * Handle the defined event and trigger the effect for each defined target.
105
128
  */
@@ -124,15 +147,25 @@ class ActionEvent {
124
147
  * Execute the effect for all targets.
125
148
  */
126
149
  executeEffect(targets, effect, event) {
150
+ const { action } = this;
127
151
  for (const target of targets) {
128
152
  try {
129
153
  const [currentTarget] = Object.values(target).flat();
130
- const value = effect(target, event, currentTarget, this.action, this.action);
154
+ const args = [
155
+ target,
156
+ event,
157
+ currentTarget,
158
+ action,
159
+ action,
160
+ currentTarget.$el,
161
+ ...this.instances.values()
162
+ ];
163
+ const value = effect.apply(action.$el, args);
131
164
  if (isFunction(value)) {
132
- value(target, event, currentTarget, this.action, this.action);
165
+ value.apply(action.$el, args);
133
166
  }
134
167
  } catch (err) {
135
- this.action.$warn(err);
168
+ action.$warn(err);
136
169
  }
137
170
  }
138
171
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Action/ActionEvent.ts"],
4
- "sourcesContent": ["import { getInstances } from '@studiometa/js-toolkit';\nimport type { Base } from '@studiometa/js-toolkit';\nimport { isFunction } from '@studiometa/js-toolkit/utils';\n\n/**\n * Extract component name and an optional additional selector from a string.\n * @type {RegExp}\n */\nconst TARGET_REGEX = /([a-zA-Z]+)(\\((.*)\\))?/;\n\nconst effectCache = new Map<string, Function>();\n\nexport type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture' | 'debounce';\n\nexport class ActionEvent<T extends Base> {\n static modifierSeparator = '.';\n static targetSeparator = ' ';\n static effectSeparator = '->';\n\n /**\n * Timer for debouncing event handling.\n */\n private debounceTimer?: number;\n\n /**\n * The Action instance.\n */\n action: T;\n\n /**\n * The event to listen to.\n */\n event: string;\n\n /**\n * The modifiers to apply to the event.\n */\n modifiers: Modifiers[];\n\n /**\n * The debounce delay in milliseconds.\n */\n debounceDelay: number = 100;\n\n /**\n * Target definition.\n * Ex: `Target Target(.selector)`.\n */\n targetDefinition: string;\n\n /**\n * The content of the effect callback function.\n */\n effectDefinition: string;\n\n /**\n * Class constructor.\n * @param {T} action The parent Action instance.\n * @param {string} eventDefinition The event with its modifiers: `click.prevent.stop`\n * @param {string} effectDefinition The target and effect definition: `Target(.selector)->target.$destroy()`\n */\n constructor(action: T, eventDefinition: string, effectDefinition: string) {\n this.action = action;\n const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);\n this.event = event;\n\n // Process modifiers and extract debounce delay if present\n const processedModifiers: Modifiers[] = [];\n for (const modifier of modifiers) {\n if (modifier.startsWith('debounce')) {\n processedModifiers.push('debounce');\n this.debounceDelay = parseInt(modifier.replace('debounce', '') || '100');\n } else {\n processedModifiers.push(modifier as Modifiers);\n }\n }\n\n this.modifiers = processedModifiers;\n\n let effect = effectDefinition;\n let targetDefinition = '';\n\n if (effect.includes(ActionEvent.effectSeparator)) {\n [targetDefinition, effect] = effect.split(ActionEvent.effectSeparator);\n }\n\n this.targetDefinition = targetDefinition.trim();\n this.effectDefinition = effect.trim();\n }\n\n /**\n * Get the generated function for the defined effect.\n */\n get effect() {\n const { effectDefinition } = this;\n\n if (!effectCache.has(effectDefinition)) {\n effectCache.set(\n effectDefinition,\n new Function('ctx', 'event', 'target', 'action', 'self', `return ${effectDefinition}`),\n );\n }\n\n return effectCache.get(effectDefinition) as Function;\n }\n\n /**\n * Get the targets object for the defined targets string.\n */\n get targets() {\n const { targetDefinition } = this;\n\n if (!targetDefinition) {\n return [{ Action: this.action }];\n }\n\n // Extract component's names and selectors.\n const parts = targetDefinition.split(ActionEvent.targetSeparator).map((part) => {\n const [, name, , selector] = part.match(TARGET_REGEX) ?? [];\n return [name, selector];\n });\n\n const targets = [] as Array<Record<string, Base>>;\n\n for (const instance of getInstances()) {\n const { name } = instance.__config;\n\n for (const part of parts) {\n const shouldPush =\n part[0] === name && (!part[1] || (part[1] && instance.$el.matches(part[1])));\n if (shouldPush) {\n targets.push({ [instance.__config.name]: instance });\n }\n }\n }\n\n return targets;\n }\n\n /**\n * Handle the defined event and trigger the effect for each defined target.\n */\n handleEvent(event: Event) {\n const { targets, effect, modifiers } = this;\n\n if (modifiers.includes('prevent')) {\n event.preventDefault();\n }\n\n if (modifiers.includes('stop')) {\n event.stopPropagation();\n }\n\n if (modifiers.includes('debounce')) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = window.setTimeout(() => {\n this.executeEffect(targets, effect, event);\n }, this.debounceDelay);\n } else {\n this.executeEffect(targets, effect, event);\n }\n }\n\n /**\n * Execute the effect for all targets.\n */\n private executeEffect(targets: Array<Record<string, Base>>, effect: Function, event: Event) {\n for (const target of targets) {\n try {\n const [currentTarget] = Object.values(target).flat();\n const value = effect(target, event, currentTarget, this.action, this.action);\n if (isFunction(value)) {\n value(target, event, currentTarget, this.action, this.action);\n }\n } catch (err) {\n this.action.$warn(err);\n }\n }\n }\n\n /**\n * Bind the defined event to the given Action instance root element.\n */\n attachEvent() {\n const { event, modifiers } = this;\n this.action.$el.addEventListener(event, this, {\n capture: modifiers.includes('capture'),\n once: modifiers.includes('once'),\n passive: modifiers.includes('passive'),\n });\n }\n\n /**\n * Unbind the event from the given Action instance root element.\n */\n detachEvent() {\n clearTimeout(this.debounceTimer);\n this.action.$el.removeEventListener(this.event, this);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { getInstances } from '@studiometa/js-toolkit';\nimport type { Base } from '@studiometa/js-toolkit';\nimport { isFunction } from '@studiometa/js-toolkit/utils';\n\n/**\n * Extract component name and an optional additional selector from a string.\n */\nconst TARGET_REGEX = /([a-zA-Z]+)(\\((.*)\\))?/;\n\nconst effectCache = new Map<string, Function>();\n\nexport type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture' | 'debounce';\n\nexport class ActionEvent<T extends Base> {\n static modifierSeparator = '.';\n static targetSeparator = ' ';\n static effectSeparator = '->';\n\n /**\n * Timer for debouncing event handling.\n */\n private debounceTimer?: number;\n\n /**\n * The Action instance.\n */\n action: T;\n\n /**\n * The event to listen to.\n */\n event: string;\n\n /**\n * The modifiers to apply to the event.\n */\n modifiers: Modifiers[];\n\n /**\n * The debounce delay in milliseconds.\n */\n debounceDelay: number = 100;\n\n /**\n * Target definition.\n * Ex: `Target Target(.selector)`.\n */\n targetDefinition: string;\n\n /**\n * The content of the effect callback function.\n */\n effectDefinition: string;\n\n /**\n * Class constructor.\n * @param {T} action The parent Action instance.\n * @param {string} eventDefinition The event with its modifiers: `click.prevent.stop`\n * @param {string} effectDefinition The target and effect definition: `Target(.selector)->target.$destroy()`\n */\n constructor(action: T, eventDefinition: string, effectDefinition: string) {\n this.action = action;\n const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);\n this.event = event;\n\n // Process modifiers and extract debounce delay if present\n const processedModifiers: Modifiers[] = [];\n for (const modifier of modifiers) {\n if (modifier.startsWith('debounce')) {\n processedModifiers.push('debounce');\n this.debounceDelay = parseInt(modifier.replace('debounce', '') || '100');\n } else {\n processedModifiers.push(modifier as Modifiers);\n }\n }\n\n this.modifiers = processedModifiers;\n\n let effect = effectDefinition;\n let targetDefinition = '';\n\n if (effect.includes(ActionEvent.effectSeparator)) {\n [targetDefinition, effect] = effect.split(ActionEvent.effectSeparator);\n }\n\n this.targetDefinition = targetDefinition.trim();\n this.effectDefinition = effect.trim();\n }\n\n /**\n * Get the generated function for the defined effect.\n */\n get effect() {\n const { effectDefinition } = this;\n const keys = Array.from(this.instances.keys());\n const cacheKey = effectDefinition + keys.join('');\n\n if (!effectCache.has(cacheKey)) {\n const args = [\n 'ctx',\n 'event',\n 'target',\n 'action',\n 'self',\n '$el',\n ...keys,\n `return ${effectDefinition}`,\n ];\n effectCache.set(cacheKey, new Function(...args));\n }\n\n return effectCache.get(cacheKey) as Function;\n }\n\n /**\n * Get the targets object for the defined targets string.\n */\n get targets() {\n const { targetDefinition } = this;\n\n if (!targetDefinition) {\n return [{ Action: this.action }];\n }\n\n // Extract component's names and selectors.\n const parts = targetDefinition.split(ActionEvent.targetSeparator).map((part) => {\n const [, name, , selector] = part.match(TARGET_REGEX) ?? [];\n return [name, selector];\n });\n\n const targets = [] as Array<Record<string, Base>>;\n\n for (const instance of getInstances()) {\n const { name } = instance.__config;\n\n for (const part of parts) {\n const shouldPush =\n part[0] === name && (!part[1] || (part[1] && instance.$el.matches(part[1])));\n if (shouldPush) {\n targets.push({ [instance.__config.name]: instance });\n }\n }\n }\n\n return targets;\n }\n\n /**\n * Get instances mounted on the action element.\n * @internal\n */\n get instances() {\n const { $el } = this.action;\n const instances = new Map<string, Base>();\n for (const instance of getInstances()) {\n if (instance.$el === $el) {\n instances.set(instance.$config.name, instance);\n }\n }\n\n return instances;\n }\n\n /**\n * Handle the defined event and trigger the effect for each defined target.\n */\n handleEvent(event: Event) {\n const { targets, effect, modifiers } = this;\n\n if (modifiers.includes('prevent')) {\n event.preventDefault();\n }\n\n if (modifiers.includes('stop')) {\n event.stopPropagation();\n }\n\n if (modifiers.includes('debounce')) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = window.setTimeout(() => {\n this.executeEffect(targets, effect, event);\n }, this.debounceDelay);\n } else {\n this.executeEffect(targets, effect, event);\n }\n }\n\n /**\n * Execute the effect for all targets.\n */\n executeEffect(targets: Array<Record<string, Base>>, effect: Function, event: Event) {\n const { action } = this;\n\n for (const target of targets) {\n try {\n const [currentTarget] = Object.values(target).flat();\n const args = [\n target,\n event,\n currentTarget,\n action,\n action,\n currentTarget.$el,\n ...this.instances.values(),\n ];\n const value = effect.apply(action.$el, args);\n if (isFunction(value)) {\n value.apply(action.$el, args);\n }\n } catch (err) {\n action.$warn(err);\n }\n }\n }\n\n /**\n * Bind the defined event to the given Action instance root element.\n */\n attachEvent() {\n const { event, modifiers } = this;\n this.action.$el.addEventListener(event, this, {\n capture: modifiers.includes('capture'),\n once: modifiers.includes('once'),\n passive: modifiers.includes('passive'),\n });\n }\n\n /**\n * Unbind the event from the given Action instance root element.\n */\n detachEvent() {\n clearTimeout(this.debounceTimer);\n this.action.$el.removeEventListener(this.event, this);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,7 +5,7 @@ export interface AnchorNavLinkProps extends AnchorScrollToProps {
5
5
  id: string;
6
6
  };
7
7
  }
8
- declare const AnchorNavLink_base: import("@studiometa/js-toolkit").BaseDecorator<import("../index.js").TransitionInterface, import("@studiometa/js-toolkit").Base<import("@studiometa/js-toolkit").BaseProps>, import("../index.js").TransitionProps>;
8
+ declare const AnchorNavLink_base: import("@studiometa/js-toolkit").BaseDecorator<import("#private/index.js").TransitionInterface, import("@studiometa/js-toolkit").Base<import("@studiometa/js-toolkit").BaseProps>, import("#private/index.js").TransitionProps>;
9
9
  /**
10
10
  * Manage a slider item and its state transition.
11
11
  */
@@ -39,13 +39,14 @@
39
39
 
40
40
  {% set theme_primary = [
41
41
  'text-white bg-black dark:text-black dark:bg-white',
42
- 'hover:bg-opacity-75 disabled:bg-opacity-50'
42
+ 'hover:bg-black/75 dark:hover:bg-white/75',
43
+ 'disabled:bg-black/50 dark:disabled:bg-white/50',
43
44
  ] %}
44
45
 
45
46
  {% set theme_secondary = [
46
- 'ring ring-inset ring-2 ring-black dark:ring-white ring-opacity-25 dark:ring-opacity-25',
47
+ 'ring ring-inset ring-2 ring-black/25 dark:ring-white/25',
47
48
  {
48
- 'hover:ring-opacity-100': (attr is defined and attr.disabled is not defined)
49
+ 'hover:ring-black dark:hover:ring-white': (attr is defined and attr.disabled is not defined)
49
50
  or attr is not defined
50
51
  }
51
52
  ] %}
@@ -0,0 +1,143 @@
1
+ import { Base, type BaseConfig, type BaseProps } from '@studiometa/js-toolkit';
2
+ export interface FetchProps extends BaseProps {
3
+ $el: HTMLAnchorElement | HTMLFormElement;
4
+ $refs: {
5
+ headers: HTMLInputElement[];
6
+ };
7
+ $options: {
8
+ history: boolean;
9
+ requestInit: RequestInit;
10
+ headers: Record<string, string>;
11
+ mode: 'replace' | 'prepend' | 'append' | 'morph';
12
+ selector: string;
13
+ };
14
+ }
15
+ export type FetchConstructor<T extends Fetch = Fetch> = {
16
+ new (...args: any[]): T;
17
+ prototype: Fetch;
18
+ } & Pick<typeof Fetch, keyof typeof Fetch>;
19
+ /**
20
+ * Fetch class.
21
+ * @link https://ui.studiometa.dev/-/components/Fetch/
22
+ */
23
+ export declare class Fetch<T extends BaseProps = BaseProps> extends Base<T & FetchProps> {
24
+ /**
25
+ * Declare the `this.constructor` type
26
+ * @link https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311
27
+ */
28
+ ['constructor']: FetchConstructor;
29
+ /**
30
+ * Fetch events enum.
31
+ */
32
+ static FETCH_EVENTS: {
33
+ readonly BEFORE_FETCH: "fetch-before";
34
+ readonly FETCH: "fetch-fetch";
35
+ readonly AFTER_FETCH: "fetch-after";
36
+ readonly BEFORE_UPDATE: "fetch-update-before";
37
+ readonly UPDATE: "fetch-update";
38
+ readonly AFTER_UPDATE: "fetch-update-after";
39
+ readonly ERROR: "fetch-error";
40
+ readonly ABORT: "fetch-abort";
41
+ };
42
+ /**
43
+ * Fetch modes enum.
44
+ */
45
+ static FETCH_MODES: {
46
+ readonly REPLACE: "replace";
47
+ readonly PREPEND: "prepend";
48
+ readonly APPEND: "append";
49
+ readonly MORPH: "morph";
50
+ };
51
+ /**
52
+ * Config.
53
+ */
54
+ static config: BaseConfig;
55
+ /**
56
+ * Header names used by the requestInit property.
57
+ * @internal
58
+ */
59
+ __headerNames: {
60
+ readonly ACCEPT: "accept";
61
+ readonly X_REQUESTED_BY: "x-requested-by";
62
+ readonly X_TRIGGERED_BY: "x-triggered-by";
63
+ readonly USER_AGENT: "user-agent";
64
+ };
65
+ /**
66
+ * DOM Parser to parse the new content to be injected.
67
+ * @internal
68
+ */
69
+ __domParser: DOMParser;
70
+ /**
71
+ * Abort controller to prevent multiple simultaneous fetches.
72
+ * @internal
73
+ */
74
+ __abortController: AbortController;
75
+ /**
76
+ * Client.
77
+ * @internal
78
+ */
79
+ __client: typeof fetch;
80
+ /**
81
+ * The client used for the fetch request.
82
+ */
83
+ get client(): typeof fetch;
84
+ /**
85
+ * The URL to use for the request.
86
+ */
87
+ get url(): URL;
88
+ /**
89
+ * Option for the fetch request.
90
+ */
91
+ get requestInit(): RequestInit;
92
+ /**
93
+ * Is the root element a link?
94
+ */
95
+ get isLink(): boolean;
96
+ /**
97
+ * Is the root element a form?
98
+ */
99
+ get isForm(): boolean;
100
+ /**
101
+ * Emit bubbling events.
102
+ * @inheritdoc
103
+ */
104
+ $emit(event: string, ...args: unknown[]): void;
105
+ /**
106
+ * If root element is a link, prevent its default behavior and fetch its URL.
107
+ */
108
+ onClick({ event }: {
109
+ event: MouseEvent;
110
+ }): void;
111
+ /**
112
+ * If root element is a form, prevent its default behavior on submit and fetch its action
113
+ * following the `method` attribute and with the form's data.
114
+ */
115
+ onSubmit({ event }: {
116
+ event: SubmitEvent;
117
+ }): void;
118
+ /**
119
+ * Update content on history back/forward navigation.
120
+ */
121
+ onWindowPopstate(): void;
122
+ /**
123
+ * Fetch given url.
124
+ */
125
+ fetch(url: URL, requestInit?: RequestInit): Promise<void>;
126
+ /**
127
+ * Update the DOM with new content from the fetched HTML.
128
+ * @internal
129
+ */
130
+ __updateDOM(fragment: Document): void;
131
+ /**
132
+ * Dispatch the contents to update to their matching FrameTarget.
133
+ */
134
+ update(url: URL, requestInit: RequestInit, content: string): Promise<void>;
135
+ /**
136
+ * Handle errors.
137
+ */
138
+ error(url: URL, requestInit: RequestInit, error: Error): void;
139
+ /**
140
+ * Abort the current request.
141
+ */
142
+ abort(reason?: any): void;
143
+ }
package/Fetch/Fetch.js ADDED
@@ -0,0 +1,292 @@
1
+ import { Base } from "@studiometa/js-toolkit";
2
+ import { domScheduler, historyPush, isFunction } from "@studiometa/js-toolkit/utils";
3
+ import morphdom from "morphdom";
4
+ import { adoptNewScripts, getScripts } from "./utils.js";
5
+ class Fetch extends Base {
6
+ /**
7
+ * Fetch events enum.
8
+ */
9
+ static FETCH_EVENTS = {
10
+ BEFORE_FETCH: "fetch-before",
11
+ FETCH: "fetch-fetch",
12
+ AFTER_FETCH: "fetch-after",
13
+ BEFORE_UPDATE: "fetch-update-before",
14
+ UPDATE: "fetch-update",
15
+ AFTER_UPDATE: "fetch-update-after",
16
+ ERROR: "fetch-error",
17
+ ABORT: "fetch-abort"
18
+ };
19
+ /**
20
+ * Fetch modes enum.
21
+ */
22
+ static FETCH_MODES = {
23
+ REPLACE: "replace",
24
+ PREPEND: "prepend",
25
+ APPEND: "append",
26
+ MORPH: "morph"
27
+ };
28
+ /**
29
+ * Config.
30
+ */
31
+ static config = {
32
+ name: "Fetch",
33
+ emits: Object.values(this.FETCH_EVENTS),
34
+ refs: ["headers[]"],
35
+ options: {
36
+ history: Boolean,
37
+ mode: {
38
+ type: String,
39
+ default: this.FETCH_MODES.REPLACE
40
+ },
41
+ requestInit: Object,
42
+ headers: Object,
43
+ selector: {
44
+ type: String,
45
+ default: "[id]"
46
+ }
47
+ }
48
+ };
49
+ /**
50
+ * Header names used by the requestInit property.
51
+ * @internal
52
+ */
53
+ __headerNames = {
54
+ ACCEPT: "accept",
55
+ X_REQUESTED_BY: "x-requested-by",
56
+ X_TRIGGERED_BY: "x-triggered-by",
57
+ USER_AGENT: "user-agent"
58
+ };
59
+ /**
60
+ * DOM Parser to parse the new content to be injected.
61
+ * @internal
62
+ */
63
+ __domParser = new DOMParser();
64
+ /**
65
+ * Abort controller to prevent multiple simultaneous fetches.
66
+ * @internal
67
+ */
68
+ __abortController = new AbortController();
69
+ /**
70
+ * Client.
71
+ * @internal
72
+ */
73
+ __client;
74
+ /**
75
+ * The client used for the fetch request.
76
+ */
77
+ get client() {
78
+ return this.__client ??= window.fetch.bind(window);
79
+ }
80
+ /**
81
+ * The URL to use for the request.
82
+ */
83
+ get url() {
84
+ const { $el, isForm } = this;
85
+ if (isForm) {
86
+ const { action, method } = this.$el;
87
+ const url = new URL(action);
88
+ if (method.toLowerCase() === "get") {
89
+ url.search = new URLSearchParams(new FormData($el)).toString();
90
+ }
91
+ return url;
92
+ }
93
+ return new URL($el.href);
94
+ }
95
+ /**
96
+ * Option for the fetch request.
97
+ */
98
+ get requestInit() {
99
+ const { __headerNames: headerNames, isForm, $el, $options, $refs } = this;
100
+ const { requestInit, headers } = $options;
101
+ const { headers: headerRefs } = $refs;
102
+ const requestedBy = "@studiometa/ui/Fetch";
103
+ const normalizedRequestInit = {
104
+ ...requestInit,
105
+ headers: {
106
+ [headerNames.USER_AGENT]: `${navigator.userAgent} ${requestedBy}`,
107
+ ...requestInit.headers,
108
+ ...headers
109
+ }
110
+ };
111
+ for (const header of headerRefs) {
112
+ if (header.dataset.name && header.value) {
113
+ normalizedRequestInit.headers[header.dataset.name] = header.value;
114
+ }
115
+ }
116
+ if (isForm) {
117
+ const form = $el;
118
+ normalizedRequestInit.method = form.method;
119
+ normalizedRequestInit.body = new FormData(form);
120
+ }
121
+ return normalizedRequestInit;
122
+ }
123
+ /**
124
+ * Is the root element a link?
125
+ */
126
+ get isLink() {
127
+ return this.$el instanceof HTMLAnchorElement;
128
+ }
129
+ /**
130
+ * Is the root element a form?
131
+ */
132
+ get isForm() {
133
+ return this.$el instanceof HTMLFormElement;
134
+ }
135
+ /**
136
+ * Emit bubbling events.
137
+ * @inheritdoc
138
+ */
139
+ $emit(event, ...args) {
140
+ const e = new CustomEvent(event, { detail: args, bubbles: true });
141
+ return super.$emit(e, ...args);
142
+ }
143
+ /**
144
+ * If root element is a link, prevent its default behavior and fetch its URL.
145
+ */
146
+ onClick({ event }) {
147
+ if (!this.isLink) return;
148
+ if (!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey && event.button === 0 && this.$el.target !== "_blank") {
149
+ event.preventDefault();
150
+ this.fetch(this.url, this.requestInit);
151
+ }
152
+ }
153
+ /**
154
+ * If root element is a form, prevent its default behavior on submit and fetch its action
155
+ * following the `method` attribute and with the form's data.
156
+ */
157
+ onSubmit({ event }) {
158
+ if (!this.isForm) return;
159
+ if (this.$el.target !== "_blank") {
160
+ event.preventDefault();
161
+ this.fetch(this.url, this.requestInit);
162
+ }
163
+ }
164
+ /**
165
+ * Update content on history back/forward navigation.
166
+ */
167
+ onWindowPopstate() {
168
+ if (!this.$options.history) return;
169
+ this.fetch(new URL(window.location.href), {
170
+ headers: {
171
+ [this.__headerNames.X_TRIGGERED_BY]: "popstate"
172
+ }
173
+ });
174
+ }
175
+ /**
176
+ * Fetch given url.
177
+ */
178
+ async fetch(url, requestInit = {}) {
179
+ const { FETCH_EVENTS } = this.constructor;
180
+ this.$emit(FETCH_EVENTS.BEFORE_FETCH, { instance: this, url, requestInit });
181
+ this.__abortController.abort();
182
+ const newController = new AbortController();
183
+ newController.signal.addEventListener("abort", () => {
184
+ this.$emit(FETCH_EVENTS.ABORT, { instance: this, url, requestInit, reason: newController.signal.reason });
185
+ });
186
+ this.__abortController = newController;
187
+ const init = {
188
+ ...this.requestInit,
189
+ ...requestInit,
190
+ headers: {
191
+ ...this.requestInit.headers,
192
+ ...requestInit.headers
193
+ },
194
+ signal: newController.signal
195
+ };
196
+ this.$log("fetch", url, init);
197
+ this.$emit(FETCH_EVENTS.FETCH, { instance: this, url, requestInit: init });
198
+ try {
199
+ const response = await this.client(url, init);
200
+ if (!response.ok) {
201
+ throw new Error(`Fetch failed with status ${response.status}`);
202
+ }
203
+ const content = await response.text();
204
+ this.$emit(FETCH_EVENTS.AFTER_FETCH, { instance: this, url, requestInit, content });
205
+ this.update(url, init, content);
206
+ } catch (error) {
207
+ this.$emit(FETCH_EVENTS.AFTER_FETCH, { instance: this, url, requestInit, error });
208
+ this.error(url, init, error);
209
+ }
210
+ }
211
+ /**
212
+ * Update the DOM with new content from the fetched HTML.
213
+ * @internal
214
+ */
215
+ __updateDOM(fragment) {
216
+ const { FETCH_MODES } = this.constructor;
217
+ const { mode, selector } = this.$options;
218
+ for (const newElement of fragment.querySelectorAll(selector)) {
219
+ const oldElement = newElement.id && document.getElementById(newElement.id);
220
+ if (!oldElement || oldElement === newElement) {
221
+ continue;
222
+ }
223
+ const oldScripts = getScripts(oldElement);
224
+ switch (mode) {
225
+ case FETCH_MODES.APPEND:
226
+ oldElement.append(...newElement.childNodes);
227
+ adoptNewScripts(getScripts(oldElement), oldScripts);
228
+ break;
229
+ case FETCH_MODES.PREPEND:
230
+ oldElement.prepend(...newElement.childNodes);
231
+ adoptNewScripts(getScripts(oldElement), oldScripts);
232
+ break;
233
+ case FETCH_MODES.MORPH:
234
+ morphdom(oldElement, newElement);
235
+ adoptNewScripts(getScripts(oldElement), oldScripts);
236
+ break;
237
+ case FETCH_MODES.REPLACE:
238
+ default:
239
+ oldElement.replaceWith(newElement);
240
+ adoptNewScripts(getScripts(newElement), oldScripts);
241
+ break;
242
+ }
243
+ }
244
+ }
245
+ /**
246
+ * Dispatch the contents to update to their matching FrameTarget.
247
+ */
248
+ async update(url, requestInit, content) {
249
+ const { FETCH_EVENTS } = this.constructor;
250
+ const { history } = this.$options;
251
+ this.$log("content", url, content);
252
+ this.$emit(FETCH_EVENTS.BEFORE_UPDATE, { instance: this, url, requestInit, content });
253
+ const fragment = this.__domParser.parseFromString(content, "text/html");
254
+ if (history) {
255
+ if (requestInit?.headers?.[this.__headerNames.X_TRIGGERED_BY] !== "popstate") {
256
+ historyPush({ path: url.pathname, search: url.searchParams });
257
+ }
258
+ domScheduler.write(() => {
259
+ if (fragment.title) {
260
+ document.title = fragment.title;
261
+ }
262
+ });
263
+ }
264
+ this.$emit(FETCH_EVENTS.UPDATE, { instance: this, url, requestInit, fragment });
265
+ if (isFunction(document.startViewTransition)) {
266
+ await document.startViewTransition(() => {
267
+ this.__updateDOM(fragment);
268
+ }).ready;
269
+ } else {
270
+ this.__updateDOM(fragment);
271
+ }
272
+ this.$emit(FETCH_EVENTS.AFTER_UPDATE, { instance: this, url, requestInit, fragment });
273
+ }
274
+ /**
275
+ * Handle errors.
276
+ */
277
+ error(url, requestInit, error) {
278
+ if (error.name === "AbortError") return;
279
+ this.$log("error", url, requestInit, error);
280
+ this.$emit(this.constructor.FETCH_EVENTS.ERROR, { instance: this, url, requestInit, error });
281
+ }
282
+ /**
283
+ * Abort the current request.
284
+ */
285
+ abort(reason) {
286
+ this.__abortController.abort(reason);
287
+ }
288
+ }
289
+ export {
290
+ Fetch
291
+ };
292
+ //# sourceMappingURL=Fetch.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../packages/ui/Fetch/Fetch.ts"],
4
+ "sourcesContent": ["import { Base, type BaseConfig, type BaseProps } from '@studiometa/js-toolkit';\nimport { domScheduler, historyPush, isFunction } from '@studiometa/js-toolkit/utils';\nimport morphdom from 'morphdom';\nimport { adoptNewScripts, getScripts } from './utils.js';\n\nexport interface FetchProps extends BaseProps {\n $el: HTMLAnchorElement | HTMLFormElement;\n $refs: {\n headers: HTMLInputElement[];\n };\n $options: {\n history: boolean;\n requestInit: RequestInit;\n headers: Record<string, string>;\n mode: 'replace' | 'prepend' | 'append' | 'morph';\n selector: string;\n };\n}\n\nexport type FetchConstructor<T extends Fetch = Fetch> = {\n new (...args: any[]): T;\n prototype: Fetch;\n} & Pick<typeof Fetch, keyof typeof Fetch>;\n\n/**\n * Fetch class.\n * @link https://ui.studiometa.dev/-/components/Fetch/\n */\nexport class Fetch<T extends BaseProps = BaseProps> extends Base<T & FetchProps> {\n /**\n * Declare the `this.constructor` type\n * @link https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311\n */\n declare ['constructor']: FetchConstructor;\n\n /**\n * Fetch events enum.\n */\n static FETCH_EVENTS = {\n BEFORE_FETCH: 'fetch-before',\n FETCH: 'fetch-fetch',\n AFTER_FETCH: 'fetch-after',\n BEFORE_UPDATE: 'fetch-update-before',\n UPDATE: 'fetch-update',\n AFTER_UPDATE: 'fetch-update-after',\n ERROR: 'fetch-error',\n ABORT: 'fetch-abort',\n } as const;\n\n /**\n * Fetch modes enum.\n */\n static FETCH_MODES = {\n REPLACE: 'replace',\n PREPEND: 'prepend',\n APPEND: 'append',\n MORPH: 'morph',\n } as const;\n\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Fetch',\n emits: Object.values(this.FETCH_EVENTS),\n refs: ['headers[]'],\n options: {\n history: Boolean,\n mode: {\n type: String,\n default: this.FETCH_MODES.REPLACE,\n },\n requestInit: Object,\n headers: Object,\n selector: {\n type: String,\n default: '[id]',\n },\n },\n };\n\n /**\n * Header names used by the requestInit property.\n * @internal\n */\n __headerNames = {\n ACCEPT: 'accept',\n X_REQUESTED_BY: 'x-requested-by',\n X_TRIGGERED_BY: 'x-triggered-by',\n USER_AGENT: 'user-agent',\n } as const;\n\n /**\n * DOM Parser to parse the new content to be injected.\n * @internal\n */\n __domParser = new DOMParser();\n\n /**\n * Abort controller to prevent multiple simultaneous fetches.\n * @internal\n */\n __abortController = new AbortController();\n\n /**\n * Client.\n * @internal\n */\n __client: typeof fetch;\n\n /**\n * The client used for the fetch request.\n */\n get client(): typeof fetch {\n return (this.__client ??= window.fetch.bind(window));\n }\n\n /**\n * The URL to use for the request.\n */\n get url(): URL {\n const { $el, isForm } = this;\n\n if (isForm) {\n const { action, method } = this.$el as HTMLFormElement;\n const url = new URL(action);\n\n if (method.toLowerCase() === 'get') {\n // @ts-expect-error URLSearchParams accepts FormData as parameter in the browser.\n url.search = new URLSearchParams(new FormData($el)).toString();\n }\n\n return url;\n }\n\n return new URL($el.href);\n }\n\n /**\n * Option for the fetch request.\n */\n get requestInit(): RequestInit {\n const { __headerNames: headerNames, isForm, $el, $options, $refs } = this;\n const { requestInit, headers } = $options;\n const { headers: headerRefs } = $refs;\n const requestedBy = '@studiometa/ui/Fetch';\n\n const normalizedRequestInit = {\n ...requestInit,\n headers: {\n [headerNames.USER_AGENT]: `${navigator.userAgent} ${requestedBy}`,\n ...requestInit.headers,\n ...headers,\n },\n };\n\n for (const header of headerRefs) {\n if (header.dataset.name && header.value) {\n normalizedRequestInit.headers[header.dataset.name] = header.value;\n }\n }\n\n if (isForm) {\n const form = $el as HTMLFormElement;\n normalizedRequestInit.method = form.method;\n normalizedRequestInit.body = new FormData(form);\n }\n\n return normalizedRequestInit;\n }\n\n /**\n * Is the root element a link?\n */\n get isLink() {\n return this.$el instanceof HTMLAnchorElement;\n }\n\n /**\n * Is the root element a form?\n */\n get isForm() {\n return this.$el instanceof HTMLFormElement;\n }\n\n /**\n * Emit bubbling events.\n * @inheritdoc\n */\n $emit(event: string, ...args: unknown[]) {\n const e = new CustomEvent(event, { detail: args, bubbles: true });\n return super.$emit(e, ...args);\n }\n\n /**\n * If root element is a link, prevent its default behavior and fetch its URL.\n */\n onClick({ event }: { event: MouseEvent }) {\n if (!this.isLink) return;\n\n if (\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey &&\n !event.metaKey &&\n event.button === 0 &&\n this.$el.target !== '_blank'\n ) {\n event.preventDefault();\n this.fetch(this.url, this.requestInit);\n }\n }\n\n /**\n * If root element is a form, prevent its default behavior on submit and fetch its action\n * following the `method` attribute and with the form's data.\n */\n onSubmit({ event }: { event: SubmitEvent }) {\n if (!this.isForm) return;\n\n if (this.$el.target !== '_blank') {\n event.preventDefault();\n this.fetch(this.url, this.requestInit);\n }\n }\n\n /**\n * Update content on history back/forward navigation.\n */\n onWindowPopstate() {\n if (!this.$options.history) return;\n\n this.fetch(new URL(window.location.href), {\n headers: {\n [this.__headerNames.X_TRIGGERED_BY]: 'popstate',\n },\n });\n }\n\n /**\n * Fetch given url.\n */\n async fetch(url: URL, requestInit: RequestInit = {}) {\n const { FETCH_EVENTS } = this.constructor;\n this.$emit(FETCH_EVENTS.BEFORE_FETCH, { instance: this, url, requestInit });\n\n this.__abortController.abort();\n const newController = new AbortController();\n newController.signal.addEventListener('abort', () => {\n this.$emit(FETCH_EVENTS.ABORT, { instance: this, url, requestInit, reason: newController.signal.reason })\n });\n this.__abortController = newController;\n const init = {\n ...this.requestInit,\n ...requestInit,\n headers: {\n ...this.requestInit.headers,\n ...requestInit.headers,\n },\n signal: newController.signal,\n };\n\n this.$log('fetch', url, init);\n this.$emit(FETCH_EVENTS.FETCH, { instance: this, url, requestInit: init });\n\n try {\n const response = await this.client(url, init);\n\n if (!response.ok) {\n throw new Error(`Fetch failed with status ${response.status}`);\n }\n\n const content = await response.text();\n this.$emit(FETCH_EVENTS.AFTER_FETCH, { instance: this, url, requestInit, content });\n this.update(url, init, content);\n } catch (error) {\n this.$emit(FETCH_EVENTS.AFTER_FETCH, { instance: this, url, requestInit, error });\n this.error(url, init, error);\n }\n }\n\n /**\n * Update the DOM with new content from the fetched HTML.\n * @internal\n */\n __updateDOM(fragment: Document) {\n const { FETCH_MODES } = this.constructor;\n const { mode, selector } = this.$options;\n\n // @ts-expect-error querySelectorAll is iterable in the browser\n for (const newElement of fragment.querySelectorAll<HTMLElement>(selector)) {\n const oldElement = newElement.id && document.getElementById(newElement.id);\n\n if (!oldElement || oldElement === newElement) {\n continue;\n }\n\n const oldScripts = getScripts(oldElement);\n\n switch (mode) {\n case FETCH_MODES.APPEND:\n oldElement.append(...newElement.childNodes);\n adoptNewScripts(getScripts(oldElement), oldScripts);\n break;\n case FETCH_MODES.PREPEND:\n oldElement.prepend(...newElement.childNodes);\n adoptNewScripts(getScripts(oldElement), oldScripts);\n break;\n case FETCH_MODES.MORPH:\n morphdom(oldElement, newElement);\n adoptNewScripts(getScripts(oldElement), oldScripts);\n break;\n case FETCH_MODES.REPLACE:\n default:\n oldElement.replaceWith(newElement);\n adoptNewScripts(getScripts(newElement), oldScripts);\n break;\n }\n }\n }\n\n /**\n * Dispatch the contents to update to their matching FrameTarget.\n */\n async update(url: URL, requestInit: RequestInit, content: string) {\n const { FETCH_EVENTS } = this.constructor;\n const { history } = this.$options;\n\n this.$log('content', url, content);\n this.$emit(FETCH_EVENTS.BEFORE_UPDATE, { instance: this, url, requestInit, content });\n\n const fragment = this.__domParser.parseFromString(content, 'text/html');\n\n if (history) {\n if (requestInit?.headers?.[this.__headerNames.X_TRIGGERED_BY] !== 'popstate') {\n historyPush({ path: url.pathname, search: url.searchParams });\n }\n domScheduler.write(() => {\n if (fragment.title) {\n document.title = fragment.title;\n }\n });\n }\n\n this.$emit(FETCH_EVENTS.UPDATE, { instance: this, url, requestInit, fragment });\n\n if (isFunction(document.startViewTransition)) {\n await document.startViewTransition(() => {\n this.__updateDOM(fragment);\n }).ready;\n } else {\n this.__updateDOM(fragment);\n }\n\n this.$emit(FETCH_EVENTS.AFTER_UPDATE, { instance: this, url, requestInit, fragment });\n }\n\n /**\n * Handle errors.\n */\n error(url: URL, requestInit: RequestInit, error: Error) {\n if (error.name === 'AbortError') return;\n\n this.$log('error', url, requestInit, error);\n this.$emit(this.constructor.FETCH_EVENTS.ERROR, { instance: this, url, requestInit, error });\n }\n\n /**\n * Abort the current request.\n */\n abort(reason?: any) {\n this.__abortController.abort(reason);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ export * from './Fetch.js';
package/Fetch/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./Fetch.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../packages/ui/Fetch/index.ts"],
4
+ "sourcesContent": ["export * from './Fetch.js';\n"],
5
+ "mappings": "AAAA,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ export declare function adoptNewScripts(newScripts: Set<HTMLScriptElement>, oldScripts: Set<HTMLScriptElement>): void;
2
+ export declare function adoptNewScript(script: HTMLScriptElement): void;
3
+ export declare function getScripts(el: HTMLElement): Set<HTMLScriptElement>;
package/Fetch/utils.js ADDED
@@ -0,0 +1,28 @@
1
+ function adoptNewScripts(newScripts, oldScripts) {
2
+ for (const script of newScripts) {
3
+ if (oldScripts.has(script)) continue;
4
+ adoptNewScript(script);
5
+ }
6
+ }
7
+ function adoptNewScript(script) {
8
+ const newScript = document.createElement("script");
9
+ for (const attribute of script.getAttributeNames()) {
10
+ newScript.setAttribute(attribute, script.getAttribute(attribute));
11
+ }
12
+ if (script.textContent) {
13
+ newScript.textContent = script.textContent;
14
+ }
15
+ script.replaceWith(newScript);
16
+ }
17
+ function getScripts(el) {
18
+ return el.tagName === "SCRIPT" ? /* @__PURE__ */ new Set([el]) : (
19
+ // @ts-expect-error querySelectoAll is iterable.
20
+ new Set(el.querySelectorAll("script"))
21
+ );
22
+ }
23
+ export {
24
+ adoptNewScript,
25
+ adoptNewScripts,
26
+ getScripts
27
+ };
28
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../packages/ui/Fetch/utils.ts"],
4
+ "sourcesContent": ["export function adoptNewScripts(\n newScripts: Set<HTMLScriptElement>,\n oldScripts: Set<HTMLScriptElement>,\n) {\n for (const script of newScripts) {\n if (oldScripts.has(script)) continue;\n adoptNewScript(script);\n }\n}\n\nexport function adoptNewScript(script: HTMLScriptElement) {\n const newScript = document.createElement('script');\n\n for (const attribute of script.getAttributeNames()) {\n newScript.setAttribute(attribute, script.getAttribute(attribute));\n }\n\n if (script.textContent) {\n newScript.textContent = script.textContent;\n }\n\n script.replaceWith(newScript);\n}\n\nexport function getScripts(el: HTMLElement): Set<HTMLScriptElement> {\n return el.tagName === 'SCRIPT'\n ? new Set([el as HTMLScriptElement])\n : // @ts-expect-error querySelectoAll is iterable.\n new Set(el.querySelectorAll('script'));\n}\n"],
5
+ "mappings": "AAAO,SAAS,gBACd,YACA,YACA;AACA,aAAW,UAAU,YAAY;AAC/B,QAAI,WAAW,IAAI,MAAM,EAAG;AAC5B,mBAAe,MAAM;AAAA,EACvB;AACF;AAEO,SAAS,eAAe,QAA2B;AACxD,QAAM,YAAY,SAAS,cAAc,QAAQ;AAEjD,aAAW,aAAa,OAAO,kBAAkB,GAAG;AAClD,cAAU,aAAa,WAAW,OAAO,aAAa,SAAS,CAAC;AAAA,EAClE;AAEA,MAAI,OAAO,aAAa;AACtB,cAAU,cAAc,OAAO;AAAA,EACjC;AAEA,SAAO,YAAY,SAAS;AAC9B;AAEO,SAAS,WAAW,IAAyC;AAClE,SAAO,GAAG,YAAY,WAClB,oBAAI,IAAI,CAAC,EAAuB,CAAC;AAAA;AAAA,IAEjC,IAAI,IAAI,GAAG,iBAAiB,QAAQ,CAAC;AAAA;AAC3C;",
6
+ "names": []
7
+ }
@@ -26,14 +26,8 @@ export declare class FrameTarget<T extends BaseProps = BaseProps> extends Transi
26
26
  * Get uniq ID.
27
27
  */
28
28
  get id(): string;
29
- /**
30
- * Get child `<script>` elements.
31
- */
32
- get __scripts(): HTMLScriptElement[];
33
29
  /**
34
30
  * Update the content from the new target.
35
31
  */
36
32
  updateContent(content?: Element): Promise<void>;
37
- adoptNewScripts(scripts: HTMLScriptElement[], oldScripts: HTMLScriptElement[]): void;
38
- adoptNewScript(script: HTMLScriptElement): void;
39
33
  }
@@ -1,5 +1,6 @@
1
1
  import { Transition } from "../Transition/index.js";
2
2
  import morphdom from "morphdom";
3
+ import { adoptNewScripts } from "../Fetch/utils.js";
3
4
  class FrameTarget extends Transition {
4
5
  /**
5
6
  * Config.
@@ -29,12 +30,6 @@ class FrameTarget extends Transition {
29
30
  get id() {
30
31
  return this.$el.id;
31
32
  }
32
- /**
33
- * Get child `<script>` elements.
34
- */
35
- get __scripts() {
36
- return Array.from(this.$el.querySelectorAll("script"));
37
- }
38
33
  /**
39
34
  * Update the content from the new target.
40
35
  */
@@ -43,12 +38,14 @@ class FrameTarget extends Transition {
43
38
  return;
44
39
  }
45
40
  const { mode } = this.$options;
46
- const { $el, modes, __scripts: previousScripts } = this;
41
+ const { $el, modes } = this;
42
+ const previousScripts = new Set(this.$el.querySelectorAll("script"));
47
43
  if (mode === modes.APPEND || mode === modes.PREPEND) {
48
44
  const leaveTargets = Array.from($el.children);
49
45
  const enterTargets = Array.from(content.children);
50
46
  $el[mode](...Array.from(content.childNodes));
51
- this.adoptNewScripts(this.__scripts, previousScripts);
47
+ const newScripts = new Set(this.$el.querySelectorAll("script"));
48
+ adoptNewScripts(newScripts, previousScripts);
52
49
  await Promise.all([this.leave(leaveTargets), this.enter(enterTargets)]);
53
50
  } else {
54
51
  await this.leave();
@@ -57,28 +54,11 @@ class FrameTarget extends Transition {
57
54
  } else {
58
55
  $el.replaceChildren(...Array.from(content.childNodes));
59
56
  }
60
- this.adoptNewScripts(this.__scripts, previousScripts);
57
+ const newScripts = new Set(this.$el.querySelectorAll("script"));
58
+ adoptNewScripts(newScripts, previousScripts);
61
59
  await this.enter();
62
60
  }
63
61
  }
64
- adoptNewScripts(scripts, oldScripts) {
65
- for (const script of scripts) {
66
- if (oldScripts.includes(script)) continue;
67
- this.adoptNewScript(script);
68
- }
69
- }
70
- adoptNewScript(script) {
71
- const newScript = document.createElement("script");
72
- for (const attribute of script.getAttributeNames()) {
73
- newScript.setAttribute(attribute, script.getAttribute(attribute));
74
- }
75
- if (script.src) {
76
- newScript.src = script.src;
77
- } else if (script.textContent) {
78
- newScript.textContent = script.textContent;
79
- }
80
- script.replaceWith(newScript);
81
- }
82
62
  }
83
63
  export {
84
64
  FrameTarget
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Frame/FrameTarget.ts"],
4
- "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { Transition } from '../Transition/index.js';\nimport morphdom from 'morphdom';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append' | 'morph';\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameTarget',\n options: {\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n },\n };\n\n /**\n * Different mode of content insertion.\n */\n modes = {\n APPEND: 'append',\n PREPEND: 'prepend',\n REPLACE: 'replace',\n MORPH: 'morph',\n } as const;\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$el.id;\n }\n\n /**\n * Get child `<script>` elements.\n */\n get __scripts() {\n return Array.from(this.$el.querySelectorAll('script'));\n }\n\n /**\n * Update the content from the new target.\n */\n async updateContent(content: Element = null) {\n if (!content) {\n return;\n }\n\n const { mode } = this.$options;\n const { $el, modes, __scripts: previousScripts } = this;\n\n // In append or prepend mode, the leave transition can be used to\n // move the exisiting children of the root element, with the leave\n // transition being applied in parallel of the enter transition.\n if (mode === modes.APPEND || mode === modes.PREPEND) {\n const leaveTargets = Array.from($el.children) as HTMLElement[];\n const enterTargets = Array.from(content.children) as HTMLElement[];\n\n $el[mode](...Array.from(content.childNodes));\n this.adoptNewScripts(this.__scripts, previousScripts);\n await Promise.all([this.leave(leaveTargets), this.enter(enterTargets)]);\n } else {\n await this.leave();\n if (mode === modes.MORPH) {\n morphdom($el, content);\n } else {\n $el.replaceChildren(...Array.from(content.childNodes));\n }\n this.adoptNewScripts(this.__scripts, previousScripts);\n await this.enter();\n }\n }\n\n adoptNewScripts(scripts: HTMLScriptElement[], oldScripts: HTMLScriptElement[]) {\n for (const script of scripts) {\n if (oldScripts.includes(script)) continue;\n this.adoptNewScript(script);\n }\n }\n\n adoptNewScript(script: HTMLScriptElement) {\n const newScript = document.createElement('script');\n\n for (const attribute of script.getAttributeNames()) {\n newScript.setAttribute(attribute, script.getAttribute(attribute));\n }\n\n if (script.src) {\n newScript.src = script.src;\n } else if (script.textContent) {\n newScript.textContent = script.textContent;\n }\n\n script.replaceWith(newScript);\n }\n}\n"],
5
- "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAWd,MAAM,oBAAqD,WAAiC;AAAA;AAAA;AAAA;AAAA,EAIjG,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAY;AACd,WAAO,MAAM,KAAK,KAAK,IAAI,iBAAiB,QAAQ,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAAmB,MAAM;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,UAAM,EAAE,KAAK,OAAO,WAAW,gBAAgB,IAAI;AAKnD,QAAI,SAAS,MAAM,UAAU,SAAS,MAAM,SAAS;AACnD,YAAM,eAAe,MAAM,KAAK,IAAI,QAAQ;AAC5C,YAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ;AAEhD,UAAI,IAAI,EAAE,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAC3C,WAAK,gBAAgB,KAAK,WAAW,eAAe;AACpD,YAAM,QAAQ,IAAI,CAAC,KAAK,MAAM,YAAY,GAAG,KAAK,MAAM,YAAY,CAAC,CAAC;AAAA,IACxE,OAAO;AACL,YAAM,KAAK,MAAM;AACjB,UAAI,SAAS,MAAM,OAAO;AACxB,iBAAS,KAAK,OAAO;AAAA,MACvB,OAAO;AACL,YAAI,gBAAgB,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAAA,MACvD;AACA,WAAK,gBAAgB,KAAK,WAAW,eAAe;AACpD,YAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,gBAAgB,SAA8B,YAAiC;AAC7E,eAAW,UAAU,SAAS;AAC5B,UAAI,WAAW,SAAS,MAAM,EAAG;AACjC,WAAK,eAAe,MAAM;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,eAAe,QAA2B;AACxC,UAAM,YAAY,SAAS,cAAc,QAAQ;AAEjD,eAAW,aAAa,OAAO,kBAAkB,GAAG;AAClD,gBAAU,aAAa,WAAW,OAAO,aAAa,SAAS,CAAC;AAAA,IAClE;AAEA,QAAI,OAAO,KAAK;AACd,gBAAU,MAAM,OAAO;AAAA,IACzB,WAAW,OAAO,aAAa;AAC7B,gBAAU,cAAc,OAAO;AAAA,IACjC;AAEA,WAAO,YAAY,SAAS;AAAA,EAC9B;AACF;",
4
+ "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { Transition } from '../Transition/index.js';\nimport morphdom from 'morphdom';\nimport { adoptNewScripts } from '../Fetch/utils.js';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append' | 'morph';\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameTarget',\n options: {\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n },\n };\n\n /**\n * Different mode of content insertion.\n */\n modes = {\n APPEND: 'append',\n PREPEND: 'prepend',\n REPLACE: 'replace',\n MORPH: 'morph',\n } as const;\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$el.id;\n }\n\n /**\n * Update the content from the new target.\n */\n async updateContent(content: Element = null) {\n if (!content) {\n return;\n }\n\n const { mode } = this.$options;\n const { $el, modes } = this;\n // @ts-expect-error querySelectoAll is iterable.\n const previousScripts: Set<HTMLScriptElement> = new Set(this.$el.querySelectorAll('script'));\n\n // In append or prepend mode, the leave transition can be used to\n // move the exisiting children of the root element, with the leave\n // transition being applied in parallel of the enter transition.\n if (mode === modes.APPEND || mode === modes.PREPEND) {\n const leaveTargets = Array.from($el.children) as HTMLElement[];\n const enterTargets = Array.from(content.children) as HTMLElement[];\n\n $el[mode](...Array.from(content.childNodes));\n // @ts-expect-error querySelectoAll is iterable.\n const newScripts: Set<HTMLScriptElement> = new Set(this.$el.querySelectorAll('script'));\n adoptNewScripts(newScripts, previousScripts);\n await Promise.all([this.leave(leaveTargets), this.enter(enterTargets)]);\n } else {\n await this.leave();\n if (mode === modes.MORPH) {\n morphdom($el, content);\n } else {\n $el.replaceChildren(...Array.from(content.childNodes));\n }\n // @ts-expect-error querySelectoAll is iterable.\n const newScripts: Set<HTMLScriptElement> = new Set(this.$el.querySelectorAll('script'));\n adoptNewScripts(newScripts, previousScripts);\n await this.enter();\n }\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AACrB,SAAS,uBAAuB;AAWzB,MAAM,oBAAqD,WAAiC;AAAA;AAAA;AAAA;AAAA,EAIjG,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAAmB,MAAM;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,UAAM,EAAE,KAAK,MAAM,IAAI;AAEvB,UAAM,kBAA0C,IAAI,IAAI,KAAK,IAAI,iBAAiB,QAAQ,CAAC;AAK3F,QAAI,SAAS,MAAM,UAAU,SAAS,MAAM,SAAS;AACnD,YAAM,eAAe,MAAM,KAAK,IAAI,QAAQ;AAC5C,YAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ;AAEhD,UAAI,IAAI,EAAE,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAE3C,YAAM,aAAqC,IAAI,IAAI,KAAK,IAAI,iBAAiB,QAAQ,CAAC;AACtF,sBAAgB,YAAY,eAAe;AAC3C,YAAM,QAAQ,IAAI,CAAC,KAAK,MAAM,YAAY,GAAG,KAAK,MAAM,YAAY,CAAC,CAAC;AAAA,IACxE,OAAO;AACL,YAAM,KAAK,MAAM;AACjB,UAAI,SAAS,MAAM,OAAO;AACxB,iBAAS,KAAK,OAAO;AAAA,MACvB,OAAO;AACL,YAAI,gBAAgB,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAAA,MACvD;AAEA,YAAM,aAAqC,IAAI,IAAI,KAAK,IAAI,iBAAiB,QAAQ,CAAC;AACtF,sBAAgB,YAAY,eAAe;AAC3C,YAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -24,7 +24,7 @@ export declare class MenuList<T extends BaseProps = BaseProps> extends Transitio
24
24
  /**
25
25
  * Override `Transition` options.
26
26
  */
27
- get $options(): import("@studiometa/js-toolkit").BaseOptions & (T & MenuListProps & import("../index.js").TransitionProps)["$options"];
27
+ get $options(): import("@studiometa/js-toolkit").BaseOptions & (T & MenuListProps & import("#private/index.js").TransitionProps)["$options"];
28
28
  /**
29
29
  * Update tab indexes on mount.
30
30
  */
package/Modal/Modal.twig CHANGED
@@ -32,7 +32,7 @@
32
32
  {% set modal_attributes =
33
33
  merge_html_attributes(
34
34
  modal_attr ?? null,
35
- { class: 'z-goku fixed inset-0' },
35
+ { class: 'z-50 fixed inset-0' },
36
36
  {
37
37
  data_ref: 'modal',
38
38
  role: 'dialog',
@@ -47,7 +47,7 @@
47
47
  {% set overlay_attributes =
48
48
  merge_html_attributes(
49
49
  overlay_attr ?? null,
50
- { class: 'z-under absolute inset-0 bg-black bg-opacity-75' },
50
+ { class: '-z-10 absolute inset-0 bg-black/75' },
51
51
  { data_ref: 'overlay', tabindex: '-1' }
52
52
  )
53
53
  %}
@@ -67,7 +67,7 @@
67
67
  { class: 'bg-white rounded shadow-l' },
68
68
  {
69
69
  data_ref: 'container',
70
- class: 'z-above relative max-h-full overflow-x-hidden overflow-y-auto pointer-events-auto'
70
+ class: 'z-10 relative max-h-full overflow-x-hidden overflow-y-auto pointer-events-auto'
71
71
  }
72
72
  )
73
73
  %}
package/Panel/Panel.js CHANGED
@@ -63,7 +63,8 @@ class Panel extends Modal {
63
63
  transform: this.containerOffset
64
64
  },
65
65
  to: {
66
- transform: "none"
66
+ transform: "none",
67
+ translate: "none"
67
68
  }
68
69
  },
69
70
  "keep"
@@ -89,7 +90,8 @@ class Panel extends Modal {
89
90
  this.$refs.container,
90
91
  {
91
92
  from: {
92
- transform: "none"
93
+ transform: "none",
94
+ translate: "none"
93
95
  },
94
96
  to: {
95
97
  transform: this.containerOffset
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Panel/Panel.ts"],
4
- "sourcesContent": ["import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition, matrix } from '@studiometa/js-toolkit/utils';\nimport { Modal } from '../Modal/index.js';\n\nexport interface PanelProps extends BaseProps {\n $options: {\n position: 'top' | 'right' | 'bottom' | 'left';\n };\n}\n\nconst DEFAULT_POSITION = 'left';\n\n/**\n * Panel class.\n * @link https://ui.studiometa.dev/-/components/Panel/\n */\nexport class Panel<T extends BaseProps = BaseProps> extends Modal<T & PanelProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Panel',\n options: {\n position: {\n type: String,\n default: DEFAULT_POSITION,\n },\n },\n };\n\n static translateClasses = {\n top: '-translate-y-full',\n right: 'translate-x-full',\n bottom: 'translate-y-full',\n left: '-translate-x-full',\n };\n\n isClosing = false;\n\n /**\n * Get the translation class.\n * @returns {string}\n */\n get translateClass() {\n return (\n Panel.translateClasses[this.$options.position] ?? Panel.translateClasses[DEFAULT_POSITION]\n );\n }\n\n get containerOffset() {\n const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = this.$refs.container;\n\n const store = {\n top: {\n translateY: (offsetTop + offsetHeight) * -1,\n },\n right: {\n translateX: window.innerWidth - offsetLeft + offsetWidth * 2,\n },\n bottom: {\n translateY: window.innerHeight - offsetTop + offsetHeight * 2,\n },\n left: {\n translateX: (offsetLeft + offsetWidth) * -1,\n },\n };\n\n return matrix(store[this.$options.position]);\n }\n\n /**\n * Animate before opening.\n * @this {PanelInterface}\n * @returns {Promise<void>}\n */\n async open() {\n if (this.isOpen) {\n return Promise.resolve();\n }\n\n this.$refs.modal.classList.remove('pointer-events-none');\n transition(\n this.$refs.container,\n {\n from: {\n transform: this.containerOffset,\n },\n to: {\n transform: 'none',\n },\n },\n 'keep',\n );\n transition(this.$refs.overlay, {\n from: 'opacity-0',\n });\n\n return super.open();\n }\n\n /**\n * Animate before closing.\n * @this {PanelInterface}\n * @returns {Promise<void>}\n */\n async close() {\n if (!this.isOpen || this.isClosing) {\n return Promise.resolve();\n }\n\n this.isClosing = true;\n\n this.$refs.modal.classList.add('pointer-events-none');\n await Promise.all([\n transition(\n this.$refs.container,\n {\n from: {\n transform: 'none',\n },\n to: {\n transform: this.containerOffset,\n },\n },\n 'keep',\n ),\n transition(\n this.$refs.overlay,\n {\n to: 'opacity-0',\n },\n 'keep',\n ),\n ]);\n\n this.isClosing = false;\n\n return super.close();\n }\n}\n"],
5
- "mappings": "AACA,SAAS,YAAY,cAAc;AACnC,SAAS,aAAa;AAQtB,MAAM,mBAAmB;AAMlB,MAAM,cAA+C,MAAsB;AAAA;AAAA;AAAA;AAAA,EAIhF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,UAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,mBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EAEA,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,IAAI,iBAAiB;AACnB,WACE,MAAM,iBAAiB,KAAK,SAAS,QAAQ,KAAK,MAAM,iBAAiB,gBAAgB;AAAA,EAE7F;AAAA,EAEA,IAAI,kBAAkB;AACpB,UAAM,EAAE,WAAW,YAAY,aAAa,aAAa,IAAI,KAAK,MAAM;AAExE,UAAM,QAAQ;AAAA,MACZ,KAAK;AAAA,QACH,aAAa,YAAY,gBAAgB;AAAA,MAC3C;AAAA,MACA,OAAO;AAAA,QACL,YAAY,OAAO,aAAa,aAAa,cAAc;AAAA,MAC7D;AAAA,MACA,QAAQ;AAAA,QACN,YAAY,OAAO,cAAc,YAAY,eAAe;AAAA,MAC9D;AAAA,MACA,MAAM;AAAA,QACJ,aAAa,aAAa,eAAe;AAAA,MAC3C;AAAA,IACF;AAEA,WAAO,OAAO,MAAM,KAAK,SAAS,QAAQ,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO;AACX,QAAI,KAAK,QAAQ;AACf,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,SAAK,MAAM,MAAM,UAAU,OAAO,qBAAqB;AACvD;AAAA,MACE,KAAK,MAAM;AAAA,MACX;AAAA,QACE,MAAM;AAAA,UACJ,WAAW,KAAK;AAAA,QAClB;AAAA,QACA,IAAI;AAAA,UACF,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,IACF;AACA,eAAW,KAAK,MAAM,SAAS;AAAA,MAC7B,MAAM;AAAA,IACR,CAAC;AAED,WAAO,MAAM,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ;AACZ,QAAI,CAAC,KAAK,UAAU,KAAK,WAAW;AAClC,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,SAAK,YAAY;AAEjB,SAAK,MAAM,MAAM,UAAU,IAAI,qBAAqB;AACpD,UAAM,QAAQ,IAAI;AAAA,MAChB;AAAA,QACE,KAAK,MAAM;AAAA,QACX;AAAA,UACE,MAAM;AAAA,YACJ,WAAW;AAAA,UACb;AAAA,UACA,IAAI;AAAA,YACF,WAAW,KAAK;AAAA,UAClB;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,KAAK,MAAM;AAAA,QACX;AAAA,UACE,IAAI;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AAEjB,WAAO,MAAM,MAAM;AAAA,EACrB;AACF;",
4
+ "sourcesContent": ["import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { transition, matrix } from '@studiometa/js-toolkit/utils';\nimport { Modal } from '../Modal/index.js';\n\nexport interface PanelProps extends BaseProps {\n $options: {\n position: 'top' | 'right' | 'bottom' | 'left';\n };\n}\n\nconst DEFAULT_POSITION = 'left';\n\n/**\n * Panel class.\n * @link https://ui.studiometa.dev/-/components/Panel/\n */\nexport class Panel<T extends BaseProps = BaseProps> extends Modal<T & PanelProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Panel',\n options: {\n position: {\n type: String,\n default: DEFAULT_POSITION,\n },\n },\n };\n\n static translateClasses = {\n top: '-translate-y-full',\n right: 'translate-x-full',\n bottom: 'translate-y-full',\n left: '-translate-x-full',\n };\n\n isClosing = false;\n\n /**\n * Get the translation class.\n * @returns {string}\n */\n get translateClass() {\n return (\n Panel.translateClasses[this.$options.position] ?? Panel.translateClasses[DEFAULT_POSITION]\n );\n }\n\n get containerOffset() {\n const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = this.$refs.container;\n\n const store = {\n top: {\n translateY: (offsetTop + offsetHeight) * -1,\n },\n right: {\n translateX: window.innerWidth - offsetLeft + offsetWidth * 2,\n },\n bottom: {\n translateY: window.innerHeight - offsetTop + offsetHeight * 2,\n },\n left: {\n translateX: (offsetLeft + offsetWidth) * -1,\n },\n };\n\n return matrix(store[this.$options.position]);\n }\n\n /**\n * Animate before opening.\n * @this {PanelInterface}\n * @returns {Promise<void>}\n */\n async open() {\n if (this.isOpen) {\n return Promise.resolve();\n }\n\n this.$refs.modal.classList.remove('pointer-events-none');\n transition(\n this.$refs.container,\n {\n from: {\n transform: this.containerOffset,\n },\n to: {\n transform: 'none',\n translate: 'none',\n },\n },\n 'keep',\n );\n transition(this.$refs.overlay, {\n from: 'opacity-0',\n });\n\n return super.open();\n }\n\n /**\n * Animate before closing.\n * @this {PanelInterface}\n * @returns {Promise<void>}\n */\n async close() {\n if (!this.isOpen || this.isClosing) {\n return Promise.resolve();\n }\n\n this.isClosing = true;\n\n this.$refs.modal.classList.add('pointer-events-none');\n await Promise.all([\n transition(\n this.$refs.container,\n {\n from: {\n transform: 'none',\n translate: 'none',\n },\n to: {\n transform: this.containerOffset,\n },\n },\n 'keep',\n ),\n transition(\n this.$refs.overlay,\n {\n to: 'opacity-0',\n },\n 'keep',\n ),\n ]);\n\n this.isClosing = false;\n\n return super.close();\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,YAAY,cAAc;AACnC,SAAS,aAAa;AAQtB,MAAM,mBAAmB;AAMlB,MAAM,cAA+C,MAAsB;AAAA;AAAA;AAAA;AAAA,EAIhF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,UAAU;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,mBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EAEA,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,IAAI,iBAAiB;AACnB,WACE,MAAM,iBAAiB,KAAK,SAAS,QAAQ,KAAK,MAAM,iBAAiB,gBAAgB;AAAA,EAE7F;AAAA,EAEA,IAAI,kBAAkB;AACpB,UAAM,EAAE,WAAW,YAAY,aAAa,aAAa,IAAI,KAAK,MAAM;AAExE,UAAM,QAAQ;AAAA,MACZ,KAAK;AAAA,QACH,aAAa,YAAY,gBAAgB;AAAA,MAC3C;AAAA,MACA,OAAO;AAAA,QACL,YAAY,OAAO,aAAa,aAAa,cAAc;AAAA,MAC7D;AAAA,MACA,QAAQ;AAAA,QACN,YAAY,OAAO,cAAc,YAAY,eAAe;AAAA,MAC9D;AAAA,MACA,MAAM;AAAA,QACJ,aAAa,aAAa,eAAe;AAAA,MAC3C;AAAA,IACF;AAEA,WAAO,OAAO,MAAM,KAAK,SAAS,QAAQ,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO;AACX,QAAI,KAAK,QAAQ;AACf,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,SAAK,MAAM,MAAM,UAAU,OAAO,qBAAqB;AACvD;AAAA,MACE,KAAK,MAAM;AAAA,MACX;AAAA,QACE,MAAM;AAAA,UACJ,WAAW,KAAK;AAAA,QAClB;AAAA,QACA,IAAI;AAAA,UACF,WAAW;AAAA,UACX,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,IACF;AACA,eAAW,KAAK,MAAM,SAAS;AAAA,MAC7B,MAAM;AAAA,IACR,CAAC;AAED,WAAO,MAAM,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ;AACZ,QAAI,CAAC,KAAK,UAAU,KAAK,WAAW;AAClC,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,SAAK,YAAY;AAEjB,SAAK,MAAM,MAAM,UAAU,IAAI,qBAAqB;AACpD,UAAM,QAAQ,IAAI;AAAA,MAChB;AAAA,QACE,KAAK,MAAM;AAAA,QACX;AAAA,UACE,MAAM;AAAA,YACJ,WAAW;AAAA,YACX,WAAW;AAAA,UACb;AAAA,UACA,IAAI;AAAA,YACF,WAAW,KAAK;AAAA,UAClB;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,KAAK,MAAM;AAAA,QACX;AAAA,UACE,IAAI;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AAEjB,WAAO,MAAM,MAAM;AAAA,EACrB;AACF;",
6
6
  "names": []
7
7
  }
package/Panel/Panel.twig CHANGED
@@ -21,7 +21,7 @@
21
21
  {% set overlay_attr =
22
22
  merge_html_attributes(
23
23
  overlay_attr ?? null,
24
- { class: 'z-under absolute inset-0 bg-black bg-opacity-75' },
24
+ { class: '-z-10 absolute inset-0 bg-black/75' },
25
25
  { class: 'transition duration-500 opacity-0' }
26
26
  )
27
27
  %}
@@ -32,7 +32,7 @@
32
32
  {},
33
33
  {
34
34
  class: [
35
- 'z-above absolute top-0 w-full h-full flex pointer-events-none',
35
+ 'z-10 absolute top-0 w-full h-full flex pointer-events-none',
36
36
  {
37
37
  'top-0 left-0 items-start justify-center': position == 'top',
38
38
  'top-0 right-0 items-center justify-end': position == 'right',
@@ -1,5 +1,5 @@
1
1
  import type { BaseConfig } from '@studiometa/js-toolkit';
2
- declare const ScrollAnimationChildWithEase_base: import("@studiometa/js-toolkit").BaseDecorator<import("./animationScrollWithEase.js").AnimationScrollWithEaseInterface, import("./AbstractScrollAnimation.js").AbstractScrollAnimation<import("@studiometa/js-toolkit").BaseProps>, import("./animationScrollWithEase.js").AnimationScrollWithEaseProps>;
2
+ declare const ScrollAnimationChildWithEase_base: import("@studiometa/js-toolkit").BaseDecorator<import("#private/index.js").AnimationScrollWithEaseInterface, import("#private/index.js").AbstractScrollAnimation<import("@studiometa/js-toolkit").BaseProps>, import("#private/index.js").AnimationScrollWithEaseProps>;
3
3
  /**
4
4
  * ScrollAnimationChild class.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  import { type BaseConfig } from '@studiometa/js-toolkit';
2
- declare const ScrollAnimationWithEase_base: import("@studiometa/js-toolkit").BaseDecorator<import("./animationScrollWithEase.js").AnimationScrollWithEaseInterface, import("./AbstractScrollAnimation.js").AbstractScrollAnimation<import("@studiometa/js-toolkit").BaseProps>, import("./animationScrollWithEase.js").AnimationScrollWithEaseProps>;
2
+ declare const ScrollAnimationWithEase_base: import("@studiometa/js-toolkit").BaseDecorator<import("#private/index.js").AnimationScrollWithEaseInterface, import("#private/index.js").AbstractScrollAnimation<import("@studiometa/js-toolkit").BaseProps>, import("#private/index.js").AnimationScrollWithEaseProps>;
3
3
  /**
4
4
  * ScrollAnimation class.
5
5
  */
@@ -5,7 +5,7 @@ export interface SliderDotsProps extends BaseProps {
5
5
  dots: HTMLButtonElement[];
6
6
  };
7
7
  }
8
- declare const SliderDots_base: import("@studiometa/js-toolkit").BaseDecorator<import("../index.js").TransitionInterface, AbstractSliderChild<BaseProps>, import("../index.js").TransitionProps>;
8
+ declare const SliderDots_base: import("@studiometa/js-toolkit").BaseDecorator<import("#private/index.js").TransitionInterface, AbstractSliderChild<BaseProps>, import("#private/index.js").TransitionProps>;
9
9
  /**
10
10
  * SliderDots class.
11
11
  */
@@ -1,6 +1,6 @@
1
1
  import { Base, BaseProps } from '@studiometa/js-toolkit';
2
2
  import type { BaseConfig } from '@studiometa/js-toolkit';
3
- declare const Transition_base: import("@studiometa/js-toolkit").BaseDecorator<import("../index.js").TransitionInterface, Base<BaseProps>, import("../index.js").TransitionProps>;
3
+ declare const Transition_base: import("@studiometa/js-toolkit").BaseDecorator<import("#private/index.js").TransitionInterface, Base<BaseProps>, import("#private/index.js").TransitionProps>;
4
4
  /**
5
5
  * Transition class.
6
6
  * @link https://ui.studiometa.dev/-/components/Transition/
package/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from './Cursor/index.js';
7
7
  export * from './Data/index.js';
8
8
  export * from './decorators/index.js';
9
9
  export * from './Draggable/index.js';
10
+ export * from './Fetch/index.js';
10
11
  export * from './Figure/index.js';
11
12
  export * from './FigureVideo/index.js';
12
13
  export * from './Frame/index.js';
package/index.js CHANGED
@@ -7,6 +7,7 @@ export * from "./Cursor/index.js";
7
7
  export * from "./Data/index.js";
8
8
  export * from "./decorators/index.js";
9
9
  export * from "./Draggable/index.js";
10
+ export * from "./Fetch/index.js";
10
11
  export * from "./Figure/index.js";
11
12
  export * from "./FigureVideo/index.js";
12
13
  export * from "./Frame/index.js";
package/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../packages/ui/index.ts"],
4
- "sourcesContent": ["export * from './Accordion/index.js';\nexport * from './Action/index.js';\nexport * from './AnchorNav/index.js';\nexport * from './AnchorScrollTo/index.js';\nexport * from './CircularMarquee/index.js';\nexport * from './Cursor/index.js';\nexport * from './Data/index.js';\nexport * from './decorators/index.js';\nexport * from './Draggable/index.js';\nexport * from './Figure/index.js';\nexport * from './FigureVideo/index.js';\nexport * from './Frame/index.js';\nexport * from './Hoverable/index.js';\nexport * from './LargeText/index.js';\nexport * from './LazyInclude/index.js';\nexport * from './Menu/index.js';\nexport * from './Modal/index.js';\nexport * from './Panel/index.js';\nexport * from './Prefetch/index.js';\nexport * from './ScrollAnimation/index.js';\nexport * from './ScrollReveal/index.js';\nexport * from './Sentinel/index.js';\nexport * from './Slider/index.js';\nexport * from './Sticky/index.js';\nexport * from './Tabs/index.js';\nexport * from './Transition/index.js';\n"],
5
- "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export * from './Accordion/index.js';\nexport * from './Action/index.js';\nexport * from './AnchorNav/index.js';\nexport * from './AnchorScrollTo/index.js';\nexport * from './CircularMarquee/index.js';\nexport * from './Cursor/index.js';\nexport * from './Data/index.js';\nexport * from './decorators/index.js';\nexport * from './Draggable/index.js';\nexport * from './Fetch/index.js';\nexport * from './Figure/index.js';\nexport * from './FigureVideo/index.js';\nexport * from './Frame/index.js';\nexport * from './Hoverable/index.js';\nexport * from './LargeText/index.js';\nexport * from './LazyInclude/index.js';\nexport * from './Menu/index.js';\nexport * from './Modal/index.js';\nexport * from './Panel/index.js';\nexport * from './Prefetch/index.js';\nexport * from './ScrollAnimation/index.js';\nexport * from './ScrollReveal/index.js';\nexport * from './Sentinel/index.js';\nexport * from './Slider/index.js';\nexport * from './Sticky/index.js';\nexport * from './Tabs/index.js';\nexport * from './Transition/index.js';\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/ui",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "A set of opiniated, unstyled and accessible components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -33,9 +33,9 @@
33
33
  "morphdom": "^2.7.5"
34
34
  },
35
35
  "devDependencies": {
36
- "@studiometa/js-toolkit": "3.3.0"
36
+ "@studiometa/js-toolkit": "3.4.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "@studiometa/js-toolkit": "^3.3.0"
39
+ "@studiometa/js-toolkit": "^3.4.0"
40
40
  }
41
41
  }