@usecrow/ui 0.1.10 → 0.1.11

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.d.cts CHANGED
@@ -705,14 +705,14 @@ interface WidgetStyleContextValue {
705
705
  styles: ResolvedWidgetStyles;
706
706
  agentName: string;
707
707
  isLoading: boolean;
708
- variant: 'floating' | 'embedded';
708
+ variant: "floating" | "embedded";
709
709
  }
710
710
  interface WidgetStyleProviderProps {
711
711
  children: react__default.ReactNode;
712
712
  styles: ResolvedWidgetStyles;
713
713
  agentName?: string;
714
714
  isLoading?: boolean;
715
- variant?: 'floating' | 'embedded';
715
+ variant?: "floating" | "embedded";
716
716
  }
717
717
  /**
718
718
  * Provider for widget styles
package/dist/index.d.ts CHANGED
@@ -705,14 +705,14 @@ interface WidgetStyleContextValue {
705
705
  styles: ResolvedWidgetStyles;
706
706
  agentName: string;
707
707
  isLoading: boolean;
708
- variant: 'floating' | 'embedded';
708
+ variant: "floating" | "embedded";
709
709
  }
710
710
  interface WidgetStyleProviderProps {
711
711
  children: react__default.ReactNode;
712
712
  styles: ResolvedWidgetStyles;
713
713
  agentName?: string;
714
714
  isLoading?: boolean;
715
- variant?: 'floating' | 'embedded';
715
+ variant?: "floating" | "embedded";
716
716
  }
717
717
  /**
718
718
  * Provider for widget styles
package/dist/index.js CHANGED
@@ -1123,7 +1123,9 @@ function useWidgetStyles2() {
1123
1123
  const context = useContext(WidgetStyleContext);
1124
1124
  return context?.styles ?? DEFAULT_WIDGET_STYLES;
1125
1125
  }
1126
- var CopilotStyleContext = createContext(null);
1126
+ var CopilotStyleContext = createContext(
1127
+ null
1128
+ );
1127
1129
  function CopilotStyleProvider({
1128
1130
  children,
1129
1131
  styles,
@@ -1149,6 +1151,7 @@ function useCopilotStyles2() {
1149
1151
  const context = useContext(CopilotStyleContext);
1150
1152
  return context?.styles ?? DEFAULT_COPILOT_STYLES;
1151
1153
  }
1154
+ var PASSTHROUGH_KEYS = /* @__PURE__ */ new Set(["Escape", "Tab"]);
1152
1155
  function ShadowContainer({
1153
1156
  children,
1154
1157
  styles,
@@ -1163,6 +1166,51 @@ function ShadowContainer({
1163
1166
  setShadowRoot(shadow);
1164
1167
  }
1165
1168
  }, []);
1169
+ useEffect(() => {
1170
+ if (!shadowRoot || !hostRef.current) return;
1171
+ const hostElement = hostRef.current;
1172
+ const stopPropagationHandler = (e) => {
1173
+ const keyEvent = e;
1174
+ if (keyEvent.key && PASSTHROUGH_KEYS.has(keyEvent.key)) {
1175
+ return;
1176
+ }
1177
+ e.stopPropagation();
1178
+ };
1179
+ shadowRoot.addEventListener("keydown", stopPropagationHandler);
1180
+ shadowRoot.addEventListener("keyup", stopPropagationHandler);
1181
+ shadowRoot.addEventListener("keypress", stopPropagationHandler);
1182
+ let lastFocusedElement = null;
1183
+ const trackFocus = (e) => {
1184
+ lastFocusedElement = e.target;
1185
+ };
1186
+ const protectFocus = (e) => {
1187
+ if (e.key && PASSTHROUGH_KEYS.has(e.key)) {
1188
+ return;
1189
+ }
1190
+ const path = e.composedPath();
1191
+ if (!path.includes(hostElement) && !path.includes(shadowRoot)) {
1192
+ return;
1193
+ }
1194
+ if (lastFocusedElement) {
1195
+ const elementToRestore = lastFocusedElement;
1196
+ queueMicrotask(() => {
1197
+ const activeInShadow = shadowRoot.activeElement;
1198
+ if (!activeInShadow) {
1199
+ elementToRestore.focus();
1200
+ }
1201
+ });
1202
+ }
1203
+ };
1204
+ shadowRoot.addEventListener("focusin", trackFocus);
1205
+ document.addEventListener("keydown", protectFocus, { capture: true });
1206
+ return () => {
1207
+ shadowRoot.removeEventListener("keydown", stopPropagationHandler);
1208
+ shadowRoot.removeEventListener("keyup", stopPropagationHandler);
1209
+ shadowRoot.removeEventListener("keypress", stopPropagationHandler);
1210
+ shadowRoot.removeEventListener("focusin", trackFocus);
1211
+ document.removeEventListener("keydown", protectFocus, { capture: true });
1212
+ };
1213
+ }, [shadowRoot]);
1166
1214
  return /* @__PURE__ */ jsx("div", { ref: hostRef, id: hostId, className: hostClassName, children: shadowRoot && createPortal(
1167
1215
  /* @__PURE__ */ jsxs(Fragment, { children: [
1168
1216
  /* @__PURE__ */ jsx("style", { children: styles }),
@@ -1680,64 +1728,62 @@ function MessageList({
1680
1728
  msg.id
1681
1729
  )) });
1682
1730
  }
1683
- var MessagesContainer = forwardRef(
1684
- ({ children }, ref) => {
1685
- const styles = useWidgetStyles2();
1686
- const internalRef = useRef(null);
1687
- const lastScrollHeightRef = useRef(0);
1688
- const isUserScrollingRef = useRef(false);
1689
- const containerRef = ref || internalRef;
1690
- const isNearBottom = useCallback(() => {
1691
- const container = containerRef.current;
1692
- if (!container) return true;
1693
- const threshold = 100;
1694
- return container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
1695
- }, [containerRef]);
1696
- const scrollToBottom = useCallback(() => {
1697
- const container = containerRef.current;
1698
- if (!container) return;
1699
- container.scrollTo({
1700
- top: container.scrollHeight,
1701
- behavior: "smooth"
1702
- });
1703
- }, [containerRef]);
1704
- useEffect(() => {
1705
- const container = containerRef.current;
1706
- if (!container) return;
1707
- const handleScroll = () => {
1708
- isUserScrollingRef.current = !isNearBottom();
1709
- };
1710
- container.addEventListener("scroll", handleScroll, { passive: true });
1711
- return () => container.removeEventListener("scroll", handleScroll);
1712
- }, [containerRef, isNearBottom]);
1713
- useEffect(() => {
1714
- const container = containerRef.current;
1715
- if (!container) return;
1716
- const currentHeight = container.scrollHeight;
1717
- const heightChanged = currentHeight !== lastScrollHeightRef.current;
1718
- if (heightChanged) {
1719
- lastScrollHeightRef.current = currentHeight;
1720
- if (!isUserScrollingRef.current || isNearBottom()) {
1721
- scrollToBottom();
1722
- }
1723
- }
1731
+ var MessagesContainer = forwardRef(({ children }, ref) => {
1732
+ const styles = useWidgetStyles2();
1733
+ const internalRef = useRef(null);
1734
+ const lastScrollHeightRef = useRef(0);
1735
+ const isUserScrollingRef = useRef(false);
1736
+ const containerRef = ref || internalRef;
1737
+ const isNearBottom = useCallback(() => {
1738
+ const container = containerRef.current;
1739
+ if (!container) return true;
1740
+ const threshold = 100;
1741
+ return container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
1742
+ }, [containerRef]);
1743
+ const scrollToBottom = useCallback(() => {
1744
+ const container = containerRef.current;
1745
+ if (!container) return;
1746
+ container.scrollTo({
1747
+ top: container.scrollHeight,
1748
+ behavior: "smooth"
1724
1749
  });
1725
- return /* @__PURE__ */ jsx(
1726
- motion.div,
1727
- {
1728
- ref: containerRef,
1729
- id: MESSAGES_CONTAINER_ID,
1730
- initial: { opacity: 0 },
1731
- animate: { opacity: 1 },
1732
- exit: { opacity: 0 },
1733
- transition: { duration: styles.animations.duration },
1734
- className: "crow-relative crow-flex-1 crow-min-h-0 crow-rounded-2xl crow-mb-3 crow-overflow-y-auto crow-p-4 crow-space-y-3 crow-pointer-events-auto",
1735
- style: { background: styles.colors.messagesBackground },
1736
- children
1750
+ }, [containerRef]);
1751
+ useEffect(() => {
1752
+ const container = containerRef.current;
1753
+ if (!container) return;
1754
+ const handleScroll = () => {
1755
+ isUserScrollingRef.current = !isNearBottom();
1756
+ };
1757
+ container.addEventListener("scroll", handleScroll, { passive: true });
1758
+ return () => container.removeEventListener("scroll", handleScroll);
1759
+ }, [containerRef, isNearBottom]);
1760
+ useEffect(() => {
1761
+ const container = containerRef.current;
1762
+ if (!container) return;
1763
+ const currentHeight = container.scrollHeight;
1764
+ const heightChanged = currentHeight !== lastScrollHeightRef.current;
1765
+ if (heightChanged) {
1766
+ lastScrollHeightRef.current = currentHeight;
1767
+ if (!isUserScrollingRef.current || isNearBottom()) {
1768
+ scrollToBottom();
1737
1769
  }
1738
- );
1739
- }
1740
- );
1770
+ }
1771
+ });
1772
+ return /* @__PURE__ */ jsx(
1773
+ motion.div,
1774
+ {
1775
+ ref: containerRef,
1776
+ id: MESSAGES_CONTAINER_ID,
1777
+ initial: { opacity: 0 },
1778
+ animate: { opacity: 1 },
1779
+ exit: { opacity: 0 },
1780
+ transition: { duration: styles.animations.duration },
1781
+ className: "crow-relative crow-flex-1 crow-min-h-0 crow-rounded-2xl crow-mb-3 crow-overflow-y-auto crow-p-4 crow-space-y-3 crow-pointer-events-auto",
1782
+ style: { background: styles.colors.messagesBackground },
1783
+ children
1784
+ }
1785
+ );
1786
+ });
1741
1787
  MessagesContainer.displayName = "MessagesContainer";
1742
1788
  function ConversationList({
1743
1789
  conversations,
@@ -2009,7 +2055,13 @@ var PromptInput = React3.forwardRef(
2009
2055
  }
2010
2056
  );
2011
2057
  PromptInput.displayName = "PromptInput";
2012
- var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, placeholder, ...props }) => {
2058
+ var PromptInputTextarea = ({
2059
+ className,
2060
+ onKeyDown,
2061
+ disableAutosize = false,
2062
+ placeholder,
2063
+ ...props
2064
+ }) => {
2013
2065
  const { value, setValue, maxHeight, onSubmit, disabled } = usePromptInput();
2014
2066
  const textareaRef = React3.useRef(null);
2015
2067
  React3.useEffect(() => {
@@ -2042,7 +2094,14 @@ var PromptInputActions = ({
2042
2094
  children,
2043
2095
  className,
2044
2096
  ...props
2045
- }) => /* @__PURE__ */ jsx("div", { className: cn("crow-flex crow-items-center crow-gap-2", className), ...props, children });
2097
+ }) => /* @__PURE__ */ jsx(
2098
+ "div",
2099
+ {
2100
+ className: cn("crow-flex crow-items-center crow-gap-2", className),
2101
+ ...props,
2102
+ children
2103
+ }
2104
+ );
2046
2105
  var PromptInputAction = ({
2047
2106
  tooltip,
2048
2107
  children,
@@ -2089,7 +2148,13 @@ var PromptInputBox = React3.forwardRef(
2089
2148
  disabled: isLoading,
2090
2149
  ref: ref || promptBoxRef,
2091
2150
  children: [
2092
- /* @__PURE__ */ jsx("div", { className: "crow-transition-all crow-duration-300 crow-opacity-100", children: /* @__PURE__ */ jsx(PromptInputTextarea, { placeholder, className: "crow-text-base" }) }),
2151
+ /* @__PURE__ */ jsx("div", { className: "crow-transition-all crow-duration-300 crow-opacity-100", children: /* @__PURE__ */ jsx(
2152
+ PromptInputTextarea,
2153
+ {
2154
+ placeholder,
2155
+ className: "crow-text-base"
2156
+ }
2157
+ ) }),
2093
2158
  /* @__PURE__ */ jsxs(PromptInputActions, { className: "crow-flex crow-items-center crow-justify-between crow-gap-2 crow-p-0 crow-pt-1", children: [
2094
2159
  /* @__PURE__ */ jsx("div", { className: "crow-flex crow-items-center", children: availableModels.length > 0 && onModelChange && /* @__PURE__ */ jsx(
2095
2160
  ModelSelector,
@@ -2122,10 +2187,21 @@ var PromptInputBox = React3.forwardRef(
2122
2187
  handleSubmit();
2123
2188
  }
2124
2189
  },
2125
- children: isLoading ? /* @__PURE__ */ jsx(Square, { className: "crow-h-3.5 crow-w-3.5 crow-text-white", style: { fill: "white" } }) : /* @__PURE__ */ jsx(ArrowUp, { className: cn(
2126
- "crow-h-3.5 crow-w-3.5",
2127
- hasContent ? "crow-text-white" : "crow-text-gray-400"
2128
- ) })
2190
+ children: isLoading ? /* @__PURE__ */ jsx(
2191
+ Square,
2192
+ {
2193
+ className: "crow-h-3.5 crow-w-3.5 crow-text-white",
2194
+ style: { fill: "white" }
2195
+ }
2196
+ ) : /* @__PURE__ */ jsx(
2197
+ ArrowUp,
2198
+ {
2199
+ className: cn(
2200
+ "crow-h-3.5 crow-w-3.5",
2201
+ hasContent ? "crow-text-white" : "crow-text-gray-400"
2202
+ )
2203
+ }
2204
+ )
2129
2205
  }
2130
2206
  )
2131
2207
  }