@studiometa/ui 1.0.0-rc.6 → 1.0.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/ActionEvent.d.ts +13 -1
- package/Action/ActionEvent.js +32 -1
- package/Action/ActionEvent.js.map +2 -2
- package/Figure/Figure.twig +10 -0
- package/Frame/FrameTarget.d.ts +2 -1
- package/Frame/FrameTarget.js +11 -5
- package/Frame/FrameTarget.js.map +2 -2
- package/Sticky/Sticky.d.ts +4 -12
- package/Sticky/Sticky.js +8 -2
- package/Sticky/Sticky.js.map +2 -2
- package/Sticky/Sticky.twig +19 -7
- package/package.json +3 -3
package/Action/ActionEvent.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { Base } from '@studiometa/js-toolkit';
|
|
2
|
-
export type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture';
|
|
2
|
+
export type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture' | 'debounce';
|
|
3
3
|
export declare class ActionEvent<T extends Base> {
|
|
4
4
|
static modifierSeparator: string;
|
|
5
5
|
static targetSeparator: string;
|
|
6
6
|
static effectSeparator: string;
|
|
7
|
+
/**
|
|
8
|
+
* Timer for debouncing event handling.
|
|
9
|
+
*/
|
|
10
|
+
private debounceTimer?;
|
|
7
11
|
/**
|
|
8
12
|
* The Action instance.
|
|
9
13
|
*/
|
|
@@ -16,6 +20,10 @@ export declare class ActionEvent<T extends Base> {
|
|
|
16
20
|
* The modifiers to apply to the event.
|
|
17
21
|
*/
|
|
18
22
|
modifiers: Modifiers[];
|
|
23
|
+
/**
|
|
24
|
+
* The debounce delay in milliseconds.
|
|
25
|
+
*/
|
|
26
|
+
debounceDelay: number;
|
|
19
27
|
/**
|
|
20
28
|
* Target definition.
|
|
21
29
|
* Ex: `Target Target(.selector)`.
|
|
@@ -44,6 +52,10 @@ export declare class ActionEvent<T extends Base> {
|
|
|
44
52
|
* Handle the defined event and trigger the effect for each defined target.
|
|
45
53
|
*/
|
|
46
54
|
handleEvent(event: Event): void;
|
|
55
|
+
/**
|
|
56
|
+
* Execute the effect for all targets.
|
|
57
|
+
*/
|
|
58
|
+
private executeEffect;
|
|
47
59
|
/**
|
|
48
60
|
* Bind the defined event to the given Action instance root element.
|
|
49
61
|
*/
|
package/Action/ActionEvent.js
CHANGED
|
@@ -6,6 +6,10 @@ class ActionEvent {
|
|
|
6
6
|
static modifierSeparator = ".";
|
|
7
7
|
static targetSeparator = " ";
|
|
8
8
|
static effectSeparator = "->";
|
|
9
|
+
/**
|
|
10
|
+
* Timer for debouncing event handling.
|
|
11
|
+
*/
|
|
12
|
+
debounceTimer;
|
|
9
13
|
/**
|
|
10
14
|
* The Action instance.
|
|
11
15
|
*/
|
|
@@ -18,6 +22,10 @@ class ActionEvent {
|
|
|
18
22
|
* The modifiers to apply to the event.
|
|
19
23
|
*/
|
|
20
24
|
modifiers;
|
|
25
|
+
/**
|
|
26
|
+
* The debounce delay in milliseconds.
|
|
27
|
+
*/
|
|
28
|
+
debounceDelay = 100;
|
|
21
29
|
/**
|
|
22
30
|
* Target definition.
|
|
23
31
|
* Ex: `Target Target(.selector)`.
|
|
@@ -37,7 +45,16 @@ class ActionEvent {
|
|
|
37
45
|
this.action = action;
|
|
38
46
|
const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);
|
|
39
47
|
this.event = event;
|
|
40
|
-
|
|
48
|
+
const processedModifiers = [];
|
|
49
|
+
for (const modifier of modifiers) {
|
|
50
|
+
if (modifier.startsWith("debounce")) {
|
|
51
|
+
processedModifiers.push("debounce");
|
|
52
|
+
this.debounceDelay = parseInt(modifier.replace("debounce", "") || "100");
|
|
53
|
+
} else {
|
|
54
|
+
processedModifiers.push(modifier);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.modifiers = processedModifiers;
|
|
41
58
|
let effect = effectDefinition;
|
|
42
59
|
let targetDefinition = "";
|
|
43
60
|
if (effect.includes(ActionEvent.effectSeparator)) {
|
|
@@ -94,6 +111,19 @@ class ActionEvent {
|
|
|
94
111
|
if (modifiers.includes("stop")) {
|
|
95
112
|
event.stopPropagation();
|
|
96
113
|
}
|
|
114
|
+
if (modifiers.includes("debounce")) {
|
|
115
|
+
clearTimeout(this.debounceTimer);
|
|
116
|
+
this.debounceTimer = window.setTimeout(() => {
|
|
117
|
+
this.executeEffect(targets, effect, event);
|
|
118
|
+
}, this.debounceDelay);
|
|
119
|
+
} else {
|
|
120
|
+
this.executeEffect(targets, effect, event);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Execute the effect for all targets.
|
|
125
|
+
*/
|
|
126
|
+
executeEffect(targets, effect, event) {
|
|
97
127
|
for (const target of targets) {
|
|
98
128
|
try {
|
|
99
129
|
const [currentTarget] = Object.values(target).flat();
|
|
@@ -121,6 +151,7 @@ class ActionEvent {
|
|
|
121
151
|
* Unbind the event from the given Action instance root element.
|
|
122
152
|
*/
|
|
123
153
|
detachEvent() {
|
|
154
|
+
clearTimeout(this.debounceTimer);
|
|
124
155
|
this.action.$el.removeEventListener(this.event, this);
|
|
125
156
|
}
|
|
126
157
|
}
|
|
@@ -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';\n\nexport class ActionEvent<T extends Base> {\n static modifierSeparator = '.';\n static targetSeparator = ' ';\n static effectSeparator = '->';\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 * 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
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,kBAAkB;AAM3B,MAAM,eAAe;AAErB,MAAM,cAAc,oBAAI,IAAsB;AAIvC,MAAM,YAA4B;AAAA,EACvC,OAAO,oBAAoB;AAAA,EAC3B,OAAO,kBAAkB;AAAA,EACzB,OAAO,kBAAkB;AAAA;AAAA;AAAA;AAAA,
|
|
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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/Figure/Figure.twig
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* @param string $alt
|
|
12
12
|
* @param string $caption
|
|
13
13
|
* @param boolean $lazy
|
|
14
|
+
* @param boolean $lazy_fallback
|
|
15
|
+
* Define if a fallback image should be added for SEO purpose.
|
|
14
16
|
* @param 'cover'|'contain'|'fill'|'none' $fit
|
|
15
17
|
* Define how the image will fit.
|
|
16
18
|
* @param boolean $absolute
|
|
@@ -114,6 +116,14 @@
|
|
|
114
116
|
<figure {{ html_attributes(attributes) }}>
|
|
115
117
|
<div {{ html_attributes(inner_attributes) }}>
|
|
116
118
|
<img {{ html_attributes(img_attributes) }} />
|
|
119
|
+
{% if lazy and (lazy_fallback ?? false) %}
|
|
120
|
+
{% set img_noscript_attributes = img_attributes|twig_toolkit_without('data_src', 'data_ref')|merge({
|
|
121
|
+
src: img_attributes.data_src,
|
|
122
|
+
}) %}
|
|
123
|
+
<noscript>
|
|
124
|
+
<img {{ html_attributes(img_noscript_attributes) }}>
|
|
125
|
+
</noscript>
|
|
126
|
+
{% endif %}
|
|
117
127
|
</div>
|
|
118
128
|
{% if caption is defined %}
|
|
119
129
|
{% block caption %}
|
package/Frame/FrameTarget.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';
|
|
|
2
2
|
import { Transition } from '../Transition/index.js';
|
|
3
3
|
export interface FrameTargetProps extends BaseProps {
|
|
4
4
|
$options: {
|
|
5
|
-
mode: 'replace' | 'prepend' | 'append';
|
|
5
|
+
mode: 'replace' | 'prepend' | 'append' | 'morph';
|
|
6
6
|
};
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
@@ -20,6 +20,7 @@ export declare class FrameTarget<T extends BaseProps = BaseProps> extends Transi
|
|
|
20
20
|
readonly APPEND: "append";
|
|
21
21
|
readonly PREPEND: "prepend";
|
|
22
22
|
readonly REPLACE: "replace";
|
|
23
|
+
readonly MORPH: "morph";
|
|
23
24
|
};
|
|
24
25
|
/**
|
|
25
26
|
* Get uniq ID.
|
package/Frame/FrameTarget.js
CHANGED
|
@@ -20,7 +20,8 @@ class FrameTarget extends Transition {
|
|
|
20
20
|
modes = {
|
|
21
21
|
APPEND: "append",
|
|
22
22
|
PREPEND: "prepend",
|
|
23
|
-
REPLACE: "replace"
|
|
23
|
+
REPLACE: "replace",
|
|
24
|
+
MORPH: "morph"
|
|
24
25
|
};
|
|
25
26
|
/**
|
|
26
27
|
* Get uniq ID.
|
|
@@ -36,17 +37,22 @@ class FrameTarget extends Transition {
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
const { mode } = this.$options;
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
const { $el, modes } = this;
|
|
41
|
+
if (mode === modes.APPEND || mode === modes.PREPEND) {
|
|
42
|
+
const leaveTargets = Array.from($el.children);
|
|
41
43
|
const enterTargets = Array.from(content.children);
|
|
42
|
-
|
|
44
|
+
$el[mode](...Array.from(content.childNodes));
|
|
43
45
|
await Promise.all([
|
|
44
46
|
this.leave(leaveTargets),
|
|
45
47
|
this.enter(enterTargets)
|
|
46
48
|
]);
|
|
47
49
|
} else {
|
|
48
50
|
await this.leave();
|
|
49
|
-
|
|
51
|
+
if (mode === modes.MORPH) {
|
|
52
|
+
morphdom($el, content);
|
|
53
|
+
} else {
|
|
54
|
+
$el.replaceChildren(content);
|
|
55
|
+
}
|
|
50
56
|
await this.enter();
|
|
51
57
|
}
|
|
52
58
|
}
|
package/Frame/FrameTarget.js.map
CHANGED
|
@@ -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';\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 } 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\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 ===
|
|
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,
|
|
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 * 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\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\n await Promise.all([\n this.leave(leaveTargets),\n this.enter(enterTargets),\n ]);\n } else {\n await this.leave();\n if (mode === modes.MORPH) {\n morphdom($el, content);\n } else {\n $el.replaceChildren(content);\n }\n await this.enter();\n }\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,MAAM,cAAc,UAAmB,MAAM;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,UAAM,EAAE,KAAK,MAAM,IAAI;AAKvB,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,QAAQ,IAAI;AAAA,QAChB,KAAK,MAAM,YAAY;AAAA,QACvB,KAAK,MAAM,YAAY;AAAA,MACzB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,MAAM;AACjB,UAAI,SAAS,MAAM,OAAO;AACxB,iBAAS,KAAK,OAAO;AAAA,MACvB,OAAO;AACL,YAAI,gBAAgB,OAAO;AAAA,MAC7B;AACA,YAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/Sticky/Sticky.d.ts
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
import { Base } from '@studiometa/js-toolkit';
|
|
2
2
|
import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';
|
|
3
3
|
import { Sentinel } from '../Sentinel/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {object} StickyRefs
|
|
6
|
-
* @property {HTMLElement} inner
|
|
7
|
-
* @property {HTMLElement} sentinelRef
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {object} StickyPrivateInterface
|
|
11
|
-
* @property {StickyRefs} $refs
|
|
12
|
-
* @property {{ zIndex: number, hideWhenUp: boolean, hideWhenDown: boolean }} $options
|
|
13
|
-
* @property {{ Sentinel: Sentinel[] }} $children
|
|
14
|
-
*/
|
|
15
4
|
export interface StickyProps extends BaseProps {
|
|
16
5
|
$refs: {
|
|
17
6
|
inner: HTMLElement;
|
|
18
|
-
sentinelRef: HTMLElement;
|
|
19
7
|
};
|
|
20
8
|
$options: {
|
|
21
9
|
zIndex: number;
|
|
@@ -54,6 +42,10 @@ export declare class Sticky<T extends BaseProps = BaseProps> extends Base<T & St
|
|
|
54
42
|
* Get instances as array.
|
|
55
43
|
*/
|
|
56
44
|
get instances(): Sticky[];
|
|
45
|
+
/**
|
|
46
|
+
* Get the sentinel instance.
|
|
47
|
+
*/
|
|
48
|
+
get sentinel(): Sentinel;
|
|
57
49
|
/**
|
|
58
50
|
* Mounted hook.
|
|
59
51
|
*/
|
package/Sticky/Sticky.js
CHANGED
|
@@ -6,7 +6,7 @@ class Sticky extends Base {
|
|
|
6
6
|
*/
|
|
7
7
|
static config = {
|
|
8
8
|
name: "Sticky",
|
|
9
|
-
refs: ["inner"
|
|
9
|
+
refs: ["inner"],
|
|
10
10
|
components: {
|
|
11
11
|
Sentinel
|
|
12
12
|
},
|
|
@@ -44,6 +44,12 @@ class Sticky extends Base {
|
|
|
44
44
|
get instances() {
|
|
45
45
|
return Array.from(Sticky.instances);
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the sentinel instance.
|
|
49
|
+
*/
|
|
50
|
+
get sentinel() {
|
|
51
|
+
return this.$children.Sentinel[0];
|
|
52
|
+
}
|
|
47
53
|
/**
|
|
48
54
|
* Mounted hook.
|
|
49
55
|
*/
|
|
@@ -117,7 +123,7 @@ class Sticky extends Base {
|
|
|
117
123
|
// Test each instance sticky context against the current element
|
|
118
124
|
(instance) => this.closestRelativeElement(instance.$el).contains(this.$el)
|
|
119
125
|
).reduce((acc, instance) => acc + instance.$el.offsetHeight, 0);
|
|
120
|
-
this.$
|
|
126
|
+
this.sentinel.$el.style.height = `${height + 1}px`;
|
|
121
127
|
this.$el.style.top = `${height}px`;
|
|
122
128
|
this.$el.style.zIndex = String(this.$options.zIndex - index);
|
|
123
129
|
}
|
package/Sticky/Sticky.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/ui/Sticky/Sticky.ts"],
|
|
4
|
-
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { Sentinel } from '../Sentinel/index.js';\n\
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AAErB,SAAS,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { Sentinel } from '../Sentinel/index.js';\n\nexport interface StickyProps extends BaseProps {\n $refs: {\n inner: HTMLElement;\n };\n $options: {\n zIndex: number;\n hideWhenUp: boolean;\n hideWhenDown: boolean;\n };\n $children: {\n Sentinel: Sentinel[];\n };\n}\n\n/**\n * Sticky class.\n */\nexport class Sticky<T extends BaseProps = BaseProps> extends Base<T & StickyProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Sticky',\n refs: ['inner'],\n components: {\n Sentinel,\n },\n options: {\n zIndex: {\n type: Number,\n default: 100,\n },\n hideWhenUp: Boolean,\n hideWhenDown: Boolean,\n },\n };\n\n /**\n * Holder for all instances.\n */\n // eslint-disable-next-line no-use-before-define\n static instances: Set<Sticky> = new Set();\n\n /**\n * Is the component sticky?\n */\n isSticky = false;\n\n /**\n * Is the component visible?\n */\n isVisible = true;\n\n /**\n * Set the Y value.\n */\n set y(value: number) {\n this.$refs.inner.style.transform = `translateY(${value}px) translateZ(0px)`;\n }\n\n /**\n * Get instances as array.\n */\n get instances(): Sticky[] {\n return Array.from(Sticky.instances);\n }\n\n /**\n * Get the sentinel instance.\n */\n get sentinel(): Sentinel {\n return this.$children.Sentinel[0];\n }\n\n /**\n * Mounted hook.\n */\n mounted() {\n Sticky.instances.add(this);\n this.setSentinelSize();\n }\n\n /**\n * Resized hook.\n */\n resized() {\n this.setSentinelSize();\n }\n\n /**\n * Destroyed hook.\n */\n destroyed() {\n Sticky.instances.delete(this);\n }\n\n /**\n * Scrolled hook.\n */\n scrolled(props) {\n if (!this.isSticky || props.y === props.last.y) {\n return;\n }\n\n if (\n (props.direction.y === 'DOWN' && this.$options.hideWhenDown) ||\n (props.direction.y === 'UP' && this.$options.hideWhenUp)\n ) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Listen to the sentinel's `intersected` event to set the `isSticky` value.\n * @param {IntersectionObserverEntry[]} entries\n * @returns {void}\n */\n onSentinelIntersected({ args: [[entry]] }: { args: [IntersectionObserverEntry[]] }) {\n this.isSticky = entry.isIntersecting && entry.boundingClientRect.y < 0;\n this.setPosition();\n }\n\n /**\n * Hide the sticky component when another one is sticky.\n */\n hide() {\n if (!this.isVisible) {\n return;\n }\n\n this.isVisible = false;\n this.$el.classList.add('pointer-events-none');\n\n this.instances.forEach((instance, index) => instance.setPosition(index));\n }\n\n /**\n * Show the sticky component when the other one is not sticky anymore.\n */\n show() {\n if (this.isVisible) {\n return;\n }\n\n this.isVisible = true;\n this.$el.classList.remove('pointer-events-none');\n this.instances.forEach((instance, index) => instance.setPosition(index));\n }\n\n /**\n * Set the sentinel height based on the previous instances.\n */\n setSentinelSize() {\n const { instances } = this;\n const index = instances.indexOf(this);\n const height = instances\n .slice(0, index)\n .filter(\n // Test each instance sticky context against the current element\n (instance) => this.closestRelativeElement(instance.$el).contains(this.$el),\n )\n .reduce((acc, instance) => acc + instance.$el.offsetHeight, 0);\n\n this.sentinel.$el.style.height = `${height + 1}px`;\n this.$el.style.top = `${height}px`;\n this.$el.style.zIndex = String(this.$options.zIndex - index);\n }\n\n /**\n * Set the component's position.\n * @param {number} [index] The instance index in all the pages' instances.\n * @returns {void}\n */\n setPosition(index?: number) {\n if (!this.isSticky) {\n this.y = 0;\n return;\n }\n\n const { instances } = this;\n\n // eslint-disable-next-line no-param-reassign\n index = index ?? instances.indexOf(this);\n\n this.y = instances\n .slice(0, index)\n .filter((instance) => instance.isSticky && !instance.isVisible)\n .reduce<number>(\n (y: number, instance) => y - instance.$refs.inner.offsetHeight,\n this.isVisible ? 0 : this.$refs.inner.offsetHeight * -1,\n ) as number;\n }\n\n /**\n * Find the first parent which has a relative position.\n */\n closestRelativeElement(element: HTMLElement) {\n let parent = element.parentElement;\n\n while (getComputedStyle(parent).position !== 'relative' && parent.parentElement) {\n parent = parent.parentElement;\n }\n\n return parent;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/Sticky/Sticky.twig
CHANGED
|
@@ -13,16 +13,28 @@
|
|
|
13
13
|
*/
|
|
14
14
|
#}
|
|
15
15
|
|
|
16
|
-
{% set
|
|
17
|
-
|
|
16
|
+
{% set attributes =
|
|
17
|
+
merge_html_attributes(
|
|
18
|
+
attr ?? null,
|
|
19
|
+
{
|
|
20
|
+
data_component: 'Sticky',
|
|
21
|
+
class: 'z-10 sticky top-0 w-full'
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
%}
|
|
18
25
|
|
|
19
|
-
{% set
|
|
20
|
-
|
|
26
|
+
{% set inner_attributes =
|
|
27
|
+
merge_html_attributes(
|
|
28
|
+
inner_attr ?? null,
|
|
29
|
+
{
|
|
30
|
+
data_ref: 'inner',
|
|
31
|
+
class: 'transition duration-500 ease-out-expo'
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
%}
|
|
21
35
|
|
|
22
36
|
<div {{ html_attributes(attributes) }}>
|
|
23
|
-
<div data-
|
|
24
|
-
data-component="Sentinel"
|
|
25
|
-
class="absolute bottom-full w-full h-px pointer-events-none"></div>
|
|
37
|
+
<div data-component="Sentinel" class="absolute bottom-full w-full h-px pointer-events-none"></div>
|
|
26
38
|
<div {{ html_attributes(inner_attributes) }}>
|
|
27
39
|
{% block content %}
|
|
28
40
|
{{ content ?? '' }}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studiometa/ui",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.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.0.
|
|
36
|
+
"@studiometa/js-toolkit": "3.0.5"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@studiometa/js-toolkit": "^3.0.
|
|
39
|
+
"@studiometa/js-toolkit": "^3.0.5"
|
|
40
40
|
}
|
|
41
41
|
}
|