@app-studio/web 0.9.82 → 0.9.84

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 (31) hide show
  1. package/dist/components/ChatWidget/ChatWidget/ChatWidget.props.d.ts +58 -0
  2. package/dist/components/ChatWidget/ChatWidget/ChatWidget.state.d.ts +12 -0
  3. package/dist/components/ChatWidget/ChatWidget/ChatWidget.style.d.ts +87 -0
  4. package/dist/components/ChatWidget/ChatWidget/ChatWidget.type.d.ts +54 -0
  5. package/dist/components/ChatWidget/ChatWidget/ChatWidget.view.d.ts +8 -0
  6. package/dist/components/ChatWidget/ChatWidget.d.ts +20 -0
  7. package/dist/components/ChatWidget/Widget/ChatWidgetWidget.d.ts +14 -0
  8. package/dist/components/ChatWidget/Widget/index.d.ts +2 -0
  9. package/dist/components/ChatWidget/Widget/useContextSelector.d.ts +22 -0
  10. package/dist/components/EditComponent/EditComponent.d.ts +14 -0
  11. package/dist/components/EditComponent/EditPanel.d.ts +7 -0
  12. package/dist/components/EditComponent/EditToolbar.d.ts +16 -0
  13. package/dist/components/EditComponent/index.d.ts +3 -0
  14. package/dist/components/Form/Password/Password/Password.state.d.ts +1 -1
  15. package/dist/components/Icon/Icon.d.ts +4 -0
  16. package/dist/components/Tabs/Tabs/Tabs.props.d.ts +1 -1
  17. package/dist/components/Tabs/Tabs/Tabs.state.d.ts +2 -3
  18. package/dist/components/index.d.ts +3 -0
  19. package/dist/pages/chatwidget.page.d.ts +3 -0
  20. package/dist/pages/editComponent.page.d.ts +3 -0
  21. package/dist/web.cjs.development.js +956 -31
  22. package/dist/web.cjs.development.js.map +1 -1
  23. package/dist/web.cjs.production.min.js +1 -1
  24. package/dist/web.cjs.production.min.js.map +1 -1
  25. package/dist/web.esm.js +953 -32
  26. package/dist/web.esm.js.map +1 -1
  27. package/dist/web.umd.development.js +956 -31
  28. package/dist/web.umd.development.js.map +1 -1
  29. package/dist/web.umd.production.min.js +1 -1
  30. package/dist/web.umd.production.min.js.map +1 -1
  31. package/package.json +1 -1
