@sevenfold/setto-client 0.28.0 → 0.29.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.
|
@@ -18,8 +18,13 @@
|
|
|
18
18
|
* back to nothing.
|
|
19
19
|
*/
|
|
20
20
|
export interface SettoLanguagesProps {
|
|
21
|
-
/**
|
|
22
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Every language the site speaks, primary first. Read from the provider's
|
|
23
|
+
* config when left out, which is what a site should do: the list lives in
|
|
24
|
+
* `setto.config.json` and grows when a customer adds a language in Språk,
|
|
25
|
+
* so a header that hard-codes it goes stale the first time they do.
|
|
26
|
+
*/
|
|
27
|
+
languages?: readonly string[];
|
|
23
28
|
/**
|
|
24
29
|
* Rendered in the flow of the page rather than fixed in a corner.
|
|
25
30
|
*
|
|
@@ -28,7 +33,7 @@ export interface SettoLanguagesProps {
|
|
|
28
33
|
*/
|
|
29
34
|
inline?: boolean;
|
|
30
35
|
}
|
|
31
|
-
export declare function SettoLanguages({ languages, inline }: SettoLanguagesProps): import("react/jsx-runtime").JSX.Element | null;
|
|
36
|
+
export declare function SettoLanguages({ languages: given, inline }: SettoLanguagesProps): import("react/jsx-runtime").JSX.Element | null;
|
|
32
37
|
/**
|
|
33
38
|
* The floating copy, mounted by the provider.
|
|
34
39
|
*
|
|
@@ -22,6 +22,7 @@ type Message = {
|
|
|
22
22
|
export declare function nextWordBoundary(content: string, visibleLength: number): number;
|
|
23
23
|
export declare function sineOut(progress: number): number;
|
|
24
24
|
export declare function isAtChatBottom(scrollHeight: number, scrollTop: number, clientHeight: number): boolean;
|
|
25
|
+
export declare function chatComposerSpace(height: number): number;
|
|
25
26
|
export declare function AgentJoinedEvent({ message }: {
|
|
26
27
|
message: Message;
|
|
27
28
|
}): import("react/jsx-runtime").JSX.Element;
|
package/dist/setto-client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState, useRef, useEffect, useMemo, useId, useInsertionEffect, Children, createContext, useContext, useCallback, useLayoutEffect, useSyncExternalStore, forwardRef, Fragment as Fragment$1 } from "react";
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
@@ -72,235 +72,6 @@ function pickInitialLanguage(available, browserLanguages = typeof navigator ===
|
|
|
72
72
|
}
|
|
73
73
|
return fallback;
|
|
74
74
|
}
|
|
75
|
-
function normalise(pathname) {
|
|
76
|
-
const path2 = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
77
|
-
return path2.length > 1 && path2.endsWith("/") ? path2.slice(0, -1) : path2;
|
|
78
|
-
}
|
|
79
|
-
function languageFromPath(pathname, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
80
|
-
const path2 = normalise(pathname);
|
|
81
|
-
const first = path2.split("/")[1] ?? "";
|
|
82
|
-
const match = languages.find(
|
|
83
|
-
(tag) => tag !== primary && tag.toLowerCase() === first.toLowerCase()
|
|
84
|
-
);
|
|
85
|
-
if (!match) return { language: primary, basename: "", rest: path2 };
|
|
86
|
-
const rest = path2.slice(first.length + 1);
|
|
87
|
-
return { language: match, basename: `/${match}`, rest: rest === "" ? "/" : rest };
|
|
88
|
-
}
|
|
89
|
-
function pathForLanguage(pathname, target, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
90
|
-
const { rest } = languageFromPath(pathname, languages, primary);
|
|
91
|
-
if (target === primary) return rest;
|
|
92
|
-
return rest === "/" ? `/${target}` : `/${target}${rest}`;
|
|
93
|
-
}
|
|
94
|
-
function alternateLinks(origin, pathname, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
95
|
-
if (languages.length < 2) return [];
|
|
96
|
-
const links = languages.map((tag) => ({
|
|
97
|
-
hreflang: tag,
|
|
98
|
-
href: origin + pathForLanguage(pathname, tag, languages, primary)
|
|
99
|
-
}));
|
|
100
|
-
links.push({
|
|
101
|
-
hreflang: "x-default",
|
|
102
|
-
href: origin + pathForLanguage(pathname, primary, languages, primary)
|
|
103
|
-
});
|
|
104
|
-
return links;
|
|
105
|
-
}
|
|
106
|
-
function isReservedPath(pathname) {
|
|
107
|
-
return pathname === "/setto" || pathname.startsWith("/setto/");
|
|
108
|
-
}
|
|
109
|
-
function redirectForVisitor(pathname, languages, browserLanguages, stored, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
110
|
-
if (languages.length < 2) return null;
|
|
111
|
-
if (isReservedPath(pathname)) return null;
|
|
112
|
-
const current = languageFromPath(pathname, languages, primary);
|
|
113
|
-
if (current.basename !== "") return null;
|
|
114
|
-
if (stored) {
|
|
115
|
-
return stored !== primary && languages.includes(stored) ? pathForLanguage(pathname, stored, languages, primary) : null;
|
|
116
|
-
}
|
|
117
|
-
for (const wanted of browserLanguages) {
|
|
118
|
-
const base = wanted.toLowerCase().split("-")[0];
|
|
119
|
-
if (!base) continue;
|
|
120
|
-
if (base === primary.toLowerCase().split("-")[0]) return null;
|
|
121
|
-
const norwegian2 = ["no", "nb", "nn"];
|
|
122
|
-
if (norwegian2.includes(base) && norwegian2.includes(primary.toLowerCase())) return null;
|
|
123
|
-
const hit = languages.find((tag) => tag.toLowerCase().split("-")[0] === base);
|
|
124
|
-
if (hit && hit !== primary) return pathForLanguage(pathname, hit, languages, primary);
|
|
125
|
-
}
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
const INLINE_MARKER = "data-setto-languages-inline";
|
|
129
|
-
function SettoLanguages({ languages, inline = false }) {
|
|
130
|
-
const { i18n } = useTranslation();
|
|
131
|
-
const [open, setOpen] = useState(false);
|
|
132
|
-
const ref = useRef(null);
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (!inline) return;
|
|
135
|
-
const root2 = document.documentElement;
|
|
136
|
-
const count = Number(root2.getAttribute(INLINE_MARKER) ?? "0") + 1;
|
|
137
|
-
root2.setAttribute(INLINE_MARKER, String(count));
|
|
138
|
-
return () => {
|
|
139
|
-
const left = Number(root2.getAttribute(INLINE_MARKER) ?? "1") - 1;
|
|
140
|
-
if (left > 0) root2.setAttribute(INLINE_MARKER, String(left));
|
|
141
|
-
else root2.removeAttribute(INLINE_MARKER);
|
|
142
|
-
};
|
|
143
|
-
}, [inline]);
|
|
144
|
-
useEffect(() => {
|
|
145
|
-
if (!open) return;
|
|
146
|
-
const onDown = (e) => {
|
|
147
|
-
if (!ref.current?.contains(e.target)) setOpen(false);
|
|
148
|
-
};
|
|
149
|
-
const onKey = (e) => {
|
|
150
|
-
if (e.key === "Escape") setOpen(false);
|
|
151
|
-
};
|
|
152
|
-
document.addEventListener("mousedown", onDown);
|
|
153
|
-
document.addEventListener("keydown", onKey);
|
|
154
|
-
return () => {
|
|
155
|
-
document.removeEventListener("mousedown", onDown);
|
|
156
|
-
document.removeEventListener("keydown", onKey);
|
|
157
|
-
};
|
|
158
|
-
}, [open]);
|
|
159
|
-
if (languages.length < 2) return null;
|
|
160
|
-
const current = i18n.language;
|
|
161
|
-
const choose = (tag) => {
|
|
162
|
-
setOpen(false);
|
|
163
|
-
if (tag === current) return;
|
|
164
|
-
storeLanguage(tag);
|
|
165
|
-
const target = pathForLanguage(window.location.pathname, tag, languages);
|
|
166
|
-
window.location.assign(target + window.location.search + window.location.hash);
|
|
167
|
-
};
|
|
168
|
-
return /* @__PURE__ */ jsxs("div", { ref, style: inline ? inlineWrapStyle : floatingWrapStyle, children: [
|
|
169
|
-
/* @__PURE__ */ jsxs(
|
|
170
|
-
"button",
|
|
171
|
-
{
|
|
172
|
-
type: "button",
|
|
173
|
-
onClick: () => setOpen((o) => !o),
|
|
174
|
-
"aria-expanded": open,
|
|
175
|
-
"aria-haspopup": "listbox",
|
|
176
|
-
"aria-label": `Språk: ${languageName(current)}`,
|
|
177
|
-
style: inline ? inlineTriggerStyle : floatingTriggerStyle,
|
|
178
|
-
children: [
|
|
179
|
-
/* @__PURE__ */ jsx(GlobeIcon, {}),
|
|
180
|
-
languageName(current)
|
|
181
|
-
]
|
|
182
|
-
}
|
|
183
|
-
),
|
|
184
|
-
open ? /* @__PURE__ */ jsx("ul", { role: "listbox", style: inline ? inlineListStyle : floatingListStyle, children: languages.map((tag) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
185
|
-
"button",
|
|
186
|
-
{
|
|
187
|
-
type: "button",
|
|
188
|
-
role: "option",
|
|
189
|
-
"aria-selected": tag === current,
|
|
190
|
-
onClick: () => choose(tag),
|
|
191
|
-
style: {
|
|
192
|
-
...optionStyle,
|
|
193
|
-
fontWeight: tag === current ? 600 : 400
|
|
194
|
-
},
|
|
195
|
-
children: languageName(tag)
|
|
196
|
-
}
|
|
197
|
-
) }, tag)) }) : null
|
|
198
|
-
] });
|
|
199
|
-
}
|
|
200
|
-
function AutoLanguageSwitcher({ languages }) {
|
|
201
|
-
const [inlineElsewhere, setInlineElsewhere] = useState(false);
|
|
202
|
-
useEffect(() => {
|
|
203
|
-
const check = () => setInlineElsewhere(document.documentElement.hasAttribute(INLINE_MARKER));
|
|
204
|
-
check();
|
|
205
|
-
const observer = new MutationObserver(check);
|
|
206
|
-
observer.observe(document.documentElement, {
|
|
207
|
-
attributes: true,
|
|
208
|
-
attributeFilter: [INLINE_MARKER]
|
|
209
|
-
});
|
|
210
|
-
return () => observer.disconnect();
|
|
211
|
-
}, []);
|
|
212
|
-
if (inlineElsewhere || languages.length < 2) return null;
|
|
213
|
-
return /* @__PURE__ */ jsx(SettoLanguages, { languages });
|
|
214
|
-
}
|
|
215
|
-
function GlobeIcon() {
|
|
216
|
-
return /* @__PURE__ */ jsxs(
|
|
217
|
-
"svg",
|
|
218
|
-
{
|
|
219
|
-
width: "15",
|
|
220
|
-
height: "15",
|
|
221
|
-
viewBox: "0 0 24 24",
|
|
222
|
-
fill: "none",
|
|
223
|
-
stroke: "currentColor",
|
|
224
|
-
strokeWidth: "1.8",
|
|
225
|
-
strokeLinecap: "round",
|
|
226
|
-
strokeLinejoin: "round",
|
|
227
|
-
"aria-hidden": "true",
|
|
228
|
-
children: [
|
|
229
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
|
|
230
|
-
/* @__PURE__ */ jsx("path", { d: "M3 12h18M12 3c2.4 2.6 3.6 5.6 3.6 9s-1.2 6.4-3.6 9c-2.4-2.6-3.6-5.6-3.6-9S9.6 5.6 12 3z" })
|
|
231
|
-
]
|
|
232
|
-
}
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
const floatingWrapStyle = {
|
|
236
|
-
position: "fixed",
|
|
237
|
-
left: "max(16px, env(safe-area-inset-left))",
|
|
238
|
-
bottom: "max(16px, env(safe-area-inset-bottom))",
|
|
239
|
-
zIndex: 2147482e3,
|
|
240
|
-
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
241
|
-
};
|
|
242
|
-
const inlineWrapStyle = {
|
|
243
|
-
position: "relative",
|
|
244
|
-
display: "inline-block",
|
|
245
|
-
fontFamily: "inherit"
|
|
246
|
-
};
|
|
247
|
-
const triggerBase = {
|
|
248
|
-
display: "inline-flex",
|
|
249
|
-
alignItems: "center",
|
|
250
|
-
gap: 7,
|
|
251
|
-
minHeight: 40,
|
|
252
|
-
fontSize: 13.5,
|
|
253
|
-
fontWeight: 500,
|
|
254
|
-
lineHeight: 1,
|
|
255
|
-
cursor: "pointer"
|
|
256
|
-
};
|
|
257
|
-
const floatingTriggerStyle = {
|
|
258
|
-
...triggerBase,
|
|
259
|
-
padding: "8px 14px",
|
|
260
|
-
borderRadius: 999,
|
|
261
|
-
border: "1px solid rgba(127, 127, 127, 0.32)",
|
|
262
|
-
background: "rgba(255, 255, 255, 0.82)",
|
|
263
|
-
backdropFilter: "blur(8px)",
|
|
264
|
-
WebkitBackdropFilter: "blur(8px)",
|
|
265
|
-
color: "#1a1a1a",
|
|
266
|
-
boxShadow: "0 4px 14px rgba(0, 0, 0, 0.12)"
|
|
267
|
-
};
|
|
268
|
-
const inlineTriggerStyle = {
|
|
269
|
-
...triggerBase,
|
|
270
|
-
padding: "8px 6px",
|
|
271
|
-
border: 0,
|
|
272
|
-
borderRadius: 8,
|
|
273
|
-
background: "transparent",
|
|
274
|
-
color: "inherit",
|
|
275
|
-
opacity: 0.75
|
|
276
|
-
};
|
|
277
|
-
const listBase = {
|
|
278
|
-
position: "absolute",
|
|
279
|
-
margin: 0,
|
|
280
|
-
padding: 4,
|
|
281
|
-
listStyle: "none",
|
|
282
|
-
minWidth: 150,
|
|
283
|
-
borderRadius: 12,
|
|
284
|
-
border: "1px solid rgba(127, 127, 127, 0.24)",
|
|
285
|
-
background: "#ffffff",
|
|
286
|
-
boxShadow: "0 12px 32px rgba(0, 0, 0, 0.18)",
|
|
287
|
-
zIndex: 1
|
|
288
|
-
};
|
|
289
|
-
const floatingListStyle = { ...listBase, left: 0, bottom: "calc(100% + 8px)" };
|
|
290
|
-
const inlineListStyle = { ...listBase, left: 0, top: "calc(100% + 8px)" };
|
|
291
|
-
const optionStyle = {
|
|
292
|
-
display: "block",
|
|
293
|
-
width: "100%",
|
|
294
|
-
minHeight: 40,
|
|
295
|
-
padding: "9px 12px",
|
|
296
|
-
border: 0,
|
|
297
|
-
borderRadius: 8,
|
|
298
|
-
background: "transparent",
|
|
299
|
-
color: "#1a1a1a",
|
|
300
|
-
fontSize: 13.5,
|
|
301
|
-
textAlign: "left",
|
|
302
|
-
cursor: "pointer"
|
|
303
|
-
};
|
|
304
75
|
function __rest(s, e) {
|
|
305
76
|
var t = {};
|
|
306
77
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -21473,6 +21244,59 @@ class I18nStore {
|
|
|
21473
21244
|
for (const fn of this.listeners) fn(this.cachedSnapshot);
|
|
21474
21245
|
}
|
|
21475
21246
|
}
|
|
21247
|
+
function normalise(pathname) {
|
|
21248
|
+
const path2 = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
21249
|
+
return path2.length > 1 && path2.endsWith("/") ? path2.slice(0, -1) : path2;
|
|
21250
|
+
}
|
|
21251
|
+
function languageFromPath(pathname, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
21252
|
+
const path2 = normalise(pathname);
|
|
21253
|
+
const first = path2.split("/")[1] ?? "";
|
|
21254
|
+
const match = languages.find(
|
|
21255
|
+
(tag) => tag !== primary && tag.toLowerCase() === first.toLowerCase()
|
|
21256
|
+
);
|
|
21257
|
+
if (!match) return { language: primary, basename: "", rest: path2 };
|
|
21258
|
+
const rest = path2.slice(first.length + 1);
|
|
21259
|
+
return { language: match, basename: `/${match}`, rest: rest === "" ? "/" : rest };
|
|
21260
|
+
}
|
|
21261
|
+
function pathForLanguage(pathname, target, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
21262
|
+
const { rest } = languageFromPath(pathname, languages, primary);
|
|
21263
|
+
if (target === primary) return rest;
|
|
21264
|
+
return rest === "/" ? `/${target}` : `/${target}${rest}`;
|
|
21265
|
+
}
|
|
21266
|
+
function alternateLinks(origin, pathname, languages, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
21267
|
+
if (languages.length < 2) return [];
|
|
21268
|
+
const links = languages.map((tag) => ({
|
|
21269
|
+
hreflang: tag,
|
|
21270
|
+
href: origin + pathForLanguage(pathname, tag, languages, primary)
|
|
21271
|
+
}));
|
|
21272
|
+
links.push({
|
|
21273
|
+
hreflang: "x-default",
|
|
21274
|
+
href: origin + pathForLanguage(pathname, primary, languages, primary)
|
|
21275
|
+
});
|
|
21276
|
+
return links;
|
|
21277
|
+
}
|
|
21278
|
+
function isReservedPath(pathname) {
|
|
21279
|
+
return pathname === "/setto" || pathname.startsWith("/setto/");
|
|
21280
|
+
}
|
|
21281
|
+
function redirectForVisitor(pathname, languages, browserLanguages, stored, primary = languages[0] ?? DEFAULT_LANGUAGE) {
|
|
21282
|
+
if (languages.length < 2) return null;
|
|
21283
|
+
if (isReservedPath(pathname)) return null;
|
|
21284
|
+
const current = languageFromPath(pathname, languages, primary);
|
|
21285
|
+
if (current.basename !== "") return null;
|
|
21286
|
+
if (stored) {
|
|
21287
|
+
return stored !== primary && languages.includes(stored) ? pathForLanguage(pathname, stored, languages, primary) : null;
|
|
21288
|
+
}
|
|
21289
|
+
for (const wanted of browserLanguages) {
|
|
21290
|
+
const base = wanted.toLowerCase().split("-")[0];
|
|
21291
|
+
if (!base) continue;
|
|
21292
|
+
if (base === primary.toLowerCase().split("-")[0]) return null;
|
|
21293
|
+
const norwegian2 = ["no", "nb", "nn"];
|
|
21294
|
+
if (norwegian2.includes(base) && norwegian2.includes(primary.toLowerCase())) return null;
|
|
21295
|
+
const hit = languages.find((tag) => tag.toLowerCase().split("-")[0] === base);
|
|
21296
|
+
if (hit && hit !== primary) return pathForLanguage(pathname, hit, languages, primary);
|
|
21297
|
+
}
|
|
21298
|
+
return null;
|
|
21299
|
+
}
|
|
21476
21300
|
const SETTO_IMAGE_REPO_DIR = "public/images/setto";
|
|
21477
21301
|
const SETTO_IMAGE_URL_PREFIX = "/images/setto";
|
|
21478
21302
|
const MIME_EXT = {
|
|
@@ -34830,6 +34654,9 @@ function sineOut(progress) {
|
|
|
34830
34654
|
function isAtChatBottom(scrollHeight, scrollTop, clientHeight) {
|
|
34831
34655
|
return scrollHeight - scrollTop - clientHeight <= 4;
|
|
34832
34656
|
}
|
|
34657
|
+
function chatComposerSpace(height) {
|
|
34658
|
+
return Math.max(0, Math.ceil(height)) + 16;
|
|
34659
|
+
}
|
|
34833
34660
|
function createWordRevealer(onReveal) {
|
|
34834
34661
|
let target = "";
|
|
34835
34662
|
let visibleLength = 0;
|
|
@@ -35453,6 +35280,24 @@ function useConversationChannel(supabase, topic, handlers2) {
|
|
|
35453
35280
|
}, [supabase, topic]);
|
|
35454
35281
|
return channelRef;
|
|
35455
35282
|
}
|
|
35283
|
+
function useChatComposerSpace(active, composerRef, logRef) {
|
|
35284
|
+
useEffect(() => {
|
|
35285
|
+
if (!active) return;
|
|
35286
|
+
const composer = composerRef.current;
|
|
35287
|
+
const log = logRef.current;
|
|
35288
|
+
if (!composer || !log) return;
|
|
35289
|
+
const update = () => {
|
|
35290
|
+
log.style.setProperty("--setto-chat-composer-space", `${chatComposerSpace(composer.getBoundingClientRect().height)}px`);
|
|
35291
|
+
};
|
|
35292
|
+
const observer = new ResizeObserver(update);
|
|
35293
|
+
observer.observe(composer);
|
|
35294
|
+
update();
|
|
35295
|
+
return () => {
|
|
35296
|
+
observer.disconnect();
|
|
35297
|
+
log.style.removeProperty("--setto-chat-composer-space");
|
|
35298
|
+
};
|
|
35299
|
+
}, [active, composerRef, logRef]);
|
|
35300
|
+
}
|
|
35456
35301
|
function SettoChat() {
|
|
35457
35302
|
const { config, supabase } = useSetto();
|
|
35458
35303
|
const { i18n } = useTranslation();
|
|
@@ -35477,6 +35322,7 @@ function SettoChat() {
|
|
|
35477
35322
|
const visitor = useRef(null);
|
|
35478
35323
|
const chatRef = useRef(null);
|
|
35479
35324
|
const logRef = useRef(null);
|
|
35325
|
+
const composerShellRef = useRef(null);
|
|
35480
35326
|
const pinToBottomRef = useRef(true);
|
|
35481
35327
|
const programmaticScrollRef = useRef(false);
|
|
35482
35328
|
const filesRef = useRef([]);
|
|
@@ -35531,6 +35377,7 @@ function SettoChat() {
|
|
|
35531
35377
|
useChatViewport(mounted && !desktopPopup, logRef, pinToBottomRef, programmaticScrollRef);
|
|
35532
35378
|
useChatPinTracking(mounted, logRef, pinToBottomRef, programmaticScrollRef);
|
|
35533
35379
|
useChatAutoScroll(mounted, logRef, pinToBottomRef, programmaticScrollRef);
|
|
35380
|
+
useChatComposerSpace(mounted, composerShellRef, logRef);
|
|
35534
35381
|
useChatInputIsolation(Boolean(settings?.enabled), mounted, chatRef, logRef);
|
|
35535
35382
|
const locale = i18n.language || "no";
|
|
35536
35383
|
const isNo = norwegian(locale);
|
|
@@ -35807,6 +35654,29 @@ function SettoChat() {
|
|
|
35807
35654
|
window.addEventListener("keydown", closeOnEscape);
|
|
35808
35655
|
return () => window.removeEventListener("keydown", closeOnEscape);
|
|
35809
35656
|
}, [mounted]);
|
|
35657
|
+
const newestMessageKey = (() => {
|
|
35658
|
+
const newest = messages.at(-1);
|
|
35659
|
+
return newest ? `${messages.length}:${newest.id ?? newest.role}` : "empty";
|
|
35660
|
+
})();
|
|
35661
|
+
useEffect(() => {
|
|
35662
|
+
if (!mounted || newestMessageKey === "empty") return;
|
|
35663
|
+
pinToBottomRef.current = true;
|
|
35664
|
+
let releaseFrame = 0;
|
|
35665
|
+
const frame = window.requestAnimationFrame(() => {
|
|
35666
|
+
const log = logRef.current;
|
|
35667
|
+
if (!log) return;
|
|
35668
|
+
programmaticScrollRef.current = true;
|
|
35669
|
+
log.scrollTop = Math.max(0, log.scrollHeight - log.clientHeight);
|
|
35670
|
+
releaseFrame = window.requestAnimationFrame(() => {
|
|
35671
|
+
programmaticScrollRef.current = false;
|
|
35672
|
+
});
|
|
35673
|
+
});
|
|
35674
|
+
return () => {
|
|
35675
|
+
window.cancelAnimationFrame(frame);
|
|
35676
|
+
window.cancelAnimationFrame(releaseFrame);
|
|
35677
|
+
programmaticScrollRef.current = false;
|
|
35678
|
+
};
|
|
35679
|
+
}, [mounted, newestMessageKey]);
|
|
35810
35680
|
if (!settings || window.location.pathname.startsWith("/setto")) return null;
|
|
35811
35681
|
function show() {
|
|
35812
35682
|
pinToBottomRef.current = true;
|
|
@@ -36111,7 +35981,7 @@ function SettoChat() {
|
|
|
36111
35981
|
] })
|
|
36112
35982
|
}
|
|
36113
35983
|
),
|
|
36114
|
-
/* @__PURE__ */ jsxs("div", { className: "setto-chat__composer-shell", children: [
|
|
35984
|
+
/* @__PURE__ */ jsxs("div", { className: "setto-chat__composer-shell", ref: composerShellRef, children: [
|
|
36115
35985
|
/* @__PURE__ */ jsx(
|
|
36116
35986
|
SiteChatComposer,
|
|
36117
35987
|
{
|
|
@@ -36186,7 +36056,7 @@ function useChatStyles() {
|
|
|
36186
36056
|
.setto-chat{position:fixed;right:max(18px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom));z-index:2147483000;overscroll-behavior:contain;color:var(--setto-chat-ink);font-family:"Archivo Variable",Archivo,system-ui,sans-serif;-webkit-font-smoothing:antialiased}.setto-chat *,.setto-chat *::before,.setto-chat *::after{box-sizing:border-box}.setto-chat button,.setto-chat input,.setto-chat textarea{font:inherit}.setto-chat--mounted{top:0;right:auto;bottom:auto;left:0;width:100vw;height:var(--setto-chat-layout-height,100lvh);overflow:hidden;background:var(--setto-chat-canvas);opacity:0;transition:opacity ${CLOSE_MS}ms ease}.setto-chat--visible{opacity:1}.setto-chat__shell{position:absolute;top:var(--setto-chat-top,0);left:0;width:100%;height:var(--setto-chat-height,100svh);display:flex;overflow:hidden;overscroll-behavior:contain;background:var(--setto-chat-canvas);opacity:0;transform:translateY(12px) scale(.994);transform-origin:center bottom;transition:opacity ${CLOSE_MS}ms ease,transform ${CLOSE_MS}ms cubic-bezier(.16,1,.3,1)}.setto-chat--visible .setto-chat__shell{opacity:1;transform:none}
|
|
36187
36057
|
.setto-chat__scrim{position:absolute;inset:0;z-index:45;border:0;background:rgba(33,23,17,.32);opacity:0;pointer-events:none;transition:opacity 220ms ease}.setto-chat__scrim.is-open{opacity:1;pointer-events:auto}.setto-chat__chats{position:relative;z-index:50;width:min(84vw,280px);height:100%;flex:0 0 280px;padding:1rem .85rem calc(1rem + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:.9rem;background:color-mix(in srgb,var(--setto-chat-crema) 32%,var(--setto-chat-canvas));border-right:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);overflow:hidden}.setto-chat__chats-heading{display:flex;align-items:center;justify-content:space-between;gap:.5rem;min-height:34px;font-size:.66rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent)}.setto-chat__chats-heading button{width:34px;height:34px;padding:0;border:0;border-radius:8px;background:transparent;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.setto-chat__new{display:flex;align-items:center;gap:.55rem;width:100%;padding:.5rem .55rem;border:0;border-radius:8px;background:transparent;color:var(--setto-chat-ink);font-weight:600;font-size:.9rem;text-align:left;cursor:pointer;transition:background 140ms ease}.setto-chat__new:hover{background:color-mix(in srgb,var(--setto-chat-ink) 5%,transparent)}.setto-chat__chat-list{display:flex;flex-direction:column;gap:.1rem;flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;margin-right:-.85rem;padding-right:.3rem}.setto-chat__chat-list p{margin:.35rem .55rem;font-size:.85rem;line-height:1.5;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent)}.setto-chat__chat-row{width:100%;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.4rem;padding:.55rem;border:0;border-radius:8px;background:transparent;color:var(--setto-chat-ink);text-align:left;cursor:pointer}.setto-chat__chat-row:hover,.setto-chat__chat-row.is-active{background:color-mix(in srgb,var(--setto-chat-ink) 7.5%,transparent)}.setto-chat__chat-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.9rem;font-weight:600}.setto-chat__chat-row time{font-size:.72rem;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent)}
|
|
36188
36058
|
.setto-chat__main{position:relative;z-index:1;display:flex;flex:1;min-width:0;max-width:820px;height:100%;margin:0 auto;flex-direction:column;background:var(--setto-chat-canvas)}.setto-chat__header{position:absolute;inset:0 0 auto;z-index:30;min-height:58px;padding:.35rem .75rem;display:flex;align-items:center;gap:.5rem;background:linear-gradient(to bottom,color-mix(in srgb,var(--setto-chat-crema) 88%,transparent),color-mix(in srgb,var(--setto-chat-crema) 72%,transparent));border-bottom:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);backdrop-filter:blur(20px) saturate(150%);-webkit-backdrop-filter:blur(20px) saturate(150%);isolation:isolate}.setto-chat__round-button{flex:none;width:46px;height:46px;padding:0;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);border-radius:50%;background:var(--setto-chat-raised);color:var(--setto-chat-ink);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background 160ms ease,border-color 160ms ease,color 160ms ease}.setto-chat__round-button:hover{background:var(--setto-chat-crema);border-color:var(--setto-chat-accent);color:var(--setto-chat-accent)}.setto-chat__round-button:active{transform:scale(.96)}.setto-chat__brand{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;line-height:1.15;text-align:center}.setto-chat__brand h2{margin:0;color:var(--setto-chat-ink);font-size:1.02rem;font-weight:600;line-height:1.15}.setto-chat__brand p{max-width:100%;margin:2px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:color-mix(in srgb,var(--setto-chat-ink) 56%,transparent);font-size:.78rem;line-height:1.15}
|
|
36189
|
-
.setto-chat__body{position:relative;display:flex;flex:1 1 auto;min-height:0;height:100%;flex-direction:column}.setto-chat__log{display:flex;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;flex-direction:column;padding:calc(58px + 1.3rem) .75rem 8rem;scroll-behavior:auto;-webkit-overflow-scrolling:touch}.setto-chat__message-list{display:flex;flex-direction:column}.setto-chat__message{--setto-chat-bubble:color-mix(in srgb,var(--setto-chat-ink) 7%,var(--setto-chat-canvas));display:flex;align-items:flex-end;gap:.55rem;width:100%;margin-bottom:1rem;color:color-mix(in srgb,var(--setto-chat-ink) 92%,transparent);font-size:16px;line-height:1.5;overflow-wrap:anywhere}.setto-chat__message-stack{display:flex;min-width:0;max-width:min(78%,36rem);flex-direction:column;align-items:flex-start}.setto-chat__message-bubble{position:relative;min-width:2.5rem;padding:.58rem .82rem;border-radius:19px 19px 19px 5px;background:var(--setto-chat-bubble);white-space:pre-wrap}.setto-chat__message--assistant .setto-chat__message-bubble::before,.setto-chat__message--human .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;left:-7px;bottom:0;width:16px;height:17px;border-bottom-right-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--assistant .setto-chat__message-bubble::after,.setto-chat__message--human .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;left:-10px;bottom:0;width:10px;height:18px;border-bottom-right-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message-copy,.setto-chat__image{position:relative;z-index:2}.setto-chat__message--visitor{--setto-chat-bubble:#0a84ff;justify-content:flex-end;color:#fff}.setto-chat__message--visitor .setto-chat__message-stack{align-items:flex-end}.setto-chat__message--visitor .setto-chat__message-bubble{border-radius:19px 19px 5px 19px}.setto-chat__message--visitor .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;right:-7px;bottom:0;width:16px;height:17px;border-bottom-left-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--visitor .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;right:-10px;bottom:0;width:10px;height:18px;border-bottom-left-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message--system{justify-content:center;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent);font-size:.78rem;line-height:1.45;text-align:center}.setto-chat__message--system .setto-chat__message-stack{max-width:85%;align-items:center}.setto-chat__message--system .setto-chat__message-bubble{padding:.25rem .6rem;background:transparent}.setto-chat__avatar{position:relative;z-index:3;display:grid;place-items:center;flex:0 0 34px;width:34px;height:34px;margin-bottom:1px;overflow:hidden;border:2px solid var(--setto-chat-canvas);border-radius:50%;background:var(--setto-chat-crema);color:var(--setto-chat-ink);box-shadow:0 2px 8px color-mix(in srgb,var(--setto-chat-ink) 14%,transparent)}.setto-chat__avatar--assistant{background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__avatar img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__speaker{display:block;margin:0 0 .2rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__typing{display:inline-block;animation:setto-chat-pulse 1s ease-in-out infinite}.setto-chat__image{display:block;width:max-content;max-width:100%;margin-top:.65rem;overflow:hidden;border-radius:13px}.setto-chat__image img{display:block;width:min(280px,100%);max-height:260px;object-fit:cover}
|
|
36059
|
+
.setto-chat__body{position:relative;display:flex;flex:1 1 auto;min-height:0;height:100%;flex-direction:column}.setto-chat__log{display:flex;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;flex-direction:column;padding:calc(58px + 1.3rem) .75rem var(--setto-chat-composer-space,8rem);scroll-padding-bottom:var(--setto-chat-composer-space,8rem);scroll-behavior:auto;-webkit-overflow-scrolling:touch}.setto-chat__message-list{display:flex;flex-direction:column}.setto-chat__message{--setto-chat-bubble:color-mix(in srgb,var(--setto-chat-ink) 7%,var(--setto-chat-canvas));display:flex;align-items:flex-end;gap:.55rem;width:100%;margin-bottom:1rem;color:color-mix(in srgb,var(--setto-chat-ink) 92%,transparent);font-size:16px;line-height:1.5;overflow-wrap:anywhere}.setto-chat__message-stack{display:flex;min-width:0;max-width:min(78%,36rem);flex-direction:column;align-items:flex-start}.setto-chat__message-bubble{position:relative;min-width:2.5rem;padding:.58rem .82rem;border-radius:19px 19px 19px 5px;background:var(--setto-chat-bubble);white-space:pre-wrap}.setto-chat__message--assistant .setto-chat__message-bubble::before,.setto-chat__message--human .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;left:-7px;bottom:0;width:16px;height:17px;border-bottom-right-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--assistant .setto-chat__message-bubble::after,.setto-chat__message--human .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;left:-10px;bottom:0;width:10px;height:18px;border-bottom-right-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message-copy,.setto-chat__image{position:relative;z-index:2}.setto-chat__message--visitor{--setto-chat-bubble:#0a84ff;justify-content:flex-end;color:#fff}.setto-chat__message--visitor .setto-chat__message-stack{align-items:flex-end}.setto-chat__message--visitor .setto-chat__message-bubble{border-radius:19px 19px 5px 19px}.setto-chat__message--visitor .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;right:-7px;bottom:0;width:16px;height:17px;border-bottom-left-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--visitor .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;right:-10px;bottom:0;width:10px;height:18px;border-bottom-left-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message--system{justify-content:center;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent);font-size:.78rem;line-height:1.45;text-align:center}.setto-chat__message--system .setto-chat__message-stack{max-width:85%;align-items:center}.setto-chat__message--system .setto-chat__message-bubble{padding:.25rem .6rem;background:transparent}.setto-chat__avatar{position:relative;z-index:3;display:grid;place-items:center;flex:0 0 34px;width:34px;height:34px;margin-bottom:1px;overflow:hidden;border:2px solid var(--setto-chat-canvas);border-radius:50%;background:var(--setto-chat-crema);color:var(--setto-chat-ink);box-shadow:0 2px 8px color-mix(in srgb,var(--setto-chat-ink) 14%,transparent)}.setto-chat__avatar--assistant{background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__avatar img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__speaker{display:block;margin:0 0 .2rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__typing{display:inline-block;min-width:1.8rem;animation:setto-chat-pulse 1s ease-in-out infinite}.setto-chat__image{display:block;width:max-content;max-width:100%;margin-top:.65rem;overflow:hidden;border-radius:13px}.setto-chat__image img{display:block;width:min(280px,100%);max-height:260px;object-fit:cover}
|
|
36190
36060
|
.setto-chat__message--agent-joined{justify-content:flex-start;align-items:center;gap:.55rem;padding:.1rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 62%,transparent);font-size:.8rem;line-height:1.4;text-align:left}.setto-chat__message--agent-joined .setto-chat__message-stack{max-width:calc(100% - 38px);align-items:flex-start}.setto-chat__message--agent-joined .setto-chat__message-bubble{min-width:0;padding:.2rem 0;background:transparent;white-space:normal}.setto-chat__avatar--joined{flex-basis:30px;width:30px;height:30px;margin:0;border-width:1px;box-shadow:0 2px 7px color-mix(in srgb,var(--setto-chat-ink) 12%,transparent)}
|
|
36191
36061
|
.setto-chat__receipt{display:block;margin:.26rem .45rem 0 0;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__message--typing{animation:setto-chat-typing-in 180ms cubic-bezier(.2,.8,.2,1) both}.setto-chat__message--typing .setto-chat__message-bubble{min-width:3.25rem;text-align:center}.setto-chat__message--typing .setto-chat__typing{font-weight:700;letter-spacing:.06em}@keyframes setto-chat-typing-in{from{opacity:0;transform:translateY(4px)}}@media(prefers-reduced-motion:reduce){.setto-chat__message--typing{animation:none}}
|
|
36192
36062
|
.setto-chat__composer-shell{position:absolute;left:0;right:0;bottom:0;z-index:25;display:grid;grid-template-columns:minmax(0,1fr);padding:1.5rem .75rem 0;background:transparent;isolation:isolate}.setto-chat__composer-shell::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,transparent 0%,color-mix(in srgb,var(--setto-chat-canvas) 82%,transparent) 46%,var(--setto-chat-canvas) 66%);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%);mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%)}.setto-chat__composer{position:relative;z-index:1;display:flex;flex-direction:column;gap:.15rem;width:100%;min-width:0;margin:0;padding:.35rem .4rem;border:2px solid color-mix(in srgb,var(--setto-chat-ink) 10%,transparent);border-radius:24px;background:var(--setto-chat-canvas);box-shadow:0 8px 24px -16px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent);transition:padding 220ms cubic-bezier(.16,1,.3,1),border-color 200ms ease,box-shadow 360ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open{padding:.55rem .5rem}.setto-chat__composer:focus-within{border-color:var(--setto-chat-accent)}.setto-chat__composer textarea,.setto-chat__composer textarea:hover,.setto-chat__composer textarea:focus,.setto-chat__composer textarea:focus-visible{width:100%;min-height:36px;max-height:200px;padding:.45rem .25rem;resize:none;-webkit-appearance:none!important;appearance:none!important;border:0!important;border-radius:0!important;outline:0!important;box-shadow:none!important;background:transparent!important;color:var(--setto-chat-ink);font-family:"Archivo Variable",Archivo,system-ui,sans-serif;font-size:16px;line-height:1.35;transition:min-height 220ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open textarea{min-height:40px}.setto-chat__composer textarea::placeholder{color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent)}.setto-chat__composer-tools{display:flex;align-items:center;gap:.4rem;width:100%;min-width:0}.setto-chat__attach{flex:none;width:34px;height:34px;padding:0;border:0;border-radius:50%;background:transparent;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background 160ms ease,color 160ms ease}.setto-chat__attach:hover:not(:disabled){background:color-mix(in srgb,var(--setto-chat-ink) 6%,transparent);color:var(--setto-chat-ink)}.setto-chat__attach:disabled{opacity:.4;cursor:default}.setto-chat__send{flex:none;width:36px;height:36px;margin-left:auto;padding:0;border:0;border-radius:50%;background:var(--setto-chat-accent);color:var(--setto-chat-raised);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform 360ms cubic-bezier(.16,1,.3,1),box-shadow 360ms cubic-bezier(.16,1,.3,1),background 200ms ease,opacity 200ms ease}.setto-chat__send:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 12px 24px -12px color-mix(in srgb,var(--setto-chat-ink) 45%,transparent)}.setto-chat__send:active:not(:disabled){transform:translateY(0);box-shadow:0 4px 10px -8px color-mix(in srgb,var(--setto-chat-ink) 40%,transparent);transition-duration:90ms}.setto-chat__send:disabled{opacity:.35;cursor:default}.setto-chat__send.is-queued{animation:setto-chat-queued 1.1s ease-in-out infinite}.setto-chat__attachments{display:flex;flex-wrap:wrap;gap:.4rem;list-style:none;margin:0;padding:.15rem .15rem 0}.setto-chat__attachments li{position:relative;width:56px;height:56px;border-radius:10px;overflow:hidden;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);background:var(--setto-chat-crema)}.setto-chat__attachments img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__attachments button{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:0;border-radius:50%;background:color-mix(in srgb,var(--setto-chat-ink) 72%,transparent);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.setto-chat__composer-floor{position:relative;z-index:1;width:calc(100% + 1.5rem);height:max(.35rem,env(safe-area-inset-bottom));margin-left:-.75rem;background:var(--setto-chat-canvas)}
|
|
@@ -36322,6 +36192,219 @@ function useSetto() {
|
|
|
36322
36192
|
}
|
|
36323
36193
|
return ctx;
|
|
36324
36194
|
}
|
|
36195
|
+
const INLINE_MARKER = "data-setto-languages-inline";
|
|
36196
|
+
function SettoLanguages({ languages: given, inline = false }) {
|
|
36197
|
+
const { i18n } = useTranslation();
|
|
36198
|
+
const setto = useContext(SettoContext);
|
|
36199
|
+
const configured = setto?.config.languages;
|
|
36200
|
+
const languages = given ?? siteLanguages(configured, configured?.[0]);
|
|
36201
|
+
const [open, setOpen] = useState(false);
|
|
36202
|
+
const [hover, setHover] = useState(false);
|
|
36203
|
+
const [surface, setSurface] = useState(null);
|
|
36204
|
+
const ref = useRef(null);
|
|
36205
|
+
useEffect(() => {
|
|
36206
|
+
if (!inline) return;
|
|
36207
|
+
const root2 = document.documentElement;
|
|
36208
|
+
const count = Number(root2.getAttribute(INLINE_MARKER) ?? "0") + 1;
|
|
36209
|
+
root2.setAttribute(INLINE_MARKER, String(count));
|
|
36210
|
+
return () => {
|
|
36211
|
+
const left = Number(root2.getAttribute(INLINE_MARKER) ?? "1") - 1;
|
|
36212
|
+
if (left > 0) root2.setAttribute(INLINE_MARKER, String(left));
|
|
36213
|
+
else root2.removeAttribute(INLINE_MARKER);
|
|
36214
|
+
};
|
|
36215
|
+
}, [inline]);
|
|
36216
|
+
useEffect(() => {
|
|
36217
|
+
if (!open) return;
|
|
36218
|
+
const onDown = (e) => {
|
|
36219
|
+
if (!ref.current?.contains(e.target)) setOpen(false);
|
|
36220
|
+
};
|
|
36221
|
+
const onKey = (e) => {
|
|
36222
|
+
if (e.key === "Escape") setOpen(false);
|
|
36223
|
+
};
|
|
36224
|
+
document.addEventListener("mousedown", onDown);
|
|
36225
|
+
document.addEventListener("keydown", onKey);
|
|
36226
|
+
return () => {
|
|
36227
|
+
document.removeEventListener("mousedown", onDown);
|
|
36228
|
+
document.removeEventListener("keydown", onKey);
|
|
36229
|
+
};
|
|
36230
|
+
}, [open]);
|
|
36231
|
+
if (languages.length < 2) return null;
|
|
36232
|
+
const current = i18n.language;
|
|
36233
|
+
const toggle = () => {
|
|
36234
|
+
if (!open && inline && ref.current) setSurface(surroundings(ref.current));
|
|
36235
|
+
setOpen((o) => !o);
|
|
36236
|
+
};
|
|
36237
|
+
const choose = (tag) => {
|
|
36238
|
+
setOpen(false);
|
|
36239
|
+
if (tag === current) return;
|
|
36240
|
+
storeLanguage(tag);
|
|
36241
|
+
const target = pathForLanguage(window.location.pathname, tag, languages);
|
|
36242
|
+
window.location.assign(target + window.location.search + window.location.hash);
|
|
36243
|
+
};
|
|
36244
|
+
return /* @__PURE__ */ jsxs("div", { ref, style: inline ? inlineWrapStyle : floatingWrapStyle, children: [
|
|
36245
|
+
/* @__PURE__ */ jsxs(
|
|
36246
|
+
"button",
|
|
36247
|
+
{
|
|
36248
|
+
type: "button",
|
|
36249
|
+
onClick: toggle,
|
|
36250
|
+
onMouseEnter: () => setHover(true),
|
|
36251
|
+
onMouseLeave: () => setHover(false),
|
|
36252
|
+
"aria-expanded": open,
|
|
36253
|
+
"aria-haspopup": "listbox",
|
|
36254
|
+
"aria-label": `Språk: ${languageName(current)}`,
|
|
36255
|
+
title: inline ? languageName(current) : void 0,
|
|
36256
|
+
style: inline ? { ...inlineTriggerStyle, opacity: hover || open ? 1 : inlineTriggerStyle.opacity } : floatingTriggerStyle,
|
|
36257
|
+
children: [
|
|
36258
|
+
/* @__PURE__ */ jsx(GlobeIcon, {}),
|
|
36259
|
+
inline ? shortCode(current) : languageName(current)
|
|
36260
|
+
]
|
|
36261
|
+
}
|
|
36262
|
+
),
|
|
36263
|
+
open ? /* @__PURE__ */ jsx(
|
|
36264
|
+
"ul",
|
|
36265
|
+
{
|
|
36266
|
+
role: "listbox",
|
|
36267
|
+
style: inline ? { ...inlineListStyle, ...surface ? { background: surface.background, color: surface.color } : {} } : floatingListStyle,
|
|
36268
|
+
children: languages.map((tag) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
36269
|
+
"button",
|
|
36270
|
+
{
|
|
36271
|
+
type: "button",
|
|
36272
|
+
role: "option",
|
|
36273
|
+
"aria-selected": tag === current,
|
|
36274
|
+
onClick: () => choose(tag),
|
|
36275
|
+
style: {
|
|
36276
|
+
...optionStyle,
|
|
36277
|
+
...inline ? { color: "inherit" } : {},
|
|
36278
|
+
fontWeight: tag === current ? 600 : 400
|
|
36279
|
+
},
|
|
36280
|
+
children: languageName(tag)
|
|
36281
|
+
}
|
|
36282
|
+
) }, tag))
|
|
36283
|
+
}
|
|
36284
|
+
) : null
|
|
36285
|
+
] });
|
|
36286
|
+
}
|
|
36287
|
+
function AutoLanguageSwitcher({ languages }) {
|
|
36288
|
+
const [inlineElsewhere, setInlineElsewhere] = useState(false);
|
|
36289
|
+
useEffect(() => {
|
|
36290
|
+
const check = () => setInlineElsewhere(document.documentElement.hasAttribute(INLINE_MARKER));
|
|
36291
|
+
check();
|
|
36292
|
+
const observer = new MutationObserver(check);
|
|
36293
|
+
observer.observe(document.documentElement, {
|
|
36294
|
+
attributes: true,
|
|
36295
|
+
attributeFilter: [INLINE_MARKER]
|
|
36296
|
+
});
|
|
36297
|
+
return () => observer.disconnect();
|
|
36298
|
+
}, []);
|
|
36299
|
+
if (inlineElsewhere || languages.length < 2) return null;
|
|
36300
|
+
return /* @__PURE__ */ jsx(SettoLanguages, { languages });
|
|
36301
|
+
}
|
|
36302
|
+
function shortCode(tag) {
|
|
36303
|
+
return tag.toUpperCase();
|
|
36304
|
+
}
|
|
36305
|
+
function surroundings(el) {
|
|
36306
|
+
const color2 = getComputedStyle(el).color;
|
|
36307
|
+
for (let node2 = el; node2; node2 = node2.parentElement) {
|
|
36308
|
+
const background = getComputedStyle(node2).backgroundColor;
|
|
36309
|
+
if (background && !/^(transparent|rgba\(.*,\s*0\))$/.test(background)) return { background, color: color2 };
|
|
36310
|
+
}
|
|
36311
|
+
return { background: "#ffffff", color: "#1a1a1a" };
|
|
36312
|
+
}
|
|
36313
|
+
function GlobeIcon() {
|
|
36314
|
+
return /* @__PURE__ */ jsxs(
|
|
36315
|
+
"svg",
|
|
36316
|
+
{
|
|
36317
|
+
width: "15",
|
|
36318
|
+
height: "15",
|
|
36319
|
+
viewBox: "0 0 24 24",
|
|
36320
|
+
fill: "none",
|
|
36321
|
+
stroke: "currentColor",
|
|
36322
|
+
strokeWidth: "1.8",
|
|
36323
|
+
strokeLinecap: "round",
|
|
36324
|
+
strokeLinejoin: "round",
|
|
36325
|
+
"aria-hidden": "true",
|
|
36326
|
+
children: [
|
|
36327
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
|
|
36328
|
+
/* @__PURE__ */ jsx("path", { d: "M3 12h18M12 3c2.4 2.6 3.6 5.6 3.6 9s-1.2 6.4-3.6 9c-2.4-2.6-3.6-5.6-3.6-9S9.6 5.6 12 3z" })
|
|
36329
|
+
]
|
|
36330
|
+
}
|
|
36331
|
+
);
|
|
36332
|
+
}
|
|
36333
|
+
const floatingWrapStyle = {
|
|
36334
|
+
position: "fixed",
|
|
36335
|
+
left: "max(16px, env(safe-area-inset-left))",
|
|
36336
|
+
bottom: "max(16px, env(safe-area-inset-bottom))",
|
|
36337
|
+
zIndex: 2147482e3,
|
|
36338
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
36339
|
+
};
|
|
36340
|
+
const inlineWrapStyle = {
|
|
36341
|
+
position: "relative",
|
|
36342
|
+
display: "inline-block",
|
|
36343
|
+
fontFamily: "inherit"
|
|
36344
|
+
};
|
|
36345
|
+
const triggerBase = {
|
|
36346
|
+
display: "inline-flex",
|
|
36347
|
+
alignItems: "center",
|
|
36348
|
+
gap: 7,
|
|
36349
|
+
minHeight: 40,
|
|
36350
|
+
fontSize: 13.5,
|
|
36351
|
+
fontWeight: 500,
|
|
36352
|
+
lineHeight: 1,
|
|
36353
|
+
cursor: "pointer"
|
|
36354
|
+
};
|
|
36355
|
+
const floatingTriggerStyle = {
|
|
36356
|
+
...triggerBase,
|
|
36357
|
+
padding: "8px 14px",
|
|
36358
|
+
borderRadius: 999,
|
|
36359
|
+
border: "1px solid rgba(127, 127, 127, 0.32)",
|
|
36360
|
+
background: "rgba(255, 255, 255, 0.82)",
|
|
36361
|
+
backdropFilter: "blur(8px)",
|
|
36362
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
36363
|
+
color: "#1a1a1a",
|
|
36364
|
+
boxShadow: "0 4px 14px rgba(0, 0, 0, 0.12)"
|
|
36365
|
+
};
|
|
36366
|
+
const inlineTriggerStyle = {
|
|
36367
|
+
...triggerBase,
|
|
36368
|
+
gap: 5,
|
|
36369
|
+
minHeight: 36,
|
|
36370
|
+
padding: "6px 6px",
|
|
36371
|
+
border: 0,
|
|
36372
|
+
borderRadius: 8,
|
|
36373
|
+
background: "transparent",
|
|
36374
|
+
color: "inherit",
|
|
36375
|
+
fontSize: 12,
|
|
36376
|
+
fontWeight: 500,
|
|
36377
|
+
letterSpacing: "0.06em",
|
|
36378
|
+
opacity: 0.7,
|
|
36379
|
+
transition: "opacity 160ms ease"
|
|
36380
|
+
};
|
|
36381
|
+
const listBase = {
|
|
36382
|
+
position: "absolute",
|
|
36383
|
+
margin: 0,
|
|
36384
|
+
padding: 4,
|
|
36385
|
+
listStyle: "none",
|
|
36386
|
+
minWidth: 150,
|
|
36387
|
+
borderRadius: 12,
|
|
36388
|
+
border: "1px solid rgba(127, 127, 127, 0.24)",
|
|
36389
|
+
background: "#ffffff",
|
|
36390
|
+
boxShadow: "0 12px 32px rgba(0, 0, 0, 0.18)",
|
|
36391
|
+
zIndex: 1
|
|
36392
|
+
};
|
|
36393
|
+
const floatingListStyle = { ...listBase, left: 0, bottom: "calc(100% + 8px)" };
|
|
36394
|
+
const inlineListStyle = { ...listBase, right: 0, top: "calc(100% + 8px)" };
|
|
36395
|
+
const optionStyle = {
|
|
36396
|
+
display: "block",
|
|
36397
|
+
width: "100%",
|
|
36398
|
+
minHeight: 40,
|
|
36399
|
+
padding: "9px 12px",
|
|
36400
|
+
border: 0,
|
|
36401
|
+
borderRadius: 8,
|
|
36402
|
+
background: "transparent",
|
|
36403
|
+
color: "#1a1a1a",
|
|
36404
|
+
fontSize: 13.5,
|
|
36405
|
+
textAlign: "left",
|
|
36406
|
+
cursor: "pointer"
|
|
36407
|
+
};
|
|
36325
36408
|
function GuestEditProvider({ children }) {
|
|
36326
36409
|
const { guestEdit, themeStore } = useSetto();
|
|
36327
36410
|
const SectionTools = useSettoChromeSlot("section-toolbar");
|