@folio-agent/widget 0.6.1 → 0.7.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/dist/answer.d.ts +1 -0
- package/dist/answer.js +48 -0
- package/dist/styles.d.ts +1 -1
- package/dist/styles.js +5 -0
- package/dist/widget-element.js +10 -2
- package/package.json +1 -1
package/dist/answer.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderAnswer(text: string): Node[];
|
package/dist/answer.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// handler が返す回答の形式(プレーンテキスト、記法はリンクの [表示する文字](http(s)://…) だけ)を描く。
|
|
2
|
+
// HTML は解釈せず、テキストノードと <a> を組み立てる。形式を守らせるのは handler の check_answer で、
|
|
3
|
+
// ここでは古い handler が URL をそのまま返した場合にだけ、その URL をリンクにする。
|
|
4
|
+
const TOKEN = /\[([^\]\n]+)\]\((https?:\/\/[^\s)]+)\)|https?:\/\/[^\s<>"'()「」『』【】、。]+/g;
|
|
5
|
+
const TRAILING_PUNCTUATION = /[.,;:!?)\]]+$/;
|
|
6
|
+
function isSameOrigin(url) {
|
|
7
|
+
try {
|
|
8
|
+
return new URL(url).origin === window.location.origin;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function link(url, label) {
|
|
15
|
+
const a = document.createElement("a");
|
|
16
|
+
a.href = url;
|
|
17
|
+
a.textContent = label;
|
|
18
|
+
// サイト内(Contact など)は訪問者がいまいるタブで開き、外部だけ新しいタブにする
|
|
19
|
+
if (!isSameOrigin(url)) {
|
|
20
|
+
a.target = "_blank";
|
|
21
|
+
a.rel = "noopener noreferrer";
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
}
|
|
25
|
+
export function renderAnswer(text) {
|
|
26
|
+
const nodes = [];
|
|
27
|
+
let last = 0;
|
|
28
|
+
for (const match of text.matchAll(TOKEN)) {
|
|
29
|
+
const start = match.index;
|
|
30
|
+
let end = start + match[0].length;
|
|
31
|
+
let node;
|
|
32
|
+
if (match[1] !== undefined && match[2] !== undefined) {
|
|
33
|
+
node = link(match[2], match[1]);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const url = match[0].replace(TRAILING_PUNCTUATION, "");
|
|
37
|
+
end = start + url.length;
|
|
38
|
+
node = link(url, url);
|
|
39
|
+
}
|
|
40
|
+
if (start > last)
|
|
41
|
+
nodes.push(document.createTextNode(text.slice(last, start)));
|
|
42
|
+
nodes.push(node);
|
|
43
|
+
last = end;
|
|
44
|
+
}
|
|
45
|
+
if (last < text.length)
|
|
46
|
+
nodes.push(document.createTextNode(text.slice(last)));
|
|
47
|
+
return nodes;
|
|
48
|
+
}
|
package/dist/styles.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const WIDGET_STYLES = "\n :host {\n all: initial;\n color: inherit;\n color-scheme: inherit;\n font-family: var(--folio-agent-font, inherit);\n\n --_surface: var(--folio-agent-surface, Canvas);\n --_text: var(--folio-agent-text, CanvasText);\n --_accent: var(--folio-agent-accent, var(--_text));\n --_accent-contrast: var(--folio-agent-accent-contrast, var(--_surface));\n --_muted: var(--folio-agent-muted, color-mix(in srgb, var(--_text) 62%, var(--_surface)));\n --_hair: color-mix(in srgb, var(--_text) 12%, transparent);\n --_glass: color-mix(in srgb, var(--_surface) 76%, transparent);\n --_glass-strong: color-mix(in srgb, var(--_surface) 94%, transparent);\n --_field: color-mix(in srgb, var(--_text) 5%, color-mix(in srgb, var(--_surface) 80%, transparent));\n --_chip: color-mix(in srgb, var(--_surface) 60%, transparent);\n --_focus: color-mix(in srgb, var(--_accent) 70%, var(--_text));\n }\n * {\n box-sizing: border-box;\n }\n button,\n textarea {\n font: inherit;\n }\n svg {\n display: block;\n }\n /* \u30DB\u30B9\u30C8\u5074\u306E ::selection \u306F Shadow DOM \u306E\u4E2D\u3078\u5C4A\u304B\u306A\u3044\u306E\u3067\u3001\u3053\u3053\u3067 accent \u304B\u3089\u4F5C\u308B\u3002\n \u6307\u5B9A\u3057\u306A\u3044\u3068\u30D6\u30E9\u30A6\u30B6\u65E2\u5B9A\u306E\u9752\u306B\u306A\u308A\u3001\u30B5\u30A4\u30C8\u306E\u914D\u8272\u304B\u3089\u6D6E\u304F */\n ::selection {\n background: color-mix(in srgb, var(--_accent) 32%, transparent);\n color: var(--_text);\n }\n\n .toggle {\n position: fixed;\n right: 20px;\n bottom: calc(20px + env(safe-area-inset-bottom, 0px));\n z-index: 2147483000;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 46px;\n padding: 0 18px 0 14px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--_accent-contrast) 14%, transparent);\n background: color-mix(in srgb, var(--_accent) 88%, transparent);\n -webkit-backdrop-filter: blur(16px) saturate(1.6);\n backdrop-filter: blur(16px) saturate(1.6);\n color: var(--_accent-contrast);\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 10px 30px rgba(16, 20, 28, 0.22);\n transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.2s ease;\n }\n .toggle:hover {\n transform: translateY(-1px);\n }\n .toggle:active {\n transform: scale(0.97);\n }\n .toggle svg {\n width: 20px;\n height: 20px;\n flex: none;\n }\n .root.open .toggle {\n opacity: 0;\n transform: scale(0.85);\n pointer-events: none;\n }\n\n .panel {\n position: fixed;\n right: 20px;\n bottom: calc(20px + env(safe-area-inset-bottom, 0px));\n z-index: 2147483001;\n width: min(400px, calc(100vw - 40px));\n height: min(620px, calc(100dvh - 40px));\n display: flex;\n flex-direction: column;\n border-radius: 22px;\n border: 1px solid var(--_hair);\n background: var(--_glass);\n -webkit-backdrop-filter: blur(28px) saturate(1.8);\n backdrop-filter: blur(28px) saturate(1.8);\n box-shadow: 0 24px 64px rgba(16, 20, 28, 0.2), 0 2px 6px rgba(16, 20, 28, 0.08);\n color: var(--_text);\n overflow: hidden;\n transform-origin: calc(100% - 40px) calc(100% - 20px);\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px) scale(0.9);\n transition:\n opacity 0.2s ease,\n transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),\n visibility 0s linear 0.32s;\n }\n .root.open .panel {\n opacity: 1;\n visibility: visible;\n transform: none;\n transition:\n opacity 0.22s ease,\n transform 0.38s cubic-bezier(0.2, 0.9, 0.25, 1.05),\n visibility 0s;\n }\n\n .header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 14px 12px 12px 18px;\n border-bottom: 1px solid var(--_hair);\n }\n .titles {\n flex: 1;\n min-width: 0;\n }\n .heading {\n font-size: 15px;\n font-weight: 700;\n line-height: 1.3;\n }\n .subheading {\n font-size: 12px;\n line-height: 1.4;\n color: var(--_muted);\n }\n .close,\n .reset {\n flex: none;\n display: grid;\n place-items: center;\n width: 34px;\n height: 34px;\n border: 0;\n border-radius: 50%;\n background: color-mix(in srgb, var(--_text) 7%, transparent);\n color: var(--_text);\n cursor: pointer;\n }\n .reset {\n background: transparent;\n color: var(--_muted);\n }\n .reset[hidden] {\n display: none;\n }\n .close:hover,\n .reset:hover {\n background: color-mix(in srgb, var(--_text) 12%, transparent);\n }\n .close svg,\n .reset svg {\n width: 16px;\n height: 16px;\n }\n\n .messages {\n flex: 1;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 18px 18px 8px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n font-size: 15px;\n line-height: 1.7;\n }\n .message,\n .greeting {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n animation: fade-in 0.28s ease both;\n }\n .message.assistant,\n .greeting {\n align-self: stretch;\n }\n .message.user {\n align-self: flex-end;\n max-width: 85%;\n padding: 8px 14px;\n border-radius: 18px 18px 6px 18px;\n background: color-mix(in srgb, var(--_accent) 14%, var(--_surface));\n border: 1px solid color-mix(in srgb, var(--_accent) 28%, var(--_surface));\n }\n @keyframes fade-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n }\n\n .suggestions {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .suggestions button {\n padding: 7px 14px;\n border: 1px solid var(--_hair);\n border-radius: 999px;\n background: var(--_chip);\n color: var(--_text);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n .suggestions button:hover {\n background: color-mix(in srgb, var(--_text) 8%, transparent);\n }\n\n .typing {\n display: inline-flex;\n gap: 5px;\n padding: 8px 0;\n }\n .typing span {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--_muted);\n animation: typing-dot 1.1s ease-in-out infinite;\n }\n .typing span:nth-child(2) {\n animation-delay: 0.15s;\n }\n .typing span:nth-child(3) {\n animation-delay: 0.3s;\n }\n @keyframes typing-dot {\n 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n }\n\n form {\n padding: 8px 12px calc(10px + env(safe-area-inset-bottom, 0px));\n }\n .field {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 6px 6px 6px 14px;\n border: 1px solid var(--_hair);\n border-radius: 22px;\n background: var(--_field);\n transition: border-color 0.15s ease;\n }\n .field:focus-within {\n border-color: color-mix(in srgb, var(--_text) 32%, transparent);\n }\n textarea {\n flex: 1;\n min-width: 0;\n max-height: 144px;\n padding: 6px 0;\n border: 0;\n outline: 0;\n resize: none;\n background: transparent;\n color: var(--_text);\n caret-color: var(--_accent);\n /* 16px \u672A\u6E80\u3060\u3068 iOS Safari \u304C\u30D5\u30A9\u30FC\u30AB\u30B9\u6642\u306B\u30DA\u30FC\u30B8\u3092\u62E1\u5927\u3059\u308B */\n font-size: 16px;\n line-height: 1.5;\n }\n textarea::placeholder {\n color: var(--_muted);\n }\n .send {\n flex: none;\n display: grid;\n place-items: center;\n width: 34px;\n height: 34px;\n border: 0;\n border-radius: 50%;\n background: var(--_accent);\n color: var(--_accent-contrast);\n cursor: pointer;\n transition: opacity 0.15s ease, transform 0.15s ease;\n }\n .send:disabled {\n opacity: 0.25;\n cursor: default;\n }\n .send:not(:disabled):active {\n transform: scale(0.92);\n }\n .send svg {\n width: 18px;\n height: 18px;\n }\n .disclosure {\n margin: 8px 0 0;\n font-size: 11px;\n line-height: 1.5;\n text-align: center;\n color: var(--_muted);\n }\n .disclosure a {\n color: inherit;\n }\n\n .toggle:focus-visible,\n .close:focus-visible,\n .reset:focus-visible,\n .send:focus-visible,\n .suggestions button:focus-visible {\n outline: 2px solid var(--_focus);\n outline-offset: 2px;\n }\n\n @media (max-width: 640px) {\n .toggle {\n right: 16px;\n bottom: calc(16px + env(safe-area-inset-bottom, 0px));\n }\n /* \u9AD8\u3055\u3068\u4E0A\u7AEF\u306F visualViewport \u304B\u3089 JS \u304C\u6D41\u3057\u8FBC\u3080\u3002\u30AD\u30FC\u30DC\u30FC\u30C9\u8868\u793A\u4E2D\u3082\u5165\u529B\u6B04\u3092\u898B\u3048\u308B\u4F4D\u7F6E\u306B\u4FDD\u3064\u305F\u3081 */\n .panel {\n top: var(--vv-top, 0px);\n right: 0;\n bottom: auto;\n left: 0;\n width: 100%;\n height: var(--vv-height, 100dvh);\n border: 0;\n border-radius: 0;\n background: var(--_glass-strong);\n transform-origin: 50% 100%;\n transform: translateY(32px);\n }\n .header {\n padding-top: calc(12px + env(safe-area-inset-top, 0px));\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .toggle,\n .panel,\n .root.open .panel {\n transform: none;\n }\n .panel {\n transition: opacity 0.15s linear, visibility 0s linear 0.15s;\n }\n .root.open .panel {\n transition: opacity 0.15s linear;\n }\n .message,\n .greeting,\n .typing span {\n animation: none;\n }\n }\n";
|
|
1
|
+
export declare const WIDGET_STYLES = "\n :host {\n all: initial;\n color: inherit;\n color-scheme: inherit;\n font-family: var(--folio-agent-font, inherit);\n\n --_surface: var(--folio-agent-surface, Canvas);\n --_text: var(--folio-agent-text, CanvasText);\n --_accent: var(--folio-agent-accent, var(--_text));\n --_accent-contrast: var(--folio-agent-accent-contrast, var(--_surface));\n --_muted: var(--folio-agent-muted, color-mix(in srgb, var(--_text) 62%, var(--_surface)));\n --_hair: color-mix(in srgb, var(--_text) 12%, transparent);\n --_glass: color-mix(in srgb, var(--_surface) 76%, transparent);\n --_glass-strong: color-mix(in srgb, var(--_surface) 94%, transparent);\n --_field: color-mix(in srgb, var(--_text) 5%, color-mix(in srgb, var(--_surface) 80%, transparent));\n --_chip: color-mix(in srgb, var(--_surface) 60%, transparent);\n --_focus: color-mix(in srgb, var(--_accent) 70%, var(--_text));\n }\n * {\n box-sizing: border-box;\n }\n button,\n textarea {\n font: inherit;\n }\n svg {\n display: block;\n }\n /* \u30DB\u30B9\u30C8\u5074\u306E ::selection \u306F Shadow DOM \u306E\u4E2D\u3078\u5C4A\u304B\u306A\u3044\u306E\u3067\u3001\u3053\u3053\u3067 accent \u304B\u3089\u4F5C\u308B\u3002\n \u6307\u5B9A\u3057\u306A\u3044\u3068\u30D6\u30E9\u30A6\u30B6\u65E2\u5B9A\u306E\u9752\u306B\u306A\u308A\u3001\u30B5\u30A4\u30C8\u306E\u914D\u8272\u304B\u3089\u6D6E\u304F */\n ::selection {\n background: color-mix(in srgb, var(--_accent) 32%, transparent);\n color: var(--_text);\n }\n\n .toggle {\n position: fixed;\n right: 20px;\n bottom: calc(20px + env(safe-area-inset-bottom, 0px));\n z-index: 2147483000;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 46px;\n padding: 0 18px 0 14px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--_accent-contrast) 14%, transparent);\n background: color-mix(in srgb, var(--_accent) 88%, transparent);\n -webkit-backdrop-filter: blur(16px) saturate(1.6);\n backdrop-filter: blur(16px) saturate(1.6);\n color: var(--_accent-contrast);\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 10px 30px rgba(16, 20, 28, 0.22);\n transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.2s ease;\n }\n .toggle:hover {\n transform: translateY(-1px);\n }\n .toggle:active {\n transform: scale(0.97);\n }\n .toggle svg {\n width: 20px;\n height: 20px;\n flex: none;\n }\n .root.open .toggle {\n opacity: 0;\n transform: scale(0.85);\n pointer-events: none;\n }\n\n .panel {\n position: fixed;\n right: 20px;\n bottom: calc(20px + env(safe-area-inset-bottom, 0px));\n z-index: 2147483001;\n width: min(400px, calc(100vw - 40px));\n height: min(620px, calc(100dvh - 40px));\n display: flex;\n flex-direction: column;\n border-radius: 22px;\n border: 1px solid var(--_hair);\n background: var(--_glass);\n -webkit-backdrop-filter: blur(28px) saturate(1.8);\n backdrop-filter: blur(28px) saturate(1.8);\n box-shadow: 0 24px 64px rgba(16, 20, 28, 0.2), 0 2px 6px rgba(16, 20, 28, 0.08);\n color: var(--_text);\n overflow: hidden;\n transform-origin: calc(100% - 40px) calc(100% - 20px);\n opacity: 0;\n visibility: hidden;\n transform: translateY(10px) scale(0.9);\n transition:\n opacity 0.2s ease,\n transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),\n visibility 0s linear 0.32s;\n }\n .root.open .panel {\n opacity: 1;\n visibility: visible;\n transform: none;\n transition:\n opacity 0.22s ease,\n transform 0.38s cubic-bezier(0.2, 0.9, 0.25, 1.05),\n visibility 0s;\n }\n\n .header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 14px 12px 12px 18px;\n border-bottom: 1px solid var(--_hair);\n }\n .titles {\n flex: 1;\n min-width: 0;\n }\n .heading {\n font-size: 15px;\n font-weight: 700;\n line-height: 1.3;\n }\n .subheading {\n font-size: 12px;\n line-height: 1.4;\n color: var(--_muted);\n }\n .close,\n .reset {\n flex: none;\n display: grid;\n place-items: center;\n width: 34px;\n height: 34px;\n border: 0;\n border-radius: 50%;\n background: color-mix(in srgb, var(--_text) 7%, transparent);\n color: var(--_text);\n cursor: pointer;\n }\n .reset {\n background: transparent;\n color: var(--_muted);\n }\n .reset[hidden] {\n display: none;\n }\n .close:hover,\n .reset:hover {\n background: color-mix(in srgb, var(--_text) 12%, transparent);\n }\n .close svg,\n .reset svg {\n width: 16px;\n height: 16px;\n }\n\n .messages {\n flex: 1;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 18px 18px 8px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n font-size: 15px;\n line-height: 1.7;\n }\n .message,\n .greeting {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n animation: fade-in 0.28s ease both;\n }\n .message.assistant,\n .greeting {\n align-self: stretch;\n }\n .message a {\n color: inherit;\n text-decoration-color: color-mix(in srgb, var(--_accent) 70%, transparent);\n text-underline-offset: 2px;\n }\n .message.user {\n align-self: flex-end;\n max-width: 85%;\n padding: 8px 14px;\n border-radius: 18px 18px 6px 18px;\n background: color-mix(in srgb, var(--_accent) 14%, var(--_surface));\n border: 1px solid color-mix(in srgb, var(--_accent) 28%, var(--_surface));\n }\n @keyframes fade-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n }\n\n .suggestions {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .suggestions button {\n padding: 7px 14px;\n border: 1px solid var(--_hair);\n border-radius: 999px;\n background: var(--_chip);\n color: var(--_text);\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n .suggestions button:hover {\n background: color-mix(in srgb, var(--_text) 8%, transparent);\n }\n\n .typing {\n display: inline-flex;\n gap: 5px;\n padding: 8px 0;\n }\n .typing span {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--_muted);\n animation: typing-dot 1.1s ease-in-out infinite;\n }\n .typing span:nth-child(2) {\n animation-delay: 0.15s;\n }\n .typing span:nth-child(3) {\n animation-delay: 0.3s;\n }\n @keyframes typing-dot {\n 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n }\n\n form {\n padding: 8px 12px calc(10px + env(safe-area-inset-bottom, 0px));\n }\n .field {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 6px 6px 6px 14px;\n border: 1px solid var(--_hair);\n border-radius: 22px;\n background: var(--_field);\n transition: border-color 0.15s ease;\n }\n .field:focus-within {\n border-color: color-mix(in srgb, var(--_text) 32%, transparent);\n }\n textarea {\n flex: 1;\n min-width: 0;\n max-height: 144px;\n padding: 6px 0;\n border: 0;\n outline: 0;\n resize: none;\n background: transparent;\n color: var(--_text);\n caret-color: var(--_accent);\n /* 16px \u672A\u6E80\u3060\u3068 iOS Safari \u304C\u30D5\u30A9\u30FC\u30AB\u30B9\u6642\u306B\u30DA\u30FC\u30B8\u3092\u62E1\u5927\u3059\u308B */\n font-size: 16px;\n line-height: 1.5;\n }\n textarea::placeholder {\n color: var(--_muted);\n }\n .send {\n flex: none;\n display: grid;\n place-items: center;\n width: 34px;\n height: 34px;\n border: 0;\n border-radius: 50%;\n background: var(--_accent);\n color: var(--_accent-contrast);\n cursor: pointer;\n transition: opacity 0.15s ease, transform 0.15s ease;\n }\n .send:disabled {\n opacity: 0.25;\n cursor: default;\n }\n .send:not(:disabled):active {\n transform: scale(0.92);\n }\n .send svg {\n width: 18px;\n height: 18px;\n }\n .disclosure {\n margin: 8px 0 0;\n font-size: 11px;\n line-height: 1.5;\n text-align: center;\n color: var(--_muted);\n }\n .disclosure a {\n color: inherit;\n }\n\n .toggle:focus-visible,\n .close:focus-visible,\n .reset:focus-visible,\n .send:focus-visible,\n .suggestions button:focus-visible {\n outline: 2px solid var(--_focus);\n outline-offset: 2px;\n }\n\n @media (max-width: 640px) {\n .toggle {\n right: 16px;\n bottom: calc(16px + env(safe-area-inset-bottom, 0px));\n }\n /* \u9AD8\u3055\u3068\u4E0A\u7AEF\u306F visualViewport \u304B\u3089 JS \u304C\u6D41\u3057\u8FBC\u3080\u3002\u30AD\u30FC\u30DC\u30FC\u30C9\u8868\u793A\u4E2D\u3082\u5165\u529B\u6B04\u3092\u898B\u3048\u308B\u4F4D\u7F6E\u306B\u4FDD\u3064\u305F\u3081 */\n .panel {\n top: var(--vv-top, 0px);\n right: 0;\n bottom: auto;\n left: 0;\n width: 100%;\n height: var(--vv-height, 100dvh);\n border: 0;\n border-radius: 0;\n background: var(--_glass-strong);\n transform-origin: 50% 100%;\n transform: translateY(32px);\n }\n .header {\n padding-top: calc(12px + env(safe-area-inset-top, 0px));\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .toggle,\n .panel,\n .root.open .panel {\n transform: none;\n }\n .panel {\n transition: opacity 0.15s linear, visibility 0s linear 0.15s;\n }\n .root.open .panel {\n transition: opacity 0.15s linear;\n }\n .message,\n .greeting,\n .typing span {\n animation: none;\n }\n }\n";
|
package/dist/styles.js
CHANGED
|
@@ -188,6 +188,11 @@ export const WIDGET_STYLES = `
|
|
|
188
188
|
.greeting {
|
|
189
189
|
align-self: stretch;
|
|
190
190
|
}
|
|
191
|
+
.message a {
|
|
192
|
+
color: inherit;
|
|
193
|
+
text-decoration-color: color-mix(in srgb, var(--_accent) 70%, transparent);
|
|
194
|
+
text-underline-offset: 2px;
|
|
195
|
+
}
|
|
191
196
|
.message.user {
|
|
192
197
|
align-self: flex-end;
|
|
193
198
|
max-width: 85%;
|
package/dist/widget-element.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { renderAnswer } from "./answer.js";
|
|
1
2
|
import { WIDGET_STYLES } from "./styles.js";
|
|
2
3
|
const WIDGET_TEXT = {
|
|
3
4
|
ja: {
|
|
@@ -120,8 +121,12 @@ export class FolioAgentWidgetElement extends HTMLElement {
|
|
|
120
121
|
const titles = element("div", "titles");
|
|
121
122
|
const headingEl = element("div", "heading");
|
|
122
123
|
headingEl.textContent = heading;
|
|
124
|
+
// 学習元の説明は導入サイトごとに違い、リンクも含めたいので、属性ではなく slot で受ける
|
|
123
125
|
const subheading = element("div", "subheading");
|
|
124
|
-
|
|
126
|
+
const subheadingSlot = element("slot");
|
|
127
|
+
subheadingSlot.name = "subheading";
|
|
128
|
+
subheadingSlot.textContent = this.#text.subheadingText;
|
|
129
|
+
subheading.appendChild(subheadingSlot);
|
|
125
130
|
titles.append(headingEl, subheading);
|
|
126
131
|
const close = element("button", "close");
|
|
127
132
|
close.type = "button";
|
|
@@ -367,7 +372,10 @@ export class FolioAgentWidgetElement extends HTMLElement {
|
|
|
367
372
|
if (!this.#messagesEl)
|
|
368
373
|
return;
|
|
369
374
|
const el = element("div", `message ${message.role}`);
|
|
370
|
-
|
|
375
|
+
if (message.role === "assistant")
|
|
376
|
+
el.append(...renderAnswer(message.text));
|
|
377
|
+
else
|
|
378
|
+
el.textContent = message.text;
|
|
371
379
|
this.#messagesEl.appendChild(el);
|
|
372
380
|
this.#scrollToEnd();
|
|
373
381
|
}
|