package/dist/web.esm.js CHANGED
@@ -808,6 +808,9 @@ var ZoomInIcon = /*#__PURE__*/createIcon('zoom-in', {
808
808
  var DragHandleLinesIcon = /*#__PURE__*/createIcon('grip-horizontal', {
809
809
  filled: false
810
810
  });
811
+ var MousePointerIcon = /*#__PURE__*/createIcon('mouse-pointer-2', {
812
+ filled: false
813
+ });
811
814
 
812
815
  /**
813
816
  * Alert Styles
@@ -3313,7 +3316,7 @@ var ButtonView = _ref5 => {
3313
3316
  var mainColorKey = (_ref6 = backgroundColor != null ? backgroundColor : color) != null ? _ref6 : 'theme.button.background';
3314
3317
  // Decide which theme token to resolve based on state
3315
3318
  var stateColorKey = isDisabled ? 'theme.disabled' : isLoading ? 'theme.loading' : mainColorKey;
3316
- // Resolve to actual hex color.
3319
+ // Resolve to actual hex color.
3317
3320
  // If 'theme.button.background' isn't defined, it falls back to 'theme.primary'
3318
3321
  var mainTone = getColorHex(stateColorKey);
3319
3322
  if (mainTone === 'theme.button.background' || mainTone === 'theme.loading') {
@@ -16652,40 +16655,46 @@ Table.Template = TableView;
16652
16655
  * @param defaultValue - The optional title of the tab to be initially active.
16653
16656
  * @returns An object containing the current activeTab and a function to update it.
16654
16657
  */
16655
- var useTabsState = (propTabs, defaultValue) => {
16658
+ var useTabsState = (propTabs, defaultValue, value) => {
16659
+ // Helper to extract the identifier (value or title) from a tab
16660
+ var getTabId = tab => tab.value !== undefined ? tab.value : tab.title;
16656
16661
  // Find the initial tab based on defaultValue, or default to the first tab.
16657
- // Ensure propTabs is not empty before accessing index 0.
16658
16662
  var findInitialTab = () => {
16659
16663
  if (!propTabs || propTabs.length === 0) {
16660
- return undefined; // No tabs, no initial active tab
16664
+ return undefined;
16661
16665
  }
16662
16666
  if (defaultValue !== undefined) {
16663
- var foundTab = propTabs.find(tab => tab.title === defaultValue);
16667
+ var foundTab = propTabs.find(tab => getTabId(tab) === defaultValue);
16664
16668
  if (foundTab) {
16665
16669
  return foundTab;
16666
16670
  }
16667
- // Warn if defaultValue is provided but not found
16668
- // console.warn(
16669
- // `Tabs: defaultValue "${defaultValue}" not found in tabs. Defaulting to the first tab.`
16670
- // );
16671
16671
  }
16672
- return propTabs[0]; // Default to the first tab
16672
+ return propTabs[0];
16673
16673
  };
16674
- var [activeTab, setActiveTab] = useState(findInitialTab());
16675
- // Effect to update the active tab if the defaultValue prop changes
16676
- // or if the tabs array changes and the current active tab is no longer valid.
16674
+ var [internalActiveTab, setInternalActiveTab] = useState(findInitialTab());
16675
+ // Determine the effective active tab
16676
+ // In controlled mode (value provided), find the tab matching value.
16677
+ // In uncontrolled mode, use internal state.
16678
+ var activeTab = value !== undefined ? propTabs.find(tab => getTabId(tab) === value) : internalActiveTab;
16679
+ var setActiveTab = tab => {
16680
+ // Only update internal state if uncontrolled
16681
+ if (value === undefined) {
16682
+ setInternalActiveTab(tab);
16683
+ }
16684
+ };
16685
+ // Effect to update internal active tab if defaultValue changes or tabs change
16677
16686
  useEffect(() => {
16687
+ if (value !== undefined) return; // Skip logic if controlled
16678
16688
  var newInitialTab = findInitialTab();
16679
- // Update only if the calculated initial tab is different from the current active tab
16680
- // or if the current active tab is no longer in the list (and there are tabs)
16681
- var currentActiveTabStillValid = activeTab && propTabs.some(t => t.title === activeTab.title);
16682
- if (newInitialTab && (!currentActiveTabStillValid || defaultValue !== undefined && (activeTab == null ? void 0 : activeTab.title) !== defaultValue)) {
16683
- setActiveTab(newInitialTab);
16684
- } else if (!newInitialTab && activeTab) {
16685
- // Handle case where all tabs are removed
16686
- setActiveTab(undefined);
16687
- }
16688
- }, [propTabs, defaultValue]); // Rerun when tabs or initial title changes
16689
+ var currentActiveTabStillValid = internalActiveTab && propTabs.some(t => getTabId(t) === getTabId(internalActiveTab));
16690
+ // If current tab is invalid, or if defaultValue changed and suggests a different tab
16691
+ // (Note: The original logic forced reset on defaultValue change, we keep that behavior)
16692
+ if (newInitialTab && (!currentActiveTabStillValid || defaultValue !== undefined && internalActiveTab && getTabId(internalActiveTab) !== defaultValue)) {
16693
+ setInternalActiveTab(newInitialTab);
16694
+ } else if (!newInitialTab && internalActiveTab) {
16695
+ setInternalActiveTab(undefined);
16696
+ }
16697
+ }, [propTabs, defaultValue]); // Remove internalActiveTab dependency to avoid loops, though it shouldn't cause one if guarded
16689
16698
  return {
16690
16699
  activeTab,
16691
16700
  setActiveTab
@@ -16772,6 +16781,10 @@ var TabHeader = _ref => {
16772
16781
  var getGap = () => {
16773
16782
  return ['top', 'bottom'].includes(iconPosition) ? '4px' : '8px';
16774
16783
  };
16784
+ // Clone icon to apply active styles (e.g. bold stroke) if valid
16785
+ var iconElement = tab.icon && /*#__PURE__*/React.isValidElement(tab.icon) ? /*#__PURE__*/React.cloneElement(tab.icon, {
16786
+ strokeWidth: isActive ? 2.5 : 2
16787
+ }) : tab.icon;
16775
16788
  return /*#__PURE__*/React.createElement(Element, Object.assign({
16776
16789
  as: "div",
16777
16790
  role: "tab",
@@ -16782,7 +16795,23 @@ var TabHeader = _ref => {
16782
16795
  gap: getGap(),
16783
16796
  onClick: onClick,
16784
16797
  "data-state": isActive ? 'active' : 'inactive'
16785
- }), tab.icon && /*#__PURE__*/React.createElement(Element, null, tab.icon), /*#__PURE__*/React.createElement(Text, Object.assign({}, textStyles), tab.title));
16798
+ }), iconElement && (/*#__PURE__*/React.createElement(Element, {
16799
+ key: isActive ? 'active-icon' : 'inactive-icon'
16800
+ }, iconElement)), /*#__PURE__*/React.createElement(Element, {
16801
+ display: "grid",
16802
+ alignItems: "center",
16803
+ justifyContent: "center"
16804
+ }, /*#__PURE__*/React.createElement(Text, Object.assign({}, textStyles, {
16805
+ fontWeight: "600",
16806
+ visibility: "hidden",
16807
+ gridColumn: "1",
16808
+ gridRow: "1",
16809
+ "aria-hidden": "true"
16810
+ }), tab.title), /*#__PURE__*/React.createElement(Text, Object.assign({}, textStyles, {
16811
+ fontWeight: isActive ? '600' : '500',
16812
+ gridColumn: "1",
16813
+ gridRow: "1"
16814
+ }), tab.title)));
16786
16815
  };
16787
16816
 
16788
16817
  /**
@@ -16818,7 +16847,7 @@ var TabsView = _ref => {
16818
16847
  borderBottomColor: "color.gray.200"
16819
16848
  }, views.headerTabs), tabs.map(tab => {
16820
16849
  // Determine if the current tab in the loop is the active one
16821
- var isActive = tab.title === activeTab.title;
16850
+ var isActive = (tab.value !== undefined ? tab.value : tab.title) === (activeTab.value !== undefined ? activeTab.value : activeTab.title);
16822
16851
  // Prepare the onClick handler for this specific tab
16823
16852
  var onClick = () => handleTabClick(tab);
16824
16853
  // Use the custom renderTab function if provided
@@ -16937,7 +16966,7 @@ var TabsComponent = _ref => {
16937
16966
  // For compound component pattern
16938
16967
  var compoundState = useTabsCompoundState(defaultValue, value, onValueChange);
16939
16968
  // For data-driven pattern
16940
- var dataState = useTabsState(tabs || [], defaultValue);
16969
+ var dataState = useTabsState(tabs || [], defaultValue, value);
16941
16970
  // If using compound component pattern (children provided)
16942
16971
  if (children) {
16943
16972
  return /*#__PURE__*/React.createElement(TabsContext.Provider, {
@@ -16948,9 +16977,9 @@ var TabsComponent = _ref => {
16948
16977
  if (tabs) {
16949
16978
  // Handler function to change the active tab and trigger the callback
16950
16979
  var handleTabClick = tab => {
16951
- var _dataState$activeTab;
16980
+ var getTabId = t => t.value !== undefined ? t.value : t.title;
16952
16981
  // Only update state and call callback if the clicked tab is different from the current one
16953
- if (((_dataState$activeTab = dataState.activeTab) == null ? void 0 : _dataState$activeTab.title) !== tab.title) {
16982
+ if (!dataState.activeTab || getTabId(dataState.activeTab) !== getTabId(tab)) {
16954
16983
  dataState.setActiveTab(tab);
16955
16984
  // Call the onTabChange callback if provided
16956
16985
  if (onTabChange) {
@@ -17547,11 +17576,11 @@ var TitleView = _ref => {
17547
17576
  lastIndex = match.index + match[0].length;
17548
17577
  }
17549
17578
  if (lastIndex < text.length) parts.push(text.substring(lastIndex));
17550
- return /*#__PURE__*/React.createElement(Element, Object.assign({}, containerProps, views == null ? void 0 : views.container, props), parts.map((part, idx) => typeof part === 'string' ? (/*#__PURE__*/React.createElement(Text, {
17579
+ return /*#__PURE__*/React.createElement(Element, Object.assign({}, containerProps, views == null ? void 0 : views.container, props), parts.map((part, idx) => typeof part === 'string' ? (/*#__PURE__*/React.createElement(Text, Object.assign({
17551
17580
  key: "text-" + idx,
17552
17581
  as: "span",
17553
17582
  display: "inline"
17554
- }, renderWithLineBreaks(part))) : (/*#__PURE__*/React.createElement(Text, Object.assign({
17583
+ }, views == null ? void 0 : views.text), renderWithLineBreaks(part))) : (/*#__PURE__*/React.createElement(Text, Object.assign({
17555
17584
  key: "highlight-" + idx,
17556
17585
  as: "span",
17557
17586
  display: "inline",
@@ -17567,7 +17596,7 @@ var TitleView = _ref => {
17567
17596
  }, !highlightSlide ? highlightProps : {}, views == null ? void 0 : views.highlight), renderHighlightedContent(text)));
17568
17597
  }
17569
17598
  // Case 3: Default - no highlighting
17570
- return /*#__PURE__*/React.createElement(Text, Object.assign({}, containerProps, props, views == null ? void 0 : views.container), renderWithLineBreaks(text));
17599
+ return /*#__PURE__*/React.createElement(Text, Object.assign({}, containerProps, props, views == null ? void 0 : views.container, views == null ? void 0 : views.text), renderWithLineBreaks(text));
17571
17600
  };
17572
17601
 
17573
17602
  /**
@@ -26293,5 +26322,897 @@ var Background = /*#__PURE__*/Object.assign(BackgroundComponent, {
26293
26322
  });
26294
26323
  Background.displayName = 'Background';
26295
26324
 
26296
- export { Accordion, Alert, ArrowIcon, AspectRatio, AttachmentIcon, AttachmentPreview, AudioIcon, AudioInput, AudioWaveform, Avatar, BackIcon, Background, Badge, BatteryIcon, BluetoothIcon, BoldArrowIcon, BookmarkIcon, Button, CalendarIcon, CameraIcon, Card, Carousel, Chart, ChartIcon, ChatInput, CheckIcon, Checkbox, ChevronIcon, ClockIcon, CloseEyeIcon, CloseIcon, CloudIcon, ColorInput, ColorPicker, ComboBox, Command, ContextMenu, CookieConsent, CopyIcon, CountryPicker, CreditCardIcon, CropIcon, DatePicker, DeleteIcon, Divider, DocumentIcon, DownloadIcon, DragAndDrop, DragAndDropComponent, DragHandleIcon, DragHandleLinesIcon, Drawer, DropdownMenu, DustBinIcon, EditIcon, EmojiPicker, ErrorIcon, ExternalLinkIcon, FacebookIcon, FileIcon, FileImage, FileSVG, FilterIcon, FolderIcon, FormikChatInput, FormikCheckbox, FormikColorInput, FormikComboBox, FormikCountryPicker, FormikDatePicker, FormikForm, FormikOTPInput, FormikPassword, FormikSelect, FormikSelector, FormikSlider, FormikSwitch, FormikTagInput, FormikTextArea, FormikTextField, FormikUploader, GiftIcon, HeartIcon, HelpIcon, HomeIcon, HoverCard, Icon, ImageIcon, InfoIcon, InstagramIcon, LayoutIcon, LikeIcon, Link, LinkIcon, LinkedinIcon, Loader, LoadingSpinnerIcon, LockIcon, LogoutIcon, MagicWandIcon, MapPinIcon, MediaPreview, MenuIcon, Menubar, MessageLayout, MessageView, MicrophoneIcon, MinusIcon, Modal, MoonIcon, MoreIcon, NavigationMenu, NotificationIcon, OTPInput, OpenEyeIcon, Pagination, PanelIcon, Password, PauseIcon, PlayIcon, PlusIcon, PowerOffIcon, PrintIcon, ProfileIcon, ProgressBar, RefreshIcon, Resizable, RotateIcon, SaveIcon, SearchIcon, Select, Selector, SendIcon, Separator, SettingsIcon, ShapeIcon, ShareButton, ShareIcon, ShieldIcon, Sidebar, Slider, SliderIcon, SpinnerIcon, StarIcon, StatusIndicator, StopIcon, SuccessIcon, Switch, Table, Tabs, TagInput, TextArea, TextField, TextIcon, ThreadsIcon, TickIcon, Title, Toast, Toggle, ToggleGroup, Tooltip, TrashIcon, TwitchIcon, TwitterIcon, UnLikeIcon, UnlockIcon, UploadIcon, Uploader, UserIcon, VideoIcon, WarningIcon, WifiIcon, XIcon, YoutubeIcon, ZapIcon, ZoomInIcon, ZoomOutIcon, hideMessage, hideModal, showMessage, showModal, showToast, useMessageStore, useModalStore, useToast$1 as useToast };
26325
+ /**
26326
+ * Custom hook for managing ChatWidget component state
26327
+ */
26328
+ function useChatWidgetState(props) {
26329
+ var {
26330
+ inputValue,
26331
+ onInputChange,
26332
+ onSubmit,
26333
+ messages = []
26334
+ } = props;
26335
+ // Internal state for uncontrolled input
26336
+ var [internalInputValue, setInternalInputValue] = useState('');
26337
+ // Refs
26338
+ var inputRef = useRef(null);
26339
+ var messagesRef = useRef(null);
26340
+ // Determine if the component is controlled
26341
+ var isControlled = inputValue !== undefined;
26342
+ // Get the current input value
26343
+ var currentInputValue = inputValue !== undefined ? inputValue : internalInputValue;
26344
+ // Handle input changes
26345
+ var handleInputChange = useCallback(value => {
26346
+ if (isControlled) {
26347
+ onInputChange == null || onInputChange(value);
26348
+ } else {
26349
+ setInternalInputValue(value);
26350
+ }
26351
+ }, [isControlled, onInputChange]);
26352
+ // Handle message submission
26353
+ var handleSubmit = useCallback(e => {
26354
+ if (e) {
26355
+ e.preventDefault();
26356
+ }
26357
+ var trimmedValue = currentInputValue.trim();
26358
+ if (trimmedValue && onSubmit) {
26359
+ onSubmit(trimmedValue);
26360
+ // Clear input after submission (only for uncontrolled)
26361
+ if (!isControlled) {
26362
+ setInternalInputValue('');
26363
+ }
26364
+ // Reset textarea height
26365
+ if (inputRef.current) {
26366
+ inputRef.current.style.height = 'auto';
26367
+ }
26368
+ }
26369
+ }, [currentInputValue, onSubmit, isControlled]);
26370
+ // Auto-scroll to bottom when new messages arrive
26371
+ useEffect(() => {
26372
+ if (messagesRef.current) {
26373
+ messagesRef.current.scrollTop = messagesRef.current.scrollHeight;
26374
+ }
26375
+ }, [messages.length]);
26376
+ return {
26377
+ internalInputValue: currentInputValue,
26378
+ handleInputChange,
26379
+ handleSubmit,
26380
+ inputRef,
26381
+ messagesRef
26382
+ };
26383
+ }
26384
+
26385
+ /** Size mappings for the ChatWidget component */
26386
+ var Sizes$5 = {
26387
+ sm: {
26388
+ fontSize: '13px',
26389
+ padding: '8px'
26390
+ },
26391
+ md: {
26392
+ fontSize: '14px',
26393
+ padding: '12px'
26394
+ },
26395
+ lg: {
26396
+ fontSize: '16px',
26397
+ padding: '16px'
26398
+ }
26399
+ };
26400
+ /** Variant mappings for the ChatWidget component */
26401
+ var Variants$4 = {
26402
+ default: {
26403
+ backgroundColor: '#ffffff',
26404
+ border: '1px solid #e5e7eb',
26405
+ borderRadius: '16px'
26406
+ },
26407
+ glassy: {
26408
+ backgroundColor: 'rgba(255, 255, 255, 0.6)',
26409
+ backdropFilter: 'blur(12px)',
26410
+ border: '1px solid rgba(0, 0, 0, 0.1)',
26411
+ borderRadius: '16px',
26412
+ boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)'
26413
+ },
26414
+ minimal: {
26415
+ backgroundColor: 'transparent',
26416
+ border: 'none'
26417
+ }
26418
+ };
26419
+ /** Bubble size mappings */
26420
+ var BubbleSizes = {
26421
+ sm: {
26422
+ fontSize: '13px',
26423
+ padding: '6px 10px',
26424
+ borderRadius: '14px'
26425
+ },
26426
+ md: {
26427
+ fontSize: '14px',
26428
+ padding: '8px 12px',
26429
+ borderRadius: '16px'
26430
+ },
26431
+ lg: {
26432
+ fontSize: '16px',
26433
+ padding: '10px 16px',
26434
+ borderRadius: '18px'
26435
+ }
26436
+ };
26437
+ /** User bubble styles (blue, aligned right) */
26438
+ var UserBubbleStyles = {
26439
+ backgroundColor: 'rgba(37, 99, 235, 0.9)',
26440
+ color: '#ffffff',
26441
+ alignSelf: 'flex-end',
26442
+ borderBottomRightRadius: '4px',
26443
+ boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)'
26444
+ };
26445
+ /** Assistant bubble styles (gray, aligned left) */
26446
+ var AssistantBubbleStyles = {
26447
+ backgroundColor: 'rgba(244, 244, 245, 0.6)',
26448
+ color: '#18181b',
26449
+ alignSelf: 'flex-start',
26450
+ borderBottomLeftRadius: '4px',
26451
+ boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)'
26452
+ };
26453
+ /** Input container styles with glassmorphic effect */
26454
+ var InputContainerStyles = {
26455
+ position: 'relative',
26456
+ backgroundColor: 'rgba(244, 244, 245, 0.05)',
26457
+ backdropFilter: 'blur(12px)',
26458
+ borderRadius: '16px',
26459
+ border: '1px solid rgba(0, 0, 0, 0.1)',
26460
+ boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
26461
+ padding: '8px 12px',
26462
+ display: 'flex',
26463
+ alignItems: 'flex-end',
26464
+ gap: '8px',
26465
+ transition: 'all 0.2s ease'
26466
+ };
26467
+ /** Default ChatWidget component styles */
26468
+ var DefaultChatWidgetStyles = {
26469
+ container: {
26470
+ display: 'flex',
26471
+ flexDirection: 'column',
26472
+ width: '100%',
26473
+ height: '100%',
26474
+ overflow: 'hidden'
26475
+ },
26476
+ messagesContainer: {
26477
+ flex: 1,
26478
+ overflowY: 'auto',
26479
+ display: 'flex',
26480
+ flexDirection: 'column',
26481
+ gap: '8px',
26482
+ padding: '16px'
26483
+ },
26484
+ inputContainer: InputContainerStyles,
26485
+ bubble: {
26486
+ maxWidth: '80%',
26487
+ position: 'relative',
26488
+ wordWrap: 'break-word',
26489
+ animation: 'chatBubbleAppear 0.3s ease-out'
26490
+ },
26491
+ timestamp: {
26492
+ position: 'absolute',
26493
+ top: '-24px',
26494
+ fontSize: '12px',
26495
+ color: 'rgba(0, 0, 0, 0.5)',
26496
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
26497
+ padding: '2px 8px',
26498
+ borderRadius: '9999px',
26499
+ opacity: 0,
26500
+ transition: 'opacity 0.15s ease-out',
26501
+ boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)'
26502
+ },
26503
+ input: {
26504
+ flex: 1,
26505
+ border: 'none',
26506
+ outline: 'none',
26507
+ backgroundColor: 'transparent',
26508
+ resize: 'none',
26509
+ fontFamily: 'inherit',
26510
+ fontSize: '14px',
26511
+ minHeight: '24px',
26512
+ maxHeight: '120px'
26513
+ },
26514
+ sendButton: {
26515
+ width: '32px',
26516
+ height: '32px',
26517
+ borderRadius: '50%',
26518
+ border: 'none',
26519
+ cursor: 'pointer',
26520
+ display: 'flex',
26521
+ alignItems: 'center',
26522
+ justifyContent: 'center',
26523
+ transition: 'all 0.2s ease',
26524
+ flexShrink: 0
26525
+ },
26526
+ attachmentButton: {
26527
+ width: '32px',
26528
+ height: '32px',
26529
+ borderRadius: '50%',
26530
+ border: 'none',
26531
+ cursor: 'pointer',
26532
+ display: 'flex',
26533
+ alignItems: 'center',
26534
+ justifyContent: 'center',
26535
+ backgroundColor: 'transparent',
26536
+ transition: 'background-color 0.2s ease',
26537
+ flexShrink: 0
26538
+ }
26539
+ };
26540
+
26541
+ var _excluded$1p = ["messages", "inputPlaceholder", "disableInput", "variant", "size", "showTimestamps", "enableAttachments", "enableContextPicker", "selectedContextElements", "onContextPickerClick", "onRemoveContextElement", "isLoading", "loadingText", "styles", "maxHeight", "internalInputValue", "handleInputChange", "handleSubmit", "inputRef", "messagesRef"],
26542
+ _excluded2$n = ["onSubmit"];
26543
+ /**
26544
+ * ChatWidget View Component
26545
+ * Presentational component for the ChatWidget interface
26546
+ */
26547
+ var ChatWidgetView = _ref => {
26548
+ var _styles$contextPicker;
26549
+ var {
26550
+ messages = [],
26551
+ inputPlaceholder = 'Type a message...',
26552
+ disableInput = false,
26553
+ variant = 'default',
26554
+ size = 'md',
26555
+ showTimestamps = true,
26556
+ enableAttachments = false,
26557
+ enableContextPicker = false,
26558
+ selectedContextElements = [],
26559
+ onContextPickerClick,
26560
+ onRemoveContextElement,
26561
+ isLoading = false,
26562
+ loadingText = 'Loading...',
26563
+ styles = {},
26564
+ maxHeight = '600px',
26565
+ internalInputValue,
26566
+ handleInputChange,
26567
+ handleSubmit,
26568
+ inputRef,
26569
+ messagesRef
26570
+ } = _ref,
26571
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1p);
26572
+ // Combine styles
26573
+ var containerStyles = Object.assign({}, DefaultChatWidgetStyles.container, Variants$4[variant], styles.container);
26574
+ var messagesContainerStyles = Object.assign({}, DefaultChatWidgetStyles.messagesContainer, {
26575
+ maxHeight
26576
+ }, styles.messagesContainer);
26577
+ var inputContainerStyles = Object.assign({}, DefaultChatWidgetStyles.inputContainer, styles.inputContainer);
26578
+ var inputStyles = Object.assign({}, DefaultChatWidgetStyles.input, Sizes$5[size], styles.input);
26579
+ // Auto-resize textarea
26580
+ var handleTextareaChange = useCallback(e => {
26581
+ handleInputChange(e.target.value);
26582
+ // Auto-resize
26583
+ e.target.style.height = 'auto';
26584
+ e.target.style.height = e.target.scrollHeight + "px";
26585
+ }, [handleInputChange]);
26586
+ // Handle Enter key to submit
26587
+ var handleKeyDown = useCallback(e => {
26588
+ if (e.key === 'Enter' && !e.shiftKey) {
26589
+ e.preventDefault();
26590
+ handleSubmit();
26591
+ }
26592
+ }, [handleSubmit]);
26593
+ var hasText = internalInputValue.trim().length > 0;
26594
+ // Separate onSubmit from other props to avoid type conflict
26595
+ var viewProps = _objectWithoutPropertiesLoose(props, _excluded2$n);
26596
+ return /*#__PURE__*/React.createElement(View, Object.assign({}, containerStyles, viewProps), /*#__PURE__*/React.createElement(View, Object.assign({
26597
+ ref: messagesRef
26598
+ }, messagesContainerStyles), messages.length === 0 ? (/*#__PURE__*/React.createElement(View, {
26599
+ display: "flex",
26600
+ alignItems: "center",
26601
+ justifyContent: "center",
26602
+ flex: 1,
26603
+ color: "color.gray.400"
26604
+ }, /*#__PURE__*/React.createElement(Text, {
26605
+ fontSize: "14px"
26606
+ }, "No messages yet. Start a conversation!"))) : messages.map(message => (/*#__PURE__*/React.createElement(ChatBubble, {
26607
+ key: message.id,
26608
+ message: message,
26609
+ size: size,
26610
+ showTimestamp: showTimestamps,
26611
+ styles: {
26612
+ bubble: styles.bubble,
26613
+ userBubble: styles.userBubble,
26614
+ assistantBubble: styles.assistantBubble,
26615
+ timestamp: styles.timestamp,
26616
+ reasoningContainer: styles.reasoningContainer,
26617
+ reasoningContent: styles.reasoningContent,
26618
+ errorMessage: styles.errorMessage,
26619
+ systemMessage: styles.systemMessage,
26620
+ toolMessage: styles.toolMessage
26621
+ }
26622
+ }))), isLoading && (/*#__PURE__*/React.createElement(Horizontal, Object.assign({
26623
+ justifyContent: "flex-start",
26624
+ alignItems: "center",
26625
+ gap: 8,
26626
+ marginTop: "8px"
26627
+ }, styles.loadingIndicator), /*#__PURE__*/React.createElement(LoadingSpinnerIcon, {
26628
+ widthHeight: 12,
26629
+ color: "currentColor",
26630
+ filled: false,
26631
+ style: {
26632
+ animation: 'spin 1s linear infinite'
26633
+ }
26634
+ }), /*#__PURE__*/React.createElement(Text, {
26635
+ color: "color.gray.500",
26636
+ fontSize: "14px"
26637
+ }, loadingText)))), /*#__PURE__*/React.createElement(View, null, selectedContextElements.length > 0 && (/*#__PURE__*/React.createElement(Horizontal, Object.assign({
26638
+ gap: 8,
26639
+ marginBottom: "8px",
26640
+ flexWrap: "wrap",
26641
+ paddingHorizontal: "20px"
26642
+ }, styles.contextChipsContainer), selectedContextElements.map(element => (/*#__PURE__*/React.createElement(Horizontal, {
26643
+ key: element.id,
26644
+ backgroundColor: "rgba(37, 99, 235, 0.1)",
26645
+ border: "1px solid rgba(37, 99, 235, 0.2)",
26646
+ borderRadius: "6px",
26647
+ padding: "4px 8px",
26648
+ alignItems: "center",
26649
+ gap: 6
26650
+ }, /*#__PURE__*/React.createElement(Text, {
26651
+ fontSize: "12px",
26652
+ color: "color.blue.700",
26653
+ fontWeight: "500"
26654
+ }, element.name), /*#__PURE__*/React.createElement(View, {
26655
+ as: "button",
26656
+ type: "button",
26657
+ onClick: () => onRemoveContextElement == null ? void 0 : onRemoveContextElement(element.id),
26658
+ cursor: "pointer",
26659
+ border: "none",
26660
+ backgroundColor: "transparent",
26661
+ display: "flex",
26662
+ alignItems: "center"
26663
+ }, /*#__PURE__*/React.createElement(CloseIcon, {
26664
+ widthHeight: 12,
26665
+ color: "color.blue.700"
26666
+ }))))))), /*#__PURE__*/React.createElement(View, Object.assign({
26667
+ as: "form",
26668
+ onSubmit: handleSubmit
26669
+ }, inputContainerStyles), enableAttachments && (/*#__PURE__*/React.createElement(View, Object.assign({
26670
+ as: "button",
26671
+ type: "button"
26672
+ }, DefaultChatWidgetStyles.attachmentButton, styles.attachmentButton, {
26673
+ _hover: {
26674
+ backgroundColor: 'color.gray.100'
26675
+ }
26676
+ }), /*#__PURE__*/React.createElement(AttachmentIcon, {
26677
+ widthHeight: 16,
26678
+ color: "color.gray.600"
26679
+ }))), /*#__PURE__*/React.createElement(View, Object.assign({
26680
+ as: "textarea",
26681
+ ref: inputRef,
26682
+ value: internalInputValue,
26683
+ onChange: handleTextareaChange,
26684
+ onKeyDown: handleKeyDown,
26685
+ placeholder: inputPlaceholder,
26686
+ disabled: disableInput || isLoading
26687
+ }, inputStyles, {
26688
+ style: Object.assign({}, inputStyles, {
26689
+ opacity: disableInput || isLoading ? 0.5 : 1
26690
+ })
26691
+ })), /*#__PURE__*/React.createElement(Vertical, {
26692
+ gap: 4,
26693
+ alignItems: "center"
26694
+ }, enableContextPicker && (/*#__PURE__*/React.createElement(View, Object.assign({
26695
+ as: "button",
26696
+ type: "button",
26697
+ onClick: onContextPickerClick
26698
+ }, DefaultChatWidgetStyles.attachmentButton, styles.contextPickerButton, {
26699
+ _hover: Object.assign({
26700
+ backgroundColor: 'color.gray.100'
26701
+ }, (_styles$contextPicker = styles.contextPickerButton) == null ? void 0 : _styles$contextPicker._hover),
26702
+ title: "Select element from page"
26703
+ }), /*#__PURE__*/React.createElement(MousePointerIcon, {
26704
+ widthHeight: 16,
26705
+ color: "color.gray.600"
26706
+ }))), /*#__PURE__*/React.createElement(View, Object.assign({
26707
+ as: "button",
26708
+ type: "submit",
26709
+ disabled: !hasText || disableInput || isLoading
26710
+ }, DefaultChatWidgetStyles.sendButton, {
26711
+ backgroundColor: hasText ? 'theme.primary' : 'color.gray.300',
26712
+ _hover: {
26713
+ backgroundColor: hasText ? 'color.blue.600' : 'color.gray.300'
26714
+ }
26715
+ }, styles.sendButton, {
26716
+ style: {
26717
+ cursor: hasText ? 'pointer' : 'not-allowed',
26718
+ opacity: !hasText || disableInput || isLoading ? 0.6 : 1
26719
+ }
26720
+ }), /*#__PURE__*/React.createElement(SendIcon, {
26721
+ widthHeight: 16,
26722
+ color: "color.white",
26723
+ filled: false
26724
+ }))))));
26725
+ };
26726
+ var ChatBubble = _ref2 => {
26727
+ var {
26728
+ message,
26729
+ size,
26730
+ showTimestamp,
26731
+ styles
26732
+ } = _ref2;
26733
+ var [showTimestampOverlay, setShowTimestampOverlay] = React.useState(false);
26734
+ var [isReasoningOpen, setIsReasoningOpen] = React.useState(false);
26735
+ var isUser = message.role === 'user';
26736
+ var isSystem = message.messageType === 'system';
26737
+ var isError = message.messageType === 'error';
26738
+ var isTool = message.messageType === 'tool';
26739
+ // System Message Rendering
26740
+ if (isSystem) {
26741
+ return /*#__PURE__*/React.createElement(View, Object.assign({
26742
+ display: "flex",
26743
+ justifyContent: "center",
26744
+ padding: "8px",
26745
+ width: "100%"
26746
+ }, styles.systemMessage), /*#__PURE__*/React.createElement(Horizontal, {
26747
+ gap: 6,
26748
+ alignItems: "center",
26749
+ opacity: 0.7
26750
+ }, /*#__PURE__*/React.createElement(InfoIcon, {
26751
+ widthHeight: 12,
26752
+ color: "color.gray.600"
26753
+ }), /*#__PURE__*/React.createElement(Text, {
26754
+ fontSize: "12px",
26755
+ color: "color.gray.600",
26756
+ fontStyle: "italic"
26757
+ }, message.content)));
26758
+ }
26759
+ // Tool Message Rendering
26760
+ if (isTool) {
26761
+ return /*#__PURE__*/React.createElement(View, Object.assign({
26762
+ display: "flex",
26763
+ justifyContent: "flex-start",
26764
+ padding: "8px 16px",
26765
+ width: "100%"
26766
+ }, styles.toolMessage), /*#__PURE__*/React.createElement(Horizontal, {
26767
+ gap: 8,
26768
+ alignItems: "center",
26769
+ backgroundColor: "rgba(0,0,0,0.03)",
26770
+ padding: "8px",
26771
+ borderRadius: "8px",
26772
+ width: "100%",
26773
+ border: "1px solid rgba(0,0,0,0.05)"
26774
+ }, /*#__PURE__*/React.createElement(SettingsIcon, {
26775
+ widthHeight: 14,
26776
+ color: "color.gray.600"
26777
+ }), /*#__PURE__*/React.createElement(Vertical, {
26778
+ gap: 2
26779
+ }, /*#__PURE__*/React.createElement(Text, {
26780
+ fontSize: "11px",
26781
+ fontWeight: "600",
26782
+ color: "color.gray.700"
26783
+ }, "Tool Usage"), /*#__PURE__*/React.createElement(Text, {
26784
+ fontSize: "12px",
26785
+ color: "color.gray.600",
26786
+ fontFamily: "monospace"
26787
+ }, message.content))));
26788
+ }
26789
+ // Bubble Styles construction
26790
+ var bubbleStyles = Object.assign({}, DefaultChatWidgetStyles.bubble, BubbleSizes[size], isUser ? UserBubbleStyles : AssistantBubbleStyles, isError ? {
26791
+ backgroundColor: 'rgba(239, 68, 68, 0.1)',
26792
+ border: '1px solid rgba(239, 68, 68, 0.2)',
26793
+ color: '#b91c1c'
26794
+ } : {}, styles.bubble, isUser ? styles.userBubble : styles.assistantBubble, isError ? styles.errorMessage : {});
26795
+ var timestampStyles = Object.assign({}, DefaultChatWidgetStyles.timestamp, {
26796
+ [isUser ? 'right' : 'left']: '8px',
26797
+ opacity: showTimestampOverlay ? 1 : 0
26798
+ }, styles.timestamp);
26799
+ return /*#__PURE__*/React.createElement(View, {
26800
+ position: "relative",
26801
+ onMouseEnter: () => setShowTimestampOverlay(true),
26802
+ onMouseLeave: () => setShowTimestampOverlay(false),
26803
+ display: "flex",
26804
+ justifyContent: isUser ? 'flex-end' : 'flex-start'
26805
+ }, /*#__PURE__*/React.createElement(View, Object.assign({}, bubbleStyles), showTimestamp && (/*#__PURE__*/React.createElement(View, Object.assign({}, timestampStyles), message.timestamp.toLocaleTimeString([], {
26806
+ hour: '2-digit',
26807
+ minute: '2-digit'
26808
+ }))), isError && (/*#__PURE__*/React.createElement(Horizontal, {
26809
+ gap: 6,
26810
+ marginBottom: "4px",
26811
+ alignItems: "center"
26812
+ }, /*#__PURE__*/React.createElement(ErrorIcon, {
26813
+ widthHeight: 14,
26814
+ color: "#b91c1c"
26815
+ }), /*#__PURE__*/React.createElement(Text, {
26816
+ fontWeight: "600",
26817
+ fontSize: "12px"
26818
+ }, "Error"))), message.reasoning && (/*#__PURE__*/React.createElement(View, Object.assign({
26819
+ marginBottom: "8px",
26820
+ borderBottom: "1px solid rgba(0,0,0,0.05)",
26821
+ paddingBottom: "8px"
26822
+ }, styles.reasoningContainer), /*#__PURE__*/React.createElement(Horizontal, {
26823
+ as: "button",
26824
+ onClick: () => setIsReasoningOpen(!isReasoningOpen),
26825
+ cursor: "pointer",
26826
+ gap: 4,
26827
+ alignItems: "center",
26828
+ backgroundColor: "transparent",
26829
+ border: "none",
26830
+ padding: 0
26831
+ }, /*#__PURE__*/React.createElement(Text, {
26832
+ fontSize: "11px",
26833
+ color: "color.gray.500",
26834
+ fontWeight: "600"
26835
+ }, "Thinking Process"), /*#__PURE__*/React.createElement(ChevronIcon, {
26836
+ orientation: isReasoningOpen ? 'down' : 'right',
26837
+ widthHeight: 10,
26838
+ color: "color.gray.500"
26839
+ })), isReasoningOpen && (/*#__PURE__*/React.createElement(View, Object.assign({
26840
+ padding: "8px",
26841
+ backgroundColor: "rgba(0,0,0,0.03)",
26842
+ borderRadius: "8px",
26843
+ marginTop: "4px"
26844
+ }, styles.reasoningContent), /*#__PURE__*/React.createElement(Text, {
26845
+ fontSize: "12px",
26846
+ color: "color.gray.600",
26847
+ fontStyle: "italic"
26848
+ }, message.reasoning))))), /*#__PURE__*/React.createElement(View, {
26849
+ whiteSpace: "pre-wrap",
26850
+ wordBreak: "break-word"
26851
+ }, message.content), message.attachments && message.attachments.length > 0 && (/*#__PURE__*/React.createElement(Vertical, {
26852
+ gap: 4,
26853
+ marginTop: "8px"
26854
+ }, message.attachments.map(attachment => (/*#__PURE__*/React.createElement(Horizontal, {
26855
+ key: attachment.id,
26856
+ gap: 6,
26857
+ padding: "6px 8px",
26858
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
26859
+ borderRadius: "8px",
26860
+ fontSize: "12px"
26861
+ }, /*#__PURE__*/React.createElement(AttachmentIcon, {
26862
+ widthHeight: 14
26863
+ }), /*#__PURE__*/React.createElement(Text, null, attachment.name)))))), message.contextElements && message.contextElements.length > 0 && (/*#__PURE__*/React.createElement(Vertical, {
26864
+ gap: 4,
26865
+ marginTop: "8px"
26866
+ }, /*#__PURE__*/React.createElement(Text, {
26867
+ fontSize: "11px",
26868
+ color: "rgba(0,0,0,0.5)",
26869
+ fontWeight: "600"
26870
+ }, "Context:"), message.contextElements.map(element => (/*#__PURE__*/React.createElement(Horizontal, {
26871
+ key: element.id,
26872
+ gap: 6,
26873
+ padding: "4px 8px",
26874
+ backgroundColor: "rgba(37, 99, 235, 0.1)",
26875
+ borderRadius: "6px",
26876
+ fontSize: "11px",
26877
+ border: "1px solid rgba(37, 99, 235, 0.2)"
26878
+ }, /*#__PURE__*/React.createElement(Text, {
26879
+ color: "color.blue.700",
26880
+ fontWeight: "500"
26881
+ }, element.name))))))));
26882
+ };
26883
+
26884
+ /**
26885
+ * ChatWidget Component
26886
+ *
26887
+ * A configurable chat interface component inspired by the ChatWidget toolbar design.
26888
+ * This is a UI-only component without backend/LLM connections.
26889
+ *
26890
+ * @example
26891
+ * ```tsx
26892
+ * <ChatWidget
26893
+ * messages={messages}
26894
+ * onSubmit={(message) => console.log(message)}
26895
+ * variant="glassy"
26896
+ * size="md"
26897
+ * />
26898
+ * ```
26899
+ */
26900
+ var ChatWidgetComponent = props => {
26901
+ var state = useChatWidgetState(props);
26902
+ return /*#__PURE__*/React.createElement(ChatWidgetView, Object.assign({}, props, state));
26903
+ };
26904
+ ChatWidgetComponent.displayName = 'ChatWidget';
26905
+ var ChatWidget = ChatWidgetComponent;
26906
+
26907
+ function useContextSelector(_ref) {
26908
+ var {
26909
+ onSelect,
26910
+ onCancel,
26911
+ active
26912
+ } = _ref;
26913
+ var [highlightedElement, setHighlightedElement] = useState(null);
26914
+ var overlayRef = useRef(null);
26915
+ // Handle mouse move to consistently highlight elements
26916
+ var handleMouseMove = useCallback(e => {
26917
+ var _target$innerText;
26918
+ if (!active) return;
26919
+ var target = document.elementFromPoint(e.clientX, e.clientY);
26920
+ // Ignore if targeting the overlay itself or the widget
26921
+ if (!target || target === document.body || target.closest('[data-chatwidget-ignore="true"]') || target.closest('#chatwidget-overlay')) {
26922
+ setHighlightedElement(null);
26923
+ return;
26924
+ }
26925
+ var rect = target.getBoundingClientRect();
26926
+ // Compute a helpful name
26927
+ var name = target.tagName.toLowerCase();
26928
+ if (target.id) name += "#" + target.id;else if (target.className && typeof target.className === 'string') {
26929
+ // Just take the first class for brevity
26930
+ var firstClass = target.className.split(' ')[0];
26931
+ if (firstClass) name += "." + firstClass;
26932
+ }
26933
+ // Get some text content if available for better context
26934
+ var text = (_target$innerText = target.innerText) == null ? void 0 : _target$innerText.slice(0, 20);
26935
+ if (text) name += " (\"" + text + "...\")";
26936
+ setHighlightedElement({
26937
+ id: target.id || "el-" + Date.now(),
26938
+ name,
26939
+ tagName: target.tagName.toLowerCase(),
26940
+ rect
26941
+ });
26942
+ }, [active]);
26943
+ // Handle click to select
26944
+ var handleClick = useCallback(e => {
26945
+ if (!active) return;
26946
+ // If clicking inside the widget, don't trigger selection
26947
+ var target = e.target;
26948
+ if (target.closest('[data-chatwidget-ignore="true"]')) {
26949
+ return;
26950
+ }
26951
+ e.preventDefault();
26952
+ e.stopPropagation();
26953
+ if (highlightedElement) {
26954
+ onSelect(highlightedElement);
26955
+ }
26956
+ }, [active, highlightedElement, onSelect]);
26957
+ // Handle escape to cancel
26958
+ var handleKeyDown = useCallback(e => {
26959
+ if (!active) return;
26960
+ if (e.key === 'Escape') {
26961
+ onCancel();
26962
+ }
26963
+ }, [active, onCancel]);
26964
+ useEffect(() => {
26965
+ if (active) {
26966
+ document.addEventListener('mousemove', handleMouseMove);
26967
+ document.addEventListener('click', handleClick, true); // Capture phase to prevent default
26968
+ document.addEventListener('keydown', handleKeyDown);
26969
+ document.body.style.cursor = 'crosshair';
26970
+ } else {
26971
+ setHighlightedElement(null);
26972
+ document.removeEventListener('mousemove', handleMouseMove);
26973
+ document.removeEventListener('click', handleClick, true);
26974
+ document.removeEventListener('keydown', handleKeyDown);
26975
+ document.body.style.cursor = '';
26976
+ }
26977
+ return () => {
26978
+ document.removeEventListener('mousemove', handleMouseMove);
26979
+ document.removeEventListener('click', handleClick, true);
26980
+ document.removeEventListener('keydown', handleKeyDown);
26981
+ document.body.style.cursor = '';
26982
+ };
26983
+ }, [active, handleMouseMove, handleClick, handleKeyDown]);
26984
+ return {
26985
+ highlightedElement
26986
+ };
26987
+ }
26988
+ /**
26989
+ * Overlay component to render the highlight box
26990
+ */
26991
+ function ContextOverlay(_ref2) {
26992
+ var {
26993
+ element
26994
+ } = _ref2;
26995
+ if (!element) return null;
26996
+ return /*#__PURE__*/React.createElement("div", {
26997
+ id: "chatwidget-overlay",
26998
+ style: {
26999
+ position: 'fixed',
27000
+ top: element.rect.top,
27001
+ left: element.rect.left,
27002
+ width: element.rect.width,
27003
+ height: element.rect.height,
27004
+ border: '2px solid #2563eb',
27005
+ backgroundColor: 'rgba(37, 99, 235, 0.1)',
27006
+ pointerEvents: 'none',
27007
+ zIndex: 99999,
27008
+ transition: 'all 0.1s ease-out',
27009
+ borderRadius: '4px'
27010
+ }
27011
+ }, /*#__PURE__*/React.createElement("div", {
27012
+ style: {
27013
+ position: 'absolute',
27014
+ top: '-24px',
27015
+ left: '0',
27016
+ backgroundColor: '#2563eb',
27017
+ color: 'white',
27018
+ padding: '2px 8px',
27019
+ borderRadius: '4px',
27020
+ fontSize: '12px',
27021
+ fontWeight: 'bold',
27022
+ whiteSpace: 'nowrap'
27023
+ }
27024
+ }, element.name));
27025
+ }
27026
+
27027
+ /**
27028
+ * ChatWidget Widget Component
27029
+ * A floating chat widget with DOM element selection capabilities.
27030
+ */
27031
+ var ChatWidgetWidget = _ref => {
27032
+ var {
27033
+ initialMessages = [],
27034
+ onSendMessage,
27035
+ bubbleSize = 'md'
27036
+ } = _ref;
27037
+ var [isOpen, setIsOpen] = useState(false);
27038
+ var [isContextPickerActive, setIsContextPickerActive] = useState(false);
27039
+ var [messages, setMessages] = useState(initialMessages);
27040
+ var [contextElements, setContextElements] = useState([]);
27041
+ // Hook for context selection
27042
+ var {
27043
+ highlightedElement
27044
+ } = useContextSelector({
27045
+ active: isContextPickerActive,
27046
+ onSelect: element => {
27047
+ setContextElements(prev => [...prev, element]);
27048
+ setIsContextPickerActive(false);
27049
+ setIsOpen(true); // Re-open chat after selection
27050
+ },
27051
+ onCancel: () => {
27052
+ setIsContextPickerActive(false);
27053
+ setIsOpen(true);
27054
+ }
27055
+ });
27056
+ var toggleOpen = () => setIsOpen(!isOpen);
27057
+ var handleContextPickerClick = () => {
27058
+ setIsContextPickerActive(true);
27059
+ setIsOpen(false); // Minimize chat while picking
27060
+ };
27061
+ var handleRemoveContextElement = id => {
27062
+ setContextElements(prev => prev.filter(el => el.id !== id));
27063
+ };
27064
+ var handleSubmit = content => {
27065
+ // Add user message
27066
+ var newMessage = {
27067
+ id: Date.now().toString(),
27068
+ role: 'user',
27069
+ content,
27070
+ timestamp: new Date(),
27071
+ contextElements: [...contextElements]
27072
+ };
27073
+ setMessages(prev => [...prev, newMessage]);
27074
+ onSendMessage == null || onSendMessage(content, contextElements);
27075
+ // Clear context after sending
27076
+ setContextElements([]);
27077
+ // Simulate assistant response
27078
+ setTimeout(() => {
27079
+ var _newMessage$contextEl;
27080
+ var isToolCall = Math.random() > 0.7;
27081
+ var hasReasoning = Math.random() > 0.4;
27082
+ var assistantMessage = {
27083
+ id: (Date.now() + 1).toString(),
27084
+ role: 'assistant',
27085
+ timestamp: new Date(),
27086
+ content: isToolCall ? 'I will highlight the selected element.' : "I received your message regarding: " + (((_newMessage$contextEl = newMessage.contextElements) == null ? void 0 : _newMessage$contextEl.map(e => e.name).join(', ')) || 'general context') + ". How can I assist you further?",
27087
+ messageType: isToolCall ? 'tool' : 'text',
27088
+ reasoning: hasReasoning ? 'Analyzing the user input and context... The user seems to be asking about specific elements. I should tailor my response to the selected context.' : undefined
27089
+ };
27090
+ setMessages(prev => [...prev, assistantMessage]);
27091
+ if (isToolCall) {
27092
+ // Add a follow-up system message after a tool call
27093
+ setTimeout(() => {
27094
+ setMessages(prev => [...prev, {
27095
+ id: (Date.now() + 2).toString(),
27096
+ role: 'assistant',
27097
+ messageType: 'system',
27098
+ content: 'Tool "highlightElement" executed successfully.',
27099
+ timestamp: new Date()
27100
+ }]);
27101
+ }, 800);
27102
+ }
27103
+ }, 1000);
27104
+ };
27105
+ return /*#__PURE__*/React.createElement(View, {
27106
+ position: "fixed",
27107
+ bottom: 24,
27108
+ right: 24,
27109
+ zIndex: 9999
27110
+ }, /*#__PURE__*/React.createElement(ContextOverlay, {
27111
+ element: highlightedElement
27112
+ }), isContextPickerActive && (/*#__PURE__*/React.createElement(View, {
27113
+ position: "fixed",
27114
+ top: 24,
27115
+ left: "50%",
27116
+ transform: "translateX(-50%)",
27117
+ backgroundColor: "rgba(0,0,0,0.8)",
27118
+ color: "white",
27119
+ padding: "8px 16px",
27120
+ borderRadius: "24px",
27121
+ zIndex: 10000,
27122
+ boxShadow: "0 4px 6px rgba(0,0,0,0.1)"
27123
+ }, /*#__PURE__*/React.createElement(Text, {
27124
+ fontWeight: "600",
27125
+ fontSize: "14px"
27126
+ }, "Click an element to select it. Press ESC to cancel."))), isOpen && (/*#__PURE__*/React.createElement(View, {
27127
+ position: "absolute",
27128
+ bottom: 60,
27129
+ right: 0,
27130
+ width: "400px",
27131
+ height: "600px",
27132
+ marginBottom: "16px",
27133
+ backgroundColor: "rgba(255, 255, 255, 0.8)",
27134
+ backdropFilter: "blur(20px)",
27135
+ borderRadius: "24px",
27136
+ border: "1px solid rgba(255, 255, 255, 0.4)",
27137
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
27138
+ overflow: "hidden",
27139
+ animation: "slideUp 0.3s ease-out",
27140
+ style: {
27141
+ animation: 'fadeIn 0.2s ease-out',
27142
+ transformOrigin: 'bottom right'
27143
+ }
27144
+ }, /*#__PURE__*/React.createElement(View, {
27145
+ padding: "16px",
27146
+ borderBottom: "1px solid rgba(0,0,0,0.05)",
27147
+ display: "flex",
27148
+ justifyContent: "space-between",
27149
+ alignItems: "center"
27150
+ }, /*#__PURE__*/React.createElement(Text, {
27151
+ fontWeight: "bold",
27152
+ color: "color.gray.800"
27153
+ }, "ChatWidget Assistant"), /*#__PURE__*/React.createElement(View, {
27154
+ as: "button",
27155
+ onClick: () => setIsOpen(false),
27156
+ cursor: "pointer",
27157
+ padding: "4px",
27158
+ borderRadius: "50%",
27159
+ border: "none",
27160
+ backgroundColor: "transparent",
27161
+ _hover: {
27162
+ backgroundColor: 'rgba(0,0,0,0.05)'
27163
+ }
27164
+ }, /*#__PURE__*/React.createElement(CloseIcon, {
27165
+ widthHeight: 16,
27166
+ color: "color.gray.500"
27167
+ }))), /*#__PURE__*/React.createElement(ChatWidget, {
27168
+ messages: messages,
27169
+ onSubmit: handleSubmit,
27170
+ size: bubbleSize,
27171
+ variant: "minimal",
27172
+ enableContextPicker: true,
27173
+ selectedContextElements: contextElements,
27174
+ onContextPickerClick: handleContextPickerClick,
27175
+ onRemoveContextElement: handleRemoveContextElement,
27176
+ styles: {
27177
+ container: {
27178
+ height: 'calc(100% - 60px)',
27179
+ backgroundColor: 'transparent'
27180
+ },
27181
+ inputContainer: {
27182
+ backgroundColor: 'white',
27183
+ margin: '0 16px 16px 16px',
27184
+ boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)'
27185
+ }
27186
+ }
27187
+ }))), !isContextPickerActive && (/*#__PURE__*/React.createElement(View, {
27188
+ as: "button",
27189
+ onClick: toggleOpen,
27190
+ width: "56px",
27191
+ height: "56px",
27192
+ borderRadius: "50%",
27193
+ backgroundColor: "theme.primary",
27194
+ border: "none",
27195
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
27196
+ cursor: "pointer",
27197
+ display: "flex",
27198
+ alignItems: "center",
27199
+ justifyContent: "center",
27200
+ transition: "transform 0.2s ease",
27201
+ _hover: {
27202
+ transform: 'scale(1.05)'
27203
+ },
27204
+ _active: {
27205
+ transform: 'scale(0.95)'
27206
+ },
27207
+ "data-chatwidget-ignore": "true" // Ignore clicks on the widget itself for context picking
27208
+ }, isOpen ? (/*#__PURE__*/React.createElement(CloseIcon, {
27209
+ widthHeight: 24,
27210
+ color: "white"
27211
+ })) : (/*#__PURE__*/React.createElement(PanelIcon, {
27212
+ widthHeight: 24,
27213
+ color: "white"
27214
+ })))));
27215
+ };
27216
+
27217
+ export { Accordion, Alert, ArrowIcon, AspectRatio, AttachmentIcon, AttachmentPreview, AudioIcon, AudioInput, AudioWaveform, Avatar, BackIcon, Background, Badge, BatteryIcon, BluetoothIcon, BoldArrowIcon, BookmarkIcon, Button, CalendarIcon, CameraIcon, Card, Carousel, Chart, ChartIcon, ChatInput, ChatWidget, ChatWidgetComponent, ChatWidgetWidget, CheckIcon, Checkbox, ChevronIcon, ClockIcon, CloseEyeIcon, CloseIcon, CloudIcon, ColorInput, ColorPicker, ComboBox, Command, ContextMenu, CookieConsent, CopyIcon, CountryPicker, CreditCardIcon, CropIcon, DatePicker, DeleteIcon, Divider, DocumentIcon, DownloadIcon, DragAndDrop, DragAndDropComponent, DragHandleIcon, DragHandleLinesIcon, Drawer, DropdownMenu, DustBinIcon, EditIcon, EmojiPicker, ErrorIcon, ExternalLinkIcon, FacebookIcon, FileIcon, FileImage, FileSVG, FilterIcon, FolderIcon, FormikChatInput, FormikCheckbox, FormikColorInput, FormikComboBox, FormikCountryPicker, FormikDatePicker, FormikForm, FormikOTPInput, FormikPassword, FormikSelect, FormikSelector, FormikSlider, FormikSwitch, FormikTagInput, FormikTextArea, FormikTextField, FormikUploader, GiftIcon, HeartIcon, HelpIcon, HomeIcon, HoverCard, Icon, ImageIcon, InfoIcon, InstagramIcon, LayoutIcon, LikeIcon, Link, LinkIcon, LinkedinIcon, Loader, LoadingSpinnerIcon, LockIcon, LogoutIcon, MagicWandIcon, MapPinIcon, MediaPreview, MenuIcon, Menubar, MessageLayout, MessageView, MicrophoneIcon, MinusIcon, Modal, MoonIcon, MoreIcon, MousePointerIcon, NavigationMenu, NotificationIcon, OTPInput, OpenEyeIcon, Pagination, PanelIcon, Password, PauseIcon, PlayIcon, PlusIcon, PowerOffIcon, PrintIcon, ProfileIcon, ProgressBar, RefreshIcon, Resizable, RotateIcon, SaveIcon, SearchIcon, Select, Selector, SendIcon, Separator, SettingsIcon, ShapeIcon, ShareButton, ShareIcon, ShieldIcon, Sidebar, Slider, SliderIcon, SpinnerIcon, StarIcon, StatusIndicator, StopIcon, SuccessIcon, Switch, Table, Tabs, TagInput, TextArea, TextField, TextIcon, ThreadsIcon, TickIcon, Title, Toast, Toggle, ToggleGroup, Tooltip, TrashIcon, TwitchIcon, TwitterIcon, UnLikeIcon, UnlockIcon, UploadIcon, Uploader, UserIcon, VideoIcon, WarningIcon, WifiIcon, XIcon, YoutubeIcon, ZapIcon, ZoomInIcon, ZoomOutIcon, hideMessage, hideModal, showMessage, showModal, showToast, useMessageStore, useModalStore, useToast$1 as useToast };
26297
27218
  //# sourceMappingURL=web.esm.js.map