@polymorfa/react 0.1.0-dev.20260926213449 → 0.1.0-dev.20260926231105
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/README.md +14 -0
- package/dist/call-number-picker.d.ts +22 -0
- package/dist/call-number-picker.d.ts.map +1 -0
- package/dist/call-number-picker.js +47 -0
- package/dist/calls.d.ts.map +1 -1
- package/dist/calls.js +41 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -301,3 +301,17 @@ While an answer is in flight, the incoming card disables Answer, Join, Reject
|
|
|
301
301
|
and its camera and microphone choices. A failed answer shows a notice on the
|
|
302
302
|
incoming card: on the call itself when it is still ringing, or on the next
|
|
303
303
|
waiting call when the answered call's media failed.
|
|
304
|
+
|
|
305
|
+
### Choosing an outgoing Number
|
|
306
|
+
|
|
307
|
+
`CallNumberPicker` selects an application-authorized Number. Each option has a
|
|
308
|
+
unique `id`, a display `label`, and the `controller` of a separate
|
|
309
|
+
`createBrowserCalls` instance. Supply `value` and `onChange`; use the selected
|
|
310
|
+
instance for `DialPad` and keep each active `CallSurface` under its fixed Number
|
|
311
|
+
label. The picker locks while any supplied client places, answers, or carries a
|
|
312
|
+
call and rechecks state in its change handler.
|
|
313
|
+
|
|
314
|
+
The component does not discover Numbers or mint credentials. Give each client
|
|
315
|
+
its own token provider, authorized for that Number's session. Selection must
|
|
316
|
+
never replace the token or session on an existing client. The session option
|
|
317
|
+
does not override the session bound to the client token.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CallsController } from "@polymorfa/browser";
|
|
2
|
+
/** A Number authorized by the application, with its own fixed Calls client. */
|
|
3
|
+
export interface CallNumberOption {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly controller: CallsController;
|
|
7
|
+
}
|
|
8
|
+
export interface CallNumberPickerProps {
|
|
9
|
+
readonly numbers: readonly CallNumberOption[];
|
|
10
|
+
readonly value: string;
|
|
11
|
+
/** Select the existing Number client; never replace its token or session. */
|
|
12
|
+
readonly onChange: (id: string) => void;
|
|
13
|
+
readonly disabled?: boolean;
|
|
14
|
+
readonly className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Choose an outgoing Number from application-authorized clients. Locks while
|
|
18
|
+
* any supplied client places, answers, or carries a call. It does not connect,
|
|
19
|
+
* disconnect, discover Numbers, mint credentials, or retarget an existing call.
|
|
20
|
+
*/
|
|
21
|
+
export declare function CallNumberPicker({ numbers, value, onChange, disabled, className, }: CallNumberPickerProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=call-number-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-number-picker.d.ts","sourceRoot":"","sources":["../src/call-number-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAK1D,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;CACtC;AACD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAmBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,EAAE,qBAAqB,+BAyDvB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useId, useSyncExternalStore } from "react";
|
|
3
|
+
import { usePolymorfa } from "./context.js";
|
|
4
|
+
import { safeSubscribe } from "./hooks.js";
|
|
5
|
+
function busy(numbers) {
|
|
6
|
+
return numbers.some(({ controller }) => {
|
|
7
|
+
const state = controller.getSnapshot();
|
|
8
|
+
return (state.placing === true ||
|
|
9
|
+
state.answering === true ||
|
|
10
|
+
[
|
|
11
|
+
"ringing",
|
|
12
|
+
"accepted",
|
|
13
|
+
"connecting",
|
|
14
|
+
"connected",
|
|
15
|
+
"reconnecting",
|
|
16
|
+
].includes(state.status));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Choose an outgoing Number from application-authorized clients. Locks while
|
|
21
|
+
* any supplied client places, answers, or carries a call. It does not connect,
|
|
22
|
+
* disconnect, discover Numbers, mint credentials, or retarget an existing call.
|
|
23
|
+
*/
|
|
24
|
+
export function CallNumberPicker({ numbers, value, onChange, disabled, className, }) {
|
|
25
|
+
const { locale } = usePolymorfa();
|
|
26
|
+
const id = useId();
|
|
27
|
+
const subscribe = useCallback((listener) => {
|
|
28
|
+
const stop = numbers.map(({ controller }) => safeSubscribe(controller)(listener));
|
|
29
|
+
return () => {
|
|
30
|
+
for (const unsubscribe of stop)
|
|
31
|
+
unsubscribe();
|
|
32
|
+
};
|
|
33
|
+
}, [numbers]);
|
|
34
|
+
const getBusy = useCallback(() => busy(numbers), [numbers]);
|
|
35
|
+
const active = useSyncExternalStore(subscribe, getBusy, getBusy);
|
|
36
|
+
if (numbers.some((number, index) => !number.id || numbers.findIndex(({ id }) => id === number.id) !== index))
|
|
37
|
+
throw new Error("Call Number choices require unique nonempty ids.");
|
|
38
|
+
const selected = numbers.find((number) => number.id === value);
|
|
39
|
+
return (_jsxs("div", { className: className, dir: locale.direction, "data-pmfa": "call-number-picker", children: [_jsx("label", { htmlFor: id, children: locale.messages["calls.outgoingNumber"] }), _jsxs("select", { id: id, value: selected?.id ?? "", disabled: disabled === true || active || numbers.length === 0, onChange: (event) => {
|
|
40
|
+
// Re-read on interaction: placement may have started before React rendered.
|
|
41
|
+
if (disabled === true || busy(numbers))
|
|
42
|
+
return;
|
|
43
|
+
const next = numbers.find((number) => number.id === event.target.value);
|
|
44
|
+
if (next !== undefined)
|
|
45
|
+
onChange(next.id);
|
|
46
|
+
}, children: [selected === undefined && (_jsx("option", { value: "", disabled: true, children: locale.messages["calls.chooseNumber"] })), numbers.map((number) => (_jsx("option", { value: number.id, children: number.label }, number.id)))] })] }));
|
|
47
|
+
}
|
package/dist/calls.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calls.d.ts","sourceRoot":"","sources":["../src/calls.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAOL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAKf,KAAK,eAAe,GAAG;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,eAAe,CAAC;CACnD,CAAC;
|
|
1
|
+
{"version":3,"file":"calls.d.ts","sourceRoot":"","sources":["../src/calls.tsx"],"names":[],"mappings":"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"}
|
package/dist/calls.js
CHANGED
|
@@ -56,6 +56,7 @@ const MicIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("path", { d: "M12 1a
|
|
|
56
56
|
const MicOffIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("line", { x1: "1", y1: "1", x2: "23", y2: "23" }), _jsx("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6" }), _jsx("path", { d: "M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23" }), _jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }), _jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })] }));
|
|
57
57
|
const VideoIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("path", { d: "M23 7l-7 5 7 5V7z" }), _jsx("rect", { x: "1", y: "5", width: "15", height: "14", rx: "2", ry: "2" })] }));
|
|
58
58
|
const VideoOffIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("path", { d: "M16 16v1a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2m5.66 0H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10" }), _jsx("line", { x1: "1", y1: "1", x2: "23", y2: "23" })] }));
|
|
59
|
+
const ScreenIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }), _jsx("path", { d: "M8 21h8M12 17v4M8 10l4-4 4 4M12 6v8" })] }));
|
|
59
60
|
const EraseIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("path", { d: "M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z" }), _jsx("line", { x1: "18", y1: "9", x2: "12", y2: "15" }), _jsx("line", { x1: "12", y1: "9", x2: "18", y2: "15" })] }));
|
|
60
61
|
const UserIcon = (p) => (_jsxs(Icon, { ...p, children: [_jsx("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }), _jsx("circle", { cx: "12", cy: "7", r: "4" })] }));
|
|
61
62
|
const ChevronDownIcon = (p) => (_jsx(Icon, { ...p, children: _jsx("polyline", { points: "6 9 12 15 18 9" }) }));
|
|
@@ -490,19 +491,23 @@ export function CallStage({ controller, createController, displayName, avatarUrl
|
|
|
490
491
|
snapshot.status === "ringing" && snapshot.direction === "outgoing"
|
|
491
492
|
? t(locale, "calls.ringingTo", { peer })
|
|
492
493
|
: null;
|
|
493
|
-
const identity = (_jsx(CallIdentity, { name: displayName ?? peer, peer: displayName === undefined ? null : peer, live: live, ringingLine: ringingLine, errorLine: snapshot.error?.code === "
|
|
494
|
-
? t(locale, "calls.
|
|
495
|
-
:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
494
|
+
const identity = (_jsx(CallIdentity, { name: displayName ?? peer, peer: displayName === undefined ? null : peer, live: live, ringingLine: ringingLine, errorLine: snapshot.error?.code === "screen_share_failed"
|
|
495
|
+
? t(locale, "calls.screenShareFailed")
|
|
496
|
+
: snapshot.error?.code === "media_control_failed"
|
|
497
|
+
? t(locale, "calls.mediaControlFailed")
|
|
498
|
+
: snapshot.error?.code === "call_control_failed"
|
|
499
|
+
? t(locale, "calls.controlFailed")
|
|
500
|
+
: null, flashPeer: flashPeer, seconds: seconds }));
|
|
501
|
+
return (_jsxs("div", { className: root.className, style: root.style, dir: root.dir, "data-pmfa": "call", children: [snapshot.remoteAudioMuted === true && (_jsx("p", { role: "status", children: t(locale, "calls.remoteMuted") })), snapshot.videoDelivery === "unconfirmed" && !snapshot.videoMuted && (_jsx("p", { role: "status", children: t(locale, "calls.videoDeliveryUnconfirmed") })), _jsx("div", { className: `pmfa-calls-stage${className === undefined ? "" : ` ${className}`}`, children: renderMedia !== undefined ? (renderMedia({
|
|
502
|
+
...(localStream === undefined ? {} : { local: localStream }),
|
|
503
|
+
...(remoteStream === undefined ? {} : { remote: remoteStream }),
|
|
504
|
+
videos: remoteVideos.flatMap((info) => {
|
|
505
|
+
const stream = resolved.remoteVideos.find((video) => video.key === info.key)?.stream;
|
|
506
|
+
return stream === undefined
|
|
507
|
+
? []
|
|
508
|
+
: [{ key: info.key, info, stream }];
|
|
509
|
+
}),
|
|
510
|
+
})) : (_jsxs(_Fragment, { children: [_jsx("video", { ref: remoteRef, className: "pmfa-calls-audio-sink", autoPlay: true, playsInline: true, "aria-hidden": "true" }), remoteHasVideo && (_jsx(ParticipantVideoGrid, { controller: resolved, ...(labelVideo === undefined ? {} : { labelVideo }) })), !remoteHasVideo ? (preAccept ? (_jsxs("div", { className: "pmfa-calls-hero-preview", children: [identity, _jsx("div", { className: "pmfa-calls-inset", children: _jsx("video", { ref: localRef, className: "pmfa-calls-preview", autoPlay: true, playsInline: true, muted: true }) })] })) : (_jsxs("div", { className: "pmfa-calls-audio-hero", children: [_jsx(CallAvatar, { displayName: displayName, avatarUrl: peerAvatar, peer: peer }), identity] }))) : (_jsx("div", { className: "pmfa-calls-stage-id", children: identity })), showLocalVideo && !preAccept && (_jsx("div", { className: "pmfa-calls-pip", children: _jsx("video", { ref: localRef, autoPlay: true, playsInline: true, muted: true, style: snapshot.screenSharing ? { transform: "none" } : undefined }) }))] })) })] }));
|
|
506
511
|
}
|
|
507
512
|
function defaultVideoLabel(video, locale) {
|
|
508
513
|
return (video.participant?.phoneNumber ??
|
|
@@ -555,6 +560,9 @@ export function ParticipantList({ controller, createController, className, resol
|
|
|
555
560
|
participant.phoneNumber ??
|
|
556
561
|
participant.id }), _jsx("span", { className: "pmfa-calls-others-state", children: [
|
|
557
562
|
state === undefined ? undefined : t(locale, state),
|
|
563
|
+
participant.handRaised
|
|
564
|
+
? t(locale, "calls.handRaised")
|
|
565
|
+
: undefined,
|
|
558
566
|
participant.audioMuted
|
|
559
567
|
? t(locale, "calls.participantMuted")
|
|
560
568
|
: undefined,
|
|
@@ -593,7 +601,9 @@ export function CallControls({ controller, createController, className, disableV
|
|
|
593
601
|
// an upgrade the media session can actually perform. A session that cannot
|
|
594
602
|
// renegotiate therefore shows the same disabled button as a call that has
|
|
595
603
|
// not connected yet, instead of a live one that does nothing.
|
|
596
|
-
const cameraReady = live &&
|
|
604
|
+
const cameraReady = live &&
|
|
605
|
+
!snapshot.screenSharing &&
|
|
606
|
+
(snapshot.video || resolved.canEnableVideo);
|
|
597
607
|
const cameraOff = !snapshot.video || snapshot.videoMuted;
|
|
598
608
|
const onCamera = () => {
|
|
599
609
|
// On a video call the button mutes/unmutes the outgoing track; on an
|
|
@@ -608,7 +618,23 @@ export function CallControls({ controller, createController, className, disableV
|
|
|
608
618
|
else
|
|
609
619
|
void resolved.enableVideo().catch(() => undefined);
|
|
610
620
|
};
|
|
611
|
-
return (_jsx("div", { className: root.className, style: root.style, dir: root.dir, "data-pmfa": "call", children: _jsxs("div", { className: "pmfa-calls-dock-col", children: [open === "mic" && (_jsx("div", { className: "pmfa-calls-pop", role: "group", "aria-label": t(locale, "calls.microphoneSettings"), children: _jsx(DeviceFields, { controller: resolved, snapshot: snapshot, fields: ["audioInput", "audioOutput"], locale: locale }) })), open === "cam" && (_jsx("div", { className: "pmfa-calls-pop", role: "group", "aria-label": t(locale, "calls.cameraSettings"), children: _jsx(DeviceFields, { controller: resolved, snapshot: snapshot, fields: ["videoInput"], locale: locale }) })), _jsxs("div", { className: `pmfa-calls-dock${className === undefined ? "" : ` ${className}`}`, children: [
|
|
621
|
+
return (_jsx("div", { className: root.className, style: root.style, dir: root.dir, "data-pmfa": "call", children: _jsxs("div", { className: "pmfa-calls-dock-col", children: [open === "mic" && (_jsx("div", { className: "pmfa-calls-pop", role: "group", "aria-label": t(locale, "calls.microphoneSettings"), children: _jsx(DeviceFields, { controller: resolved, snapshot: snapshot, fields: ["audioInput", "audioOutput"], locale: locale }) })), open === "cam" && (_jsx("div", { className: "pmfa-calls-pop", role: "group", "aria-label": t(locale, "calls.cameraSettings"), children: _jsx(DeviceFields, { controller: resolved, snapshot: snapshot, fields: ["videoInput"], locale: locale }) })), _jsxs("div", { className: `pmfa-calls-dock${className === undefined ? "" : ` ${className}`}`, children: [live && snapshot.socialSupported && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "pmfa-calls-btn pmfa-calls-btn-ctrl", "aria-pressed": snapshot.handRaised === true, "aria-label": t(locale, snapshot.handRaised ? "calls.lowerHand" : "calls.raiseHand"), onClick: () => void resolved
|
|
622
|
+
.setHandRaised(!snapshot.handRaised)
|
|
623
|
+
.catch(() => undefined), children: "\u270B" }), _jsxs("select", { "aria-label": t(locale, "calls.react"), value: "", onChange: (event) => {
|
|
624
|
+
const emoji = event.currentTarget.value;
|
|
625
|
+
if (emoji)
|
|
626
|
+
void resolved
|
|
627
|
+
.sendReaction(emoji === "clear"
|
|
628
|
+
? ""
|
|
629
|
+
: emoji)
|
|
630
|
+
.catch(() => undefined);
|
|
631
|
+
}, children: [_jsx("option", { value: "", disabled: true, children: t(locale, "calls.react") }), ["👍", "❤️", "😂", "😮", "😢", "🙏"].map((emoji) => (_jsx("option", { value: emoji, children: emoji }, emoji))), _jsx("option", { value: "clear", children: t(locale, "calls.clearReaction") })] })] })), snapshot.socialError && (_jsx("span", { role: "alert", children: t(locale, "calls.socialFailed") })), snapshot.reaction?.emoji && (_jsx("span", { role: "status", children: snapshot.reaction.emoji })), showCamera && (_jsxs("div", { className: `pmfa-calls-group${cameraReady ? "" : " pmfa-calls-disabled"}`, children: [_jsx("button", { type: "button", className: `pmfa-calls-btn pmfa-calls-btn-ctrl${cameraOff ? " pmfa-calls-on" : ""}`, onClick: onCamera, disabled: !cameraReady, "aria-label": t(locale, cameraOff ? "calls.cameraOn" : "calls.cameraOff"), "aria-pressed": cameraOff, children: cameraOff ? _jsx(VideoOffIcon, {}) : _jsx(VideoIcon, {}) }), _jsx("button", { type: "button", className: `pmfa-calls-btn pmfa-calls-btn-acc${open === "cam" ? " pmfa-calls-open" : ""}`, onClick: () => toggle("cam"), disabled: !live, "aria-label": t(locale, "calls.cameraSettings"), "aria-expanded": open === "cam", children: _jsx(ChevronDownIcon, {}) })] })), showCamera && resolved.canShareScreen && (_jsx("button", { type: "button", className: "pmfa-calls-btn pmfa-calls-btn-ctrl", disabled: !live, "aria-pressed": snapshot.screenSharing === true, "aria-label": t(locale, snapshot.screenSharing
|
|
632
|
+
? "calls.stopSharing"
|
|
633
|
+
: "calls.shareScreen"), onClick: () => {
|
|
634
|
+
void (snapshot.screenSharing
|
|
635
|
+
? resolved.stopScreenShare()
|
|
636
|
+
: resolved.startScreenShare()).catch(() => undefined);
|
|
637
|
+
}, children: _jsx(ScreenIcon, {}) })), snapshot.capabilities.mute && (_jsxs("div", { className: "pmfa-calls-group", children: [_jsx("button", { type: "button", className: `pmfa-calls-btn pmfa-calls-btn-ctrl${snapshot.audioMuted ? " pmfa-calls-on" : ""}`, onClick: () => ignoreDisposed(() => resolved.setMuted({ audio: !snapshot.audioMuted })), "aria-label": t(locale, snapshot.audioMuted ? "calls.unmute" : "calls.mute"), "aria-pressed": snapshot.audioMuted, children: snapshot.audioMuted ? _jsx(MicOffIcon, {}) : _jsx(MicIcon, {}) }), _jsx("button", { type: "button", className: `pmfa-calls-btn pmfa-calls-btn-acc${open === "mic" ? " pmfa-calls-open" : ""}`, onClick: () => toggle("mic"), "aria-label": t(locale, "calls.microphoneSettings"), "aria-expanded": open === "mic", children: _jsx(ChevronDownIcon, {}) })] })), leaveShown && (_jsx("button", { type: "button", className: "pmfa-calls-btn pmfa-calls-btn-ctrl pmfa-calls-btn-leave", onClick: () => void resolved.leave().catch(() => undefined), "aria-label": t(locale, "calls.leave"), title: t(locale, "calls.leave"), children: _jsx(LeaveIcon, {}) })), _jsx("button", { type: "button", className: "pmfa-calls-btn pmfa-calls-btn-hangup",
|
|
612
638
|
// Rejects on a disposed controller, which a mounted surface
|
|
613
639
|
// holding an application-supplied one can still be clicked
|
|
614
640
|
// against; the call is over either way.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export { CALLS_STYLES, CallControls, CallStage, CallSurface, DialPad, IncomingCa
|
|
|
6
6
|
export { useOptionalPolymorfaClient, usePermission, usePermissions, usePolymorfaClient, type PolymorfaPermissions, } from "./context.js";
|
|
7
7
|
export { ConnectWhatsAppButton, ContactPanel, ConversationList, Inbox, SessionStatus, TemplateManager, type ConnectWhatsAppButtonProps, type ContactPanelProps, type ConversationListProps, type InboxProps, type SessionStatusProps, type TemplateManagerProps, } from "./dropin.js";
|
|
8
8
|
export { CallButton, type CallButtonProps } from "./call-button.js";
|
|
9
|
+
export { CallNumberPicker, type CallNumberOption, type CallNumberPickerProps, } from "./call-number-picker.js";
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,GACjC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,UAAU,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,eAAe,EACf,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,GACjC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,UAAU,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,eAAe,EACf,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,3 +5,4 @@ export { CALLS_STYLES, CallControls, CallStage, CallSurface, DialPad, IncomingCa
|
|
|
5
5
|
export { useOptionalPolymorfaClient, usePermission, usePermissions, usePolymorfaClient, } from "./context.js";
|
|
6
6
|
export { ConnectWhatsAppButton, ContactPanel, ConversationList, Inbox, SessionStatus, TemplateManager, } from "./dropin.js";
|
|
7
7
|
export { CallButton } from "./call-button.js";
|
|
8
|
+
export { CallNumberPicker, } from "./call-number-picker.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polymorfa/react",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.20260926231105",
|
|
4
4
|
"description": "React bindings for Polymorfa browser controllers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@polymorfa/ui": "0.1.0-dev.
|
|
35
|
+
"@polymorfa/ui": "0.1.0-dev.20260926231105"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@polymorfa/browser": "0.1.0-dev.
|
|
38
|
+
"@polymorfa/browser": "0.1.0-dev.20260926231105",
|
|
39
39
|
"react": ">=18.2.0 <20"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|