@uplifted/react 0.22.6
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/AddClientSheet.d.ts +39 -0
- package/dist/AddClientSheet.d.ts.map +1 -0
- package/dist/AddClientSheet.js +108 -0
- package/dist/AddClientSheet.js.map +1 -0
- package/dist/AiSettingsSheet.d.ts +20 -0
- package/dist/AiSettingsSheet.d.ts.map +1 -0
- package/dist/AiSettingsSheet.js +274 -0
- package/dist/AiSettingsSheet.js.map +1 -0
- package/dist/AssistantGrid.d.ts +30 -0
- package/dist/AssistantGrid.d.ts.map +1 -0
- package/dist/AssistantGrid.js +68 -0
- package/dist/AssistantGrid.js.map +1 -0
- package/dist/AttachmentPicker.d.ts +38 -0
- package/dist/AttachmentPicker.d.ts.map +1 -0
- package/dist/AttachmentPicker.js +173 -0
- package/dist/AttachmentPicker.js.map +1 -0
- package/dist/BulkGenerateSheet.d.ts +25 -0
- package/dist/BulkGenerateSheet.d.ts.map +1 -0
- package/dist/BulkGenerateSheet.js +65 -0
- package/dist/BulkGenerateSheet.js.map +1 -0
- package/dist/ChannelBadge.d.ts +16 -0
- package/dist/ChannelBadge.d.ts.map +1 -0
- package/dist/ChannelBadge.js +19 -0
- package/dist/ChannelBadge.js.map +1 -0
- package/dist/ChannelExplainer.d.ts +17 -0
- package/dist/ChannelExplainer.d.ts.map +1 -0
- package/dist/ChannelExplainer.js +25 -0
- package/dist/ChannelExplainer.js.map +1 -0
- package/dist/ClientList.d.ts +43 -0
- package/dist/ClientList.d.ts.map +1 -0
- package/dist/ClientList.js +76 -0
- package/dist/ClientList.js.map +1 -0
- package/dist/ClosedWindowBanner.d.ts +12 -0
- package/dist/ClosedWindowBanner.d.ts.map +1 -0
- package/dist/ClosedWindowBanner.js +15 -0
- package/dist/ClosedWindowBanner.js.map +1 -0
- package/dist/Composer.d.ts +49 -0
- package/dist/Composer.d.ts.map +1 -0
- package/dist/Composer.js +99 -0
- package/dist/Composer.js.map +1 -0
- package/dist/ComposerExtras.d.ts +15 -0
- package/dist/ComposerExtras.d.ts.map +1 -0
- package/dist/ComposerExtras.js +14 -0
- package/dist/ComposerExtras.js.map +1 -0
- package/dist/ConversationPane.d.ts +33 -0
- package/dist/ConversationPane.d.ts.map +1 -0
- package/dist/ConversationPane.js +126 -0
- package/dist/ConversationPane.js.map +1 -0
- package/dist/DeliveryReceipt.d.ts +7 -0
- package/dist/DeliveryReceipt.d.ts.map +1 -0
- package/dist/DeliveryReceipt.js +13 -0
- package/dist/DeliveryReceipt.js.map +1 -0
- package/dist/DraftGrid.d.ts +17 -0
- package/dist/DraftGrid.d.ts.map +1 -0
- package/dist/DraftGrid.js +43 -0
- package/dist/DraftGrid.js.map +1 -0
- package/dist/HostPreviewPane.d.ts +37 -0
- package/dist/HostPreviewPane.d.ts.map +1 -0
- package/dist/HostPreviewPane.js +106 -0
- package/dist/HostPreviewPane.js.map +1 -0
- package/dist/InlineDrafts.d.ts +14 -0
- package/dist/InlineDrafts.d.ts.map +1 -0
- package/dist/InlineDrafts.js +19 -0
- package/dist/InlineDrafts.js.map +1 -0
- package/dist/ItemActions.d.ts +23 -0
- package/dist/ItemActions.d.ts.map +1 -0
- package/dist/ItemActions.js +83 -0
- package/dist/ItemActions.js.map +1 -0
- package/dist/MediaAttachment.d.ts +7 -0
- package/dist/MediaAttachment.d.ts.map +1 -0
- package/dist/MediaAttachment.js +37 -0
- package/dist/MediaAttachment.js.map +1 -0
- package/dist/OfferSheet.d.ts +32 -0
- package/dist/OfferSheet.d.ts.map +1 -0
- package/dist/OfferSheet.js +84 -0
- package/dist/OfferSheet.js.map +1 -0
- package/dist/ProactiveOptionsSheet.d.ts +14 -0
- package/dist/ProactiveOptionsSheet.d.ts.map +1 -0
- package/dist/ProactiveOptionsSheet.js +58 -0
- package/dist/ProactiveOptionsSheet.js.map +1 -0
- package/dist/QuickSend.d.ts +15 -0
- package/dist/QuickSend.d.ts.map +1 -0
- package/dist/QuickSend.js +90 -0
- package/dist/QuickSend.js.map +1 -0
- package/dist/SegmentEditor.d.ts +25 -0
- package/dist/SegmentEditor.d.ts.map +1 -0
- package/dist/SegmentEditor.js +95 -0
- package/dist/SegmentEditor.js.map +1 -0
- package/dist/Sheet.d.ts +13 -0
- package/dist/Sheet.d.ts.map +1 -0
- package/dist/Sheet.js +64 -0
- package/dist/Sheet.js.map +1 -0
- package/dist/ThreadFeed.d.ts +27 -0
- package/dist/ThreadFeed.d.ts.map +1 -0
- package/dist/ThreadFeed.js +42 -0
- package/dist/ThreadFeed.js.map +1 -0
- package/dist/UpliftPanel.d.ts +40 -0
- package/dist/UpliftPanel.d.ts.map +1 -0
- package/dist/UpliftPanel.js +219 -0
- package/dist/UpliftPanel.js.map +1 -0
- package/dist/UpliftProvider.d.ts +15 -0
- package/dist/UpliftProvider.d.ts.map +1 -0
- package/dist/UpliftProvider.js +19 -0
- package/dist/UpliftProvider.js.map +1 -0
- package/dist/WaitingTemplateGhost.d.ts +12 -0
- package/dist/WaitingTemplateGhost.d.ts.map +1 -0
- package/dist/WaitingTemplateGhost.js +16 -0
- package/dist/WaitingTemplateGhost.js.map +1 -0
- package/dist/channels.d.ts +22 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +31 -0
- package/dist/channels.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/host.d.ts +45 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +35 -0
- package/dist/host.js.map +1 -0
- package/dist/icons.d.ts +48 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +71 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/labels.d.ts +58 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +86 -0
- package/dist/labels.js.map +1 -0
- package/dist/phone.d.ts +18 -0
- package/dist/phone.d.ts.map +1 -0
- package/dist/phone.js +27 -0
- package/dist/phone.js.map +1 -0
- package/dist/proactiveIcons.d.ts +6 -0
- package/dist/proactiveIcons.d.ts.map +1 -0
- package/dist/proactiveIcons.js +39 -0
- package/dist/proactiveIcons.js.map +1 -0
- package/dist/purposes.d.ts +19 -0
- package/dist/purposes.d.ts.map +1 -0
- package/dist/purposes.js +20 -0
- package/dist/purposes.js.map +1 -0
- package/dist/segments.d.ts +29 -0
- package/dist/segments.d.ts.map +1 -0
- package/dist/segments.js +75 -0
- package/dist/segments.js.map +1 -0
- package/dist/smsSegments.d.ts +28 -0
- package/dist/smsSegments.d.ts.map +1 -0
- package/dist/smsSegments.js +100 -0
- package/dist/smsSegments.js.map +1 -0
- package/dist/styles.d.ts +15 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +545 -0
- package/dist/styles.js.map +1 -0
- package/dist/time.d.ts +14 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +80 -0
- package/dist/time.js.map +1 -0
- package/dist/useAiSettings.d.ts +11 -0
- package/dist/useAiSettings.d.ts.map +1 -0
- package/dist/useAiSettings.js +21 -0
- package/dist/useAiSettings.js.map +1 -0
- package/dist/useBilling.d.ts +40 -0
- package/dist/useBilling.d.ts.map +1 -0
- package/dist/useBilling.js +155 -0
- package/dist/useBilling.js.map +1 -0
- package/dist/useBulkDrafts.d.ts +41 -0
- package/dist/useBulkDrafts.d.ts.map +1 -0
- package/dist/useBulkDrafts.js +112 -0
- package/dist/useBulkDrafts.js.map +1 -0
- package/dist/useClients.d.ts +16 -0
- package/dist/useClients.d.ts.map +1 -0
- package/dist/useClients.js +22 -0
- package/dist/useClients.js.map +1 -0
- package/dist/useDeliveryStatus.d.ts +7 -0
- package/dist/useDeliveryStatus.d.ts.map +1 -0
- package/dist/useDeliveryStatus.js +39 -0
- package/dist/useDeliveryStatus.js.map +1 -0
- package/dist/useDrafts.d.ts +19 -0
- package/dist/useDrafts.d.ts.map +1 -0
- package/dist/useDrafts.js +60 -0
- package/dist/useDrafts.js.map +1 -0
- package/dist/useInstructions.d.ts +9 -0
- package/dist/useInstructions.d.ts.map +1 -0
- package/dist/useInstructions.js +20 -0
- package/dist/useInstructions.js.map +1 -0
- package/dist/useLiveUpdates.d.ts +9 -0
- package/dist/useLiveUpdates.d.ts.map +1 -0
- package/dist/useLiveUpdates.js +48 -0
- package/dist/useLiveUpdates.js.map +1 -0
- package/dist/usePolling.d.ts +6 -0
- package/dist/usePolling.d.ts.map +1 -0
- package/dist/usePolling.js +31 -0
- package/dist/usePolling.js.map +1 -0
- package/dist/usePreviewDrafts.d.ts +15 -0
- package/dist/usePreviewDrafts.d.ts.map +1 -0
- package/dist/usePreviewDrafts.js +77 -0
- package/dist/usePreviewDrafts.js.map +1 -0
- package/dist/useProactiveOptions.d.ts +15 -0
- package/dist/useProactiveOptions.d.ts.map +1 -0
- package/dist/useProactiveOptions.js +39 -0
- package/dist/useProactiveOptions.js.map +1 -0
- package/dist/useSend.d.ts +16 -0
- package/dist/useSend.d.ts.map +1 -0
- package/dist/useSend.js +50 -0
- package/dist/useSend.js.map +1 -0
- package/dist/useStickToBottom.d.ts +12 -0
- package/dist/useStickToBottom.d.ts.map +1 -0
- package/dist/useStickToBottom.js +71 -0
- package/dist/useStickToBottom.js.map +1 -0
- package/dist/useThread.d.ts +26 -0
- package/dist/useThread.d.ts.map +1 -0
- package/dist/useThread.js +76 -0
- package/dist/useThread.js.map +1 -0
- package/dist/useWhatsAppWindow.d.ts +8 -0
- package/dist/useWhatsAppWindow.d.ts.map +1 -0
- package/dist/useWhatsAppWindow.js +22 -0
- package/dist/useWhatsAppWindow.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Sheet } from "./Sheet.js";
|
|
4
|
+
import { CHANNELS } from "./channels.js";
|
|
5
|
+
import { IconCheck } from "./icons.js";
|
|
6
|
+
import { ChannelExplainer, ChannelInfoButton } from "./ChannelExplainer.js";
|
|
7
|
+
import { avatarColor, firstName, initials } from "./labels.js";
|
|
8
|
+
import { formatPlan, useBilling } from "./useBilling.js";
|
|
9
|
+
const BENEFITS = [
|
|
10
|
+
["Celebrate every win", "PRs and streaks, drafted with the real numbers in them"],
|
|
11
|
+
["Catch clients before they slip", "a no-guilt nudge the moment someone goes quiet"],
|
|
12
|
+
["Nail every check-in", "their whole week, in your voice, in seconds"],
|
|
13
|
+
];
|
|
14
|
+
function namesLine(cs) {
|
|
15
|
+
const n = cs.map((c) => firstName(c.name));
|
|
16
|
+
if (n.length <= 1)
|
|
17
|
+
return n.join("");
|
|
18
|
+
if (n.length === 2)
|
|
19
|
+
return `${n[0]} and ${n[1]}`;
|
|
20
|
+
return `${n.slice(0, 2).join(", ")} and ${n.length - 2} more`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The paywall (S5 pricing), worded for why it opened, then the required "How Uplift messaging
|
|
24
|
+
* works" step before checkout (D9). A coach who already has connected clients went through that
|
|
25
|
+
* explanation when adding them, so the CTA goes straight to checkout. The price comes from the
|
|
26
|
+
* Stripe price via GET /billing/plan, never from the host. Copy follows the Uplift Propane page.
|
|
27
|
+
*/
|
|
28
|
+
export function OfferSheet({ onClose, onCheckout, freeClients = 2, hostName, reason = "pitch", connecting, connected = [], onUpgraded }) {
|
|
29
|
+
const billing = useBilling();
|
|
30
|
+
const [step, setStep] = useState("offer");
|
|
31
|
+
const [tick, setTick] = useState(false);
|
|
32
|
+
const [hostOpening, setHostOpening] = useState(false);
|
|
33
|
+
const [explain, setExplain] = useState(null);
|
|
34
|
+
const first = connecting ? firstName(connecting) : null;
|
|
35
|
+
// Adding a client already required acknowledging how messages are sent.
|
|
36
|
+
const seenHow = connected.length > 0;
|
|
37
|
+
const shown = billing.plan ? formatPlan(billing.plan) : null;
|
|
38
|
+
const unavailable = !onCheckout && billing.unavailable;
|
|
39
|
+
const opening = onCheckout ? hostOpening : billing.status === "opening";
|
|
40
|
+
const eyebrow = reason === "client_limit" ? `Free plan · ${Math.min(connected.length, freeClients)} of ${freeClients} clients connected`
|
|
41
|
+
: reason === "plan_inactive" ? "Your Uplift plan isn't active"
|
|
42
|
+
: reason === "feature" ? "Paid plan"
|
|
43
|
+
: `Uplift for ${hostName}`;
|
|
44
|
+
const title = reason === "client_limit" ? (first ? `Connect ${first} with Uplift` : "Unlock unlimited clients")
|
|
45
|
+
: reason === "plan_inactive" ? "Pick up where you left off"
|
|
46
|
+
: reason === "feature" ? "Unlock canned answers and phase goals"
|
|
47
|
+
: "Coach 10x more clients in 10% the time.";
|
|
48
|
+
const cta = reason === "client_limit" ? (first ? `Upgrade to connect ${first}` : "Upgrade")
|
|
49
|
+
: reason === "plan_inactive" ? "Reactivate"
|
|
50
|
+
: reason === "feature" ? "Upgrade"
|
|
51
|
+
: "Get Uplift";
|
|
52
|
+
// The webhook switched the plan on: resume what the coach was doing, or say so.
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (billing.status !== "active")
|
|
55
|
+
return;
|
|
56
|
+
if (onUpgraded)
|
|
57
|
+
onUpgraded();
|
|
58
|
+
else
|
|
59
|
+
setStep("done");
|
|
60
|
+
}, [billing.status]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
61
|
+
const checkout = () => {
|
|
62
|
+
if ((!tick && !seenHow) || opening || unavailable)
|
|
63
|
+
return;
|
|
64
|
+
if (!onCheckout) {
|
|
65
|
+
billing.start();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
setHostOpening(true);
|
|
69
|
+
Promise.resolve(onCheckout()).then(() => { onUpgraded?.(); }, () => { }).finally(() => setHostOpening(false));
|
|
70
|
+
};
|
|
71
|
+
const ctaButton = (label, enabled) => (_jsx("button", { type: "button", className: "u-send", disabled: !enabled || opening || unavailable, "aria-busy": opening, onClick: checkout, children: opening ? "Opening checkout…" : label }));
|
|
72
|
+
const note = unavailable
|
|
73
|
+
? _jsx("div", { className: "u-note u-note-warn", role: "status", children: "Upgrading isn't available yet. Please try again later." })
|
|
74
|
+
: billing.error ? _jsx("div", { className: "u-note u-note-warn", role: "alert", children: billing.error }) : null;
|
|
75
|
+
if (billing.status === "waiting" && step !== "done") {
|
|
76
|
+
return (_jsxs(Sheet, { labelledBy: "u-offer-title", onClose: onClose, children: [_jsx("p", { className: "u-eyebrow", children: "Checkout is open in a new tab" }), _jsx("h3", { id: "u-offer-title", children: "Finish checkout in the new tab" }), _jsxs("p", { className: "u-lede", children: ["Pay securely with Stripe. This updates by itself once your payment goes through", first ? `, then we'll carry on connecting ${first}` : "", "."] }), _jsx("p", { className: "u-hint", role: "status", "aria-live": "polite", children: "Waiting for payment\u2026" }), billing.url && _jsxs("p", { className: "u-hint", children: ["Tab didn't open? ", _jsx("a", { className: "u-linkbtn", href: billing.url, target: "_blank", rel: "noopener noreferrer", children: "Open checkout" })] }), _jsxs("div", { className: "u-actions", children: [_jsx("button", { type: "button", className: "u-secondary", onClick: () => { billing.reset(); }, children: "\u2190 Back" }), _jsx("span", { className: "u-sp" }), _jsx("button", { type: "button", className: "u-send", onClick: billing.recheck, children: "I've paid, check now" })] })] }));
|
|
77
|
+
}
|
|
78
|
+
return (_jsxs(Sheet, { labelledBy: "u-offer-title", onClose: onClose, children: [step === "done" && (_jsxs(_Fragment, { children: [_jsx("p", { className: "u-eyebrow", children: "Plan active" }), _jsx("h3", { id: "u-offer-title", children: "You're on Uplift" }), _jsx("p", { className: "u-lede", children: "Unlimited clients from now on. Stripe has emailed your receipt." }), _jsxs("div", { className: "u-actions", children: [_jsx("span", { className: "u-sp" }), _jsx("button", { type: "button", className: "u-send", onClick: onClose, children: "Done" })] })] })), step === "offer" && (_jsxs(_Fragment, { children: [_jsx("p", { className: "u-eyebrow", children: eyebrow }), _jsx("h3", { id: "u-offer-title", children: title }), reason === "client_limit" && connected.length > 0 && (_jsxs("div", { className: "u-offer-who", children: [_jsx("span", { className: "u-offer-avs", "aria-hidden": "true", children: connected.slice(0, 3).map((c) => _jsx("span", { className: "u-av u-av-sm", style: { background: avatarColor(c.id) }, children: initials(c.name) }, c.id)) }), _jsxs("span", { children: [namesLine(connected), " ", connected.length === 1 ? "is" : "are", " on your free plan."] })] })), _jsxs("p", { className: "u-lede", children: [_jsx("b", { children: "Uplift does the heavy lifting. You build the relationship." }), " Every update in ", hostName, " becomes a message in your voice, ready to send in seconds."] }), _jsx("ul", { className: "u-offer-list", children: BENEFITS.map(([h, t]) => _jsxs("li", { children: [_jsx("span", { className: "u-offer-tick", children: _jsx(IconCheck, {}) }), _jsxs("span", { children: [_jsx("b", { children: h }), ": ", t] })] }, h)) }), _jsxs("div", { className: "u-plan", children: [shown
|
|
79
|
+
? _jsxs("div", { className: "u-plan-price", children: [shown.price, _jsxs("small", { children: ["/", shown.per] })] })
|
|
80
|
+
: !unavailable && _jsx("div", { className: "u-plan-vs", children: "Price shown at checkout" }), _jsx("div", { className: "u-plan-vs", children: "Unlimited clients \u00B7 canned answers and phase goals \u00B7 cancel any time" })] }), seenHow && note, _jsxs("div", { className: "u-actions", children: [_jsx("button", { type: "button", className: "u-secondary", onClick: onClose, children: "Not now" }), _jsx("span", { className: "u-sp" }), seenHow
|
|
81
|
+
? ctaButton(`${cta} →`, true)
|
|
82
|
+
: _jsxs("button", { type: "button", className: "u-send", disabled: unavailable, onClick: () => setStep("how"), children: [cta, " \u2192"] })] }), !seenHow && unavailable && note] })), step === "how" && (_jsxs(_Fragment, { children: [_jsx("p", { className: "u-eyebrow", children: "Before you pay" }), _jsx("h3", { id: "u-offer-title", children: "How Uplift messaging works" }), _jsxs("p", { className: "u-lede", children: ["Your messages go from ", _jsx("b", { children: "Uplift's number" }), " straight to each client's own WhatsApp or SMS, ", _jsxs("b", { children: ["outside ", hostName] }), ". Clients stay on the app they already use, and their replies come back to this panel."] }), CHANNELS.map((c) => (_jsxs("div", { className: "u-chanbox", children: [_jsxs("h4", { className: "u-cx-h4", children: [c.label, _jsx(ChannelInfoButton, { channel: c.key, label: c.label, onOpen: setExplain })] }), _jsx("p", { children: c.summary })] }, c.key))), _jsxs("label", { className: "u-tick", children: [_jsx("input", { type: "checkbox", checked: tick, onChange: (e) => setTick(e.target.checked) }), _jsx("span", { children: "I understand how messages are sent" })] }), note, _jsxs("div", { className: "u-actions", children: [_jsx("button", { type: "button", className: "u-secondary", onClick: () => setStep("offer"), children: "\u2190 Back" }), _jsx("span", { className: "u-sp" }), ctaButton("Continue to checkout", tick)] })] })), explain && _jsx(ChannelExplainer, { channel: explain, onClose: () => setExplain(null) })] }));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=OfferSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OfferSheet.js","sourceRoot":"","sources":["../src/OfferSheet.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA2BzD,MAAM,QAAQ,GAA4B;IACxC,CAAC,qBAAqB,EAAE,wDAAwD,CAAC;IACjF,CAAC,gCAAgC,EAAE,gDAAgD,CAAC;IACpF,CAAC,qBAAqB,EAAE,6CAA6C,CAAC;CACvE,CAAC;AAEF,SAAS,SAAS,CAAC,EAAmC;IACpD,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,UAAU,EAAE,SAAS,GAAG,EAAE,EAAE,UAAU,EAAmB;IACtJ,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAO,OAAO,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,wEAAwE;IACxE,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,MAAM,WAAW,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC;IAExE,MAAM,OAAO,GAAG,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,WAAW,oBAAoB;QACtI,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,+BAA+B;YAC9D,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW;gBACpC,CAAC,CAAC,cAAc,QAAQ,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,KAAK,cAAc,CAAC,CAAC,CAAC,0BAA0B,CAAC;QAC7G,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,4BAA4B;YAC3D,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,uCAAuC;gBAChE,CAAC,CAAC,yCAAyC,CAAC;IAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACzF,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,YAAY;YAC3C,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS;gBAClC,CAAC,CAAC,YAAY,CAAC;IAEjB,gFAAgF;IAChF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO;QACxC,IAAI,UAAU;YAAE,UAAU,EAAE,CAAC;;YAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,kDAAkD;IAExE,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,WAAW;YAAE,OAAO;QAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAC7C,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/G,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,OAAgB,EAAE,EAAE,CAAC,CACrD,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,OAAO,IAAI,OAAO,IAAI,WAAW,eAAa,OAAO,EAAE,OAAO,EAAE,QAAQ,YACzH,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,GAC/B,CACV,CAAC;IACF,MAAM,IAAI,GAAG,WAAW;QACtB,CAAC,CAAC,cAAK,SAAS,EAAC,oBAAoB,EAAC,IAAI,EAAC,QAAQ,uEAA6D;QAChH,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,oBAAoB,EAAC,IAAI,EAAC,OAAO,YAAE,OAAO,CAAC,KAAK,GAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAElG,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpD,OAAO,CACL,MAAC,KAAK,IAAC,UAAU,EAAC,eAAe,EAAC,OAAO,EAAE,OAAO,aAChD,YAAG,SAAS,EAAC,WAAW,8CAAkC,EAC1D,aAAI,EAAE,EAAC,eAAe,+CAAoC,EAC1D,aAAG,SAAS,EAAC,QAAQ,gGAAiF,KAAK,CAAC,CAAC,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAM,EACpK,YAAG,SAAS,EAAC,QAAQ,EAAC,IAAI,EAAC,QAAQ,eAAW,QAAQ,0CAAyB,EAC9E,OAAO,CAAC,GAAG,IAAI,aAAG,SAAS,EAAC,QAAQ,kCAAkB,YAAG,SAAS,EAAC,WAAW,EAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,8BAAkB,IAAI,EAClK,eAAK,SAAS,EAAC,WAAW,aACxB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,aAAa,EAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,4BAAiB,EAClG,eAAM,SAAS,EAAC,MAAM,GAAG,EACzB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,qCAA+B,IAC5F,IACA,CACT,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,KAAK,IAAC,UAAU,EAAC,eAAe,EAAC,OAAO,EAAE,OAAO,aAC/C,IAAI,KAAK,MAAM,IAAI,CAClB,8BACE,YAAG,SAAS,EAAC,WAAW,4BAAgB,EACxC,aAAI,EAAE,EAAC,eAAe,iCAAsB,EAC5C,YAAG,SAAS,EAAC,QAAQ,gFAAoE,EACzF,eAAK,SAAS,EAAC,WAAW,aAAC,eAAM,SAAS,EAAC,MAAM,GAAG,EAAA,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,qBAAe,IAAM,IACjI,CACJ,EACA,IAAI,KAAK,OAAO,IAAI,CACnB,8BACE,YAAG,SAAS,EAAC,WAAW,YAAE,OAAO,GAAK,EACtC,aAAI,EAAE,EAAC,eAAe,YAAE,KAAK,GAAM,EAClC,MAAM,KAAK,cAAc,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CACpD,eAAK,SAAS,EAAC,aAAa,aAC1B,eAAM,SAAS,EAAC,aAAa,iBAAa,MAAM,YAC7C,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAiB,SAAS,EAAC,cAAc,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,YAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAA1F,CAAC,CAAC,EAAE,CAA8F,CAAC,GAC3I,EACP,2BAAO,SAAS,CAAC,SAAS,CAAC,OAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,2BAA2B,IAC1F,CACP,EACD,aAAG,SAAS,EAAC,QAAQ,aAAC,qFAAiE,uBAAkB,QAAQ,mEAAgE,EACjL,aAAI,SAAS,EAAC,cAAc,YACzB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,yBAAY,eAAM,SAAS,EAAC,cAAc,YAAC,KAAC,SAAS,KAAG,GAAO,EAAA,2BAAM,sBAAI,CAAC,GAAK,QAAG,CAAC,IAAQ,KAAlF,CAAC,CAAsF,CAAC,GACxH,EACL,eAAK,SAAS,EAAC,QAAQ,aACpB,KAAK;gCACJ,CAAC,CAAC,eAAK,SAAS,EAAC,cAAc,aAAE,KAAK,CAAC,KAAK,EAAC,iCAAS,KAAK,CAAC,GAAG,IAAS,IAAM;gCAC9E,CAAC,CAAC,CAAC,WAAW,IAAI,cAAK,SAAS,EAAC,WAAW,wCAA8B,EAC5E,cAAK,SAAS,EAAC,WAAW,+FAA2E,IACjG,EACL,OAAO,IAAI,IAAI,EAChB,eAAK,SAAS,EAAC,WAAW,aACxB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,aAAa,EAAC,OAAO,EAAE,OAAO,wBAAkB,EAChF,eAAM,SAAS,EAAC,MAAM,GAAG,EACxB,OAAO;gCACN,CAAC,CAAC,SAAS,CAAC,GAAG,GAAG,IAAI,EAAE,IAAI,CAAC;gCAC7B,CAAC,CAAC,kBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,aAAG,GAAG,eAAY,IAC/G,EACL,CAAC,OAAO,IAAI,WAAW,IAAI,IAAI,IAC/B,CACJ,EACA,IAAI,KAAK,KAAK,IAAI,CACjB,8BACE,YAAG,SAAS,EAAC,WAAW,+BAAmB,EAC3C,aAAI,EAAE,EAAC,eAAe,2CAAgC,EACtD,aAAG,SAAS,EAAC,QAAQ,uCAAuB,0CAAsB,sDAAgD,oCAAY,QAAQ,IAAK,8FAA0F,EACpO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACnB,eAAiB,SAAS,EAAC,WAAW,aACpC,cAAI,SAAS,EAAC,SAAS,aAAE,CAAC,CAAC,KAAK,EAAC,KAAC,iBAAiB,IAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAI,IAAK,EAC/G,sBAAI,CAAC,CAAC,OAAO,GAAK,KAFV,CAAC,CAAC,GAAG,CAGT,CACP,CAAC,EACF,iBAAO,SAAS,EAAC,QAAQ,aACvB,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAI,EACpF,gEAA+C,IACzC,EACP,IAAI,EACL,eAAK,SAAS,EAAC,WAAW,aACxB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,aAAa,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,4BAAiB,EAC9F,eAAM,SAAS,EAAC,MAAM,GAAG,EACxB,SAAS,CAAC,sBAAsB,EAAE,IAAI,CAAC,IACpC,IACL,CACJ,EACA,OAAO,IAAI,KAAC,gBAAgB,IAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAI,IAC7E,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProactiveOptionsState } from "./useProactiveOptions.js";
|
|
2
|
+
/**
|
|
3
|
+
* In-panel editor for the ✨ menu, a port of native Settings › AI › Proactive (ProactiveOptionsEditor):
|
|
4
|
+
* icon, label, order, AI guidance or an exact message, up to ten; Save, and Restore defaults.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ProactiveOptionsSheet({ state, onClose }: {
|
|
7
|
+
state: ProactiveOptionsState;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
/** The ✨ options editor itself, also the Proactive tab of AI settings. */
|
|
11
|
+
export declare function ProactiveOptionsEditor({ state }: {
|
|
12
|
+
state: ProactiveOptionsState;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=ProactiveOptionsSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProactiveOptionsSheet.d.ts","sourceRoot":"","sources":["../src/ProactiveOptionsSheet.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAsBtE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAAE,KAAK,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BAQ9G;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,qBAAqB,CAAA;CAAE,+BAmDjF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { IconChevronDown, IconChevronUp, IconX } from "./icons.js";
|
|
4
|
+
import { PROACTIVE_ICON_MAP, PROACTIVE_ICON_NAMES, proactiveIcon } from "./proactiveIcons.js";
|
|
5
|
+
import { Sheet } from "./Sheet.js";
|
|
6
|
+
const MAX_OPTIONS = 10;
|
|
7
|
+
function IconPicker({ value, onPick }) {
|
|
8
|
+
const [open, setOpen] = useState(false);
|
|
9
|
+
const Cur = proactiveIcon(value);
|
|
10
|
+
return (_jsxs("div", { className: "u-po-iconwrap", children: [_jsx("button", { type: "button", className: "u-po-iconbtn", title: "Change icon", "aria-label": `Icon: ${value}. Change icon`, "aria-expanded": open, onClick: () => setOpen((o) => !o), children: _jsx(Cur, {}) }), open && (_jsx("div", { className: "u-po-iconpick", role: "listbox", "aria-label": "Icons", children: PROACTIVE_ICON_NAMES.map((name) => {
|
|
11
|
+
const I = PROACTIVE_ICON_MAP[name];
|
|
12
|
+
return (_jsx("button", { type: "button", role: "option", "aria-selected": name === value, className: `u-po-iconbtn${name === value ? " u-po-iconbtn-on" : ""}`, title: name, "aria-label": name, onClick: () => { onPick(name); setOpen(false); }, children: _jsx(I, {}) }, name));
|
|
13
|
+
}) }))] }));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* In-panel editor for the ✨ menu, a port of native Settings › AI › Proactive (ProactiveOptionsEditor):
|
|
17
|
+
* icon, label, order, AI guidance or an exact message, up to ten; Save, and Restore defaults.
|
|
18
|
+
*/
|
|
19
|
+
export function ProactiveOptionsSheet({ state, onClose }) {
|
|
20
|
+
return (_jsxs(Sheet, { labelledBy: "u-po-title", onClose: onClose, children: [_jsx("p", { className: "u-eyebrow", children: "Settings" }), _jsx("h3", { id: "u-po-title", children: "Generate message options" }), _jsx(ProactiveOptionsEditor, { state: state })] }));
|
|
21
|
+
}
|
|
22
|
+
/** The ✨ options editor itself, also the Proactive tab of AI settings. */
|
|
23
|
+
export function ProactiveOptionsEditor({ state }) {
|
|
24
|
+
const toRows = (ps) => ps.map((p) => ({ id: p.id, label: p.label, icon: p.icon, prompt: p.prompt, cannedText: p.cannedText ?? "" }));
|
|
25
|
+
const [rows, setRows] = useState(() => toRows(state.purposes));
|
|
26
|
+
const [saved, setSaved] = useState(false);
|
|
27
|
+
const [localError, setLocalError] = useState(null);
|
|
28
|
+
const update = (i, field, value) => setRows((rs) => rs.map((r, j) => (j === i ? { ...r, [field]: value } : r)));
|
|
29
|
+
const move = (i, dir) => setRows((rs) => { const j = i + dir; if (j < 0 || j >= rs.length)
|
|
30
|
+
return rs; const next = rs.slice(); [next[i], next[j]] = [next[j], next[i]]; return next; });
|
|
31
|
+
const remove = (i) => setRows((rs) => rs.filter((_, j) => j !== i));
|
|
32
|
+
const add = () => setRows((rs) => [...rs, { id: null, label: "", icon: "message-circle", prompt: "", cannedText: "" }]);
|
|
33
|
+
const persist = async () => {
|
|
34
|
+
setLocalError(null);
|
|
35
|
+
const payload = rows.map((r) => ({ ...(r.id ? { id: r.id } : {}), label: r.label.trim(), icon: r.icon, ...(r.prompt.trim() ? { prompt: r.prompt.trim() } : {}), ...(r.cannedText.trim() ? { cannedText: r.cannedText.trim() } : {}) }));
|
|
36
|
+
if (payload.some((p) => !p.label)) {
|
|
37
|
+
setLocalError("Every option needs a label");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (payload.some((p) => !p.prompt && !p.cannedText)) {
|
|
41
|
+
setLocalError("Each option needs AI guidance or an exact message");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const ok = await state.save(payload);
|
|
45
|
+
if (ok) {
|
|
46
|
+
setSaved(true);
|
|
47
|
+
setTimeout(() => setSaved(false), 2000);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const restore = async () => {
|
|
51
|
+
setLocalError(null);
|
|
52
|
+
const ok = await state.save(null);
|
|
53
|
+
if (ok)
|
|
54
|
+
setRows(toRows(state.purposes.length ? state.purposes : []));
|
|
55
|
+
};
|
|
56
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: "u-po-help", children: "These are the \u2728 options on every conversation. Give each one AI guidance (what kind of message to write) or an exact message to send as written, lightly personalised. Edits show in Uplift too." }), _jsx("div", { className: "u-po-list", children: rows.map((o, i) => (_jsxs("div", { className: "u-po-row", children: [_jsxs("div", { className: "u-po-top", children: [_jsx(IconPicker, { value: o.icon, onPick: (name) => update(i, "icon", name) }), _jsx("input", { className: "u-po-label", "aria-label": `Option ${i + 1} label`, placeholder: "Label (e.g. Weekly Check-In)", maxLength: 24, value: o.label, onChange: (e) => update(i, "label", e.target.value) }), _jsx("button", { type: "button", className: "u-po-iconbtn", onClick: () => move(i, -1), disabled: i === 0, title: "Move up", "aria-label": `Move option ${i + 1} up`, children: _jsx(IconChevronUp, {}) }), _jsx("button", { type: "button", className: "u-po-iconbtn", onClick: () => move(i, 1), disabled: i === rows.length - 1, title: "Move down", "aria-label": `Move option ${i + 1} down`, children: _jsx(IconChevronDown, {}) }), _jsx("button", { type: "button", className: "u-po-iconbtn u-po-remove", onClick: () => remove(i), title: "Remove option", "aria-label": `Remove option ${i + 1}`, children: _jsx(IconX, {}) })] }), _jsx("textarea", { className: "u-po-text", "aria-label": `Option ${i + 1} AI guidance`, maxLength: 500, rows: 2, placeholder: "AI guidance \u2014 what kind of message should this write? (e.g. Check in with the client depending on the time of day)", value: o.prompt, onChange: (e) => update(i, "prompt", e.target.value) }), _jsx("textarea", { className: "u-po-text", "aria-label": `Option ${i + 1} exact message`, maxLength: 2000, rows: 2, placeholder: "Exact message (optional) — sent as written, lightly personalized. Great for a questionnaire, e.g.\n1. How were workouts this week?\n2. How is sleep?", value: o.cannedText, onChange: (e) => update(i, "cannedText", e.target.value) })] }, i))) }), rows.length < MAX_OPTIONS && _jsx("button", { type: "button", className: "u-po-add", onClick: add, children: "+ Add option" }), (localError || state.error) && _jsx("div", { className: "u-note u-note-err", role: "alert", children: localError ?? state.error?.message }), _jsxs("div", { className: "u-po-actions", children: [_jsx("button", { type: "button", className: "u-send", onClick: () => { void persist(); }, disabled: state.saving || rows.length === 0, "aria-busy": state.saving, children: state.saving ? "Saving…" : saved ? "Saved ✓" : "Save options" }), state.isCustom && _jsx("button", { type: "button", className: "u-gen", onClick: () => { void restore(); }, disabled: state.saving, title: "Go back to the six built-in options", children: "Restore defaults" })] })] }));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ProactiveOptionsSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProactiveOptionsSheet.js","sourceRoot":"","sources":["../src/ProactiveOptionsSheet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Client, DraftSet } from "@uplifted/sdk";
|
|
2
|
+
export declare const QS_INTRO_KEY = "uplift_quicksend_intro_seen";
|
|
3
|
+
export declare const QS_UNDO_SECONDS = 5;
|
|
4
|
+
/**
|
|
5
|
+
* The quick-send chip on an inbox row, a port of native ClientRow's QuickSendButton: the shortest
|
|
6
|
+
* prepared draft, sent with no editing. Tap → a 5-second "Undo (n)" countdown → send. The first
|
|
7
|
+
* ever tap explains itself once (remembered in localStorage). Stops propagation so the row does
|
|
8
|
+
* not open.
|
|
9
|
+
*/
|
|
10
|
+
export declare function QuickSend({ client, drafts, onSent }: {
|
|
11
|
+
client: Client;
|
|
12
|
+
drafts: DraftSet;
|
|
13
|
+
onSent?: ((client: Client, body: string) => void) | undefined;
|
|
14
|
+
}): import("react").JSX.Element | null;
|
|
15
|
+
//# sourceMappingURL=QuickSend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuickSend.d.ts","sourceRoot":"","sources":["../src/QuickSend.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKtD,eAAO,MAAM,YAAY,gCAAgC,CAAC;AAC1D,eAAO,MAAM,eAAe,IAAI,CAAC;AAQjC;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAAE,sCA+ExJ"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { IconCheckCircle, IconLoader, IconUndo, IconZap } from "./icons.js";
|
|
4
|
+
import { Sheet } from "./Sheet.js";
|
|
5
|
+
import { useUplift } from "./UpliftProvider.js";
|
|
6
|
+
export const QS_INTRO_KEY = "uplift_quicksend_intro_seen";
|
|
7
|
+
export const QS_UNDO_SECONDS = 5;
|
|
8
|
+
function newKey() {
|
|
9
|
+
const c = globalThis.crypto;
|
|
10
|
+
return c && typeof c.randomUUID === "function" ? c.randomUUID() : `k_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 12)}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The quick-send chip on an inbox row, a port of native ClientRow's QuickSendButton: the shortest
|
|
14
|
+
* prepared draft, sent with no editing. Tap → a 5-second "Undo (n)" countdown → send. The first
|
|
15
|
+
* ever tap explains itself once (remembered in localStorage). Stops propagation so the row does
|
|
16
|
+
* not open.
|
|
17
|
+
*/
|
|
18
|
+
export function QuickSend({ client, drafts, onSent }) {
|
|
19
|
+
const { client: api } = useUplift();
|
|
20
|
+
const draft = drafts.five_words || drafts.happy || "";
|
|
21
|
+
const [phase, setPhase] = useState("idle");
|
|
22
|
+
const [countdown, setCountdown] = useState(QS_UNDO_SECONDS);
|
|
23
|
+
const [showIntro, setShowIntro] = useState(false);
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
const timer = useRef(null);
|
|
26
|
+
const key = useRef(newKey());
|
|
27
|
+
useEffect(() => () => { if (timer.current)
|
|
28
|
+
clearInterval(timer.current); }, []);
|
|
29
|
+
const words = draft.trim().split(/\s+/);
|
|
30
|
+
const truncated = words.length <= 6 ? draft : `${words.slice(0, 6).join(" ")}…`;
|
|
31
|
+
const doSend = useCallback(async () => {
|
|
32
|
+
setPhase("sending");
|
|
33
|
+
try {
|
|
34
|
+
await api.send(client.id, { body: draft, idempotencyKey: key.current });
|
|
35
|
+
setPhase("sent");
|
|
36
|
+
setTimeout(() => onSent?.(client, draft), 600);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
setError(err?.message || "Failed to send");
|
|
40
|
+
setPhase("error");
|
|
41
|
+
key.current = newKey();
|
|
42
|
+
}
|
|
43
|
+
}, [api, client, draft, onSent]);
|
|
44
|
+
const startCountdown = useCallback(() => {
|
|
45
|
+
setPhase("countdown");
|
|
46
|
+
let remaining = QS_UNDO_SECONDS;
|
|
47
|
+
setCountdown(remaining);
|
|
48
|
+
timer.current = setInterval(() => {
|
|
49
|
+
remaining -= 1;
|
|
50
|
+
setCountdown(remaining);
|
|
51
|
+
if (remaining <= 0) {
|
|
52
|
+
if (timer.current)
|
|
53
|
+
clearInterval(timer.current);
|
|
54
|
+
void doSend();
|
|
55
|
+
}
|
|
56
|
+
}, 1000);
|
|
57
|
+
}, [doSend]);
|
|
58
|
+
const seenIntro = () => { try {
|
|
59
|
+
return !!localStorage.getItem(QS_INTRO_KEY);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return true;
|
|
63
|
+
} };
|
|
64
|
+
const rememberIntro = () => { try {
|
|
65
|
+
localStorage.setItem(QS_INTRO_KEY, "1");
|
|
66
|
+
}
|
|
67
|
+
catch { /* ignore */ } };
|
|
68
|
+
if (!draft)
|
|
69
|
+
return null;
|
|
70
|
+
const isCountdown = phase === "countdown";
|
|
71
|
+
return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: `u-qsend${isCountdown ? " u-qsend-count" : ""}${phase === "sending" ? " u-qsend-sending" : ""}${phase === "sent" ? " u-qsend-sent" : ""}${phase === "error" ? " u-qsend-err" : ""}`, onClick: (e) => {
|
|
72
|
+
e.stopPropagation();
|
|
73
|
+
if (isCountdown) {
|
|
74
|
+
if (timer.current)
|
|
75
|
+
clearInterval(timer.current);
|
|
76
|
+
setPhase("idle");
|
|
77
|
+
setCountdown(QS_UNDO_SECONDS);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (phase !== "idle" && phase !== "error")
|
|
81
|
+
return;
|
|
82
|
+
setError(null);
|
|
83
|
+
if (!seenIntro()) {
|
|
84
|
+
setShowIntro(true);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
startCountdown();
|
|
88
|
+
}, disabled: phase === "sending" || phase === "sent", title: isCountdown ? "Tap to cancel" : phase === "error" ? `${error}. Tap to try again.` : draft, "aria-label": isCountdown ? `Undo sending to ${client.name} (${countdown})` : `Quick send to ${client.name}: ${draft}`, children: [phase === "sent" && _jsx(IconCheckCircle, {}), phase === "sending" && _jsx(IconLoader, {}), isCountdown && _jsx(IconUndo, {}), (phase === "idle" || phase === "error") && _jsx(IconZap, {}), _jsx("span", { className: "u-qsend-label", children: phase === "sent" ? "Sent" : phase === "sending" ? "Sending…" : isCountdown ? `Undo (${countdown})` : phase === "error" ? "Not sent, retry" : truncated })] }), showIntro && (_jsxs(Sheet, { labelledBy: "u-qs-intro-title", onClose: () => setShowIntro(false), children: [_jsx("p", { className: "u-eyebrow", children: "Quick send" }), _jsx("h3", { id: "u-qs-intro-title", children: "Send without editing?" }), _jsxs("p", { className: "u-lede", children: ["The ", _jsx("strong", { children: "quick reply" }), " is a short draft you can send without any editing. If you want to edit a message or write your own, open the client row instead."] }), _jsxs("div", { className: "u-po-actions", children: [_jsx("button", { type: "button", className: "u-send", onClick: () => { rememberIntro(); setShowIntro(false); startCountdown(); }, children: "Confirm send" }), _jsx("button", { type: "button", className: "u-gen", onClick: () => setShowIntro(false), children: "Cancel" })] })] }))] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=QuickSend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuickSend.js","sourceRoot":"","sources":["../src/QuickSend.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** A draft to drop into the editor as pills. A new `key` injects again even if the text repeats. `locked` = one pill, no ×, not editable. */
|
|
2
|
+
export interface Injection {
|
|
3
|
+
text: string;
|
|
4
|
+
key: number;
|
|
5
|
+
locked?: boolean | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface SegmentEditorProps {
|
|
8
|
+
/** Plain text the parent holds. Always plain, in both modes. */
|
|
9
|
+
value: string;
|
|
10
|
+
onChange: (plain: string) => void;
|
|
11
|
+
inject?: Injection | null | undefined;
|
|
12
|
+
placeholder?: string | undefined;
|
|
13
|
+
ariaLabel: string;
|
|
14
|
+
disabled?: boolean | undefined;
|
|
15
|
+
/** Nothing can be typed or removed: the box shows fixed text (Uplift's stock intro) and only Send applies. */
|
|
16
|
+
readOnly?: boolean | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Two modes, like native Uplift's editor: a plain textarea for typing, and a contentEditable
|
|
20
|
+
* box that shows an injected draft as coloured pills the coach can delete one by one. The DOM
|
|
21
|
+
* of the pill box is owned by hand (written on inject, read on change), never by React, so the
|
|
22
|
+
* caret and the browser's own editing stay intact. The parent only ever sees plain text.
|
|
23
|
+
*/
|
|
24
|
+
export declare function SegmentEditor({ value, onChange, inject, placeholder, ariaLabel, disabled, readOnly }: SegmentEditorProps): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=SegmentEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentEditor.d.ts","sourceRoot":"","sources":["../src/SegmentEditor.tsx"],"names":[],"mappings":"AAGA,6IAA6I;AAC7I,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE;AAEtF,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,kBAAkB,+BA6GxH"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
3
|
+
import { reconstructMessage, SEG_CLASS, SEG_DELETE_CLASS, toLockedPillHtml, toPillHtml } from "./segments.js";
|
|
4
|
+
/**
|
|
5
|
+
* Two modes, like native Uplift's editor: a plain textarea for typing, and a contentEditable
|
|
6
|
+
* box that shows an injected draft as coloured pills the coach can delete one by one. The DOM
|
|
7
|
+
* of the pill box is owned by hand (written on inject, read on change), never by React, so the
|
|
8
|
+
* caret and the browser's own editing stay intact. The parent only ever sees plain text.
|
|
9
|
+
*/
|
|
10
|
+
export function SegmentEditor({ value, onChange, inject, placeholder, ariaLabel, disabled, readOnly }) {
|
|
11
|
+
const [rich, setRich] = useState(false);
|
|
12
|
+
const boxRef = useRef(null);
|
|
13
|
+
const taRef = useRef(null);
|
|
14
|
+
const lastKey = useRef(null);
|
|
15
|
+
const pendingHtml = useRef(null);
|
|
16
|
+
// Inject: switch to pills. Done in a layout effect so the box exists before we write to it.
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!inject || !inject.text.trim() || inject.key === lastKey.current)
|
|
19
|
+
return;
|
|
20
|
+
lastKey.current = inject.key;
|
|
21
|
+
pendingHtml.current = inject.locked ? toLockedPillHtml(inject.text, inject.key) : toPillHtml(inject.text, inject.key);
|
|
22
|
+
setRich(true);
|
|
23
|
+
}, [inject]);
|
|
24
|
+
useLayoutEffect(() => {
|
|
25
|
+
if (!rich || pendingHtml.current === null)
|
|
26
|
+
return;
|
|
27
|
+
const el = boxRef.current;
|
|
28
|
+
if (!el)
|
|
29
|
+
return;
|
|
30
|
+
el.innerHTML = pendingHtml.current;
|
|
31
|
+
pendingHtml.current = null;
|
|
32
|
+
// Caret at the end, after the last pill, so typing continues the message. Native does the same.
|
|
33
|
+
const t = setTimeout(() => {
|
|
34
|
+
el.focus();
|
|
35
|
+
const marker = document.createTextNode("");
|
|
36
|
+
el.appendChild(marker);
|
|
37
|
+
const range = document.createRange();
|
|
38
|
+
range.setStart(marker, 1);
|
|
39
|
+
range.setEnd(marker, 1);
|
|
40
|
+
const sel = window.getSelection();
|
|
41
|
+
sel?.removeAllRanges();
|
|
42
|
+
sel?.addRange(range);
|
|
43
|
+
el.removeChild(marker);
|
|
44
|
+
}, 80);
|
|
45
|
+
return () => clearTimeout(t);
|
|
46
|
+
}, [rich]);
|
|
47
|
+
// The parent cleared the text (sent, or switched client): leave pill mode.
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (rich && value === "") {
|
|
50
|
+
setRich(false);
|
|
51
|
+
if (boxRef.current)
|
|
52
|
+
boxRef.current.innerHTML = "";
|
|
53
|
+
}
|
|
54
|
+
}, [value, rich]);
|
|
55
|
+
const readBack = useCallback(() => {
|
|
56
|
+
const el = boxRef.current;
|
|
57
|
+
if (!el)
|
|
58
|
+
return;
|
|
59
|
+
const html = el.innerHTML;
|
|
60
|
+
const plain = reconstructMessage(html);
|
|
61
|
+
onChange(plain);
|
|
62
|
+
// Typed over every pill: back to the plain textarea with the same text.
|
|
63
|
+
if (!html.includes(SEG_CLASS) && plain)
|
|
64
|
+
setRich(false);
|
|
65
|
+
if (!html.includes(SEG_CLASS) && !plain)
|
|
66
|
+
setRich(false);
|
|
67
|
+
}, [onChange]);
|
|
68
|
+
const removePill = useCallback((id) => {
|
|
69
|
+
const el = boxRef.current?.querySelector(`.${SEG_CLASS}[data-seg="${id}"]`);
|
|
70
|
+
if (!el)
|
|
71
|
+
return;
|
|
72
|
+
el.remove();
|
|
73
|
+
readBack();
|
|
74
|
+
}, [readBack]);
|
|
75
|
+
const onClick = useCallback((e) => {
|
|
76
|
+
const t = e.target;
|
|
77
|
+
if (t.classList.contains(SEG_DELETE_CLASS)) {
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
removePill(t.getAttribute("data-seg") ?? "");
|
|
81
|
+
}
|
|
82
|
+
}, [removePill]);
|
|
83
|
+
const onKeyDown = useCallback((e) => {
|
|
84
|
+
const t = e.target;
|
|
85
|
+
if (t.classList.contains(SEG_DELETE_CLASS) && (e.key === "Enter" || e.key === " ")) {
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
removePill(t.getAttribute("data-seg") ?? "");
|
|
88
|
+
}
|
|
89
|
+
}, [removePill]);
|
|
90
|
+
if (rich) {
|
|
91
|
+
return (_jsx("div", { ref: boxRef, className: `u-editor u-editor-rich${readOnly ? " u-editor-locked" : ""}`, role: "textbox", "aria-multiline": "true", "aria-label": ariaLabel, "aria-disabled": disabled || undefined, "aria-readonly": readOnly || undefined, contentEditable: !disabled && !readOnly, suppressContentEditableWarning: true, "data-placeholder": placeholder, onInput: readBack, onClick: onClick, onKeyDown: onKeyDown }));
|
|
92
|
+
}
|
|
93
|
+
return (_jsx("textarea", { ref: taRef, className: "u-editor", "aria-label": ariaLabel, placeholder: placeholder, value: value, disabled: disabled, readOnly: readOnly, onChange: (e) => onChange(e.target.value), rows: 3 }));
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=SegmentEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentEditor.js","sourceRoot":"","sources":["../src/SegmentEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAuC,MAAM,OAAO,CAAC;AACvH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAiB9G;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAsB;IACvH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAA6B,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAEhD,4FAA4F;IAC5F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,OAAO;YAAE,OAAO;QAC7E,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC;QAC7B,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACtH,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO;QAClD,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,EAAE,CAAC,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC;QACnC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,gGAAgG;QAChG,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE;YACxB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAC5C,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;YACrC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACxB,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;YAClC,GAAG,EAAE,eAAe,EAAE,CAAC;YACvB,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,2EAA2E;IAC3E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAAC,IAAI,MAAM,CAAC,OAAO;gBAAE,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;QAAC,CAAC;IAClG,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAElB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC;QAC1B,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACvC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,wEAAwE;QACxE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,EAAU,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,SAAS,cAAc,EAAE,IAAI,CAAC,CAAC;QAC5E,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,EAAE,CAAC,MAAM,EAAE,CAAC;QACZ,QAAQ,EAAE,CAAC;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAA6B,EAAE,EAAE;QAC5D,MAAM,CAAC,GAAG,CAAC,CAAC,MAAqB,CAAC;QAClC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC3C,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAgC,EAAE,EAAE;QACjE,MAAM,CAAC,GAAG,CAAC,CAAC,MAAqB,CAAC;QAClC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;YACnF,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CACL,cACE,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,yBAAyB,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,EACxE,IAAI,EAAC,SAAS,oBACC,MAAM,gBACT,SAAS,mBACN,QAAQ,IAAI,SAAS,mBACrB,QAAQ,IAAI,SAAS,EACpC,eAAe,EAAE,CAAC,QAAQ,IAAI,CAAC,QAAQ,EACvC,8BAA8B,4BACZ,WAAW,EAC7B,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,GACpB,CACH,CAAC;IACJ,CAAC;IACD,OAAO,CACL,mBACE,GAAG,EAAE,KAAK,EACV,SAAS,EAAC,UAAU,gBACR,SAAS,EACrB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,IAAI,EAAE,CAAC,GACP,CACH,CAAC;AACJ,CAAC"}
|
package/dist/Sheet.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface SheetProps {
|
|
3
|
+
/** id of the heading element inside, for aria-labelledby. */
|
|
4
|
+
labelledBy: string;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A dialog rendered inside the panel (not a portal, so host tokens and the container
|
|
10
|
+
* query still apply). D17: traps focus, closes on Esc, returns focus to the opener.
|
|
11
|
+
*/
|
|
12
|
+
export declare function Sheet({ labelledBy, onClose, children }: SheetProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=Sheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sheet.d.ts","sourceRoot":"","sources":["../src/Sheet.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,MAAM,WAAW,UAAU;IACzB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,UAAU,+BAgDlE"}
|
package/dist/Sheet.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
3
|
+
const FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
4
|
+
/**
|
|
5
|
+
* A dialog rendered inside the panel (not a portal, so host tokens and the container
|
|
6
|
+
* query still apply). D17: traps focus, closes on Esc, returns focus to the opener.
|
|
7
|
+
*/
|
|
8
|
+
export function Sheet({ labelledBy, onClose, children }) {
|
|
9
|
+
const box = useRef(null);
|
|
10
|
+
const opener = useRef(null);
|
|
11
|
+
// Layout effect: focus returns to the opener in the same commit that removes the dialog, so there is
|
|
12
|
+
// no moment with focus on <body> (a passive cleanup runs after paint).
|
|
13
|
+
useLayoutEffect(() => {
|
|
14
|
+
opener.current = document.activeElement;
|
|
15
|
+
const first = box.current?.querySelector(FOCUSABLE);
|
|
16
|
+
(first ?? box.current)?.focus();
|
|
17
|
+
return () => { opener.current?.focus?.(); };
|
|
18
|
+
}, []);
|
|
19
|
+
// When the focused control is removed (deleting a row), the browser drops focus to <body> and the
|
|
20
|
+
// dialog's own key handler stops hearing keys: Escape still closes, Tab comes back inside.
|
|
21
|
+
const close = useRef(onClose);
|
|
22
|
+
close.current = onClose;
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const onDocKey = (e) => {
|
|
25
|
+
if (document.activeElement && document.activeElement !== document.body)
|
|
26
|
+
return;
|
|
27
|
+
if (e.key === "Escape") {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
close.current();
|
|
30
|
+
}
|
|
31
|
+
else if (e.key === "Tab") {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
(box.current?.querySelector(FOCUSABLE) ?? box.current)?.focus();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
document.addEventListener("keydown", onDocKey);
|
|
37
|
+
return () => document.removeEventListener("keydown", onDocKey);
|
|
38
|
+
}, []);
|
|
39
|
+
const onKeyDown = (e) => {
|
|
40
|
+
if (e.key === "Escape") {
|
|
41
|
+
e.stopPropagation();
|
|
42
|
+
onClose();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (e.key !== "Tab" || !box.current)
|
|
46
|
+
return;
|
|
47
|
+
const items = Array.from(box.current.querySelectorAll(FOCUSABLE));
|
|
48
|
+
if (items.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
const firstEl = items[0];
|
|
51
|
+
const lastEl = items[items.length - 1];
|
|
52
|
+
if (e.shiftKey && document.activeElement === firstEl) {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
lastEl.focus();
|
|
55
|
+
}
|
|
56
|
+
else if (!e.shiftKey && document.activeElement === lastEl) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
firstEl.focus();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
return (_jsx("div", { className: "u-sheet-wrap", onMouseDown: (e) => { if (e.target === e.currentTarget)
|
|
62
|
+
onClose(); }, children: _jsx("div", { ref: box, className: "u-sheet", role: "dialog", "aria-modal": "true", "aria-labelledby": labelledBy, tabIndex: -1, onKeyDown: onKeyDown, children: children }) }));
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=Sheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sheet.js","sourceRoot":"","sources":["../src/Sheet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Message } from "@uplifted/sdk";
|
|
3
|
+
import type { ThreadState } from "./useThread.js";
|
|
4
|
+
export interface ThreadFeedProps {
|
|
5
|
+
thread: ThreadState;
|
|
6
|
+
clientName: string;
|
|
7
|
+
/** How host activity cards name their source, e.g. "PulseKit". */
|
|
8
|
+
activitySourceLabel: string;
|
|
9
|
+
now: Date;
|
|
10
|
+
/** The action row for one item (reply options, Config AI); rendered inside activity cards and under client messages. */
|
|
11
|
+
actions?: (m: Message) => ReactNode;
|
|
12
|
+
/** Rendered at the foot of the feed (the closed-window ghost). */
|
|
13
|
+
foot?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export declare function ThreadFeed({ thread, clientName, activitySourceLabel, now, actions, foot }: ThreadFeedProps): import("react").JSX.Element;
|
|
16
|
+
type FeedItem = {
|
|
17
|
+
type: "day";
|
|
18
|
+
key: string;
|
|
19
|
+
at: string;
|
|
20
|
+
} | {
|
|
21
|
+
type: "message";
|
|
22
|
+
message: Message;
|
|
23
|
+
};
|
|
24
|
+
/** Insert a day separator wherever the local calendar day changes. */
|
|
25
|
+
export declare function withDays(messages: Message[]): FeedItem[];
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=ThreadFeed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadFeed.d.ts","sourceRoot":"","sources":["../src/ThreadFeed.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAK7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,IAAI,CAAC;IACV,wHAAwH;IACxH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC;IACpC,kEAAkE;IAClE,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,eAAe,+BAwC1G;AAED,KAAK,QAAQ,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEjG,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAYxD"}
|