@ews-admin/global-design-system 1.38.0 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { useId, useState, useRef, useEffect, forwardRef, useCallback, createContext, useContext } from 'react';
4
- import { Stethoscope, Heart, User, ChevronDown, EyeOff, Eye, X, Search, Check, AlertCircle, CheckCircle, AlertTriangle, Pencil, Trash, Lock, Delete, ArrowUp, AudioLines, Mic, SendHorizontal, ShieldCheck, SquarePen, MessageSquare, UserRound, Loader2, RotateCcw, Sparkles, ArrowRight, MicOff, History, Minimize2, Maximize2 } from 'lucide-react';
4
+ import { Stethoscope, Heart, User, ChevronDown, EyeOff, Eye, X, Search, Check, AlertCircle, CheckCircle, AlertTriangle, Pencil, Trash, Lock, Delete, ArrowUp, AudioLines, Mic, SendHorizontal, ShieldCheck, SquarePen, MessageSquare, UserRound, Loader2, RotateCcw, Sparkles, ArrowRight, MicOff, History, ArrowLeft, Minimize2, Maximize2 } from 'lucide-react';
5
5
  export * from 'lucide-react';
6
6
  import { useController, Controller } from 'react-hook-form';
7
7
 
@@ -3969,7 +3969,7 @@ function conversationTitle(firstMessage, max = 60) {
3969
3969
  * Server-rendering safe: nothing touches `window` at render time, the
3970
3970
  * speech API is detected after mount.
3971
3971
  */
3972
- const AssistantChat = ({ transport, language, texts, suggestions, conversations = [], activeConversationId = null, initialMessages, onConversationCreated, onSelectConversation, onNewConversation, signInHref, headerAction, disclaimer, heroBackground, voice = true, pendingConfirmation = null, onConfirm, onCancelConfirmation, layout = "page", queuedPrompt = null, voiceRequest = null, composerDraft = null, onNavigate, historyOpen = false, onHistoryOpenChange, className, }) => {
3972
+ const AssistantChat = ({ transport, language, texts, suggestions, conversations = [], activeConversationId = null, initialMessages, onConversationCreated, onSelectConversation, onNewConversation, signInHref, headerAction, disclaimer, heroBackground, heroLogo, voice = true, pendingConfirmation = null, onConfirm, onCancelConfirmation, layout = "page", queuedPrompt = null, voiceRequest = null, composerDraft = null, onNavigate, historyOpen = false, onHistoryOpenChange, className, }) => {
3973
3973
  const [messages, setMessages] = useState(initialMessages ?? []);
3974
3974
  const [activity, setActivity] = useState(null);
3975
3975
  const [busy, setBusy] = useState(false);
@@ -4119,7 +4119,7 @@ const AssistantChat = ({ transport, language, texts, suggestions, conversations
4119
4119
  onHistoryOpenChange?.(false);
4120
4120
  }, texts: texts, signInHref: signInHref, className: "w-72 max-w-full border-e border-ews-gray-200 shadow-xl" }), jsx("div", { className: "flex-1 bg-black/20", onClick: () => onHistoryOpenChange?.(false), "data-testid": "assistant-history-overlay" })] })), jsxs("div", { className: "relative flex min-h-0 min-w-0 flex-1 flex-col", children: [jsxs("header", { className: "flex items-center justify-between gap-3 border-b border-ews-gray-200 px-4 py-3", children: [jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-ews-primary text-sm font-bold text-white", "aria-hidden": "true", children: texts.brandName.charAt(0) }), jsx("span", { className: "truncate font-semibold text-ews-gray-900", children: texts.brandName }), jsx("span", { className: "rounded-full bg-ews-gray-100 px-2 py-0.5 text-xs font-medium text-ews-gray-600", children: "AI" }), jsxs("span", { className: "flex items-center gap-1 text-xs text-ews-gray-500", children: [jsx("span", { className: "h-2 w-2 rounded-full bg-ews-success", "aria-hidden": "true" }), texts.online] })] }), jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [compact && onHistoryOpenChange && (jsx("button", { type: "button", onClick: () => onHistoryOpenChange(!historyOpen), "aria-label": historyLabel, "aria-pressed": historyOpen, title: historyLabel, className: cn("rounded-full p-2 hover:bg-ews-gray-100 hover:text-ews-primary focus:outline-none focus:ring-2 focus:ring-ews-primary", historyOpen ? "bg-ews-gray-100 text-ews-primary" : "text-ews-gray-500"), "data-testid": "assistant-history-toggle", children: jsx(History, { className: "h-4 w-4", "aria-hidden": "true" }) })), !withList && !empty && (jsx("button", { type: "button", onClick: startNewConversation, "aria-label": texts.newConversation, title: texts.newConversation, className: "rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-primary focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-new-conversation", children: jsx(SquarePen, { className: "h-4 w-4", "aria-hidden": "true" }) })), headerAction] })] }), jsx("div", { className: "flex flex-1 flex-col overflow-y-auto", children: empty ? (jsxs(Fragment, { children: [jsxs("section", { className: cn("relative overflow-hidden bg-ews-primary-light text-center",
4121
4121
  // Extra bottom room: the white sheet of cards overlaps the hero (mockup tools).
4122
- compact ? "px-4 pb-12 pt-8" : "px-6 pb-16 pt-12"), children: [heroBackground && jsx("div", { className: "absolute inset-0", "aria-hidden": "true", children: heroBackground }), jsxs("div", { className: "relative", children: [jsx("h2", { className: cn("font-bold text-ews-gray-900", compact ? "text-xl" : "text-2xl sm:text-3xl"), children: texts.heroTitle }), jsx("p", { className: cn("mx-auto mt-2 max-w-xl text-ews-gray-700", compact && "text-sm"), children: texts.heroSubtitle })] })] }), jsx("div", {
4122
+ compact ? "px-4 pb-20 pt-10" : "px-6 pb-24 pt-14"), children: [heroBackground && jsx("div", { className: "absolute inset-0", "aria-hidden": "true", children: heroBackground }), jsxs("div", { className: "relative", children: [heroLogo && (jsx("div", { className: "mb-4 flex justify-center", "data-testid": "assistant-hero-logo", children: heroLogo })), jsx("h2", { className: cn("font-bold text-ews-gray-900", compact ? "text-xl" : "text-2xl sm:text-3xl"), children: texts.heroTitle }), jsx("p", { className: cn("mx-auto mt-4 max-w-xl text-ews-gray-700", compact && "text-sm"), children: texts.heroSubtitle })] })] }), jsx("div", {
4123
4123
  // A white sheet rounded on top, slid over the bottom of the hero, holding the cards.
4124
4124
  className: cn("relative -mt-6 grid flex-1 content-start gap-3 rounded-t-3xl bg-white px-4 py-5", compact ? "grid-cols-2" : "grid-cols-2 lg:grid-cols-4"), "data-testid": "assistant-suggestions", children: suggestions.map((suggestion) => (jsx(AssistantSuggestionCard, { suggestion: suggestion, onSelect: (selected) => void send(selected.prompt), exampleLabel: texts.exampleLabel, disabled: busy }, suggestion.id))) })] })) : (jsxs("div", { className: "flex-1 px-4 py-5", children: [jsx(AssistantMessages, { messages: messages, activity: activity, onRetry: retry, texts: texts, linkOptions: onNavigate
4125
4125
  ? {
@@ -4233,7 +4233,7 @@ const DIRECTION = {
4233
4233
  * goes to the composer on open and back to the bar on close. In Arabic the
4234
4234
  * panel slides from the left (`end-0` follows `dir`).
4235
4235
  */
4236
- const AssistantLauncher = ({ launcherTexts, open, defaultOpen = false, onOpenChange, expanded, defaultExpanded = false, onExpandedChange, bottomOffset = 16, hidden = false, className, panelClassName, headerAction, voice = true, conversations: hostConversations, activeConversationId: hostActiveId, initialMessages: hostInitialMessages, onConversationCreated, onSelectConversation, onNewConversation, ...chatProps }) => {
4236
+ const AssistantLauncher = ({ launcherTexts, open, defaultOpen = false, onOpenChange, expanded, defaultExpanded = false, onExpandedChange, bottomOffset = 16, hidden = false, className, panelClassName, embed, onEmbedClose, headerAction, voice = true, conversations: hostConversations, activeConversationId: hostActiveId, initialMessages: hostInitialMessages, onConversationCreated, onSelectConversation, onNewConversation, ...chatProps }) => {
4237
4237
  const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
4238
4238
  const isOpen = open ?? uncontrolledOpen;
4239
4239
  const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);
@@ -4369,12 +4369,15 @@ const AssistantLauncher = ({ launcherTexts, open, defaultOpen = false, onOpenCha
4369
4369
  }, placeholder: launcherTexts.open, "aria-label": launcherTexts.open, "aria-haspopup": "dialog", "aria-controls": panelId, className: "min-w-0 flex-1 cursor-text bg-transparent py-2 text-lg text-ews-gray-800 placeholder:text-ews-gray-400 focus:outline-none", "data-testid": "assistant-launcher-input" }), showMic && (jsx(ActionTooltip, { label: chatProps.texts.holdToTalk, children: (describedBy) => (jsx("button", { type: "button", "aria-label": chatProps.texts.holdToTalk, "aria-describedby": describedBy, onClick: openVoice, className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-ews-gray-600 transition-colors hover:bg-ews-gray-100 hover:text-ews-primary focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-launcher-mic", children: jsx(Mic, { className: "h-5 w-5", "aria-hidden": "true" }) })) })), jsx(ActionTooltip, { label: dictateLabel, children: (describedBy) => (jsx("button", { type: "button", onClick: speechSupported ? () => setDictating(true) : () => setOpen(true), "aria-label": dictateLabel, "aria-describedby": describedBy, className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-ews-gray-100 text-ews-gray-700 transition-colors hover:bg-ews-gray-200 focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-launcher-voice", children: jsx(AudioLines, { className: "h-5 w-5", "aria-hidden": "true" }) })) }), jsx("button", { type: "button", onClick: () => submitFromBar(draft), "aria-label": chatProps.texts.send, title: chatProps.texts.send, className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-ews-primary text-white shadow-sm transition-colors hover:bg-ews-primary-hover focus:outline-none focus:ring-2 focus:ring-ews-primary focus:ring-offset-1", "data-testid": "assistant-launcher-send", children: jsx(ArrowUp, { className: "h-5 w-5", "aria-hidden": "true" }) })] }))] }) })), jsxs("div", { dir: dir, className: cn("fixed inset-0 z-[90]", !isOpen && "hidden"), "aria-hidden": !isOpen, "data-testid": "assistant-launcher-panel", children: [jsx("div", {
4370
4370
  // Mobile: a dimmed page under a full-screen panel. From tablets up the panel floats over the
4371
4371
  // page, which stays visible (no dimming); a click outside still closes it.
4372
- className: "absolute inset-0 bg-black/40 sm:bg-transparent", onClick: () => setOpen(false), "data-testid": "assistant-launcher-overlay" }), jsx("section", { ref: panelRef, id: panelId, role: "dialog", "aria-modal": "true", "aria-label": launcherTexts.open, "data-expanded": isExpanded, className: cn("absolute inset-y-0 end-0 flex w-full flex-col bg-white shadow-2xl transition-[width,max-width,height] duration-200",
4372
+ className: "absolute inset-0 bg-black/40 sm:bg-transparent", onClick: () => setOpen(false), "data-testid": "assistant-launcher-overlay" }), jsxs("section", { ref: panelRef, id: panelId, role: "dialog", "aria-modal": "true", "aria-label": launcherTexts.open, "data-expanded": isExpanded, className: cn("absolute inset-y-0 end-0 flex w-full flex-col bg-white shadow-2xl",
4373
4373
  // From tablets up: a floating card (MED-1801, like the Notiwa widget), clear of the top,
4374
4374
  // the bottom and the side of the screen, rounded, with a soft border and shadow.
4375
- "sm:inset-y-auto sm:bottom-6 sm:end-6 sm:overflow-hidden sm:rounded-3xl sm:border sm:border-ews-gray-100", "sm:shadow-[0_24px_60px_rgba(15,23,42,0.22)]", isExpanded ? "sm:h-[calc(100vh-3rem)]" : "sm:h-[calc(100vh-6rem)]",
4375
+ "sm:inset-y-auto sm:bottom-6 sm:end-6 sm:overflow-hidden sm:rounded-3xl sm:border sm:border-ews-gray-100", "sm:shadow-[0_24px_60px_rgba(15,23,42,0.22)]",
4376
+ // Only fixed widths and heights, so expanding animates from one size to the other (a
4377
+ // max-width switching to none jumped to full width first).
4378
+ "sm:max-w-[calc(100vw-3rem)] sm:transition-[width,height] sm:duration-300 sm:ease-out", isExpanded ? "sm:h-[calc(100vh-3rem)]" : "sm:h-[calc(100vh-6rem)]",
4376
4379
  // Expanded: a dashboard reaching the middle of the screen (never full width), tablets and up.
4377
- isExpanded ? "sm:max-w-md md:w-[max(50vw,40rem)] md:max-w-none" : "sm:max-w-md", panelClassName), children: jsx(AssistantChat, { ...chatProps, texts: texts, voice: voice, layout: isExpanded ? "wide" : "panel", queuedPrompt: queuedPrompt, voiceRequest: voiceRequest, composerDraft: composerDraft, conversations: hostManaged ? hostConversations : storedConversations, activeConversationId: hostManaged ? hostActiveId : managedActiveId, initialMessages: hostManaged ? hostInitialMessages : managedMessages, onConversationCreated: handleConversationCreated, onSelectConversation: handleSelectConversation, onNewConversation: handleNewConversation, historyOpen: historyOpen, onHistoryOpenChange: setHistoryOpen, className: "flex-1", headerAction: jsxs(Fragment, { children: [headerAction, jsx("button", { type: "button", onClick: () => setExpanded(!isExpanded), "aria-label": isExpanded ? collapseLabel : expandLabel, "aria-pressed": isExpanded, title: isExpanded ? collapseLabel : expandLabel, className: "hidden rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary md:inline-flex", "data-testid": "assistant-launcher-expand", children: isExpanded ? (jsx(Minimize2, { className: "h-5 w-5", "aria-hidden": "true" })) : (jsx(Maximize2, { className: "h-5 w-5", "aria-hidden": "true" })) }), jsx("button", { type: "button", onClick: () => setOpen(false), "aria-label": launcherTexts.close, title: launcherTexts.close, className: "rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-launcher-close", children: jsx(X, { className: "h-5 w-5", "aria-hidden": "true" }) })] }) }) })] })] }));
4380
+ isExpanded ? "sm:w-[32rem] md:w-[max(50vw,40rem)]" : "sm:w-[32rem]", panelClassName), children: [embed && (jsxs("div", { className: "absolute inset-0 z-20 flex flex-col bg-white", "data-testid": "assistant-launcher-embed", children: [jsxs("div", { className: "flex items-center gap-2 border-b border-ews-gray-100 px-3 py-2", children: [jsx("button", { type: "button", onClick: onEmbedClose, "aria-label": launcherTexts.backToConversation ?? launcherTexts.close, title: launcherTexts.backToConversation ?? launcherTexts.close, className: "rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-launcher-embed-back", children: jsx(ArrowLeft, { className: "h-5 w-5 rtl:rotate-180", "aria-hidden": "true" }) }), jsx("h2", { className: "min-w-0 flex-1 truncate text-base font-semibold text-ews-gray-900", children: embed.title }), jsx("button", { type: "button", onClick: () => setOpen(false), "aria-label": launcherTexts.close, title: launcherTexts.close, className: "rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary", children: jsx(X, { className: "h-5 w-5", "aria-hidden": "true" }) })] }), jsx("iframe", { title: embed.title, src: embed.url, className: "block w-full flex-1 border-0" })] })), jsx(AssistantChat, { ...chatProps, texts: texts, voice: voice, layout: isExpanded ? "wide" : "panel", queuedPrompt: queuedPrompt, voiceRequest: voiceRequest, composerDraft: composerDraft, conversations: hostManaged ? hostConversations : storedConversations, activeConversationId: hostManaged ? hostActiveId : managedActiveId, initialMessages: hostManaged ? hostInitialMessages : managedMessages, onConversationCreated: handleConversationCreated, onSelectConversation: handleSelectConversation, onNewConversation: handleNewConversation, historyOpen: historyOpen, onHistoryOpenChange: setHistoryOpen, className: "flex-1", headerAction: jsxs(Fragment, { children: [headerAction, jsx("button", { type: "button", onClick: () => setExpanded(!isExpanded), "aria-label": isExpanded ? collapseLabel : expandLabel, "aria-pressed": isExpanded, title: isExpanded ? collapseLabel : expandLabel, className: "hidden rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary md:inline-flex", "data-testid": "assistant-launcher-expand", children: isExpanded ? (jsx(Minimize2, { className: "h-5 w-5", "aria-hidden": "true" })) : (jsx(Maximize2, { className: "h-5 w-5", "aria-hidden": "true" })) }), jsx("button", { type: "button", onClick: () => setOpen(false), "aria-label": launcherTexts.close, title: launcherTexts.close, className: "rounded-full p-2 text-ews-gray-500 hover:bg-ews-gray-100 hover:text-ews-gray-900 focus:outline-none focus:ring-2 focus:ring-ews-primary", "data-testid": "assistant-launcher-close", children: jsx(X, { className: "h-5 w-5", "aria-hidden": "true" }) })] }) })] })] })] }));
4378
4381
  };
4379
4382
 
4380
4383
  /** Turns one SSE text stream into assistant events; frames may arrive split across chunks. */