@clubmed/trident-ui 2.0.0-beta.57 → 2.0.0-beta.58
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/examples/advanced-toast-demo.js +2 -2
- package/examples/advanced-toast-demo.js.map +1 -1
- package/examples/advanced-toast-green-demo.js +1 -1
- package/examples/advanced-toast-green-demo.js.map +1 -1
- package/examples/advanced-toast-no-dismiss-demo.js +1 -1
- package/examples/advanced-toast-no-dismiss-demo.js.map +1 -1
- package/examples/advanced-toast-red-demo.js +1 -1
- package/examples/advanced-toast-red-demo.js.map +1 -1
- package/examples/advanced-toast-with-details-demo.js +2 -2
- package/examples/advanced-toast-with-details-demo.js.map +1 -1
- package/examples/chat-window-quote-demo.d.ts +1 -0
- package/examples/chat-window-quote-demo.js +47 -0
- package/examples/chat-window-quote-demo.js.map +1 -0
- package/examples/chat-window-quotes-demo.d.ts +1 -0
- package/examples/chat-window-quotes-demo.js +67 -0
- package/examples/chat-window-quotes-demo.js.map +1 -0
- package/package.json +1 -1
- package/ui/AdvancedToast.js +7 -4
- package/ui/AdvancedToast.js.map +1 -1
- package/ui/ChatWindow.d.ts +4 -1
- package/ui/ChatWindow.js +68 -57
- package/ui/ChatWindow.js.map +1 -1
- package/ui/ChatWindowQuote.d.ts +22 -0
- package/ui/ChatWindowQuote.js +141 -0
- package/ui/ChatWindowQuote.js.map +1 -0
|
@@ -11,14 +11,14 @@ function l() {
|
|
|
11
11
|
n.custom((r) => /* @__PURE__ */ s(t, {
|
|
12
12
|
title: "Upload Complete",
|
|
13
13
|
body: "Your file has been successfully uploaded",
|
|
14
|
-
icon: "
|
|
14
|
+
icon: "CheckFilled",
|
|
15
15
|
isVisible: r.visible,
|
|
16
16
|
labels: {
|
|
17
17
|
close: "Close",
|
|
18
18
|
details: "Details"
|
|
19
19
|
},
|
|
20
20
|
onClose: () => n.dismiss(r.id),
|
|
21
|
-
accentColor: e.
|
|
21
|
+
accentColor: e.green,
|
|
22
22
|
toastId: r.id,
|
|
23
23
|
updateHeight: l.updateHeight
|
|
24
24
|
}), { duration: Infinity });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced-toast-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Upload Complete\"\n body=\"Your file has been successfully uploaded\"\n icon=\"
|
|
1
|
+
{"version":3,"file":"advanced-toast-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Upload Complete\"\n body=\"Your file has been successfully uploaded\"\n icon=\"CheckFilled\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.green}\n toastId={t.id}\n updateHeight={handlers.updateHeight}\n />\n ),\n { duration: Infinity },\n );\n };\n\n return (\n <>\n <Toaster {...(getHotToastConfig() as ToasterProps)} />\n <button onClick={showToast}>Show Toast</button>\n </>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,IAAoB;CAC1C,IAAM,EAAE,gBAAa,GAAY,EAE3B,UAAkB;AACtB,IAAM,QACH,MACC,kBAAC,GAAD;GACE,OAAM;GACN,MAAK;GACL,MAAK;GACL,WAAW,EAAE;GACb,QAAQ;IAAE,OAAO;IAAS,SAAS;IAAW;GAC9C,eAAe,EAAM,QAAQ,EAAE,GAAG;GAClC,aAAa,EAAO;GACpB,SAAS,EAAE;GACX,cAAc,EAAS;GACvB,CAAA,EAEJ,EAAE,UAAU,UAAU,CACvB;;AAGH,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,GAAK,GAAmB,EAAqB,CAAA,EACtD,kBAAC,UAAD;EAAQ,SAAS;YAAW;EAAmB,CAAA,CAC9C,EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced-toast-green-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-green-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastGreenDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Success!\"\n body=\"Your changes have been saved successfully\"\n icon=\"
|
|
1
|
+
{"version":3,"file":"advanced-toast-green-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-green-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastGreenDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Success!\"\n body=\"Your changes have been saved successfully\"\n icon=\"CheckFilled\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.green}\n toastId={t.id}\n updateHeight={handlers.updateHeight}\n />\n ),\n { duration: Infinity },\n );\n };\n\n return (\n <>\n <Toaster {...(getHotToastConfig() as ToasterProps)} />\n <button onClick={showToast}>Show Toast</button>\n </>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,IAAyB;CAC/C,IAAM,EAAE,gBAAa,GAAY,EAE3B,UAAkB;AACtB,IAAM,QACH,MACC,kBAAC,GAAD;GACE,OAAM;GACN,MAAK;GACL,MAAK;GACL,WAAW,EAAE;GACb,QAAQ;IAAE,OAAO;IAAS,SAAS;IAAW;GAC9C,eAAe,EAAM,QAAQ,EAAE,GAAG;GAClC,aAAa,EAAO;GACpB,SAAS,EAAE;GACX,cAAc,EAAS;GACvB,CAAA,EAEJ,EAAE,UAAU,UAAU,CACvB;;AAGH,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,GAAK,GAAmB,EAAqB,CAAA,EACtD,kBAAC,UAAD;EAAQ,SAAS;YAAW;EAAmB,CAAA,CAC9C,EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced-toast-no-dismiss-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-no-dismiss-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastNoDismissDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Important Notice\"\n body=\"This notification will not auto-dismiss\"\n icon=\"Trident\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.
|
|
1
|
+
{"version":3,"file":"advanced-toast-no-dismiss-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-no-dismiss-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastNoDismissDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Important Notice\"\n body=\"This notification will not auto-dismiss\"\n icon=\"Trident\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.darkGrey}\n duration={false}\n toastId={t.id}\n updateHeight={handlers.updateHeight}\n />\n ),\n { duration: Infinity },\n );\n };\n\n return (\n <>\n <Toaster {...(getHotToastConfig() as ToasterProps)} />\n <button onClick={showToast}>Show Toast</button>\n </>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,IAA6B;CACnD,IAAM,EAAE,gBAAa,GAAY,EAE3B,UAAkB;AACtB,IAAM,QACH,MACC,kBAAC,GAAD;GACE,OAAM;GACN,MAAK;GACL,MAAK;GACL,WAAW,EAAE;GACb,QAAQ;IAAE,OAAO;IAAS,SAAS;IAAW;GAC9C,eAAe,EAAM,QAAQ,EAAE,GAAG;GAClC,aAAa,EAAO;GACpB,UAAU;GACV,SAAS,EAAE;GACX,cAAc,EAAS;GACvB,CAAA,EAEJ,EAAE,UAAU,UAAU,CACvB;;AAGH,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,GAAK,GAAmB,EAAqB,CAAA,EACtD,kBAAC,UAAD;EAAQ,SAAS;YAAW;EAAmB,CAAA,CAC9C,EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced-toast-red-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-red-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastRedDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Error\"\n body=\"Something went wrong. Please try again.\"\n icon=\"
|
|
1
|
+
{"version":3,"file":"advanced-toast-red-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-red-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastRedDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Error\"\n body=\"Something went wrong. Please try again.\"\n icon=\"Error\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.red}\n toastId={t.id}\n updateHeight={handlers.updateHeight}\n />\n ),\n { duration: Infinity },\n );\n };\n\n return (\n <>\n <Toaster {...(getHotToastConfig() as ToasterProps)} />\n <button onClick={showToast}>Show Toast</button>\n </>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,IAAuB;CAC7C,IAAM,EAAE,gBAAa,GAAY,EAE3B,UAAkB;AACtB,IAAM,QACH,MACC,kBAAC,GAAD;GACE,OAAM;GACN,MAAK;GACL,MAAK;GACL,WAAW,EAAE;GACb,QAAQ;IAAE,OAAO;IAAS,SAAS;IAAW;GAC9C,eAAe,EAAM,QAAQ,EAAE,GAAG;GAClC,aAAa,EAAO;GACpB,SAAS,EAAE;GACX,cAAc,EAAS;GACvB,CAAA,EAEJ,EAAE,UAAU,UAAU,CACvB;;AAGH,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,GAAK,GAAmB,EAAqB,CAAA,EACtD,kBAAC,UAAD;EAAQ,SAAS;YAAW;EAAmB,CAAA,CAC9C,EAAA,CAAA"}
|
|
@@ -11,14 +11,14 @@ function l() {
|
|
|
11
11
|
n.custom((r) => /* @__PURE__ */ s(t, {
|
|
12
12
|
title: "Upload Complete",
|
|
13
13
|
body: "Your file has been successfully uploaded",
|
|
14
|
-
icon: "
|
|
14
|
+
icon: "CheckFilled",
|
|
15
15
|
isVisible: r.visible,
|
|
16
16
|
labels: {
|
|
17
17
|
close: "Close",
|
|
18
18
|
details: "Details"
|
|
19
19
|
},
|
|
20
20
|
onClose: () => n.dismiss(r.id),
|
|
21
|
-
accentColor: e.
|
|
21
|
+
accentColor: e.green,
|
|
22
22
|
toastId: r.id,
|
|
23
23
|
updateHeight: l.updateHeight,
|
|
24
24
|
children: /* @__PURE__ */ c("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced-toast-with-details-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-with-details-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastWithDetailsDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Upload Complete\"\n body=\"Your file has been successfully uploaded\"\n icon=\"
|
|
1
|
+
{"version":3,"file":"advanced-toast-with-details-demo.js","names":[],"sources":["../../lib/examples/advanced-toast-with-details-demo.tsx"],"sourcesContent":["'use client';\n\nimport { AdvancedToast } from '@/ui/AdvancedToast';\nimport { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';\nimport { getHotToastConfig } from '@/ui/AdvancedToast.config';\nimport { Colors } from '@/ui/helpers/colors/colors';\n\nexport default function AdvancedToastWithDetailsDemo() {\n const { handlers } = useToaster();\n\n const showToast = () => {\n toast.custom(\n (t) => (\n <AdvancedToast\n title=\"Upload Complete\"\n body=\"Your file has been successfully uploaded\"\n icon=\"CheckFilled\"\n isVisible={t.visible}\n labels={{ close: 'Close', details: 'Details' }}\n onClose={() => toast.dismiss(t.id)}\n accentColor={Colors.green}\n toastId={t.id}\n updateHeight={handlers.updateHeight}\n >\n <div className=\"text-b4\">\n <p>File: document.pdf</p>\n <p>Size: 2.5 MB</p>\n <p>Uploaded at: {new Date().toLocaleTimeString()}</p>\n </div>\n </AdvancedToast>\n ),\n { duration: Infinity },\n );\n };\n\n return (\n <>\n <Toaster {...(getHotToastConfig() as ToasterProps)} />\n <button onClick={showToast}>Show Toast</button>\n </>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,IAA+B;CACrD,IAAM,EAAE,gBAAa,GAAY,EAE3B,UAAkB;AACtB,IAAM,QACH,MACC,kBAAC,GAAD;GACE,OAAM;GACN,MAAK;GACL,MAAK;GACL,WAAW,EAAE;GACb,QAAQ;IAAE,OAAO;IAAS,SAAS;IAAW;GAC9C,eAAe,EAAM,QAAQ,EAAE,GAAG;GAClC,aAAa,EAAO;GACpB,SAAS,EAAE;GACX,cAAc,EAAS;aAEvB,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD,EAAA,UAAG,sBAAsB,CAAA;KACzB,kBAAC,KAAD,EAAA,UAAG,gBAAgB,CAAA;KACnB,kBAAC,KAAD,EAAA,UAAA,CAAG,kCAAc,IAAI,MAAM,EAAC,oBAAoB,CAAK,EAAA,CAAA;;;GAEzC,CAAA,EAElB,EAAE,UAAU,UAAU,CACvB;;AAGH,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,GAAK,GAAmB,EAAqB,CAAA,EACtD,kBAAC,UAAD;EAAQ,SAAS;YAAW;EAAmB,CAAA,CAC9C,EAAA,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function ChatWindowQuoteDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ChatWindowQuote as e } from "../ui/ChatWindowQuote.js";
|
|
3
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
+
//#region lib/examples/chat-window-quote-demo.tsx
|
|
5
|
+
var r = {
|
|
6
|
+
id: "1",
|
|
7
|
+
resortName: "Cancún",
|
|
8
|
+
country: "Mexico",
|
|
9
|
+
imageUrl: "https://picsum.photos/seed/cancun/400/300",
|
|
10
|
+
dateRange: "15 June 2026 to 24 June 2026",
|
|
11
|
+
pax: "for 2 adults 2 children",
|
|
12
|
+
packageIncludes: [
|
|
13
|
+
"Meals and snacks at any time",
|
|
14
|
+
"Drinks, alcoholic and non-alcoholic",
|
|
15
|
+
"Sports and activities"
|
|
16
|
+
],
|
|
17
|
+
additionalInfo: "You can customise your transport and room category directly on the website."
|
|
18
|
+
}, i = {
|
|
19
|
+
id: "2",
|
|
20
|
+
resortName: "Punta Cana",
|
|
21
|
+
country: "Dominican Republic",
|
|
22
|
+
imageUrl: "https://picsum.photos/seed/puntacana/400/300",
|
|
23
|
+
dateRange: "20 July 2026 to 29 July 2026",
|
|
24
|
+
pax: "for 2 adults 2 children"
|
|
25
|
+
};
|
|
26
|
+
function a() {
|
|
27
|
+
return /* @__PURE__ */ n("div", {
|
|
28
|
+
className: "flex flex-col gap-32 w-340",
|
|
29
|
+
children: [/* @__PURE__ */ n("div", {
|
|
30
|
+
className: "flex flex-col gap-8",
|
|
31
|
+
children: [/* @__PURE__ */ t("p", {
|
|
32
|
+
className: "text-b4 font-semibold text-black",
|
|
33
|
+
children: "Single quote"
|
|
34
|
+
}), /* @__PURE__ */ t(e, { quotes: [r] })]
|
|
35
|
+
}), /* @__PURE__ */ n("div", {
|
|
36
|
+
className: "flex flex-col gap-8",
|
|
37
|
+
children: [/* @__PURE__ */ t("p", {
|
|
38
|
+
className: "text-b4 font-semibold text-black",
|
|
39
|
+
children: "Multiple quotes"
|
|
40
|
+
}), /* @__PURE__ */ t(e, { quotes: [r, i] })]
|
|
41
|
+
})]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { a as default };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=chat-window-quote-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-window-quote-demo.js","names":[],"sources":["../../lib/examples/chat-window-quote-demo.tsx"],"sourcesContent":["'use client';\n\nimport { ChatWindowQuote } from '@/ui/ChatWindowQuote';\nimport type { ChatWindowQuoteItem } from '@/ui/ChatWindowQuote';\n\nconst cancun: ChatWindowQuoteItem = {\n id: '1',\n resortName: 'Cancún',\n country: 'Mexico',\n imageUrl: 'https://picsum.photos/seed/cancun/400/300',\n dateRange: '15 June 2026 to 24 June 2026',\n pax: 'for 2 adults 2 children',\n packageIncludes: [\n 'Meals and snacks at any time',\n 'Drinks, alcoholic and non-alcoholic',\n 'Sports and activities',\n ],\n additionalInfo: 'You can customise your transport and room category directly on the website.',\n};\n\nconst puntaCana: ChatWindowQuoteItem = {\n id: '2',\n resortName: 'Punta Cana',\n country: 'Dominican Republic',\n imageUrl: 'https://picsum.photos/seed/puntacana/400/300',\n dateRange: '20 July 2026 to 29 July 2026',\n pax: 'for 2 adults 2 children',\n};\n\nexport default function ChatWindowQuoteDemo() {\n return (\n <div className=\"flex flex-col gap-32 w-340\">\n <div className=\"flex flex-col gap-8\">\n <p className=\"text-b4 font-semibold text-black\">Single quote</p>\n <ChatWindowQuote quotes={[cancun]} />\n </div>\n <div className=\"flex flex-col gap-8\">\n <p className=\"text-b4 font-semibold text-black\">Multiple quotes</p>\n <ChatWindowQuote quotes={[cancun, puntaCana]} />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;AAKA,IAAM,IAA8B;CAClC,IAAI;CACJ,YAAY;CACZ,SAAS;CACT,UAAU;CACV,WAAW;CACX,KAAK;CACL,iBAAiB;EACf;EACA;EACA;EACD;CACD,gBAAgB;CACjB,EAEK,IAAiC;CACrC,IAAI;CACJ,YAAY;CACZ,SAAS;CACT,UAAU;CACV,WAAW;CACX,KAAK;CACN;AAED,SAAwB,IAAsB;AAC5C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAmC;IAAgB,CAAA,EAChE,kBAAC,GAAD,EAAiB,QAAQ,CAAC,EAAO,EAAI,CAAA,CAAA;MAEvC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAmC;IAAmB,CAAA,EACnE,kBAAC,GAAD,EAAiB,QAAQ,CAAC,GAAQ,EAAU,EAAI,CAAA,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function ChatWindowQuotesDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ChatWindow as e } from "../ui/ChatWindow.js";
|
|
3
|
+
import { useRef as t } from "react";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
//#region lib/examples/chat-window-quotes-demo.tsx
|
|
6
|
+
var i = [
|
|
7
|
+
{
|
|
8
|
+
id: "1",
|
|
9
|
+
sender: "assistant",
|
|
10
|
+
content: "Hi. Ask me anything about Club Med. I'm here to help you find the right information quickly."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "2",
|
|
14
|
+
sender: "user",
|
|
15
|
+
content: "Can you show me some quotes for a family trip to the Caribbean?"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "3",
|
|
19
|
+
sender: "assistant",
|
|
20
|
+
content: "Of course! Here are some resorts in the Caribbean that could be perfect for your family vacation."
|
|
21
|
+
}
|
|
22
|
+
], a = [{
|
|
23
|
+
id: "1",
|
|
24
|
+
resortName: "Cancún",
|
|
25
|
+
country: "Mexico",
|
|
26
|
+
imageUrl: "https://picsum.photos/seed/cancun/400/300",
|
|
27
|
+
dateRange: "15 June 2026 to 24 June 2026",
|
|
28
|
+
pax: "for 2 adults 2 children",
|
|
29
|
+
packageIncludes: [
|
|
30
|
+
"Meals and snacks at any time",
|
|
31
|
+
"Drinks, alcoholic and non-alcoholic",
|
|
32
|
+
"Sports and activities"
|
|
33
|
+
],
|
|
34
|
+
additionalInfo: "You can customise your transport and room category directly on the website."
|
|
35
|
+
}, {
|
|
36
|
+
id: "2",
|
|
37
|
+
resortName: "Punta Cana",
|
|
38
|
+
country: "Dominican Republic",
|
|
39
|
+
imageUrl: "https://picsum.photos/seed/puntacana/400/300",
|
|
40
|
+
dateRange: "15 June 2026 to 24 June 2026",
|
|
41
|
+
pax: "for 2 adults 2 children"
|
|
42
|
+
}];
|
|
43
|
+
function o() {
|
|
44
|
+
let o = t(null);
|
|
45
|
+
return /* @__PURE__ */ r("div", {
|
|
46
|
+
className: "flex flex-col items-center gap-12",
|
|
47
|
+
children: [/* @__PURE__ */ n(e, {
|
|
48
|
+
ref: o,
|
|
49
|
+
messages: i,
|
|
50
|
+
inputValue: "",
|
|
51
|
+
onInputChange: () => {},
|
|
52
|
+
onSubmit: () => {},
|
|
53
|
+
onQuoteCtaClick: (e) => console.log("Selected quote:", e.resortName),
|
|
54
|
+
onClose: () => {},
|
|
55
|
+
className: "w-380 h-660"
|
|
56
|
+
}), /* @__PURE__ */ n("button", {
|
|
57
|
+
type: "button",
|
|
58
|
+
onClick: () => o.current?.showQuotes(a),
|
|
59
|
+
className: "px-16 py-8 bg-saffron rounded-pill text-black text-b4 font-semibold hover:opacity-80 transition-opacity",
|
|
60
|
+
children: "Trigger quotes"
|
|
61
|
+
})]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { o as default };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=chat-window-quotes-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-window-quotes-demo.js","names":[],"sources":["../../lib/examples/chat-window-quotes-demo.tsx"],"sourcesContent":["'use client';\n\nimport { useRef } from 'react';\nimport { ChatWindow } from '@/ui/ChatWindow';\nimport type { ChatWindowHandle, ChatWindowMessage, ChatWindowQuoteItem } from '@/ui/ChatWindow';\n\nconst messages: ChatWindowMessage[] = [\n {\n id: '1',\n sender: 'assistant',\n content:\n \"Hi. Ask me anything about Club Med. I'm here to help you find the right information quickly.\",\n },\n {\n id: '2',\n sender: 'user',\n content: 'Can you show me some quotes for a family trip to the Caribbean?',\n },\n {\n id: '3',\n sender: 'assistant',\n content:\n 'Of course! Here are some resorts in the Caribbean that could be perfect for your family vacation.',\n },\n];\n\nconst quotes: ChatWindowQuoteItem[] = [\n {\n id: '1',\n resortName: 'Cancún',\n country: 'Mexico',\n imageUrl: 'https://picsum.photos/seed/cancun/400/300',\n dateRange: '15 June 2026 to 24 June 2026',\n pax: 'for 2 adults 2 children',\n packageIncludes: [\n 'Meals and snacks at any time',\n 'Drinks, alcoholic and non-alcoholic',\n 'Sports and activities',\n ],\n additionalInfo: 'You can customise your transport and room category directly on the website.',\n },\n {\n id: '2',\n resortName: 'Punta Cana',\n country: 'Dominican Republic',\n imageUrl: 'https://picsum.photos/seed/puntacana/400/300',\n dateRange: '15 June 2026 to 24 June 2026',\n pax: 'for 2 adults 2 children',\n },\n];\n\nexport default function ChatWindowQuotesDemo() {\n const chatRef = useRef<ChatWindowHandle>(null);\n\n return (\n <div className=\"flex flex-col items-center gap-12\">\n <ChatWindow\n ref={chatRef}\n messages={messages}\n inputValue=\"\"\n onInputChange={() => {}}\n onSubmit={() => {}}\n onQuoteCtaClick={(quote) => console.log('Selected quote:', quote.resortName)}\n onClose={() => {}}\n className=\"w-380 h-660\"\n />\n <button\n type=\"button\"\n onClick={() => chatRef.current?.showQuotes(quotes)}\n className=\"px-16 py-8 bg-saffron rounded-pill text-black text-b4 font-semibold hover:opacity-80 transition-opacity\"\n >\n Trigger quotes\n </button>\n </div>\n );\n}\n"],"mappings":";;;;;AAMA,IAAM,IAAgC;CACpC;EACE,IAAI;EACJ,QAAQ;EACR,SACE;EACH;CACD;EACE,IAAI;EACJ,QAAQ;EACR,SAAS;EACV;CACD;EACE,IAAI;EACJ,QAAQ;EACR,SACE;;CAEL,EAEK,IAAgC,CACpC;CACE,IAAI;CACJ,YAAY;CACZ,SAAS;CACT,UAAU;CACV,WAAW;CACX,KAAK;CACL,iBAAiB;EACf;EACA;EACA;EACD;CACD,gBAAgB;CACjB,EACD;CACE,IAAI;CACJ,YAAY;CACZ,SAAS;CACT,UAAU;CACV,WAAW;CACX,KAAK;CACN,CACF;AAED,SAAwB,IAAuB;CAC7C,IAAM,IAAU,EAAyB,KAAK;AAE9C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GACE,KAAK;GACK;GACV,YAAW;GACX,qBAAqB;GACrB,gBAAgB;GAChB,kBAAkB,MAAU,QAAQ,IAAI,mBAAmB,EAAM,WAAW;GAC5E,eAAe;GACf,WAAU;GACV,CAAA,EACF,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAQ,SAAS,WAAW,EAAO;GAClD,WAAU;aACX;GAEQ,CAAA,CAAA"}
|
package/package.json
CHANGED
package/ui/AdvancedToast.js
CHANGED
|
@@ -32,10 +32,13 @@ var h = ({ className: h, title: g, body: _, icon: v, isVisible: y, labels: b, ch
|
|
|
32
32
|
onMouseUp: I,
|
|
33
33
|
onMouseLeave: L,
|
|
34
34
|
children: [
|
|
35
|
-
/* @__PURE__ */ p(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
/* @__PURE__ */ p("span", {
|
|
36
|
+
className: e("w-30 h-30 pt-4", a(S)),
|
|
37
|
+
children: /* @__PURE__ */ p(f, {
|
|
38
|
+
name: v,
|
|
39
|
+
width: "30px",
|
|
40
|
+
className: e("flex-shrink-0")
|
|
41
|
+
})
|
|
39
42
|
}),
|
|
40
43
|
/* @__PURE__ */ m("div", {
|
|
41
44
|
className: "flex flex-1 flex-col gap-12 pe-24 text-b4",
|
package/ui/AdvancedToast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvancedToast.js","names":[],"sources":["../../lib/ui/AdvancedToast.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport {\n useEffect,\n useId,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type FunctionComponent,\n} from 'react';\n\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\nimport { ElasticHeight } from './ElasticHeight';\nimport { Colors, getBgColor, getBorderColor, getTextColor } from './helpers/colors/colors';\nimport { useCountdown } from './hooks/useCountdown';\nimport useResizeObserver from './hooks/useResizeObserver';\n\ninterface Props extends ComponentPropsWithoutRef<'div'> {\n title: string;\n body: string;\n icon: IconicNames;\n isVisible: boolean;\n labels: {\n close: string;\n details: string;\n };\n onClose?: () => void;\n children?: React.ReactNode;\n accentColor?: Colors;\n moreInfoLabel?: string;\n moreInfoHref?: string;\n duration?: false | number;\n toastId: string;\n updateHeight: (id: string, height: number) => void;\n}\n\nexport const AdvancedToast: FunctionComponent<Props> = ({\n className,\n title,\n body,\n icon,\n isVisible,\n labels,\n children,\n accentColor = Colors.orange,\n duration = 10000,\n onClose,\n toastId,\n updateHeight,\n ...attrs\n}) => {\n const id = useId();\n const [isDetailsExpanded, setIsDetailsExpanded] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const toastRef = useRef<HTMLDivElement>(null!);\n\n const { progress } = useCountdown({ duration, isPaused, isVisible });\n useEffect(() => {\n if (progress === 100) {\n onClose?.();\n }\n }, [progress, onClose]);\n\n const handleMouseDown = () => setIsPaused(true);\n const handleMouseUp = () => setIsPaused(false);\n const handleMouseLeave = () => setIsPaused(false);\n\n useResizeObserver<HTMLDivElement>({\n ref: toastRef,\n onResize: () => {\n if (toastRef.current) {\n updateHeight(toastId, toastRef.current.offsetHeight);\n }\n },\n });\n\n return (\n <div\n ref={toastRef}\n {...attrs}\n className={clsx(\n isVisible ? 'animate-slide-right-enter' : 'animate-slide-right-exit opacity-0',\n 'relative isolate flex gap-x-20 rounded-16 bg-white p-20 text-black transition-opacity duration-300 border-1 overflow-hidden',\n getBorderColor(accentColor),\n className,\n )}\n role=\"note\"\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseLeave}\n >\n <
|
|
1
|
+
{"version":3,"file":"AdvancedToast.js","names":[],"sources":["../../lib/ui/AdvancedToast.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport {\n useEffect,\n useId,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type FunctionComponent,\n} from 'react';\n\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\nimport { ElasticHeight } from './ElasticHeight';\nimport { Colors, getBgColor, getBorderColor, getTextColor } from './helpers/colors/colors';\nimport { useCountdown } from './hooks/useCountdown';\nimport useResizeObserver from './hooks/useResizeObserver';\n\ninterface Props extends ComponentPropsWithoutRef<'div'> {\n title: string;\n body: string;\n icon: IconicNames;\n isVisible: boolean;\n labels: {\n close: string;\n details: string;\n };\n onClose?: () => void;\n children?: React.ReactNode;\n accentColor?: Colors;\n moreInfoLabel?: string;\n moreInfoHref?: string;\n duration?: false | number;\n toastId: string;\n updateHeight: (id: string, height: number) => void;\n}\n\nexport const AdvancedToast: FunctionComponent<Props> = ({\n className,\n title,\n body,\n icon,\n isVisible,\n labels,\n children,\n accentColor = Colors.orange,\n duration = 10000,\n onClose,\n toastId,\n updateHeight,\n ...attrs\n}) => {\n const id = useId();\n const [isDetailsExpanded, setIsDetailsExpanded] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const toastRef = useRef<HTMLDivElement>(null!);\n\n const { progress } = useCountdown({ duration, isPaused, isVisible });\n useEffect(() => {\n if (progress === 100) {\n onClose?.();\n }\n }, [progress, onClose]);\n\n const handleMouseDown = () => setIsPaused(true);\n const handleMouseUp = () => setIsPaused(false);\n const handleMouseLeave = () => setIsPaused(false);\n\n useResizeObserver<HTMLDivElement>({\n ref: toastRef,\n onResize: () => {\n if (toastRef.current) {\n updateHeight(toastId, toastRef.current.offsetHeight);\n }\n },\n });\n\n return (\n <div\n ref={toastRef}\n {...attrs}\n className={clsx(\n isVisible ? 'animate-slide-right-enter' : 'animate-slide-right-exit opacity-0',\n 'relative isolate flex gap-x-20 rounded-16 bg-white p-20 text-black transition-opacity duration-300 border-1 overflow-hidden',\n getBorderColor(accentColor),\n className,\n )}\n role=\"note\"\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseLeave}\n >\n <span className={clsx('w-30 h-30 pt-4', getTextColor(accentColor))}>\n <Icon name={icon} width=\"30px\" className={clsx('flex-shrink-0')} />\n </span>\n <div className=\"flex flex-1 flex-col gap-12 pe-24 text-b4\">\n <div>\n <p className=\" font-bold\" id={id}>\n {title}\n </p>\n <p>{body}</p>\n </div>\n\n {children && (\n <div>\n <button\n onClick={() => setIsDetailsExpanded(!isDetailsExpanded)}\n aria-expanded={isDetailsExpanded}\n className=\"flex w-fit items-center gap-8 text-b5 font-normal\"\n type=\"button\"\n >\n <span>{labels.details}</span>\n <Icon\n name=\"ArrowDefaultDown\"\n width=\"24px\"\n style={{ rotate: isDetailsExpanded ? '180deg' : '0deg' }}\n className=\"transition-all duration-300\"\n />\n </button>\n <ElasticHeight isExpanded={isDetailsExpanded}>\n <div className=\"pt-4\">{children}</div>\n </ElasticHeight>\n </div>\n )}\n </div>\n\n {onClose && (\n <button\n aria-describedby={id}\n aria-label={labels.close}\n className=\"absolute end-0 top-0 mt-20 me-13 text-black\"\n onClick={onClose}\n type=\"button\"\n >\n <Icon name=\"CrossDefault\" width=\"24px\" />\n </button>\n )}\n\n {duration !== false && (\n <div className=\"absolute bottom-0 left-0 right-0 h-4 overflow-hidden rounded-b-16\">\n <div\n className={getBgColor(accentColor)}\n style={{\n width: '100%',\n height: '100%',\n transform: `scaleX(${(100 - progress) / 100})`,\n transformOrigin: 'left',\n transition: 'transform 16ms linear',\n }}\n />\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAqCA,IAAa,KAA2C,EACtD,cACA,UACA,SACA,SACA,cACA,WACA,aACA,iBAAc,EAAO,QACrB,cAAW,KACX,YACA,YACA,iBACA,GAAG,QACC;CACJ,IAAM,IAAK,GAAO,EACZ,CAAC,GAAmB,KAAwB,EAAS,GAAM,EAC3D,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,IAAW,EAAuB,KAAM,EAExC,EAAE,gBAAa,EAAa;EAAE;EAAU;EAAU;EAAW,CAAC;AACpE,SAAgB;AACd,EAAI,MAAa,OACf,KAAW;IAEZ,CAAC,GAAU,EAAQ,CAAC;CAEvB,IAAM,UAAwB,EAAY,GAAK,EACzC,UAAsB,EAAY,GAAM,EACxC,UAAyB,EAAY,GAAM;AAWjD,QATA,EAAkC;EAChC,KAAK;EACL,gBAAgB;AACd,GAAI,EAAS,WACX,EAAa,GAAS,EAAS,QAAQ,aAAa;;EAGzD,CAAC,EAGA,kBAAC,OAAD;EACE,KAAK;EACL,GAAI;EACJ,WAAW,EACT,IAAY,8BAA8B,sCAC1C,+HACA,EAAe,EAAY,EAC3B,EACD;EACD,MAAK;EACL,aAAa;EACb,WAAW;EACX,cAAc;YAZhB;GAcE,kBAAC,QAAD;IAAM,WAAW,EAAK,kBAAkB,EAAa,EAAY,CAAC;cAChE,kBAAC,GAAD;KAAM,MAAM;KAAM,OAAM;KAAO,WAAW,EAAK,gBAAA;KAAoB,CAAA;IAC9D,CAAA;GACP,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;KAAG,WAAU;KAAiB;eAC3B;KACC,CAAA,EACJ,kBAAC,KAAD,EAAA,UAAI,GAAS,CAAA,CACT,EAAA,CAAA,EAEL,KACC,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD;KACE,eAAe,EAAqB,CAAC,EAAkB;KACvD,iBAAe;KACf,WAAU;KACV,MAAK;eAJP,CAME,kBAAC,QAAD,EAAA,UAAO,EAAO,SAAe,CAAA,EAC7B,kBAAC,GAAD;MACE,MAAK;MACL,OAAM;MACN,OAAO,EAAE,QAAQ,IAAoB,WAAW,QAAQ;MACxD,WAAU;MACV,CAAA,CAAA;QAEJ,kBAAC,GAAD;KAAe,YAAY;eACzB,kBAAC,OAAD;MAAK,WAAU;MAAQ;MAAe,CAAA;KACxB,CAAA,CACZ,EAAA,CAAA,CAAA;;GAIT,KACC,kBAAC,UAAD;IACE,oBAAkB;IAClB,cAAY,EAAO;IACnB,WAAU;IACV,SAAS;IACT,MAAK;cAEL,kBAAC,GAAD;KAAM,MAAK;KAAe,OAAM;KAAS,CAAA;IAClC,CAAA;GAGV,MAAa,MACZ,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KACE,WAAW,EAAW,EAAY;KAClC,OAAO;MACL,OAAO;MACP,QAAQ;MACR,WAAW,WAAW,MAAM,KAAY,IAAI;MAC5C,iBAAiB;MACjB,YAAY;;KAEd,CAAA;IACE,CAAA"}
|
package/ui/ChatWindow.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { HTMLAttributes, ReactNode } from 'react';
|
|
|
2
2
|
import { ChatMessageSender } from './ChatMessage';
|
|
3
3
|
import { ChatWindowCsatPromptLabels } from './ChatWindowCsatPrompt';
|
|
4
4
|
import { ChatWindowCsatThankYouLabels } from './ChatWindowCsatThankYou';
|
|
5
|
-
|
|
5
|
+
import { ChatWindowQuoteItem } from './ChatWindowQuote';
|
|
6
|
+
export type { ChatWindowCsatPromptLabels, ChatWindowCsatThankYouLabels, ChatWindowQuoteItem };
|
|
6
7
|
export interface ChatWindowMessage {
|
|
7
8
|
id: string;
|
|
8
9
|
sender: ChatMessageSender;
|
|
@@ -24,8 +25,10 @@ export interface ChatWindowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'c
|
|
|
24
25
|
csatLabels?: ChatWindowCsatPromptLabels;
|
|
25
26
|
csatRenderRatingLabel?: (rating: number) => ReactNode;
|
|
26
27
|
csatThankYouLabels?: ChatWindowCsatThankYouLabels;
|
|
28
|
+
onQuoteCtaClick?: (quote: ChatWindowQuoteItem) => void;
|
|
27
29
|
}
|
|
28
30
|
export interface ChatWindowHandle {
|
|
29
31
|
askForFeedback: () => void;
|
|
32
|
+
showQuotes: (quotes: ChatWindowQuoteItem[]) => void;
|
|
30
33
|
}
|
|
31
34
|
export declare const ChatWindow: import('react').ForwardRefExoticComponent<ChatWindowProps & import('react').RefAttributes<ChatWindowHandle>>;
|
package/ui/ChatWindow.js
CHANGED
|
@@ -5,120 +5,131 @@ import { t as n } from "../chunks/ChatMessage.js";
|
|
|
5
5
|
import { ChatTypingIndicator as r } from "./ChatTypingIndicator.js";
|
|
6
6
|
import { ChatWindowCsatPrompt as i } from "./ChatWindowCsatPrompt.js";
|
|
7
7
|
import { ChatWindowCsatThankYou as a } from "./ChatWindowCsatThankYou.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { ChatWindowQuote as o } from "./ChatWindowQuote.js";
|
|
9
|
+
import { forwardRef as s, useEffect as c, useImperativeHandle as l, useRef as u, useState as d } from "react";
|
|
10
|
+
import { Icon as f } from "@clubmed/trident-icons";
|
|
11
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
11
12
|
//#region lib/ui/ChatWindow.tsx
|
|
12
|
-
var
|
|
13
|
+
var h = /* @__PURE__ */ p("svg", {
|
|
13
14
|
className: "absolute top-full inset-x-[50%] -translate-x-1/2",
|
|
14
15
|
width: "118",
|
|
15
16
|
height: "27",
|
|
16
17
|
viewBox: "0 0 118 27",
|
|
17
|
-
children: /* @__PURE__ */
|
|
18
|
+
children: /* @__PURE__ */ p("path", {
|
|
18
19
|
d: "M0 0C10.8283 0 21.1946 5.40419 28.7327 13.2062L30.2673 14.7945C45.991 31.0685 72.009 31.0685 87.7327 14.7945L89.2673 13.2062C96.8054 5.40419 107.172 0 118 0C118 0 80.6853 0 0 0Z",
|
|
19
20
|
fill: "#F6EFE7"
|
|
20
21
|
})
|
|
21
|
-
}),
|
|
22
|
-
let
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
}), g = s(function({ title: s = "Ask me a question", greeting: g, messages: _, inputValue: v, inputPlaceholder: y, isTyping: b = !1, onInputChange: x, onSubmit: S, onClose: C, onAudioClick: w, logo: T, onFeedbackRate: E, csatLabels: D, csatRenderRatingLabel: O, csatThankYouLabels: k, onQuoteCtaClick: A, className: j, ...M }, N) {
|
|
23
|
+
let P = u(null), [F, I] = d(!1), [L, R] = d(null), [z, B] = d([]);
|
|
24
|
+
l(N, () => ({
|
|
25
|
+
askForFeedback() {
|
|
26
|
+
I(!0);
|
|
27
|
+
},
|
|
28
|
+
showQuotes(e) {
|
|
29
|
+
B((t) => [...t, e]);
|
|
30
|
+
}
|
|
31
|
+
})), c(() => {
|
|
32
|
+
let e = P.current;
|
|
27
33
|
e && e.scrollTo({
|
|
28
34
|
top: e.scrollHeight,
|
|
29
35
|
behavior: "smooth"
|
|
30
36
|
});
|
|
31
37
|
}, [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
_,
|
|
39
|
+
b,
|
|
40
|
+
F,
|
|
41
|
+
L,
|
|
42
|
+
z
|
|
36
43
|
]);
|
|
37
|
-
function
|
|
38
|
-
|
|
44
|
+
function V(e) {
|
|
45
|
+
R(String(O ? O(e) : e)), E?.(e);
|
|
39
46
|
}
|
|
40
|
-
let
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
...
|
|
43
|
-
className: e("flex flex-col gap-20 items-center",
|
|
44
|
-
children: [/* @__PURE__ */
|
|
47
|
+
let H = F && D && O;
|
|
48
|
+
return /* @__PURE__ */ m("div", {
|
|
49
|
+
...M,
|
|
50
|
+
className: e("flex flex-col gap-20 items-center", j),
|
|
51
|
+
children: [/* @__PURE__ */ m("div", {
|
|
45
52
|
className: "chat-border bg-white flex flex-col h-full w-full rounded-32 overflow-hidden",
|
|
46
53
|
children: [
|
|
47
|
-
/* @__PURE__ */
|
|
54
|
+
/* @__PURE__ */ m("div", {
|
|
48
55
|
className: "relative flex flex-col items-center shrink-0 pt-4 px-4 h-133 overflow-hidden",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
56
|
+
children: [/* @__PURE__ */ p("div", {
|
|
50
57
|
className: "absolute inset-x-4 top-4 h-102 bg-lightSand rounded-[24]",
|
|
51
|
-
children:
|
|
52
|
-
}), /* @__PURE__ */
|
|
58
|
+
children: h
|
|
59
|
+
}), /* @__PURE__ */ m("div", {
|
|
53
60
|
className: "relative flex flex-col flex-1 items-center justify-end pb-8 w-full z-10",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
61
|
+
children: [/* @__PURE__ */ p("div", {
|
|
55
62
|
className: "flex items-center justify-center px-12 py-8 w-full",
|
|
56
|
-
children: /* @__PURE__ */
|
|
63
|
+
children: /* @__PURE__ */ p("p", {
|
|
57
64
|
className: "font-serif font-bold italic text-h5 text-center text-black line-clamp-2",
|
|
58
|
-
children:
|
|
65
|
+
children: s
|
|
59
66
|
})
|
|
60
|
-
}),
|
|
67
|
+
}), T ?? /* @__PURE__ */ p("button", {
|
|
61
68
|
type: "button",
|
|
62
69
|
"aria-label": "AI assistant",
|
|
63
70
|
className: "chat-border flex items-center justify-center size-48 rounded-full bg-white",
|
|
64
|
-
children: /* @__PURE__ */ f
|
|
71
|
+
children: /* @__PURE__ */ p(f, {
|
|
65
72
|
name: "Sparkles",
|
|
66
73
|
width: "24px"
|
|
67
74
|
})
|
|
68
75
|
})]
|
|
69
76
|
})]
|
|
70
77
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
72
|
-
ref:
|
|
78
|
+
/* @__PURE__ */ m("div", {
|
|
79
|
+
ref: P,
|
|
73
80
|
role: "log",
|
|
74
81
|
"aria-label": "Chat messages",
|
|
75
82
|
"aria-live": "polite",
|
|
76
83
|
className: "chat-message-log flex flex-col flex-1 gap-20 overflow-y-auto py-20",
|
|
77
84
|
children: [
|
|
78
|
-
|
|
85
|
+
g ? /* @__PURE__ */ p("div", {
|
|
79
86
|
className: "px-20",
|
|
80
|
-
children: /* @__PURE__ */
|
|
87
|
+
children: /* @__PURE__ */ p("p", {
|
|
81
88
|
className: "text-b3 text-black",
|
|
82
|
-
children:
|
|
89
|
+
children: g
|
|
83
90
|
})
|
|
84
91
|
}) : null,
|
|
85
|
-
|
|
92
|
+
_.map((e) => /* @__PURE__ */ p(n, {
|
|
86
93
|
sender: e.sender,
|
|
87
94
|
children: e.content
|
|
88
95
|
}, e.id)),
|
|
89
|
-
|
|
96
|
+
b && /* @__PURE__ */ p("div", {
|
|
90
97
|
className: "px-12",
|
|
91
|
-
children: /* @__PURE__ */
|
|
98
|
+
children: /* @__PURE__ */ p(r, {})
|
|
92
99
|
}),
|
|
93
|
-
|
|
94
|
-
onRate:
|
|
95
|
-
labels:
|
|
96
|
-
renderRatingLabel:
|
|
100
|
+
H && /* @__PURE__ */ p(i, {
|
|
101
|
+
onRate: V,
|
|
102
|
+
labels: D,
|
|
103
|
+
renderRatingLabel: O
|
|
97
104
|
}),
|
|
98
|
-
|
|
105
|
+
L && /* @__PURE__ */ p(n, {
|
|
99
106
|
sender: "user",
|
|
100
|
-
children:
|
|
107
|
+
children: L
|
|
101
108
|
}),
|
|
102
|
-
|
|
109
|
+
L && k && /* @__PURE__ */ p(a, { labels: k }),
|
|
110
|
+
z.map((e, t) => /* @__PURE__ */ p(o, {
|
|
111
|
+
quotes: e,
|
|
112
|
+
onCtaClick: A
|
|
113
|
+
}, t))
|
|
103
114
|
]
|
|
104
115
|
}),
|
|
105
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ p("div", {
|
|
106
117
|
className: "shrink-0 px-8 pb-8 pt-12",
|
|
107
|
-
children: /* @__PURE__ */
|
|
108
|
-
value:
|
|
109
|
-
placeholder:
|
|
110
|
-
onValueChange:
|
|
111
|
-
onSubmit:
|
|
112
|
-
onAudioClick:
|
|
118
|
+
children: /* @__PURE__ */ p(t, {
|
|
119
|
+
value: v,
|
|
120
|
+
placeholder: y,
|
|
121
|
+
onValueChange: x,
|
|
122
|
+
onSubmit: S,
|
|
123
|
+
onAudioClick: w
|
|
113
124
|
})
|
|
114
125
|
})
|
|
115
126
|
]
|
|
116
|
-
}),
|
|
127
|
+
}), C && /* @__PURE__ */ p("button", {
|
|
117
128
|
type: "button",
|
|
118
129
|
"aria-label": "Close chat",
|
|
119
|
-
onClick:
|
|
130
|
+
onClick: C,
|
|
120
131
|
className: "flex items-center justify-center size-48 rounded-full bg-black border border-black text-white shrink-0 hover:opacity-80 transition-opacity",
|
|
121
|
-
children: /* @__PURE__ */ f
|
|
132
|
+
children: /* @__PURE__ */ p(f, {
|
|
122
133
|
name: "CrossDefault",
|
|
123
134
|
width: "24px"
|
|
124
135
|
})
|
|
@@ -126,6 +137,6 @@ var m = /* @__PURE__ */ f("svg", {
|
|
|
126
137
|
});
|
|
127
138
|
});
|
|
128
139
|
//#endregion
|
|
129
|
-
export {
|
|
140
|
+
export { g as ChatWindow };
|
|
130
141
|
|
|
131
142
|
//# sourceMappingURL=ChatWindow.js.map
|
package/ui/ChatWindow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWindow.js","names":[],"sources":["../../lib/ui/ChatWindow.tsx"],"sourcesContent":["'use client';\n\nimport { Icon } from '@clubmed/trident-icons';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { twMerge } from './helpers/twMerge';\nimport { ChatInput } from './ChatInput';\nimport { ChatMessage } from './ChatMessage';\nimport type { ChatMessageSender } from './ChatMessage';\nimport { ChatTypingIndicator } from './ChatTypingIndicator';\nimport { ChatWindowCsatPrompt } from './ChatWindowCsatPrompt';\nimport type { ChatWindowCsatPromptLabels } from './ChatWindowCsatPrompt';\nimport { ChatWindowCsatThankYou } from './ChatWindowCsatThankYou';\nimport type { ChatWindowCsatThankYouLabels } from './ChatWindowCsatThankYou';\n\nexport type { ChatWindowCsatPromptLabels, ChatWindowCsatThankYouLabels };\n\nexport interface ChatWindowMessage {\n id: string;\n sender: ChatMessageSender;\n content: string;\n}\n\nexport interface ChatWindowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n title?: string;\n greeting?: string;\n messages: ChatWindowMessage[];\n inputValue: string;\n inputPlaceholder?: string;\n isTyping?: boolean;\n onInputChange: (value: string) => void;\n onSubmit: () => void;\n onClose?: () => void;\n onAudioClick?: () => void;\n logo?: ReactNode;\n onFeedbackRate?: (rating: number) => void;\n csatLabels?: ChatWindowCsatPromptLabels;\n csatRenderRatingLabel?: (rating: number) => ReactNode;\n csatThankYouLabels?: ChatWindowCsatThankYouLabels;\n}\n\nexport interface ChatWindowHandle {\n askForFeedback: () => void;\n}\n\nconst headerCurve = (\n <svg\n className=\"absolute top-full inset-x-[50%] -translate-x-1/2\"\n width=\"118\"\n height=\"27\"\n viewBox=\"0 0 118 27\"\n >\n <path\n d=\"M0 0C10.8283 0 21.1946 5.40419 28.7327 13.2062L30.2673 14.7945C45.991 31.0685 72.009 31.0685 87.7327 14.7945L89.2673 13.2062C96.8054 5.40419 107.172 0 118 0C118 0 80.6853 0 0 0Z\"\n fill=\"#F6EFE7\"\n />\n </svg>\n);\n\nexport const ChatWindow = forwardRef<ChatWindowHandle, ChatWindowProps>(function ChatWindow(\n {\n title = 'Ask me a question',\n greeting,\n messages,\n inputValue,\n inputPlaceholder,\n isTyping = false,\n onInputChange,\n onSubmit,\n onClose,\n onAudioClick,\n logo,\n onFeedbackRate,\n csatLabels,\n csatRenderRatingLabel,\n csatThankYouLabels,\n className,\n ...props\n },\n ref,\n) {\n const logRef = useRef<HTMLDivElement>(null);\n const [showCsat, setShowCsat] = useState(false);\n const [csatRatingMessage, setCsatRatingMessage] = useState<string | null>(null);\n\n useImperativeHandle(ref, () => ({\n askForFeedback() {\n setShowCsat(true);\n },\n }));\n\n useEffect(() => {\n const el = logRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });\n }, [messages, isTyping, showCsat, csatRatingMessage]);\n\n function handleRate(rating: number) {\n const label = csatRenderRatingLabel ? String(csatRenderRatingLabel(rating)) : String(rating);\n setCsatRatingMessage(label);\n onFeedbackRate?.(rating);\n }\n\n const csatReady = showCsat && csatLabels && csatRenderRatingLabel;\n\n return (\n <div {...props} className={twMerge('flex flex-col gap-20 items-center', className)}>\n <div className=\"chat-border bg-white flex flex-col h-full w-full rounded-32 overflow-hidden\">\n <div className=\"relative flex flex-col items-center shrink-0 pt-4 px-4 h-133 overflow-hidden\">\n <div className=\"absolute inset-x-4 top-4 h-102 bg-lightSand rounded-[24]\">\n {headerCurve}\n </div>\n <div className=\"relative flex flex-col flex-1 items-center justify-end pb-8 w-full z-10\">\n <div className=\"flex items-center justify-center px-12 py-8 w-full\">\n <p className=\"font-serif font-bold italic text-h5 text-center text-black line-clamp-2\">\n {title}\n </p>\n </div>\n {logo ?? (\n <button\n type=\"button\"\n aria-label=\"AI assistant\"\n className=\"chat-border flex items-center justify-center size-48 rounded-full bg-white\"\n >\n <Icon name=\"Sparkles\" width=\"24px\" />\n </button>\n )}\n </div>\n </div>\n\n <div\n ref={logRef}\n role=\"log\"\n aria-label=\"Chat messages\"\n aria-live=\"polite\"\n className=\"chat-message-log flex flex-col flex-1 gap-20 overflow-y-auto py-20\"\n >\n {greeting ? (\n <div className=\"px-20\">\n <p className=\"text-b3 text-black\">{greeting}</p>\n </div>\n ) : null}\n {messages.map((msg) => (\n <ChatMessage key={msg.id} sender={msg.sender}>\n {msg.content}\n </ChatMessage>\n ))}\n {isTyping && (\n <div className=\"px-12\">\n <ChatTypingIndicator />\n </div>\n )}\n {csatReady && (\n <ChatWindowCsatPrompt\n onRate={handleRate}\n labels={csatLabels}\n renderRatingLabel={csatRenderRatingLabel}\n />\n )}\n {csatRatingMessage && <ChatMessage sender=\"user\">{csatRatingMessage}</ChatMessage>}\n {csatRatingMessage && csatThankYouLabels && (\n <ChatWindowCsatThankYou labels={csatThankYouLabels} />\n )}\n </div>\n\n <div className=\"shrink-0 px-8 pb-8 pt-12\">\n <ChatInput\n value={inputValue}\n placeholder={inputPlaceholder}\n onValueChange={onInputChange}\n onSubmit={onSubmit}\n onAudioClick={onAudioClick}\n />\n </div>\n </div>\n\n {onClose && (\n <button\n type=\"button\"\n aria-label=\"Close chat\"\n onClick={onClose}\n className=\"flex items-center justify-center size-48 rounded-full bg-black border border-black text-white shrink-0 hover:opacity-80 transition-opacity\"\n >\n <Icon name=\"CrossDefault\" width=\"24px\" />\n </button>\n )}\n </div>\n );\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatWindow.js","names":[],"sources":["../../lib/ui/ChatWindow.tsx"],"sourcesContent":["'use client';\n\nimport { Icon } from '@clubmed/trident-icons';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { twMerge } from './helpers/twMerge';\nimport { ChatInput } from './ChatInput';\nimport { ChatMessage } from './ChatMessage';\nimport type { ChatMessageSender } from './ChatMessage';\nimport { ChatTypingIndicator } from './ChatTypingIndicator';\nimport { ChatWindowCsatPrompt } from './ChatWindowCsatPrompt';\nimport type { ChatWindowCsatPromptLabels } from './ChatWindowCsatPrompt';\nimport { ChatWindowCsatThankYou } from './ChatWindowCsatThankYou';\nimport type { ChatWindowCsatThankYouLabels } from './ChatWindowCsatThankYou';\nimport { ChatWindowQuote } from './ChatWindowQuote';\nimport type { ChatWindowQuoteItem } from './ChatWindowQuote';\n\nexport type { ChatWindowCsatPromptLabels, ChatWindowCsatThankYouLabels, ChatWindowQuoteItem };\n\nexport interface ChatWindowMessage {\n id: string;\n sender: ChatMessageSender;\n content: string;\n}\n\nexport interface ChatWindowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n title?: string;\n greeting?: string;\n messages: ChatWindowMessage[];\n inputValue: string;\n inputPlaceholder?: string;\n isTyping?: boolean;\n onInputChange: (value: string) => void;\n onSubmit: () => void;\n onClose?: () => void;\n onAudioClick?: () => void;\n logo?: ReactNode;\n onFeedbackRate?: (rating: number) => void;\n csatLabels?: ChatWindowCsatPromptLabels;\n csatRenderRatingLabel?: (rating: number) => ReactNode;\n csatThankYouLabels?: ChatWindowCsatThankYouLabels;\n onQuoteCtaClick?: (quote: ChatWindowQuoteItem) => void;\n}\n\nexport interface ChatWindowHandle {\n askForFeedback: () => void;\n showQuotes: (quotes: ChatWindowQuoteItem[]) => void;\n}\n\nconst headerCurve = (\n <svg\n className=\"absolute top-full inset-x-[50%] -translate-x-1/2\"\n width=\"118\"\n height=\"27\"\n viewBox=\"0 0 118 27\"\n >\n <path\n d=\"M0 0C10.8283 0 21.1946 5.40419 28.7327 13.2062L30.2673 14.7945C45.991 31.0685 72.009 31.0685 87.7327 14.7945L89.2673 13.2062C96.8054 5.40419 107.172 0 118 0C118 0 80.6853 0 0 0Z\"\n fill=\"#F6EFE7\"\n />\n </svg>\n);\n\nexport const ChatWindow = forwardRef<ChatWindowHandle, ChatWindowProps>(function ChatWindow(\n {\n title = 'Ask me a question',\n greeting,\n messages,\n inputValue,\n inputPlaceholder,\n isTyping = false,\n onInputChange,\n onSubmit,\n onClose,\n onAudioClick,\n logo,\n onFeedbackRate,\n csatLabels,\n csatRenderRatingLabel,\n csatThankYouLabels,\n onQuoteCtaClick,\n className,\n ...props\n },\n ref,\n) {\n const logRef = useRef<HTMLDivElement>(null);\n const [showCsat, setShowCsat] = useState(false);\n const [csatRatingMessage, setCsatRatingMessage] = useState<string | null>(null);\n const [quoteGroups, setQuoteGroups] = useState<ChatWindowQuoteItem[][]>([]);\n\n useImperativeHandle(ref, () => ({\n askForFeedback() {\n setShowCsat(true);\n },\n showQuotes(quotes: ChatWindowQuoteItem[]) {\n setQuoteGroups((prev) => [...prev, quotes]);\n },\n }));\n\n useEffect(() => {\n const el = logRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });\n }, [messages, isTyping, showCsat, csatRatingMessage, quoteGroups]);\n\n function handleRate(rating: number) {\n const label = csatRenderRatingLabel ? String(csatRenderRatingLabel(rating)) : String(rating);\n setCsatRatingMessage(label);\n onFeedbackRate?.(rating);\n }\n\n const csatReady = showCsat && csatLabels && csatRenderRatingLabel;\n\n return (\n <div {...props} className={twMerge('flex flex-col gap-20 items-center', className)}>\n <div className=\"chat-border bg-white flex flex-col h-full w-full rounded-32 overflow-hidden\">\n <div className=\"relative flex flex-col items-center shrink-0 pt-4 px-4 h-133 overflow-hidden\">\n <div className=\"absolute inset-x-4 top-4 h-102 bg-lightSand rounded-[24]\">\n {headerCurve}\n </div>\n <div className=\"relative flex flex-col flex-1 items-center justify-end pb-8 w-full z-10\">\n <div className=\"flex items-center justify-center px-12 py-8 w-full\">\n <p className=\"font-serif font-bold italic text-h5 text-center text-black line-clamp-2\">\n {title}\n </p>\n </div>\n {logo ?? (\n <button\n type=\"button\"\n aria-label=\"AI assistant\"\n className=\"chat-border flex items-center justify-center size-48 rounded-full bg-white\"\n >\n <Icon name=\"Sparkles\" width=\"24px\" />\n </button>\n )}\n </div>\n </div>\n\n <div\n ref={logRef}\n role=\"log\"\n aria-label=\"Chat messages\"\n aria-live=\"polite\"\n className=\"chat-message-log flex flex-col flex-1 gap-20 overflow-y-auto py-20\"\n >\n {greeting ? (\n <div className=\"px-20\">\n <p className=\"text-b3 text-black\">{greeting}</p>\n </div>\n ) : null}\n {messages.map((msg) => (\n <ChatMessage key={msg.id} sender={msg.sender}>\n {msg.content}\n </ChatMessage>\n ))}\n {isTyping && (\n <div className=\"px-12\">\n <ChatTypingIndicator />\n </div>\n )}\n {csatReady && (\n <ChatWindowCsatPrompt\n onRate={handleRate}\n labels={csatLabels}\n renderRatingLabel={csatRenderRatingLabel}\n />\n )}\n {csatRatingMessage && <ChatMessage sender=\"user\">{csatRatingMessage}</ChatMessage>}\n {csatRatingMessage && csatThankYouLabels && (\n <ChatWindowCsatThankYou labels={csatThankYouLabels} />\n )}\n {quoteGroups.map((quotes, idx) => (\n <ChatWindowQuote key={idx} quotes={quotes} onCtaClick={onQuoteCtaClick} />\n ))}\n </div>\n\n <div className=\"shrink-0 px-8 pb-8 pt-12\">\n <ChatInput\n value={inputValue}\n placeholder={inputPlaceholder}\n onValueChange={onInputChange}\n onSubmit={onSubmit}\n onAudioClick={onAudioClick}\n />\n </div>\n </div>\n\n {onClose && (\n <button\n type=\"button\"\n aria-label=\"Close chat\"\n onClick={onClose}\n className=\"flex items-center justify-center size-48 rounded-full bg-black border border-black text-white shrink-0 hover:opacity-80 transition-opacity\"\n >\n <Icon name=\"CrossDefault\" width=\"24px\" />\n </button>\n )}\n </div>\n );\n});\n"],"mappings":";;;;;;;;;;;;AAiDA,IAAM,IACJ,kBAAC,OAAD;CACE,WAAU;CACV,OAAM;CACN,QAAO;CACP,SAAQ;WAER,kBAAC,QAAD;EACE,GAAE;EACF,MAAK;EACL,CAAA;CACE,CAAA,EAGK,IAAa,EAA8C,SACtE,EACE,WAAQ,qBACR,aACA,aACA,eACA,qBACA,cAAW,IACX,kBACA,aACA,YACA,iBACA,SACA,mBACA,eACA,0BACA,uBACA,oBACA,cACA,GAAG,KAEL,GACA;CACA,IAAM,IAAS,EAAuB,KAAK,EACrC,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,CAAC,GAAmB,KAAwB,EAAwB,KAAK,EACzE,CAAC,GAAa,KAAkB,EAAkC,EAAE,CAAC;AAW3E,CATA,EAAoB,UAAY;EAC9B,iBAAiB;AACf,KAAY,GAAK;;EAEnB,WAAW,GAA+B;AACxC,MAAgB,MAAS,CAAC,GAAG,GAAM,EAAO,CAAC;;EAE9C,EAAE,EAEH,QAAgB;EACd,IAAM,IAAK,EAAO;AAClB,EAAI,KAAI,EAAG,SAAS;GAAE,KAAK,EAAG;GAAc,UAAU;GAAU,CAAC;IAChE;EAAC;EAAU;EAAU;EAAU;EAAmB;EAAY,CAAC;CAElE,SAAS,EAAW,GAAgB;AAGlC,EADA,EADsC,OAAxB,IAA+B,EAAsB,EAAO,GAAW,EAAO,CACjE,EAC3B,IAAiB,EAAO;;CAG1B,IAAM,IAAY,KAAY,KAAc;AAE5C,QACE,kBAAC,OAAD;EAAK,GAAI;EAAO,WAAW,EAAQ,qCAAqC,EAAU;YAAlF,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBACV;QACC,CAAA;OACA,CAAA,EACL,KACC,kBAAC,UAAD;OACE,MAAK;OACL,cAAW;OACX,WAAU;iBAEV,kBAAC,GAAD;QAAM,MAAK;QAAW,OAAM;QAAS,CAAA;OAC9B,CAAA,CAAA;;;IAKf,kBAAC,OAAD;KACE,KAAK;KACL,MAAK;KACL,cAAW;KACX,aAAU;KACV,WAAU;eALZ;MAOG,IACC,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBAAsB;QAAa,CAAA;OAC5C,CAAA,GACJ;MACH,EAAS,KAAK,MACb,kBAAC,GAAD;OAA0B,QAAQ,EAAI;iBACnC,EAAI;OACO,EAFI,EAAI,GAER,CACd;MACD,KACC,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAuB,CAAA;OACnB,CAAA;MAEP,KACC,kBAAC,GAAD;OACE,QAAQ;OACR,QAAQ;OACR,mBAAmB;OACnB,CAAA;MAEH,KAAqB,kBAAC,GAAD;OAAa,QAAO;iBAAQ;OAAgC,CAAA;MACjF,KAAqB,KACpB,kBAAC,GAAD,EAAwB,QAAQ,GAAsB,CAAA;MAEvD,EAAY,KAAK,GAAQ,MACxB,kBAAC,GAAD;OAAmC;OAAQ,YAAY;OAAmB,EAApD,EAAoD,CAAA;;;IAI9E,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MACE,OAAO;MACP,aAAa;MACb,eAAe;MACL;MACI;MACd,CAAA;KACE,CAAA;;MAGP,KACC,kBAAC,UAAD;GACE,MAAK;GACL,cAAW;GACX,SAAS;GACT,WAAU;aAEV,kBAAC,GAAD;IAAM,MAAK;IAAe,OAAM;IAAS,CAAA;GAClC,CAAA,CAAA;;EAIf"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ChatWindowQuoteItem {
|
|
2
|
+
id: string;
|
|
3
|
+
resortName: string;
|
|
4
|
+
country: string;
|
|
5
|
+
imageUrl: string;
|
|
6
|
+
/** Date range, e.g. "15 June 2026 to 24 June 2026" */
|
|
7
|
+
dateRange: string;
|
|
8
|
+
/** Pax info, e.g. "for 2 adults 2 children" */
|
|
9
|
+
pax: string;
|
|
10
|
+
/** CTA button label. Defaults to "See prices" */
|
|
11
|
+
ctaLabel?: string;
|
|
12
|
+
/** Bullet-point package items. Shown in single-quote inline mode only */
|
|
13
|
+
packageIncludes?: string[];
|
|
14
|
+
/** Free-text paragraph shown in single-quote inline mode only */
|
|
15
|
+
additionalInfo?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ChatWindowQuoteProps {
|
|
18
|
+
quotes: ChatWindowQuoteItem[];
|
|
19
|
+
onCtaClick?: (quote: ChatWindowQuoteItem) => void;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function ChatWindowQuote({ quotes, onCtaClick, className }: ChatWindowQuoteProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button as e } from "./buttons/Button.js";
|
|
3
|
+
import { twMerge as t } from "./helpers/twMerge.js";
|
|
4
|
+
import { Scrollbar as n } from "./Scrollbar.js";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
//#region lib/ui/ChatWindowQuote.tsx
|
|
7
|
+
function a({ quote: t, onCtaClick: n }) {
|
|
8
|
+
return /* @__PURE__ */ i("article", {
|
|
9
|
+
"aria-label": t.resortName,
|
|
10
|
+
className: "flex flex-col bg-white border border-lightGrey rounded-32 shadow-[0px_2px_14px_0px_rgba(0,0,0,0.25)] overflow-hidden p-24 gap-16",
|
|
11
|
+
children: [/* @__PURE__ */ i("div", {
|
|
12
|
+
className: "relative h-210 w-full overflow-hidden rounded-16",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ r("img", {
|
|
15
|
+
src: t.imageUrl,
|
|
16
|
+
alt: "",
|
|
17
|
+
className: "absolute inset-0 size-full object-cover"
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ r("div", { className: "absolute inset-0 bg-gradient-to-b from-transparent from-50% to-[rgba(36,36,36,0.4)]" }),
|
|
20
|
+
/* @__PURE__ */ i("div", {
|
|
21
|
+
className: "absolute bottom-20 inset-x-0 flex flex-col items-center text-white text-center px-20",
|
|
22
|
+
children: [/* @__PURE__ */ r("p", {
|
|
23
|
+
className: "text-b2 font-semibold",
|
|
24
|
+
children: t.resortName
|
|
25
|
+
}), /* @__PURE__ */ r("p", {
|
|
26
|
+
className: "text-b3",
|
|
27
|
+
children: t.country
|
|
28
|
+
})]
|
|
29
|
+
})
|
|
30
|
+
]
|
|
31
|
+
}), /* @__PURE__ */ i("div", {
|
|
32
|
+
className: "flex flex-col gap-16 items-center",
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ i("p", {
|
|
35
|
+
className: "text-b4 font-semibold text-black text-center",
|
|
36
|
+
children: [
|
|
37
|
+
t.resortName,
|
|
38
|
+
", ",
|
|
39
|
+
t.dateRange,
|
|
40
|
+
", ",
|
|
41
|
+
t.pax
|
|
42
|
+
]
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ r(e, {
|
|
45
|
+
color: "saffron",
|
|
46
|
+
onClick: () => n?.(t),
|
|
47
|
+
children: t.ctaLabel ?? "See prices"
|
|
48
|
+
}),
|
|
49
|
+
t.packageIncludes && t.packageIncludes.length > 0 && /* @__PURE__ */ i("div", {
|
|
50
|
+
className: "flex flex-col gap-4 w-full",
|
|
51
|
+
children: [/* @__PURE__ */ r("p", {
|
|
52
|
+
className: "text-b3 font-semibold text-black",
|
|
53
|
+
children: "Your All-Inclusive package includes:"
|
|
54
|
+
}), /* @__PURE__ */ r("ul", {
|
|
55
|
+
className: "flex flex-col gap-2",
|
|
56
|
+
children: t.packageIncludes.map((e) => /* @__PURE__ */ i("li", {
|
|
57
|
+
className: "text-b3 text-black",
|
|
58
|
+
children: ["• ", e]
|
|
59
|
+
}, e))
|
|
60
|
+
})]
|
|
61
|
+
}),
|
|
62
|
+
t.additionalInfo && /* @__PURE__ */ r("p", {
|
|
63
|
+
className: "text-b3 text-black",
|
|
64
|
+
children: t.additionalInfo
|
|
65
|
+
})
|
|
66
|
+
]
|
|
67
|
+
})]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function o({ quote: t, onCtaClick: n }) {
|
|
71
|
+
return /* @__PURE__ */ i("article", {
|
|
72
|
+
"aria-label": t.resortName,
|
|
73
|
+
className: "flex flex-col gap-12 items-center shrink-0 w-200",
|
|
74
|
+
children: [/* @__PURE__ */ i("div", {
|
|
75
|
+
className: "relative size-200 rounded-16 overflow-hidden",
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ r("img", {
|
|
78
|
+
src: t.imageUrl,
|
|
79
|
+
alt: "",
|
|
80
|
+
className: "absolute inset-0 size-full object-cover"
|
|
81
|
+
}),
|
|
82
|
+
/* @__PURE__ */ r("div", { className: "absolute inset-0 rounded-16 bg-gradient-to-b from-transparent from-50% to-[rgba(36,36,36,0.4)]" }),
|
|
83
|
+
/* @__PURE__ */ i("div", {
|
|
84
|
+
className: "absolute bottom-20 inset-x-0 flex flex-col items-center text-white text-center px-8",
|
|
85
|
+
children: [/* @__PURE__ */ r("p", {
|
|
86
|
+
className: "text-b4 font-semibold",
|
|
87
|
+
children: t.resortName
|
|
88
|
+
}), /* @__PURE__ */ r("p", {
|
|
89
|
+
className: "text-b5",
|
|
90
|
+
children: t.country
|
|
91
|
+
})]
|
|
92
|
+
})
|
|
93
|
+
]
|
|
94
|
+
}), /* @__PURE__ */ i("div", {
|
|
95
|
+
className: "flex flex-col gap-8 items-center",
|
|
96
|
+
children: [/* @__PURE__ */ i("p", {
|
|
97
|
+
className: "text-b5 font-semibold text-black text-center",
|
|
98
|
+
children: [
|
|
99
|
+
t.resortName,
|
|
100
|
+
/* @__PURE__ */ r("br", {}),
|
|
101
|
+
t.dateRange,
|
|
102
|
+
",",
|
|
103
|
+
/* @__PURE__ */ r("br", {}),
|
|
104
|
+
t.pax
|
|
105
|
+
]
|
|
106
|
+
}), /* @__PURE__ */ r(e, {
|
|
107
|
+
color: "black",
|
|
108
|
+
onClick: () => n?.(t),
|
|
109
|
+
children: t.ctaLabel ?? "See prices"
|
|
110
|
+
})]
|
|
111
|
+
})]
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function s({ quotes: e, onCtaClick: i, className: s }) {
|
|
115
|
+
return e.length === 0 ? null : e.length === 1 ? /* @__PURE__ */ r("div", {
|
|
116
|
+
className: t(s),
|
|
117
|
+
children: /* @__PURE__ */ r(a, {
|
|
118
|
+
quote: e[0],
|
|
119
|
+
onCtaClick: i
|
|
120
|
+
})
|
|
121
|
+
}) : /* @__PURE__ */ r("div", {
|
|
122
|
+
className: t("flex flex-col gap-8", s),
|
|
123
|
+
children: /* @__PURE__ */ r(n, {
|
|
124
|
+
timelineName: "--chat-quote-scroller",
|
|
125
|
+
scrollerClassName: "pb-24",
|
|
126
|
+
scrollbarWidth: "60%",
|
|
127
|
+
"aria-label": "Quote options",
|
|
128
|
+
children: /* @__PURE__ */ r("div", {
|
|
129
|
+
className: "flex gap-12",
|
|
130
|
+
children: e.map((e) => /* @__PURE__ */ r(o, {
|
|
131
|
+
quote: e,
|
|
132
|
+
onCtaClick: i
|
|
133
|
+
}, e.id))
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { s as ChatWindowQuote };
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=ChatWindowQuote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWindowQuote.js","names":[],"sources":["../../lib/ui/ChatWindowQuote.tsx"],"sourcesContent":["'use client';\n\nimport { twMerge } from './helpers/twMerge';\nimport { Button } from './buttons/Button';\nimport { Scrollbar } from './Scrollbar';\n\nexport interface ChatWindowQuoteItem {\n id: string;\n resortName: string;\n country: string;\n imageUrl: string;\n /** Date range, e.g. \"15 June 2026 to 24 June 2026\" */\n dateRange: string;\n /** Pax info, e.g. \"for 2 adults 2 children\" */\n pax: string;\n /** CTA button label. Defaults to \"See prices\" */\n ctaLabel?: string;\n /** Bullet-point package items. Shown in single-quote inline mode only */\n packageIncludes?: string[];\n /** Free-text paragraph shown in single-quote inline mode only */\n additionalInfo?: string;\n}\n\nexport interface ChatWindowQuoteProps {\n quotes: ChatWindowQuoteItem[];\n onCtaClick?: (quote: ChatWindowQuoteItem) => void;\n className?: string;\n}\n\ninterface QuoteCardProps {\n quote: ChatWindowQuoteItem;\n onCtaClick?: (quote: ChatWindowQuoteItem) => void;\n}\n\nfunction SingleQuoteCard({ quote, onCtaClick }: QuoteCardProps) {\n return (\n <article\n aria-label={quote.resortName}\n className=\"flex flex-col bg-white border border-lightGrey rounded-32 shadow-[0px_2px_14px_0px_rgba(0,0,0,0.25)] overflow-hidden p-24 gap-16\"\n >\n <div className=\"relative h-210 w-full overflow-hidden rounded-16\">\n <img src={quote.imageUrl} alt=\"\" className=\"absolute inset-0 size-full object-cover\" />\n <div className=\"absolute inset-0 bg-gradient-to-b from-transparent from-50% to-[rgba(36,36,36,0.4)]\" />\n <div className=\"absolute bottom-20 inset-x-0 flex flex-col items-center text-white text-center px-20\">\n <p className=\"text-b2 font-semibold\">{quote.resortName}</p>\n <p className=\"text-b3\">{quote.country}</p>\n </div>\n </div>\n <div className=\"flex flex-col gap-16 items-center\">\n <p className=\"text-b4 font-semibold text-black text-center\">\n {quote.resortName}, {quote.dateRange}, {quote.pax}\n </p>\n <Button color=\"saffron\" onClick={() => onCtaClick?.(quote)}>\n {quote.ctaLabel ?? 'See prices'}\n </Button>\n {quote.packageIncludes && quote.packageIncludes.length > 0 && (\n <div className=\"flex flex-col gap-4 w-full\">\n <p className=\"text-b3 font-semibold text-black\">Your All-Inclusive package includes:</p>\n <ul className=\"flex flex-col gap-2\">\n {quote.packageIncludes.map((item) => (\n <li key={item} className=\"text-b3 text-black\">\n • {item}\n </li>\n ))}\n </ul>\n </div>\n )}\n {quote.additionalInfo && <p className=\"text-b3 text-black\">{quote.additionalInfo}</p>}\n </div>\n </article>\n );\n}\n\nfunction CompactQuoteCard({ quote, onCtaClick }: QuoteCardProps) {\n return (\n <article\n aria-label={quote.resortName}\n className=\"flex flex-col gap-12 items-center shrink-0 w-200\"\n >\n <div className=\"relative size-200 rounded-16 overflow-hidden\">\n <img src={quote.imageUrl} alt=\"\" className=\"absolute inset-0 size-full object-cover\" />\n <div className=\"absolute inset-0 rounded-16 bg-gradient-to-b from-transparent from-50% to-[rgba(36,36,36,0.4)]\" />\n <div className=\"absolute bottom-20 inset-x-0 flex flex-col items-center text-white text-center px-8\">\n <p className=\"text-b4 font-semibold\">{quote.resortName}</p>\n <p className=\"text-b5\">{quote.country}</p>\n </div>\n </div>\n <div className=\"flex flex-col gap-8 items-center\">\n <p className=\"text-b5 font-semibold text-black text-center\">\n {quote.resortName}\n <br />\n {quote.dateRange},\n <br />\n {quote.pax}\n </p>\n <Button color=\"black\" onClick={() => onCtaClick?.(quote)}>\n {quote.ctaLabel ?? 'See prices'}\n </Button>\n </div>\n </article>\n );\n}\n\nexport function ChatWindowQuote({ quotes, onCtaClick, className }: ChatWindowQuoteProps) {\n if (quotes.length === 0) return null;\n\n if (quotes.length === 1) {\n return (\n <div className={twMerge(className)}>\n <SingleQuoteCard quote={quotes[0]} onCtaClick={onCtaClick} />\n </div>\n );\n }\n\n return (\n <div className={twMerge('flex flex-col gap-8', className)}>\n <Scrollbar\n timelineName=\"--chat-quote-scroller\"\n scrollerClassName=\"pb-24\"\n scrollbarWidth=\"60%\"\n aria-label=\"Quote options\"\n >\n <div className=\"flex gap-12\">\n {quotes.map((quote) => (\n <CompactQuoteCard key={quote.id} quote={quote} onCtaClick={onCtaClick} />\n ))}\n </div>\n </Scrollbar>\n </div>\n );\n}\n"],"mappings":";;;;;;AAkCA,SAAS,EAAgB,EAAE,UAAO,iBAA8B;AAC9D,QACE,kBAAC,WAAD;EACE,cAAY,EAAM;EAClB,WAAU;YAFZ,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,KAAK,EAAM;KAAU,KAAI;KAAG,WAAU;KAA4C,CAAA;IACvF,kBAAC,OAAD,EAAK,WAAU,uFAAwF,CAAA;IACvG,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAyB,EAAM;MAAe,CAAA,EAC3D,kBAAC,KAAD;MAAG,WAAU;gBAAW,EAAM;MAAY,CAAA,CAAA;;;MAG9C,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAb;MACG,EAAM;MAAW;MAAG,EAAM;MAAU;MAAG,EAAM;;;IAEhD,kBAAC,GAAD;KAAQ,OAAM;KAAU,eAAe,IAAa,EAAM;eACvD,EAAM,YAAY;KACZ,CAAA;IACR,EAAM,mBAAmB,EAAM,gBAAgB,SAAS,KACvD,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAAwC,CAAA,EACxF,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAM,gBAAgB,KAAK,MAC1B,kBAAC,MAAD;OAAe,WAAU;iBAAzB,CAA8C,MACzC,EAAA;SADI,EAEJ,CAAA;MAEJ,CAAA,CAAA;;IAGR,EAAM,kBAAkB,kBAAC,KAAD;KAAG,WAAU;eAAsB,EAAM;KAAmB,CAAA;;;;;AAM7F,SAAS,EAAiB,EAAE,UAAO,iBAA8B;AAC/D,QACE,kBAAC,WAAD;EACE,cAAY,EAAM;EAClB,WAAU;YAFZ,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,KAAK,EAAM;KAAU,KAAI;KAAG,WAAU;KAA4C,CAAA;IACvF,kBAAC,OAAD,EAAK,WAAU,kGAAmG,CAAA;IAClH,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAyB,EAAM;MAAe,CAAA,EAC3D,kBAAC,KAAD;MAAG,WAAU;gBAAW,EAAM;MAAY,CAAA,CAAA;;;MAG9C,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAb;KACG,EAAM;KACP,kBAAC,MAAD,EAAM,CAAA;KACL,EAAM;KAAU;KACjB,kBAAC,MAAD,EAAM,CAAA;KACL,EAAM;;OAET,kBAAC,GAAD;IAAQ,OAAM;IAAQ,eAAe,IAAa,EAAM;cACrD,EAAM,YAAY;IACZ,CAAA,CAAA;;;;AAMjB,SAAgB,EAAgB,EAAE,WAAQ,eAAY,gBAAmC;AAWvF,QAVI,EAAO,WAAW,IAAU,OAE5B,EAAO,WAAW,IAElB,kBAAC,OAAD;EAAK,WAAW,EAAQ,EAAU;YAChC,kBAAC,GAAD;GAAiB,OAAO,EAAO;GAAgB;GAAc,CAAA;EACzD,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAW,EAAQ,uBAAuB,EAAU;YACvD,kBAAC,GAAD;GACE,cAAa;GACb,mBAAkB;GAClB,gBAAe;GACf,cAAW;aAEX,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAO,KAAK,MACX,kBAAC,GAAD;KAAwC;KAAmB;KAAc,EAAlD,EAAM,GAA4C,CAAA;IAEvE,CAAA;GACI,CAAA;EACR,CAAA"}
|