@studiometa/ui 1.3.0 → 1.4.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/AnchorNav/AnchorNavLink.d.ts +1 -1
- package/Button/StyledButton.twig +4 -3
- package/Fetch/Fetch.d.ts +133 -0
- package/Fetch/Fetch.js +275 -0
- package/Fetch/Fetch.js.map +7 -0
- package/Fetch/index.d.ts +1 -0
- package/Fetch/index.js +2 -0
- package/Fetch/index.js.map +7 -0
- package/Fetch/utils.d.ts +3 -0
- package/Fetch/utils.js +28 -0
- package/Fetch/utils.js.map +7 -0
- package/Frame/FrameTarget.d.ts +0 -6
- package/Frame/FrameTarget.js +7 -27
- package/Frame/FrameTarget.js.map +2 -2
- package/Menu/MenuList.d.ts +1 -1
- package/Modal/Modal.twig +3 -3
- package/Panel/Panel.js +4 -2
- package/Panel/Panel.js.map +2 -2
- package/Panel/Panel.twig +2 -2
- package/ScrollAnimation/ScrollAnimationChildWithEase.d.ts +1 -1
- package/ScrollAnimation/ScrollAnimationWithEase.d.ts +1 -1
- package/Slider/SliderDots.d.ts +1 -1
- package/Transition/Transition.d.ts +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +2 -2
- package/package.json +3 -3
|
@@ -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("
|
|
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
|
*/
|
package/Button/StyledButton.twig
CHANGED
|
@@ -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-
|
|
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
|
|
47
|
+
'ring ring-inset ring-2 ring-black/25 dark:ring-white/25',
|
|
47
48
|
{
|
|
48
|
-
'hover:ring-
|
|
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
|
] %}
|
package/Fetch/Fetch.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
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
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Fetch modes enum.
|
|
43
|
+
*/
|
|
44
|
+
static FETCH_MODES: {
|
|
45
|
+
readonly REPLACE: "replace";
|
|
46
|
+
readonly PREPEND: "prepend";
|
|
47
|
+
readonly APPEND: "append";
|
|
48
|
+
readonly MORPH: "morph";
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Config.
|
|
52
|
+
*/
|
|
53
|
+
static config: BaseConfig;
|
|
54
|
+
/**
|
|
55
|
+
* Header names used by the requestInit property.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
__headerNames: {
|
|
59
|
+
readonly ACCEPT: "accept";
|
|
60
|
+
readonly X_REQUESTED_BY: "x-requested-by";
|
|
61
|
+
readonly X_TRIGGERED_BY: "x-triggered-by";
|
|
62
|
+
readonly USER_AGENT: "user-agent";
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* DOM Parser to parse the new content to be injected.
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
__domParser: DOMParser;
|
|
69
|
+
/**
|
|
70
|
+
* Abort controller to prevent multiple simultaneous fetches.
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
__abortController: AbortController;
|
|
74
|
+
/**
|
|
75
|
+
* The client used for the fetch request.
|
|
76
|
+
*/
|
|
77
|
+
get client(): typeof fetch;
|
|
78
|
+
/**
|
|
79
|
+
* The URL to use for the request.
|
|
80
|
+
*/
|
|
81
|
+
get url(): URL;
|
|
82
|
+
/**
|
|
83
|
+
* Option for the fetch request.
|
|
84
|
+
*/
|
|
85
|
+
get requestInit(): RequestInit;
|
|
86
|
+
/**
|
|
87
|
+
* Is the root element a link?
|
|
88
|
+
*/
|
|
89
|
+
get isLink(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Is the root element a form?
|
|
92
|
+
*/
|
|
93
|
+
get isForm(): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Emit bubbling events.
|
|
96
|
+
* @inheritdoc
|
|
97
|
+
*/
|
|
98
|
+
$emit(event: string, ...args: unknown[]): void;
|
|
99
|
+
/**
|
|
100
|
+
* If root element is a link, prevent its default behavior and fetch its URL.
|
|
101
|
+
*/
|
|
102
|
+
onClick({ event }: {
|
|
103
|
+
event: MouseEvent;
|
|
104
|
+
}): void;
|
|
105
|
+
/**
|
|
106
|
+
* If root element is a form, prevent its default behavior on submit and fetch its action
|
|
107
|
+
* following the `method` attribute and with the form's data.
|
|
108
|
+
*/
|
|
109
|
+
onSubmit({ event }: {
|
|
110
|
+
event: SubmitEvent;
|
|
111
|
+
}): void;
|
|
112
|
+
/**
|
|
113
|
+
* Update content on history back/forward navigation.
|
|
114
|
+
*/
|
|
115
|
+
onWindowPopstate(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Fetch given url.
|
|
118
|
+
*/
|
|
119
|
+
fetch(url: URL, requestInit?: RequestInit): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Update the DOM with new content from the fetched HTML.
|
|
122
|
+
* @internal
|
|
123
|
+
*/
|
|
124
|
+
__updateDOM(fragment: Document): void;
|
|
125
|
+
/**
|
|
126
|
+
* Dispatch the contents to update to their matching FrameTarget.
|
|
127
|
+
*/
|
|
128
|
+
update(url: URL, requestInit: RequestInit, content: string): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Handle errors.
|
|
131
|
+
*/
|
|
132
|
+
error(url: URL, requestInit: RequestInit, error: Error): void;
|
|
133
|
+
}
|
package/Fetch/Fetch.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
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
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Fetch modes enum.
|
|
20
|
+
*/
|
|
21
|
+
static FETCH_MODES = {
|
|
22
|
+
REPLACE: "replace",
|
|
23
|
+
PREPEND: "prepend",
|
|
24
|
+
APPEND: "append",
|
|
25
|
+
MORPH: "morph"
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Config.
|
|
29
|
+
*/
|
|
30
|
+
static config = {
|
|
31
|
+
name: "Fetch",
|
|
32
|
+
emits: Object.values(this.FETCH_EVENTS),
|
|
33
|
+
refs: ["headers[]"],
|
|
34
|
+
options: {
|
|
35
|
+
history: Boolean,
|
|
36
|
+
mode: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: this.FETCH_MODES.REPLACE
|
|
39
|
+
},
|
|
40
|
+
requestInit: Object,
|
|
41
|
+
headers: Object,
|
|
42
|
+
selector: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: "[id]"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Header names used by the requestInit property.
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
__headerNames = {
|
|
53
|
+
ACCEPT: "accept",
|
|
54
|
+
X_REQUESTED_BY: "x-requested-by",
|
|
55
|
+
X_TRIGGERED_BY: "x-triggered-by",
|
|
56
|
+
USER_AGENT: "user-agent"
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* DOM Parser to parse the new content to be injected.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
__domParser = new DOMParser();
|
|
63
|
+
/**
|
|
64
|
+
* Abort controller to prevent multiple simultaneous fetches.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
__abortController = new AbortController();
|
|
68
|
+
/**
|
|
69
|
+
* The client used for the fetch request.
|
|
70
|
+
*/
|
|
71
|
+
get client() {
|
|
72
|
+
return window.fetch.bind(window);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The URL to use for the request.
|
|
76
|
+
*/
|
|
77
|
+
get url() {
|
|
78
|
+
const { $el, isForm } = this;
|
|
79
|
+
if (isForm) {
|
|
80
|
+
const { action, method } = this.$el;
|
|
81
|
+
const url = new URL(action);
|
|
82
|
+
if (method.toLowerCase() === "get") {
|
|
83
|
+
url.search = new URLSearchParams(new FormData($el)).toString();
|
|
84
|
+
}
|
|
85
|
+
return url;
|
|
86
|
+
}
|
|
87
|
+
return new URL($el.href);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Option for the fetch request.
|
|
91
|
+
*/
|
|
92
|
+
get requestInit() {
|
|
93
|
+
const { __headerNames: headerNames, isForm, $el, $options, $refs } = this;
|
|
94
|
+
const { requestInit, headers } = $options;
|
|
95
|
+
const { headers: headerRefs } = $refs;
|
|
96
|
+
const requestedBy = "@studiometa/ui/Fetch";
|
|
97
|
+
const normalizedRequestInit = {
|
|
98
|
+
...requestInit,
|
|
99
|
+
headers: {
|
|
100
|
+
[headerNames.USER_AGENT]: `${navigator.userAgent} ${requestedBy}`,
|
|
101
|
+
...requestInit.headers,
|
|
102
|
+
...headers
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if (headerRefs) {
|
|
106
|
+
for (const header of headerRefs) {
|
|
107
|
+
if (header.dataset.name && header.value) {
|
|
108
|
+
normalizedRequestInit.headers[header.dataset.name] = header.value;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (isForm) {
|
|
113
|
+
const form = $el;
|
|
114
|
+
normalizedRequestInit.method = form.method;
|
|
115
|
+
normalizedRequestInit.body = new FormData(form);
|
|
116
|
+
}
|
|
117
|
+
return normalizedRequestInit;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Is the root element a link?
|
|
121
|
+
*/
|
|
122
|
+
get isLink() {
|
|
123
|
+
return this.$el instanceof HTMLAnchorElement;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Is the root element a form?
|
|
127
|
+
*/
|
|
128
|
+
get isForm() {
|
|
129
|
+
return this.$el instanceof HTMLFormElement;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Emit bubbling events.
|
|
133
|
+
* @inheritdoc
|
|
134
|
+
*/
|
|
135
|
+
$emit(event, ...args) {
|
|
136
|
+
const e = new CustomEvent(event, { detail: args, bubbles: true });
|
|
137
|
+
return super.$emit(e, ...args);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* If root element is a link, prevent its default behavior and fetch its URL.
|
|
141
|
+
*/
|
|
142
|
+
onClick({ event }) {
|
|
143
|
+
if (!this.isLink) return;
|
|
144
|
+
if (!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey && event.button === 0 && this.$el.target !== "_blank") {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
this.fetch(this.url, this.requestInit);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* If root element is a form, prevent its default behavior on submit and fetch its action
|
|
151
|
+
* following the `method` attribute and with the form's data.
|
|
152
|
+
*/
|
|
153
|
+
onSubmit({ event }) {
|
|
154
|
+
if (!this.isForm) return;
|
|
155
|
+
if (this.$el.target !== "_blank") {
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
this.fetch(this.url, this.requestInit);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Update content on history back/forward navigation.
|
|
162
|
+
*/
|
|
163
|
+
onWindowPopstate() {
|
|
164
|
+
if (!this.$options.history) return;
|
|
165
|
+
this.fetch(new URL(window.location.href), {
|
|
166
|
+
headers: {
|
|
167
|
+
[this.__headerNames.X_TRIGGERED_BY]: "popstate"
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Fetch given url.
|
|
173
|
+
*/
|
|
174
|
+
async fetch(url, requestInit = {}) {
|
|
175
|
+
const { FETCH_EVENTS } = this.constructor;
|
|
176
|
+
this.$emit(FETCH_EVENTS.BEFORE_FETCH, this, url, requestInit);
|
|
177
|
+
this.__abortController.abort();
|
|
178
|
+
this.__abortController = new AbortController();
|
|
179
|
+
const init = {
|
|
180
|
+
...this.requestInit,
|
|
181
|
+
...requestInit,
|
|
182
|
+
headers: {
|
|
183
|
+
...this.requestInit.headers,
|
|
184
|
+
...requestInit.headers
|
|
185
|
+
},
|
|
186
|
+
signal: this.__abortController.signal
|
|
187
|
+
};
|
|
188
|
+
this.$log("fetch", url, init);
|
|
189
|
+
this.$emit(FETCH_EVENTS.FETCH, this, url, requestInit);
|
|
190
|
+
try {
|
|
191
|
+
const content = await this.client(url, init).then((response) => response.text());
|
|
192
|
+
this.$emit(FETCH_EVENTS.AFTER_FETCH, this, url, requestInit, content);
|
|
193
|
+
this.update(url, init, content);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
this.$emit(FETCH_EVENTS.AFTER_FETCH, this, url, requestInit);
|
|
196
|
+
this.error(url, init, error);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Update the DOM with new content from the fetched HTML.
|
|
201
|
+
* @internal
|
|
202
|
+
*/
|
|
203
|
+
__updateDOM(fragment) {
|
|
204
|
+
const { FETCH_MODES } = this.constructor;
|
|
205
|
+
const { mode, selector } = this.$options;
|
|
206
|
+
for (const newElement of fragment.querySelectorAll(selector)) {
|
|
207
|
+
const oldElement = document.querySelector(
|
|
208
|
+
`[id="${newElement.id}"]`
|
|
209
|
+
);
|
|
210
|
+
if (!oldElement) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const oldScripts = getScripts(oldElement);
|
|
214
|
+
switch (mode) {
|
|
215
|
+
case FETCH_MODES.APPEND:
|
|
216
|
+
oldElement.append(...newElement.childNodes);
|
|
217
|
+
adoptNewScripts(getScripts(oldElement), oldScripts);
|
|
218
|
+
break;
|
|
219
|
+
case FETCH_MODES.PREPEND:
|
|
220
|
+
oldElement.prepend(...newElement.childNodes);
|
|
221
|
+
adoptNewScripts(getScripts(oldElement), oldScripts);
|
|
222
|
+
break;
|
|
223
|
+
case FETCH_MODES.MORPH:
|
|
224
|
+
morphdom(oldElement, newElement);
|
|
225
|
+
adoptNewScripts(getScripts(oldElement), oldScripts);
|
|
226
|
+
break;
|
|
227
|
+
case FETCH_MODES.REPLACE:
|
|
228
|
+
default:
|
|
229
|
+
oldElement.replaceWith(newElement);
|
|
230
|
+
adoptNewScripts(getScripts(newElement), oldScripts);
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Dispatch the contents to update to their matching FrameTarget.
|
|
237
|
+
*/
|
|
238
|
+
async update(url, requestInit, content) {
|
|
239
|
+
const { FETCH_EVENTS } = this.constructor;
|
|
240
|
+
const { history } = this.$options;
|
|
241
|
+
this.$log("content", url, content);
|
|
242
|
+
this.$emit(FETCH_EVENTS.BEFORE_UPDATE, this, url, requestInit, content);
|
|
243
|
+
const fragment = this.__domParser.parseFromString(content, "text/html");
|
|
244
|
+
if (history) {
|
|
245
|
+
if (requestInit?.headers?.[this.__headerNames.X_TRIGGERED_BY] !== "popstate") {
|
|
246
|
+
historyPush({ path: url.pathname, search: url.searchParams });
|
|
247
|
+
}
|
|
248
|
+
domScheduler.write(() => {
|
|
249
|
+
if (fragment.title) {
|
|
250
|
+
document.title = fragment.title;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
this.$emit(FETCH_EVENTS.UPDATE, this, url, requestInit, fragment);
|
|
255
|
+
if (isFunction(document.startViewTransition)) {
|
|
256
|
+
await document.startViewTransition(() => {
|
|
257
|
+
this.__updateDOM(fragment);
|
|
258
|
+
}).ready;
|
|
259
|
+
} else {
|
|
260
|
+
this.__updateDOM(fragment);
|
|
261
|
+
}
|
|
262
|
+
this.$emit(FETCH_EVENTS.AFTER_UPDATE, this, url, requestInit, fragment);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Handle errors.
|
|
266
|
+
*/
|
|
267
|
+
error(url, requestInit, error) {
|
|
268
|
+
this.$log("error", url, requestInit, error);
|
|
269
|
+
this.$emit(this.constructor.FETCH_EVENTS.ERROR, this, url, requestInit, error);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export {
|
|
273
|
+
Fetch
|
|
274
|
+
};
|
|
275
|
+
//# 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 } 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 * The client used for the fetch request.\n */\n get client(): typeof fetch {\n return 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 if (headerRefs) {\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\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, this, url, requestInit);\n\n this.__abortController.abort();\n this.__abortController = new AbortController();\n const init = {\n ...this.requestInit,\n ...requestInit,\n headers: {\n ...this.requestInit.headers,\n ...requestInit.headers,\n },\n signal: this.__abortController.signal,\n };\n\n this.$log('fetch', url, init);\n this.$emit(FETCH_EVENTS.FETCH, this, url, requestInit);\n\n try {\n const content = await this.client(url, init).then((response) => response.text());\n this.$emit(FETCH_EVENTS.AFTER_FETCH, this, url, requestInit, content);\n this.update(url, init, content);\n } catch (error) {\n this.$emit(FETCH_EVENTS.AFTER_FETCH, this, url, requestInit);\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: HTMLElement = document.querySelector<HTMLElement>(\n `[id=\"${newElement.id}\"]`,\n );\n\n if (!oldElement) {\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, 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, 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, this, url, requestInit, fragment);\n }\n\n /**\n * Handle errors.\n */\n error(url: URL, requestInit: RequestInit, error: Error) {\n this.$log('error', url, requestInit, error);\n this.$emit(this.constructor.FETCH_EVENTS.ERROR, this, url, requestInit, error);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/Fetch/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Fetch.js';
|
package/Fetch/index.js
ADDED
package/Fetch/utils.d.ts
ADDED
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
|
+
}
|
package/Frame/FrameTarget.d.ts
CHANGED
|
@@ -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
|
}
|
package/Frame/FrameTarget.js
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
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
|
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' | '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 *
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;
|
|
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
|
}
|
package/Menu/MenuList.d.ts
CHANGED
|
@@ -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("
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
package/Panel/Panel.js.map
CHANGED
|
@@ -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-
|
|
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-
|
|
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("
|
|
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("
|
|
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
|
*/
|
package/Slider/SliderDots.d.ts
CHANGED
|
@@ -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("
|
|
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("
|
|
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
|
+
"version": "1.4.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.
|
|
36
|
+
"@studiometa/js-toolkit": "3.4.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@studiometa/js-toolkit": "^3.
|
|
39
|
+
"@studiometa/js-toolkit": "^3.4.0"
|
|
40
40
|
}
|
|
41
41
|
}
|