@agentforge-io/chat-sdk 2.4.0-dev.6 → 2.4.0-dev.8

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.
Files changed (2) hide show
  1. package/dist/ChatDrawer.js +48 -15
  2. package/package.json +1 -1
@@ -45,7 +45,14 @@ const react_1 = require("react");
45
45
  const react_dom_1 = require("react-dom");
46
46
  const react_2 = require("./react");
47
47
  function ChatDrawer(props) {
48
- const { open, onOpenChange, snap = 0.98, header, closeOnBackdropClick = true, drawerClassName, surfaceStyle: surfaceStyleProp, widgetProps, chatSlot, } = props;
48
+ const { open, onOpenChange, snap = 1, header, closeOnBackdropClick = true, drawerClassName, surfaceStyle: surfaceStyleProp, widgetProps, chatSlot, } = props;
49
+ // `fullscreen` mode: snap=1 (the default). The drawer occupies the
50
+ // entire visible viewport. We disable drag-to-dismiss, the backdrop,
51
+ // the rounded top corners, and the drag handle in this mode — they
52
+ // exist purely for the bottom-sheet form factor (snap<1) where the
53
+ // page peeks behind the surface. With snap=1 there's nothing behind
54
+ // and no affordance to drag against.
55
+ const fullscreen = snap >= 1;
49
56
  // We mount once and keep alive across close→reopen so the chat session
50
57
  // doesn't get destroyed. After the FIRST open the panel stays in the
51
58
  // DOM forever (toggled by `display:none`) — `hasOpened` gates the
@@ -185,25 +192,50 @@ function ChatDrawer(props) {
185
192
  // Motion / sizing portion of the surface style, kept separate from
186
193
  // the host-supplied theming so a re-render driven by drag offset
187
194
  // doesn't smash the host's CSS vars.
188
- const surfaceMotionStyle = {
189
- height: `${drawerHeight}px`,
190
- transform: `translate3d(0, ${translateY}, 0)`,
191
- bottom: `${vv.offsetTop}px`,
192
- transition: isDragging ? 'none' : 'transform 240ms cubic-bezier(.32,.72,0,1)',
193
- willChange: 'transform',
194
- };
195
+ //
196
+ // Two distinct positioning modes:
197
+ //
198
+ // **fullscreen (snap=1)**: pin the surface to the VISUAL viewport
199
+ // box. `top = visualViewport.offsetTop` + `height = visualViewport.h`
200
+ // means the drawer sits exactly on the area the user can see, with
201
+ // the bottom edge flush against the on-screen keyboard (when it's up)
202
+ // or the bottom of the screen (when it's down). No layout viewport
203
+ // gymnastics needed.
204
+ //
205
+ // **bottom-sheet (snap<1)**: anchor the surface to the bottom of the
206
+ // visual viewport. `bottom = visualViewport.offsetTop` is the legacy
207
+ // path that handles the rubber-band scroll case on iOS Safari.
208
+ const surfaceMotionStyle = fullscreen
209
+ ? {
210
+ top: `${vv.offsetTop}px`,
211
+ height: `${vv.h}px`,
212
+ transform: `translate3d(0, ${translateY}, 0)`,
213
+ transition: isDragging
214
+ ? 'none'
215
+ : 'transform 240ms cubic-bezier(.32,.72,0,1)',
216
+ willChange: 'transform',
217
+ }
218
+ : {
219
+ height: `${drawerHeight}px`,
220
+ transform: `translate3d(0, ${translateY}, 0)`,
221
+ bottom: `${vv.offsetTop}px`,
222
+ transition: isDragging
223
+ ? 'none'
224
+ : 'transform 240ms cubic-bezier(.32,.72,0,1)',
225
+ willChange: 'transform',
226
+ };
195
227
  return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", { className: "af-drawer-root", "data-state": open ? 'open' : 'closed', style: {
196
228
  position: 'fixed',
197
229
  inset: 0,
198
230
  zIndex: 2147483600,
199
231
  pointerEvents: open ? 'auto' : 'none',
200
- }, children: [(0, jsx_runtime_1.jsx)("div", { className: "af-drawer-backdrop", onClick: closeOnBackdropClick ? () => onOpenChange(false) : undefined, style: {
232
+ }, children: [!fullscreen && ((0, jsx_runtime_1.jsx)("div", { className: "af-drawer-backdrop", onClick: closeOnBackdropClick ? () => onOpenChange(false) : undefined, style: {
201
233
  position: 'absolute',
202
234
  inset: 0,
203
235
  backgroundColor: 'rgba(0, 0, 0, 0.4)',
204
236
  opacity: open ? 1 : 0,
205
237
  transition: 'opacity 200ms ease-out',
206
- }, "aria-hidden": true }), (0, jsx_runtime_1.jsxs)("div", { ref: surfaceRef, id: panelId, role: "dialog", "aria-modal": "true", className: `af-drawer-surface ${drawerClassName ?? ''}`, style: {
238
+ }, "aria-hidden": true })), (0, jsx_runtime_1.jsxs)("div", { ref: surfaceRef, id: panelId, role: "dialog", "aria-modal": "true", className: `af-drawer-surface ${drawerClassName ?? ''}`, style: {
207
239
  position: 'absolute',
208
240
  left: 0,
209
241
  right: 0,
@@ -216,9 +248,10 @@ function ChatDrawer(props) {
216
248
  // the correct path.
217
249
  backgroundColor: 'var(--af-bg, #ffffff)',
218
250
  color: 'var(--af-fg, inherit)',
219
- borderTopLeftRadius: '16px',
220
- borderTopRightRadius: '16px',
221
- boxShadow: '0 -8px 24px rgba(15, 23, 42, 0.25)',
251
+ // Bottom-sheet visuals only — fullscreen mode is flat.
252
+ borderTopLeftRadius: fullscreen ? 0 : '16px',
253
+ borderTopRightRadius: fullscreen ? 0 : '16px',
254
+ boxShadow: fullscreen ? 'none' : '0 -8px 24px rgba(15, 23, 42, 0.25)',
222
255
  display: 'flex',
223
256
  flexDirection: 'column',
224
257
  overflow: 'hidden',
@@ -227,7 +260,7 @@ function ChatDrawer(props) {
227
260
  // `height` declarations a careless host might pass.
228
261
  ...surfaceStyleProp,
229
262
  ...surfaceMotionStyle,
230
- }, children: [(0, jsx_runtime_1.jsx)("div", { onPointerDown: onHandlePointerDown, onPointerMove: onHandlePointerMove, onPointerUp: onHandlePointerUp, onPointerCancel: onHandlePointerUp, style: {
263
+ }, children: [!fullscreen && ((0, jsx_runtime_1.jsx)("div", { onPointerDown: onHandlePointerDown, onPointerMove: onHandlePointerMove, onPointerUp: onHandlePointerUp, onPointerCancel: onHandlePointerUp, style: {
231
264
  padding: '10px 0',
232
265
  cursor: 'grab',
233
266
  touchAction: 'none',
@@ -240,5 +273,5 @@ function ChatDrawer(props) {
240
273
  borderRadius: '999px',
241
274
  backgroundColor: 'var(--af-muted, rgba(100, 116, 139, 0.45))',
242
275
  display: 'block',
243
- } }) }), header, (0, jsx_runtime_1.jsx)("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: chatSlot ?? (widgetProps ? ((0, jsx_runtime_1.jsx)(react_2.ChatWidget, { ...widgetProps, inline: true, variant: widgetProps.variant ?? 'bare' })) : null) })] })] }), portalEl);
276
+ } }) })), header, (0, jsx_runtime_1.jsx)("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: chatSlot ?? (widgetProps ? ((0, jsx_runtime_1.jsx)(react_2.ChatWidget, { ...widgetProps, inline: true, variant: widgetProps.variant ?? 'bare' })) : null) })] })] }), portalEl);
244
277
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge-io/chat-sdk",
3
- "version": "2.4.0-dev.6",
3
+ "version": "2.4.0-dev.8",
4
4
  "description": "Framework-free chat session SDK for AgentForge public chat tokens. Headless — no DOM. Drop into any frontend (React, Vue, Svelte, vanilla) and listen for events.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",