@bikdotai/bik-component-library 0.0.876-beta.3 → 0.0.877-beta.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.
Files changed (28) hide show
  1. package/dist/cjs/components/bik-copilot/services/copilotDb.js +1 -1
  2. package/dist/cjs/components/bik-copilot/services/copilotDb.js.map +1 -1
  3. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js +1 -1
  4. package/dist/cjs/components/bik-copilot/services/copilotPageSession.js.map +1 -1
  5. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js +1 -1
  6. package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js.map +1 -1
  7. package/dist/cjs/components/multi-level-dropdown/MultiLevelDropdown.js +1 -1
  8. package/dist/cjs/components/multi-level-dropdown/MultiLevelDropdown.js.map +1 -1
  9. package/dist/cjs/components/multi-level-dropdown/MultiLevelDropdown.styled.js +19 -28
  10. package/dist/cjs/components/multi-level-dropdown/MultiLevelDropdown.styled.js.map +1 -1
  11. package/dist/cjs/index.js +1 -1
  12. package/dist/esm/components/bik-copilot/index.d.ts +1 -1
  13. package/dist/esm/components/bik-copilot/services/copilotDb.d.ts +15 -17
  14. package/dist/esm/components/bik-copilot/services/copilotDb.js +49 -57
  15. package/dist/esm/components/bik-copilot/services/copilotDb.js.map +1 -1
  16. package/dist/esm/components/bik-copilot/services/copilotPageSession.d.ts +10 -13
  17. package/dist/esm/components/bik-copilot/services/copilotPageSession.js +22 -25
  18. package/dist/esm/components/bik-copilot/services/copilotPageSession.js.map +1 -1
  19. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js +95 -96
  20. package/dist/esm/components/bik-copilot/useCopilotStreamChat.js.map +1 -1
  21. package/dist/esm/components/multi-level-dropdown/MultiLevelDropdown.js +44 -46
  22. package/dist/esm/components/multi-level-dropdown/MultiLevelDropdown.js.map +1 -1
  23. package/dist/esm/components/multi-level-dropdown/MultiLevelDropdown.styled.d.ts +0 -3
  24. package/dist/esm/components/multi-level-dropdown/MultiLevelDropdown.styled.js +15 -25
  25. package/dist/esm/components/multi-level-dropdown/MultiLevelDropdown.styled.js.map +1 -1
  26. package/dist/esm/components/multi-level-dropdown/type.d.ts +0 -5
  27. package/dist/esm/index.js +49 -49
  28. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useCopilotStreamChat.js","sources":["../../../../src/components/bik-copilot/useCopilotStreamChat.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { COPILOT_REGENERATE_PROMPT } from './copilotRegenerate';\nimport {\n\tCopilotFeedbackDetail,\n\tCopilotFeedbackVote,\n\tCopilotMessage,\n\tCopilotStreamEvent,\n\tUseCopilotStreamChatOptions,\n\tUseCopilotStreamChatResult,\n} from './model';\nimport {\n\tdeleteCopilotSession,\n\tloadCopilotSession,\n\tpersistCopilotTurn,\n\tpruneCopilotSessions,\n} from './services/copilotDb';\nimport { sendCopilotFeedback } from './services/copilotFeedbackClient';\nimport {\n\tCOPILOT_HISTORY_PAGE_SIZE,\n\tfetchCopilotMessages,\n} from './services/copilotMessagesClient';\nimport {\n\tgetCopilotSessionIdForRoute,\n\tresetCopilotSessionForRoute,\n\tresolveCopilotSessionIdForRoute,\n} from './services/copilotPageSession';\nimport {\n\treadCopilotEventContent,\n\tstreamCopilotChat,\n} from './services/copilotStreamClient';\nimport {\n\tDEFAULT_COPILOT_AGENT,\n\tDEFAULT_COPILOT_ROUTE,\n} from './useCopilotIcebreakers';\n\nconst GENERIC_ERROR = 'Something went wrong. Please try again.';\n\n/**\n * Runs a merchant copilot conversation against the streaming\n * `/bik-ai/copilot-chatbot` endpoint.\n *\n * Owns three things the endpoint's contract requires:\n *\n * 1. **The session id.** One per route. Navigating away and back to the same\n * route continues that conversation, and so does a refresh: the ids live in\n * memory but are recovered from the stored records, which is what keeps them\n * lined up with the history the backend keys by them (see\n * `copilotPageSession`).\n * 2. **`previousResponseId`.** Absent on the first turn; from then on it is the\n * `responseId` of the last `TEXT` event, which is what makes OpenAI replay the\n * earlier turns server side. A turn that breaks halfway returns no\n * `responseId`, and the backend means that — the next turn starts fresh.\n * 3. **The transcript**, stored in IndexedDB under `{sessionId}:{route}` and\n * written every turn, so leaving the page mid-conversation loses nothing.\n */\nconst asRestored = (messages: CopilotMessage[]): CopilotMessage[] =>\n\tmessages.map((message) =>\n\t\tmessage.role === 'assistant' ? { ...message, isRestored: true } : message,\n\t);\n\nexport const useCopilotStreamChat = ({\n\tstoreId,\n\tagent = DEFAULT_COPILOT_AGENT,\n\troute = DEFAULT_COPILOT_ROUTE,\n\tmessagesPath,\n\tfeedbackPath,\n\tuser,\n\tloadHistory = true,\n\tsystemPrompt,\n\tsessionId: pinnedSessionId,\n\tpersist = true,\n\tonError,\n\tonResponseComplete,\n\tonSessionIdChange,\n\tbaseUrl,\n\tendpointPath,\n\theaders,\n\tauthToken,\n\tgetAuthToken,\n\tfetchImpl,\n}: UseCopilotStreamChatOptions): UseCopilotStreamChatResult => {\n\tconst [messages, setMessages] = useState<CopilotMessage[]>([]);\n\tconst [sessionId, setSessionId] = useState<string | null>(\n\t\tpinnedSessionId ?? null,\n\t);\n\tconst [isStreaming, setIsStreaming] = useState(false);\n\tconst [isRestoring, setIsRestoring] = useState(true);\n\tconst [error, setError] = useState<string | undefined>();\n\tconst [previousResponseId, setPreviousResponseId] = useState<\n\t\tstring | undefined\n\t>();\n\tconst [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\tconst [hasMoreHistory, setHasMoreHistory] = useState(false);\n\n\t// Async stream handlers run long after the render that created them, so the\n\t// live values live in refs and state is only the render mirror.\n\tconst messagesRef = useRef<CopilotMessage[]>([]);\n\tconst previousResponseIdRef = useRef<string | undefined>(undefined);\n\tconst streamingIdRef = useRef<string | null>(null);\n\tconst abortRef = useRef<(() => void) | null>(null);\n\tconst sessionIdRef = useRef<string | null>(pinnedSessionId ?? null);\n\t// The active route, for the async handlers that write the transcript.\n\tconst routeRef = useRef<string>(route);\n\trouteRef.current = route;\n\t// Next page of stored history to ask for. Starts at 2 when the local cache\n\t// already holds page 1's worth, which is the steady state.\n\tconst nextHistoryPageRef = useRef(1);\n\tconst isLoadingHistoryRef = useRef(false);\n\n\tconst applyMessages = useCallback(\n\t\t(updater: (previous: CopilotMessage[]) => CopilotMessage[]) => {\n\t\t\tconst next = updater(messagesRef.current);\n\t\t\tmessagesRef.current = next;\n\t\t\tsetMessages(next);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setThreadResponseId = useCallback((responseId: string | undefined) => {\n\t\tpreviousResponseIdRef.current = responseId;\n\t\tsetPreviousResponseId(responseId);\n\t}, []);\n\n\tconst save = useCallback(() => {\n\t\tconst id = sessionIdRef.current;\n\t\tif (!persist || !id) {\n\t\t\treturn;\n\t\t}\n\t\tvoid persistCopilotTurn({\n\t\t\troute: routeRef.current,\n\t\t\tsessionId: id,\n\t\t\tmessages: messagesRef.current,\n\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\tstoreId,\n\t\t\tagent,\n\t\t});\n\t}, [agent, persist, storeId]);\n\n\t// Transport config for the async readers below. Held in a ref rather than in\n\t// the effect's deps: a host that passes an inline `headers` object would\n\t// otherwise re-run restore on every render and wipe the transcript.\n\tconst transportRef = useRef({\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t});\n\ttransportRef.current = {\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t};\n\n\tconst readHistoryPage = useCallback(async (page: number) => {\n\t\tconst transport = transportRef.current;\n\t\tconst id = sessionIdRef.current;\n\t\tif (!transport.loadHistory || !id) {\n\t\t\treturn null;\n\t\t}\n\t\tconst historyPage = await fetchCopilotMessages({\n\t\t\tbaseUrl: transport.baseUrl,\n\t\t\tendpointPath: transport.messagesPath,\n\t\t\theaders: transport.headers,\n\t\t\tauthToken: transport.authToken,\n\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\tstoreId: transport.storeId,\n\t\t\tsessionId: id,\n\t\t\tpage,\n\t\t\tpageSize: COPILOT_HISTORY_PAGE_SIZE,\n\t\t});\n\t\treturn { ...historyPage, messages: asRestored(historyPage.messages) };\n\t}, []);\n\n\t// Resolve the conversation for this route and read it back from IndexedDB.\n\t// Runs again when `route` changes, because the route is half of a\n\t// conversation's identity — a different page is a different chat.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst restore = async () => {\n\t\t\t// Chunks from the previous route's turn must not land in this one.\n\t\t\tabortRef.current?.();\n\t\t\tabortRef.current = null;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tsetIsStreaming(false);\n\t\t\tsetError(undefined);\n\t\t\tsetIsRestoring(true);\n\t\t\tsetHasMoreHistory(false);\n\t\t\tisLoadingHistoryRef.current = false;\n\t\t\tsetIsLoadingHistory(false);\n\n\t\t\tconst id =\n\t\t\t\tpinnedSessionId ??\n\t\t\t\t(persist\n\t\t\t\t\t? await resolveCopilotSessionIdForRoute({ route, storeId })\n\t\t\t\t\t: getCopilotSessionIdForRoute({ route, storeId }));\n\t\t\tconst record = persist ? await loadCopilotSession(route, id) : null;\n\t\t\tif (cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsessionIdRef.current = id;\n\t\t\tsetSessionId(id);\n\t\t\tmessagesRef.current = asRestored(record?.messages ?? []);\n\t\t\tsetMessages(messagesRef.current);\n\t\t\tsetThreadResponseId(record?.previousResponseId);\n\t\t\tsetIsRestoring(false);\n\t\t\tonSessionIdChange?.(id);\n\n\t\t\t// The cache holds at most one page, so what is on screen already *is*\n\t\t\t// page 1 and the reader's first scroll-up wants page 2.\n\t\t\tif (messagesRef.current.length > 0) {\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tsetHasMoreHistory(transportRef.current.loadHistory);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nothing cached and nothing to scroll, so page 1 has to be fetched for\n\t\t\t// the history to be reachable at all — but only for an id the host\n\t\t\t// pinned. An id this library resolved came out of the local records, so\n\t\t\t// an empty cache for it means an empty conversation, and a freshly\n\t\t\t// minted one has nothing behind it by definition. Asking anyway would\n\t\t\t// put a pointless request on the start of every new conversation.\n\t\t\tif (!pinnedSessionId) {\n\t\t\t\tnextHistoryPageRef.current = 1;\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnextHistoryPageRef.current = 1;\n\t\t\ttry {\n\t\t\t\tconst firstPage = await readHistoryPage(1);\n\t\t\t\tif (cancelled || !firstPage) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tapplyMessages(() => firstPage.messages);\n\t\t\t\tsetHasMoreHistory(firstPage.hasMore);\n\t\t\t} catch {\n\t\t\t\t// A session the backend has never heard of is the normal case for a\n\t\t\t\t// host-pinned id on its first use; the empty state covers it.\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t}\n\t\t};\n\n\t\tvoid restore();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// onSessionIdChange is event-like: re-running restore because the host\n\t\t// passed a new inline callback would wipe the transcript.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\troute,\n\t\tstoreId,\n\t\tpinnedSessionId,\n\t\tpersist,\n\t\tsetThreadResponseId,\n\t\tapplyMessages,\n\t\treadHistoryPage,\n\t]);\n\n\t/**\n\t * Prepends the page before the oldest message on screen.\n\t *\n\t * Guarded by a ref rather than the state flag because a scroll handler can\n\t * fire many times before React re-renders, and each of those would otherwise\n\t * start its own request for the same page.\n\t */\n\tconst loadOlderMessages = useCallback(() => {\n\t\tif (isLoadingHistoryRef.current || !hasMoreHistory) {\n\t\t\treturn;\n\t\t}\n\t\tisLoadingHistoryRef.current = true;\n\t\tsetIsLoadingHistory(true);\n\n\t\tconst page = nextHistoryPageRef.current;\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\tconst older = await readHistoryPage(page);\n\t\t\t\tif (!older) {\n\t\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = page + 1;\n\t\t\t\tsetHasMoreHistory(older.hasMore);\n\t\t\t\tapplyMessages((previous) => {\n\t\t\t\t\tconst known = new Set(\n\t\t\t\t\t\tprevious.flatMap((message) =>\n\t\t\t\t\t\t\tmessage.messageId\n\t\t\t\t\t\t\t\t? [message.id, message.messageId]\n\t\t\t\t\t\t\t\t: [message.id],\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst fresh = older.messages.filter(\n\t\t\t\t\t\t(message) => !known.has(message.id),\n\t\t\t\t\t);\n\t\t\t\t\treturn fresh.length > 0 ? [...fresh, ...previous] : previous;\n\t\t\t\t});\n\t\t\t} catch (historyError) {\n\t\t\t\t// Left silent in the transcript on purpose: failing to reach further\n\t\t\t\t// back is not a failure of the conversation on screen. Another\n\t\t\t\t// scroll-up retries the same page.\n\t\t\t\tonError?.(\n\t\t\t\t\thistoryError instanceof Error\n\t\t\t\t\t\t? historyError\n\t\t\t\t\t\t: new Error(String(historyError)),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tisLoadingHistoryRef.current = false;\n\t\t\t\tsetIsLoadingHistory(false);\n\t\t\t}\n\t\t})();\n\t}, [applyMessages, hasMoreHistory, onError, readHistoryPage]);\n\n\t// Records pile up one per route per page load otherwise, since every refresh\n\t// writes under a new key.\n\tuseEffect(() => {\n\t\tif (persist) {\n\t\t\tvoid pruneCopilotSessions();\n\t\t}\n\t}, [persist]);\n\n\t// Abort an in-flight turn if the copilot unmounts.\n\tuseEffect(() => () => abortRef.current?.(), []);\n\n\tconst finishStreamingBubble = useCallback(\n\t\t(mutate?: (message: CopilotMessage) => CopilotMessage) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tif (!streamingId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious\n\t\t\t\t\t.map((message) => {\n\t\t\t\t\t\tif (message.id !== streamingId) {\n\t\t\t\t\t\t\treturn message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst settled: CopilotMessage = {\n\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\tisStreaming: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn mutate ? mutate(settled) : settled;\n\t\t\t\t\t})\n\t\t\t\t\t// An assistant bubble that never received text would render as an\n\t\t\t\t\t// empty balloon; the error banner carries the information instead.\n\t\t\t\t\t// A stopped turn keeps its bubble either way — the interrupted note\n\t\t\t\t\t// is the only trace a turn the reader cut short ever happened.\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.id !== streamingId ||\n\t\t\t\t\t\t\tmessage.content.length > 0 ||\n\t\t\t\t\t\t\tmessage.wasInterrupted === true,\n\t\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[applyMessages],\n\t);\n\n\tconst handleEvent = useCallback(\n\t\t(event: CopilotStreamEvent) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\n\t\t\tif (event.type === 'STREAM') {\n\t\t\t\tconst chunk = readCopilotEventContent(event).text;\n\t\t\t\tif (!streamingId || !chunk) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tapplyMessages((previous) =>\n\t\t\t\t\tprevious.map((message) =>\n\t\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\t\t\tcontent: message.content + chunk,\n\t\t\t\t\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: message,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'TEXT') {\n\t\t\t\t// TEXT carries the whole message, so it replaces the accumulated\n\t\t\t\t// chunks rather than appending — that keeps the bubble correct even if\n\t\t\t\t// a STREAM frame was dropped or duplicated. `responseId` rides inside\n\t\t\t\t// the content payload (as `lastResponseId`).\n\t\t\t\tconst {\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tfollowUps,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tresponseId,\n\t\t\t\t} = readCopilotEventContent(event);\n\t\t\t\tfinishStreamingBubble((message) => ({\n\t\t\t\t\t...message,\n\t\t\t\t\tcontent: fullText,\n\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t...(followUps ? { followUps } : {}),\n\t\t\t\t\t// Kept on the message, not just handled in passing, so the\n\t\t\t\t\t// action button is still there after a reload.\n\t\t\t\t\t...(toolResults ? { toolResults } : {}),\n\t\t\t\t}));\n\t\t\t\tsetThreadResponseId(responseId);\n\t\t\t\tsave();\n\t\t\t\tonResponseComplete?.({\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tresponseId,\n\t\t\t\t\tfollowUps,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'ERROR') {\n\t\t\t\tsetError(readCopilotEventContent(event).text || GENERIC_ERROR);\n\t\t\t\tfinishStreamingBubble();\n\t\t\t\tsave();\n\t\t\t}\n\n\t\t\t// Unknown types (TOOL_STATUS is declared server side but not emitted)\n\t\t\t// are ignored so a new event type cannot break an existing client.\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tfinishStreamingBubble,\n\t\t\tonResponseComplete,\n\t\t\tsave,\n\t\t\tsetThreadResponseId,\n\t\t],\n\t);\n\n\tconst sendMessage = useCallback(\n\t\t(message: string) => {\n\t\t\tconst userPrompt = message.trim();\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!userPrompt || !id || isStreaming) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(undefined);\n\t\t\tconst now = Date.now();\n\t\t\tconst assistantBubbleId = `copilot-a-${now}`;\n\t\t\tstreamingIdRef.current = assistantBubbleId;\n\n\t\t\tapplyMessages((previous) => [\n\t\t\t\t...previous,\n\t\t\t\t{\n\t\t\t\t\tid: `copilot-u-${now}`,\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: userPrompt,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: assistantBubbleId,\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: '',\n\t\t\t\t\ttimestamp: now + 1,\n\t\t\t\t\tisStreaming: true,\n\t\t\t\t},\n\t\t\t]);\n\t\t\tsetIsStreaming(true);\n\t\t\tsave();\n\n\t\t\tabortRef.current = streamCopilotChat(\n\t\t\t\t{\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tendpointPath,\n\t\t\t\t\theaders,\n\t\t\t\t\tauthToken,\n\t\t\t\t\tgetAuthToken,\n\t\t\t\t\tfetchImpl,\n\t\t\t\t\tstoreId,\n\t\t\t\t\tagent,\n\t\t\t\t\troute,\n\t\t\t\t\tuserPrompt,\n\t\t\t\t\tsessionId: id,\n\t\t\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonEvent: handleEvent,\n\t\t\t\t\tonComplete: () => {\n\t\t\t\t\t\t// STOP closes the stream without a frame, so this is where a turn\n\t\t\t\t\t\t// ends. TEXT has usually already settled the bubble.\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t\tonError: (streamError) => {\n\t\t\t\t\t\tsetError(streamError.message || GENERIC_ERROR);\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t\tonError?.(streamError);\n\t\t\t\t\t},\n\t\t\t\t\tonAbort: () => {\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tauthToken,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tfetchImpl,\n\t\t\tagent,\n\t\t\tfinishStreamingBubble,\n\t\t\tgetAuthToken,\n\t\t\thandleEvent,\n\t\t\theaders,\n\t\t\tisStreaming,\n\t\t\tonError,\n\t\t\troute,\n\t\t\tsave,\n\t\t\tstoreId,\n\t\t\tsystemPrompt,\n\t\t],\n\t);\n\n\tconst regenerate = useCallback(() => {\n\t\tconst hasReply = messagesRef.current.some(\n\t\t\t(message) => message.role === 'assistant' && message.content.length > 0,\n\t\t);\n\t\tif (!hasReply) {\n\t\t\treturn;\n\t\t}\n\t\tsendMessage(COPILOT_REGENERATE_PROMPT);\n\t}, [sendMessage]);\n\n\t/**\n\t * Records a thumbs-up or thumbs-down on one reply.\n\t *\n\t * Fire-and-forget: a rating is a side note to the conversation, so a failed\n\t * post is reported through `onError` and otherwise ignored -- the thumb stays\n\t * lit either way rather than flickering back on a network hiccup.\n\t *\n\t * The reply's own text and the route ride along, so whoever reads the feedback\n\t * sees what was rated without looking the message up.\n\t */\n\tconst submitFeedback = useCallback(\n\t\t(\n\t\t\tmessageId: string,\n\t\t\tfeedback: CopilotFeedbackVote,\n\t\t\tdetail?: CopilotFeedbackDetail,\n\t\t) => {\n\t\t\tconst transport = transportRef.current;\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!id) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// A live turn's bubble carries only a local id until the final event\n\t\t\t// lands, so match on either and let the backend see whichever it gets.\n\t\t\tconst rated = messagesRef.current.find(\n\t\t\t\t(message) => (message.messageId ?? message.id) === messageId,\n\t\t\t);\n\t\t\tvoid sendCopilotFeedback({\n\t\t\t\tbaseUrl: transport.baseUrl,\n\t\t\t\tendpointPath: transport.feedbackPath,\n\t\t\t\theaders: transport.headers,\n\t\t\t\tauthToken: transport.authToken,\n\t\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\t\tstoreId: transport.storeId,\n\t\t\t\tsessionId: id,\n\t\t\t\tmessageId,\n\t\t\t\tfeedback,\n\t\t\t\troute: routeRef.current,\n\t\t\t\treply: rated?.content,\n\t\t\t\tuser: transport.user,\n\t\t\t\treasons: detail?.reasons,\n\t\t\t\tcomment: detail?.comment,\n\t\t\t}).catch((feedbackError) => {\n\t\t\t\tonError?.(\n\t\t\t\t\tfeedbackError instanceof Error\n\t\t\t\t\t\t? feedbackError\n\t\t\t\t\t\t: new Error(String(feedbackError)),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[onError],\n\t);\n\n\tconst stopStreaming = useCallback(() => {\n\t\tif (!abortRef.current) {\n\t\t\treturn;\n\t\t}\n\t\t// Flagged here rather than in `onAbort`, because an abort that lands between\n\t\t// frames ends the stream through `onComplete` instead. Whichever fires, the\n\t\t// reader stopped this turn, and whatever text had arrived stays.\n\t\tconst streamingId = streamingIdRef.current;\n\t\tif (streamingId) {\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious.map((message) =>\n\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t? { ...message, wasInterrupted: true }\n\t\t\t\t\t\t: message,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tabortRef.current();\n\t\tabortRef.current = null;\n\t}, [applyMessages]);\n\n\tconst startNewConversation = useCallback(() => {\n\t\tabortRef.current?.();\n\t\tabortRef.current = null;\n\t\tstreamingIdRef.current = null;\n\t\tsetIsStreaming(false);\n\t\tsetError(undefined);\n\t\t// A new conversation has no history behind it; the old session's pages\n\t\t// belong to the old session id.\n\t\tnextHistoryPageRef.current = 1;\n\t\tisLoadingHistoryRef.current = false;\n\t\tsetIsLoadingHistory(false);\n\t\tsetHasMoreHistory(false);\n\n\t\tconst activeRoute = routeRef.current;\n\t\t// The conversation being cleared, so its stored transcript can go with it.\n\t\tconst clearedId = sessionIdRef.current;\n\t\t// A host-pinned id is the host's to change, so only clear its transcript.\n\t\tconst nextId =\n\t\t\tpinnedSessionId ??\n\t\t\tresetCopilotSessionForRoute({ route: activeRoute, storeId });\n\t\tsessionIdRef.current = nextId;\n\t\tsetSessionId(nextId);\n\t\tmessagesRef.current = [];\n\t\tsetMessages([]);\n\t\tsetThreadResponseId(undefined);\n\n\t\t// \"Refresh chat\" wipes the record, not just the screen: the cleared\n\t\t// conversation is deleted from IndexedDB so reopening the tab starts fresh\n\t\t// instead of resuming it. Nothing is written for the new session here — its\n\t\t// first record is stamped when the first turn is sent, which is also what\n\t\t// keeps an untouched refresh from leaving an empty record behind.\n\t\tif (persist && clearedId) {\n\t\t\tvoid deleteCopilotSession(activeRoute, clearedId);\n\t\t}\n\t\tonSessionIdChange?.(nextId);\n\t}, [\n\t\tonSessionIdChange,\n\t\tpersist,\n\t\tpinnedSessionId,\n\t\tsetThreadResponseId,\n\t\tstoreId,\n\t]);\n\n\t// The thinking bubble is only for the wait before the first token; once text\n\t// starts arriving the bubble itself shows progress.\n\tconst isThinking = useMemo(\n\t\t() =>\n\t\t\tisStreaming &&\n\t\t\t!messages.some((message) => message.isStreaming && message.content),\n\t\t[isStreaming, messages],\n\t);\n\n\treturn {\n\t\tmessages,\n\t\tsessionId,\n\t\tpreviousResponseId,\n\t\tisStreaming,\n\t\tisThinking,\n\t\tisRestoring,\n\t\tisLoadingHistory,\n\t\thasMoreHistory,\n\t\terror,\n\t\tsendMessage,\n\t\tregenerate,\n\t\tsubmitFeedback,\n\t\tloadOlderMessages,\n\t\tstopStreaming,\n\t\tstartNewConversation,\n\t};\n};\n"],"names":["GENERIC_ERROR","asRestored","messages","message","useCopilotStreamChat","storeId","agent","DEFAULT_COPILOT_AGENT","route","DEFAULT_COPILOT_ROUTE","messagesPath","feedbackPath","user","loadHistory","systemPrompt","pinnedSessionId","persist","onError","onResponseComplete","onSessionIdChange","baseUrl","endpointPath","headers","authToken","getAuthToken","fetchImpl","setMessages","useState","sessionId","setSessionId","isStreaming","setIsStreaming","isRestoring","setIsRestoring","error","setError","previousResponseId","setPreviousResponseId","isLoadingHistory","setIsLoadingHistory","hasMoreHistory","setHasMoreHistory","messagesRef","useRef","previousResponseIdRef","streamingIdRef","abortRef","sessionIdRef","routeRef","nextHistoryPageRef","isLoadingHistoryRef","applyMessages","useCallback","updater","next","setThreadResponseId","responseId","save","id","persistCopilotTurn","transportRef","readHistoryPage","page","transport","historyPage","fetchCopilotMessages","COPILOT_HISTORY_PAGE_SIZE","useEffect","cancelled","resolveCopilotSessionIdForRoute","getCopilotSessionIdForRoute","record","loadCopilotSession","firstPage","loadOlderMessages","older","previous","known","fresh","historyError","pruneCopilotSessions","finishStreamingBubble","mutate","streamingId","settled","handleEvent","event","chunk","readCopilotEventContent","fullText","followUps","toolResults","sendMessage","userPrompt","now","assistantBubbleId","streamCopilotChat","streamError","regenerate","COPILOT_REGENERATE_PROMPT","submitFeedback","messageId","feedback","detail","rated","sendCopilotFeedback","feedbackError","stopStreaming","startNewConversation","activeRoute","clearedId","nextId","resetCopilotSessionForRoute","deleteCopilotSession","isThinking","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"useCopilotStreamChat.js","sources":["../../../../src/components/bik-copilot/useCopilotStreamChat.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { COPILOT_REGENERATE_PROMPT } from './copilotRegenerate';\nimport {\n\tCopilotFeedbackDetail,\n\tCopilotFeedbackVote,\n\tCopilotMessage,\n\tCopilotStreamEvent,\n\tUseCopilotStreamChatOptions,\n\tUseCopilotStreamChatResult,\n} from './model';\nimport {\n\tdeleteCopilotSession,\n\tloadCopilotSession,\n\tpersistCopilotTurn,\n\tpruneCopilotSessions,\n} from './services/copilotDb';\nimport { sendCopilotFeedback } from './services/copilotFeedbackClient';\nimport {\n\tCOPILOT_HISTORY_PAGE_SIZE,\n\tfetchCopilotMessages,\n} from './services/copilotMessagesClient';\nimport {\n\tgetCopilotSessionId,\n\tresetCopilotSession,\n\tresolveCopilotSessionId,\n} from './services/copilotPageSession';\nimport {\n\treadCopilotEventContent,\n\tstreamCopilotChat,\n} from './services/copilotStreamClient';\nimport {\n\tDEFAULT_COPILOT_AGENT,\n\tDEFAULT_COPILOT_ROUTE,\n} from './useCopilotIcebreakers';\n\nconst GENERIC_ERROR = 'Something went wrong. Please try again.';\n\n/**\n * Runs a merchant copilot conversation against the streaming\n * `/bik-ai/copilot-chatbot` endpoint.\n *\n * Owns three things the endpoint's contract requires:\n *\n * 1. **The session id.** One per store, not per route: the merchant moving\n * between dashboard pages stays in the same conversation, and so does a\n * refresh — the ids live in memory but are recovered from the stored records,\n * which is what keeps them lined up with the history the backend keys by them\n * (see `copilotPageSession`). The route travels with each turn instead, so the\n * backend still loads the POD, Area and page knowledge of wherever the\n * merchant is now.\n * 2. **`previousResponseId`.** Absent on the first turn; from then on it is the\n * `responseId` of the last `TEXT` event, which is what makes OpenAI replay the\n * earlier turns server side. A turn that breaks halfway returns no\n * `responseId`, and the backend means that — the next turn starts fresh.\n * 3. **The transcript**, stored in IndexedDB under the session id and written\n * every turn, so leaving the page mid-conversation loses nothing.\n */\nconst asRestored = (messages: CopilotMessage[]): CopilotMessage[] =>\n\tmessages.map((message) =>\n\t\tmessage.role === 'assistant' ? { ...message, isRestored: true } : message,\n\t);\n\nexport const useCopilotStreamChat = ({\n\tstoreId,\n\tagent = DEFAULT_COPILOT_AGENT,\n\troute = DEFAULT_COPILOT_ROUTE,\n\tmessagesPath,\n\tfeedbackPath,\n\tuser,\n\tloadHistory = true,\n\tsystemPrompt,\n\tsessionId: pinnedSessionId,\n\tpersist = true,\n\tonError,\n\tonResponseComplete,\n\tonSessionIdChange,\n\tbaseUrl,\n\tendpointPath,\n\theaders,\n\tauthToken,\n\tgetAuthToken,\n\tfetchImpl,\n}: UseCopilotStreamChatOptions): UseCopilotStreamChatResult => {\n\tconst [messages, setMessages] = useState<CopilotMessage[]>([]);\n\tconst [sessionId, setSessionId] = useState<string | null>(\n\t\tpinnedSessionId ?? null,\n\t);\n\tconst [isStreaming, setIsStreaming] = useState(false);\n\tconst [isRestoring, setIsRestoring] = useState(true);\n\tconst [error, setError] = useState<string | undefined>();\n\tconst [previousResponseId, setPreviousResponseId] = useState<\n\t\tstring | undefined\n\t>();\n\tconst [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\tconst [hasMoreHistory, setHasMoreHistory] = useState(false);\n\n\t// Async stream handlers run long after the render that created them, so the\n\t// live values live in refs and state is only the render mirror.\n\tconst messagesRef = useRef<CopilotMessage[]>([]);\n\tconst previousResponseIdRef = useRef<string | undefined>(undefined);\n\tconst streamingIdRef = useRef<string | null>(null);\n\tconst abortRef = useRef<(() => void) | null>(null);\n\tconst sessionIdRef = useRef<string | null>(pinnedSessionId ?? null);\n\t// The active route, for the async handlers that write the transcript.\n\tconst routeRef = useRef<string>(route);\n\trouteRef.current = route;\n\t// Next page of stored history to ask for. Starts at 2 when the local cache\n\t// already holds page 1's worth, which is the steady state.\n\tconst nextHistoryPageRef = useRef(1);\n\tconst isLoadingHistoryRef = useRef(false);\n\n\tconst applyMessages = useCallback(\n\t\t(updater: (previous: CopilotMessage[]) => CopilotMessage[]) => {\n\t\t\tconst next = updater(messagesRef.current);\n\t\t\tmessagesRef.current = next;\n\t\t\tsetMessages(next);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setThreadResponseId = useCallback((responseId: string | undefined) => {\n\t\tpreviousResponseIdRef.current = responseId;\n\t\tsetPreviousResponseId(responseId);\n\t}, []);\n\n\tconst save = useCallback(() => {\n\t\tconst id = sessionIdRef.current;\n\t\tif (!persist || !id) {\n\t\t\treturn;\n\t\t}\n\t\tvoid persistCopilotTurn({\n\t\t\troute: routeRef.current,\n\t\t\tsessionId: id,\n\t\t\tmessages: messagesRef.current,\n\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\tstoreId,\n\t\t\tagent,\n\t\t});\n\t}, [agent, persist, storeId]);\n\n\t// Transport config for the async readers below. Held in a ref rather than in\n\t// the effect's deps: a host that passes an inline `headers` object would\n\t// otherwise re-run restore on every render and wipe the transcript.\n\tconst transportRef = useRef({\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t});\n\ttransportRef.current = {\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t};\n\n\tconst readHistoryPage = useCallback(async (page: number) => {\n\t\tconst transport = transportRef.current;\n\t\tconst id = sessionIdRef.current;\n\t\tif (!transport.loadHistory || !id) {\n\t\t\treturn null;\n\t\t}\n\t\tconst historyPage = await fetchCopilotMessages({\n\t\t\tbaseUrl: transport.baseUrl,\n\t\t\tendpointPath: transport.messagesPath,\n\t\t\theaders: transport.headers,\n\t\t\tauthToken: transport.authToken,\n\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\tstoreId: transport.storeId,\n\t\t\tsessionId: id,\n\t\t\tpage,\n\t\t\tpageSize: COPILOT_HISTORY_PAGE_SIZE,\n\t\t});\n\t\treturn { ...historyPage, messages: asRestored(historyPage.messages) };\n\t}, []);\n\n\t// Resolve the store's conversation and read it back from IndexedDB.\n\t//\n\t// Deliberately not keyed on `route`: navigating is not a new chat, so a route\n\t// change must not restore, reset the transcript or abort a turn that is still\n\t// streaming. `routeRef` carries the current page into the next turn instead.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst restore = async () => {\n\t\t\tabortRef.current?.();\n\t\t\tabortRef.current = null;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tsetIsStreaming(false);\n\t\t\tsetError(undefined);\n\t\t\tsetIsRestoring(true);\n\t\t\tsetHasMoreHistory(false);\n\t\t\tisLoadingHistoryRef.current = false;\n\t\t\tsetIsLoadingHistory(false);\n\n\t\t\tconst id =\n\t\t\t\tpinnedSessionId ??\n\t\t\t\t(persist\n\t\t\t\t\t? await resolveCopilotSessionId({ storeId })\n\t\t\t\t\t: getCopilotSessionId({ storeId }));\n\t\t\tconst record = persist ? await loadCopilotSession(id) : null;\n\t\t\tif (cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsessionIdRef.current = id;\n\t\t\tsetSessionId(id);\n\t\t\tmessagesRef.current = asRestored(record?.messages ?? []);\n\t\t\tsetMessages(messagesRef.current);\n\t\t\tsetThreadResponseId(record?.previousResponseId);\n\t\t\tsetIsRestoring(false);\n\t\t\tonSessionIdChange?.(id);\n\n\t\t\t// The cache holds at most one page, so what is on screen already *is*\n\t\t\t// page 1 and the reader's first scroll-up wants page 2.\n\t\t\tif (messagesRef.current.length > 0) {\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tsetHasMoreHistory(transportRef.current.loadHistory);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nothing cached and nothing to scroll, so page 1 has to be fetched for\n\t\t\t// the history to be reachable at all — but only for an id the host\n\t\t\t// pinned. An id this library resolved came out of the local records, so\n\t\t\t// an empty cache for it means an empty conversation, and a freshly\n\t\t\t// minted one has nothing behind it by definition. Asking anyway would\n\t\t\t// put a pointless request on the start of every new conversation.\n\t\t\tif (!pinnedSessionId) {\n\t\t\t\tnextHistoryPageRef.current = 1;\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnextHistoryPageRef.current = 1;\n\t\t\ttry {\n\t\t\t\tconst firstPage = await readHistoryPage(1);\n\t\t\t\tif (cancelled || !firstPage) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tapplyMessages(() => firstPage.messages);\n\t\t\t\tsetHasMoreHistory(firstPage.hasMore);\n\t\t\t} catch {\n\t\t\t\t// A session the backend has never heard of is the normal case for a\n\t\t\t\t// host-pinned id on its first use; the empty state covers it.\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t}\n\t\t};\n\n\t\tvoid restore();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// onSessionIdChange is event-like: re-running restore because the host\n\t\t// passed a new inline callback would wipe the transcript.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\tstoreId,\n\t\tpinnedSessionId,\n\t\tpersist,\n\t\tsetThreadResponseId,\n\t\tapplyMessages,\n\t\treadHistoryPage,\n\t]);\n\n\t/**\n\t * Prepends the page before the oldest message on screen.\n\t *\n\t * Guarded by a ref rather than the state flag because a scroll handler can\n\t * fire many times before React re-renders, and each of those would otherwise\n\t * start its own request for the same page.\n\t */\n\tconst loadOlderMessages = useCallback(() => {\n\t\tif (isLoadingHistoryRef.current || !hasMoreHistory) {\n\t\t\treturn;\n\t\t}\n\t\tisLoadingHistoryRef.current = true;\n\t\tsetIsLoadingHistory(true);\n\n\t\tconst page = nextHistoryPageRef.current;\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\tconst older = await readHistoryPage(page);\n\t\t\t\tif (!older) {\n\t\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = page + 1;\n\t\t\t\tsetHasMoreHistory(older.hasMore);\n\t\t\t\tapplyMessages((previous) => {\n\t\t\t\t\tconst known = new Set(\n\t\t\t\t\t\tprevious.flatMap((message) =>\n\t\t\t\t\t\t\tmessage.messageId\n\t\t\t\t\t\t\t\t? [message.id, message.messageId]\n\t\t\t\t\t\t\t\t: [message.id],\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst fresh = older.messages.filter(\n\t\t\t\t\t\t(message) => !known.has(message.id),\n\t\t\t\t\t);\n\t\t\t\t\treturn fresh.length > 0 ? [...fresh, ...previous] : previous;\n\t\t\t\t});\n\t\t\t} catch (historyError) {\n\t\t\t\t// Left silent in the transcript on purpose: failing to reach further\n\t\t\t\t// back is not a failure of the conversation on screen. Another\n\t\t\t\t// scroll-up retries the same page.\n\t\t\t\tonError?.(\n\t\t\t\t\thistoryError instanceof Error\n\t\t\t\t\t\t? historyError\n\t\t\t\t\t\t: new Error(String(historyError)),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tisLoadingHistoryRef.current = false;\n\t\t\t\tsetIsLoadingHistory(false);\n\t\t\t}\n\t\t})();\n\t}, [applyMessages, hasMoreHistory, onError, readHistoryPage]);\n\n\t// Records pile up one per route per page load otherwise, since every refresh\n\t// writes under a new key.\n\tuseEffect(() => {\n\t\tif (persist) {\n\t\t\tvoid pruneCopilotSessions();\n\t\t}\n\t}, [persist]);\n\n\t// Abort an in-flight turn if the copilot unmounts.\n\tuseEffect(() => () => abortRef.current?.(), []);\n\n\tconst finishStreamingBubble = useCallback(\n\t\t(mutate?: (message: CopilotMessage) => CopilotMessage) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tif (!streamingId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious\n\t\t\t\t\t.map((message) => {\n\t\t\t\t\t\tif (message.id !== streamingId) {\n\t\t\t\t\t\t\treturn message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst settled: CopilotMessage = {\n\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\tisStreaming: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn mutate ? mutate(settled) : settled;\n\t\t\t\t\t})\n\t\t\t\t\t// An assistant bubble that never received text would render as an\n\t\t\t\t\t// empty balloon; the error banner carries the information instead.\n\t\t\t\t\t// A stopped turn keeps its bubble either way — the interrupted note\n\t\t\t\t\t// is the only trace a turn the reader cut short ever happened.\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.id !== streamingId ||\n\t\t\t\t\t\t\tmessage.content.length > 0 ||\n\t\t\t\t\t\t\tmessage.wasInterrupted === true,\n\t\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[applyMessages],\n\t);\n\n\tconst handleEvent = useCallback(\n\t\t(event: CopilotStreamEvent) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\n\t\t\tif (event.type === 'STREAM') {\n\t\t\t\tconst chunk = readCopilotEventContent(event).text;\n\t\t\t\tif (!streamingId || !chunk) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tapplyMessages((previous) =>\n\t\t\t\t\tprevious.map((message) =>\n\t\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\t\t\tcontent: message.content + chunk,\n\t\t\t\t\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: message,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'TEXT') {\n\t\t\t\t// TEXT carries the whole message, so it replaces the accumulated\n\t\t\t\t// chunks rather than appending — that keeps the bubble correct even if\n\t\t\t\t// a STREAM frame was dropped or duplicated. `responseId` rides inside\n\t\t\t\t// the content payload (as `lastResponseId`).\n\t\t\t\tconst {\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tfollowUps,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tresponseId,\n\t\t\t\t} = readCopilotEventContent(event);\n\t\t\t\tfinishStreamingBubble((message) => ({\n\t\t\t\t\t...message,\n\t\t\t\t\tcontent: fullText,\n\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t...(followUps ? { followUps } : {}),\n\t\t\t\t\t// Kept on the message, not just handled in passing, so the\n\t\t\t\t\t// action button is still there after a reload.\n\t\t\t\t\t...(toolResults ? { toolResults } : {}),\n\t\t\t\t}));\n\t\t\t\tsetThreadResponseId(responseId);\n\t\t\t\tsave();\n\t\t\t\tonResponseComplete?.({\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tresponseId,\n\t\t\t\t\tfollowUps,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'ERROR') {\n\t\t\t\tsetError(readCopilotEventContent(event).text || GENERIC_ERROR);\n\t\t\t\tfinishStreamingBubble();\n\t\t\t\tsave();\n\t\t\t}\n\n\t\t\t// Unknown types (TOOL_STATUS is declared server side but not emitted)\n\t\t\t// are ignored so a new event type cannot break an existing client.\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tfinishStreamingBubble,\n\t\t\tonResponseComplete,\n\t\t\tsave,\n\t\t\tsetThreadResponseId,\n\t\t],\n\t);\n\n\tconst sendMessage = useCallback(\n\t\t(message: string) => {\n\t\t\tconst userPrompt = message.trim();\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!userPrompt || !id || isStreaming) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(undefined);\n\t\t\tconst now = Date.now();\n\t\t\tconst assistantBubbleId = `copilot-a-${now}`;\n\t\t\tstreamingIdRef.current = assistantBubbleId;\n\n\t\t\tapplyMessages((previous) => [\n\t\t\t\t...previous,\n\t\t\t\t{\n\t\t\t\t\tid: `copilot-u-${now}`,\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: userPrompt,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: assistantBubbleId,\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: '',\n\t\t\t\t\ttimestamp: now + 1,\n\t\t\t\t\tisStreaming: true,\n\t\t\t\t},\n\t\t\t]);\n\t\t\tsetIsStreaming(true);\n\t\t\tsave();\n\n\t\t\tabortRef.current = streamCopilotChat(\n\t\t\t\t{\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tendpointPath,\n\t\t\t\t\theaders,\n\t\t\t\t\tauthToken,\n\t\t\t\t\tgetAuthToken,\n\t\t\t\t\tfetchImpl,\n\t\t\t\t\tstoreId,\n\t\t\t\t\tagent,\n\t\t\t\t\troute,\n\t\t\t\t\tuserPrompt,\n\t\t\t\t\tsessionId: id,\n\t\t\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonEvent: handleEvent,\n\t\t\t\t\tonComplete: () => {\n\t\t\t\t\t\t// STOP closes the stream without a frame, so this is where a turn\n\t\t\t\t\t\t// ends. TEXT has usually already settled the bubble.\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t\tonError: (streamError) => {\n\t\t\t\t\t\tsetError(streamError.message || GENERIC_ERROR);\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t\tonError?.(streamError);\n\t\t\t\t\t},\n\t\t\t\t\tonAbort: () => {\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tauthToken,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tfetchImpl,\n\t\t\tagent,\n\t\t\tfinishStreamingBubble,\n\t\t\tgetAuthToken,\n\t\t\thandleEvent,\n\t\t\theaders,\n\t\t\tisStreaming,\n\t\t\tonError,\n\t\t\troute,\n\t\t\tsave,\n\t\t\tstoreId,\n\t\t\tsystemPrompt,\n\t\t],\n\t);\n\n\tconst regenerate = useCallback(() => {\n\t\tconst hasReply = messagesRef.current.some(\n\t\t\t(message) => message.role === 'assistant' && message.content.length > 0,\n\t\t);\n\t\tif (!hasReply) {\n\t\t\treturn;\n\t\t}\n\t\tsendMessage(COPILOT_REGENERATE_PROMPT);\n\t}, [sendMessage]);\n\n\t/**\n\t * Records a thumbs-up or thumbs-down on one reply.\n\t *\n\t * Fire-and-forget: a rating is a side note to the conversation, so a failed\n\t * post is reported through `onError` and otherwise ignored -- the thumb stays\n\t * lit either way rather than flickering back on a network hiccup.\n\t *\n\t * The reply's own text and the route ride along, so whoever reads the feedback\n\t * sees what was rated without looking the message up.\n\t */\n\tconst submitFeedback = useCallback(\n\t\t(\n\t\t\tmessageId: string,\n\t\t\tfeedback: CopilotFeedbackVote,\n\t\t\tdetail?: CopilotFeedbackDetail,\n\t\t) => {\n\t\t\tconst transport = transportRef.current;\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!id) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// A live turn's bubble carries only a local id until the final event\n\t\t\t// lands, so match on either and let the backend see whichever it gets.\n\t\t\tconst rated = messagesRef.current.find(\n\t\t\t\t(message) => (message.messageId ?? message.id) === messageId,\n\t\t\t);\n\t\t\tvoid sendCopilotFeedback({\n\t\t\t\tbaseUrl: transport.baseUrl,\n\t\t\t\tendpointPath: transport.feedbackPath,\n\t\t\t\theaders: transport.headers,\n\t\t\t\tauthToken: transport.authToken,\n\t\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\t\tstoreId: transport.storeId,\n\t\t\t\tsessionId: id,\n\t\t\t\tmessageId,\n\t\t\t\tfeedback,\n\t\t\t\troute: routeRef.current,\n\t\t\t\treply: rated?.content,\n\t\t\t\tuser: transport.user,\n\t\t\t\treasons: detail?.reasons,\n\t\t\t\tcomment: detail?.comment,\n\t\t\t}).catch((feedbackError) => {\n\t\t\t\tonError?.(\n\t\t\t\t\tfeedbackError instanceof Error\n\t\t\t\t\t\t? feedbackError\n\t\t\t\t\t\t: new Error(String(feedbackError)),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[onError],\n\t);\n\n\tconst stopStreaming = useCallback(() => {\n\t\tif (!abortRef.current) {\n\t\t\treturn;\n\t\t}\n\t\t// Flagged here rather than in `onAbort`, because an abort that lands between\n\t\t// frames ends the stream through `onComplete` instead. Whichever fires, the\n\t\t// reader stopped this turn, and whatever text had arrived stays.\n\t\tconst streamingId = streamingIdRef.current;\n\t\tif (streamingId) {\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious.map((message) =>\n\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t? { ...message, wasInterrupted: true }\n\t\t\t\t\t\t: message,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tabortRef.current();\n\t\tabortRef.current = null;\n\t}, [applyMessages]);\n\n\tconst startNewConversation = useCallback(() => {\n\t\tabortRef.current?.();\n\t\tabortRef.current = null;\n\t\tstreamingIdRef.current = null;\n\t\tsetIsStreaming(false);\n\t\tsetError(undefined);\n\t\t// A new conversation has no history behind it; the old session's pages\n\t\t// belong to the old session id.\n\t\tnextHistoryPageRef.current = 1;\n\t\tisLoadingHistoryRef.current = false;\n\t\tsetIsLoadingHistory(false);\n\t\tsetHasMoreHistory(false);\n\n\t\t// The conversation being cleared, so its stored transcript can go with it.\n\t\tconst clearedId = sessionIdRef.current;\n\t\t// A host-pinned id is the host's to change, so only clear its transcript.\n\t\tconst nextId = pinnedSessionId ?? resetCopilotSession({ storeId });\n\t\tsessionIdRef.current = nextId;\n\t\tsetSessionId(nextId);\n\t\tmessagesRef.current = [];\n\t\tsetMessages([]);\n\t\tsetThreadResponseId(undefined);\n\n\t\t// \"Refresh chat\" wipes the record, not just the screen: the cleared\n\t\t// conversation is deleted from IndexedDB so reopening the tab starts fresh\n\t\t// instead of resuming it. Nothing is written for the new session here — its\n\t\t// first record is stamped when the first turn is sent, which is also what\n\t\t// keeps an untouched refresh from leaving an empty record behind.\n\t\tif (persist && clearedId) {\n\t\t\tvoid deleteCopilotSession(clearedId);\n\t\t}\n\t\tonSessionIdChange?.(nextId);\n\t}, [\n\t\tonSessionIdChange,\n\t\tpersist,\n\t\tpinnedSessionId,\n\t\tsetThreadResponseId,\n\t\tstoreId,\n\t]);\n\n\t// The thinking bubble is only for the wait before the first token; once text\n\t// starts arriving the bubble itself shows progress.\n\tconst isThinking = useMemo(\n\t\t() =>\n\t\t\tisStreaming &&\n\t\t\t!messages.some((message) => message.isStreaming && message.content),\n\t\t[isStreaming, messages],\n\t);\n\n\treturn {\n\t\tmessages,\n\t\tsessionId,\n\t\tpreviousResponseId,\n\t\tisStreaming,\n\t\tisThinking,\n\t\tisRestoring,\n\t\tisLoadingHistory,\n\t\thasMoreHistory,\n\t\terror,\n\t\tsendMessage,\n\t\tregenerate,\n\t\tsubmitFeedback,\n\t\tloadOlderMessages,\n\t\tstopStreaming,\n\t\tstartNewConversation,\n\t};\n};\n"],"names":["GENERIC_ERROR","asRestored","messages","message","useCopilotStreamChat","storeId","agent","DEFAULT_COPILOT_AGENT","route","DEFAULT_COPILOT_ROUTE","messagesPath","feedbackPath","user","loadHistory","systemPrompt","pinnedSessionId","persist","onError","onResponseComplete","onSessionIdChange","baseUrl","endpointPath","headers","authToken","getAuthToken","fetchImpl","setMessages","useState","sessionId","setSessionId","isStreaming","setIsStreaming","isRestoring","setIsRestoring","error","setError","previousResponseId","setPreviousResponseId","isLoadingHistory","setIsLoadingHistory","hasMoreHistory","setHasMoreHistory","messagesRef","useRef","previousResponseIdRef","streamingIdRef","abortRef","sessionIdRef","routeRef","nextHistoryPageRef","isLoadingHistoryRef","applyMessages","useCallback","updater","next","setThreadResponseId","responseId","save","id","persistCopilotTurn","transportRef","readHistoryPage","page","transport","historyPage","fetchCopilotMessages","COPILOT_HISTORY_PAGE_SIZE","useEffect","cancelled","resolveCopilotSessionId","getCopilotSessionId","record","loadCopilotSession","firstPage","loadOlderMessages","older","previous","known","fresh","historyError","pruneCopilotSessions","finishStreamingBubble","mutate","streamingId","settled","handleEvent","event","chunk","readCopilotEventContent","fullText","followUps","toolResults","sendMessage","userPrompt","now","assistantBubbleId","streamCopilotChat","streamError","regenerate","COPILOT_REGENERATE_PROMPT","submitFeedback","messageId","feedback","detail","rated","sendCopilotFeedback","feedbackError","stopStreaming","startNewConversation","clearedId","nextId","resetCopilotSession","deleteCopilotSession","isThinking","useMemo"],"mappings":";;;;;;;;AAmCA,MAAMA,KAAgB,2CAsBhBC,KAAa,CAACC,MACnBA,EAAS;AAAA,EAAI,CAACC,MACbA,EAAQ,SAAS,cAAc,EAAE,GAAGA,GAAS,YAAY,OAASA;AACnE,GAEYC,KAAuB,CAAC;AAAA,EACpC,SAAAC;AAAA,EACA,OAAAC,IAAQC;AAAA,EACR,OAAAC,IAAQC;AAAA,EACR,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,MAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,cAAAC;AAAA,EACA,WAAWC;AAAA,EACX,SAAAC,IAAU;AAAA,EACV,SAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,SAAAC;AAAA,EACA,cAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AACD,MAA+D;AAC9D,QAAM,CAACvB,GAAUwB,CAAW,IAAIC,EAA2B,CAAA,CAAE,GACvD,CAACC,IAAWC,EAAY,IAAIF;AAAA,IACjCZ,KAAmB;AAAA,EAAA,GAEd,CAACe,GAAaC,CAAc,IAAIJ,EAAS,EAAK,GAC9C,CAACK,IAAaC,EAAc,IAAIN,EAAS,EAAI,GAC7C,CAACO,IAAOC,CAAQ,IAAIR,EAAA,GACpB,CAACS,IAAoBC,EAAqB,IAAIV,EAAA,GAG9C,CAACW,IAAkBC,CAAmB,IAAIZ,EAAS,EAAK,GACxD,CAACa,GAAgBC,CAAiB,IAAId,EAAS,EAAK,GAIpDe,IAAcC,EAAyB,EAAE,GACzCC,IAAwBD,EAA2B,MAAS,GAC5DE,IAAiBF,EAAsB,IAAI,GAC3CG,IAAWH,EAA4B,IAAI,GAC3CI,IAAeJ,EAAsB5B,KAAmB,IAAI,GAE5DiC,IAAWL,EAAenC,CAAK;AACrC,EAAAwC,EAAS,UAAUxC;AAGnB,QAAMyC,IAAqBN,EAAO,CAAC,GAC7BO,IAAsBP,EAAO,EAAK,GAElCQ,IAAgBC;AAAA,IACrB,CAACC,MAA8D;AAC9D,YAAMC,IAAOD,EAAQX,EAAY,OAAO;AACxC,MAAAA,EAAY,UAAUY,GACtB5B,EAAY4B,CAAI;AAAA,IACjB;AAAA,IACA,CAAA;AAAA,EAAC,GAGIC,IAAsBH,EAAY,CAACI,MAAmC;AAC3E,IAAAZ,EAAsB,UAAUY,GAChCnB,GAAsBmB,CAAU;AAAA,EACjC,GAAG,CAAA,CAAE,GAECC,IAAOL,EAAY,MAAM;AAC9B,UAAMM,IAAKX,EAAa;AACxB,IAAI,CAAC/B,KAAW,CAAC0C,KAGZC,GAAmB;AAAA,MACvB,OAAOX,EAAS;AAAA,MAChB,WAAWU;AAAA,MACX,UAAUhB,EAAY;AAAA,MACtB,oBAAoBE,EAAsB;AAAA,MAC1C,SAAAvC;AAAA,MACA,OAAAC;AAAA,IAAA,CACA;AAAA,EACF,GAAG,CAACA,GAAOU,GAASX,CAAO,CAAC,GAKtBuD,IAAejB,EAAO;AAAA,IAC3B,SAAAvB;AAAA,IACA,cAAAV;AAAA,IACA,cAAAC;AAAA,IACA,SAAAW;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAC;AAAA,IACA,SAAApB;AAAA,IACA,aAAAQ;AAAA,IACA,MAAAD;AAAA,EAAA,CACA;AACD,EAAAgD,EAAa,UAAU;AAAA,IACtB,SAAAxC;AAAA,IACA,cAAAV;AAAA,IACA,cAAAC;AAAA,IACA,SAAAW;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAC;AAAA,IACA,SAAApB;AAAA,IACA,aAAAQ;AAAA,IACA,MAAAD;AAAA,EAAA;AAGD,QAAMiD,IAAkBT,EAAY,OAAOU,MAAiB;AAC3D,UAAMC,IAAYH,EAAa,SACzBF,IAAKX,EAAa;AACxB,QAAI,CAACgB,EAAU,eAAe,CAACL;AAC9B,aAAO;AAER,UAAMM,IAAc,MAAMC,GAAqB;AAAA,MAC9C,SAASF,EAAU;AAAA,MACnB,cAAcA,EAAU;AAAA,MACxB,SAASA,EAAU;AAAA,MACnB,WAAWA,EAAU;AAAA,MACrB,cAAcA,EAAU;AAAA,MACxB,WAAWA,EAAU;AAAA,MACrB,SAASA,EAAU;AAAA,MACnB,WAAWL;AAAA,MACX,MAAAI;AAAA,MACA,UAAUI;AAAA,IAAA,CACV;AACD,WAAO,EAAE,GAAGF,GAAa,UAAU/D,GAAW+D,EAAY,QAAQ,EAAA;AAAA,EACnE,GAAG,CAAA,CAAE;AAOL,EAAAG,EAAU,MAAM;AACf,QAAIC,IAAY;AAmEhB,YAjEgB,YAAY;AAC3B,MAAAtB,EAAS,UAAA,GACTA,EAAS,UAAU,MACnBD,EAAe,UAAU,MACzBd,EAAe,EAAK,GACpBI,EAAS,MAAS,GAClBF,GAAe,EAAI,GACnBQ,EAAkB,EAAK,GACvBS,EAAoB,UAAU,IAC9BX,EAAoB,EAAK;AAEzB,YAAMmB,IACL3C,MACCC,IACE,MAAMqD,GAAwB,EAAE,SAAAhE,EAAA,CAAS,IACzCiE,GAAoB,EAAE,SAAAjE,EAAA,CAAS,IAC7BkE,IAASvD,IAAU,MAAMwD,GAAmBd,CAAE,IAAI;AACxD,UAAI,CAAAU,GAcJ;AAAA,YAVArB,EAAa,UAAUW,GACvB7B,GAAa6B,CAAE,GACfhB,EAAY,UAAUzC,GAAWsE,GAAQ,YAAY,CAAA,CAAE,GACvD7C,EAAYgB,EAAY,OAAO,GAC/Ba,EAAoBgB,GAAQ,kBAAkB,GAC9CtC,GAAe,EAAK,GACpBd,IAAoBuC,CAAE,GAIlBhB,EAAY,QAAQ,SAAS,GAAG;AACnC,UAAAO,EAAmB,UAAU,GAC7BR,EAAkBmB,EAAa,QAAQ,WAAW;AAClD;AAAA,QACD;AAQA,YAAI,CAAC7C,GAAiB;AACrB,UAAAkC,EAAmB,UAAU,GAC7BR,EAAkB,EAAK;AACvB;AAAA,QACD;AAEA,QAAAQ,EAAmB,UAAU;AAC7B,YAAI;AACH,gBAAMwB,IAAY,MAAMZ,EAAgB,CAAC;AACzC,cAAIO,KAAa,CAACK;AACjB;AAED,UAAAxB,EAAmB,UAAU,GAC7BE,EAAc,MAAMsB,EAAU,QAAQ,GACtChC,EAAkBgC,EAAU,OAAO;AAAA,QACpC,QAAQ;AAGP,UAAAhC,EAAkB,EAAK;AAAA,QACxB;AAAA;AAAA,IACD,GAEK,GACE,MAAM;AACZ,MAAA2B,IAAY;AAAA,IACb;AAAA,EAID,GAAG;AAAA,IACF/D;AAAA,IACAU;AAAA,IACAC;AAAA,IACAuC;AAAA,IACAJ;AAAA,IACAU;AAAA,EAAA,CACA;AASD,QAAMa,KAAoBtB,EAAY,MAAM;AAC3C,QAAIF,EAAoB,WAAW,CAACV;AACnC;AAED,IAAAU,EAAoB,UAAU,IAC9BX,EAAoB,EAAI;AAExB,UAAMuB,IAAOb,EAAmB;AAChC,KAAM,YAAY;AACjB,UAAI;AACH,cAAM0B,IAAQ,MAAMd,EAAgBC,CAAI;AACxC,YAAI,CAACa,GAAO;AACX,UAAAlC,EAAkB,EAAK;AACvB;AAAA,QACD;AACA,QAAAQ,EAAmB,UAAUa,IAAO,GACpCrB,EAAkBkC,EAAM,OAAO,GAC/BxB,EAAc,CAACyB,MAAa;AAC3B,gBAAMC,IAAQ,IAAI;AAAA,YACjBD,EAAS;AAAA,cAAQ,CAACzE,MACjBA,EAAQ,YACL,CAACA,EAAQ,IAAIA,EAAQ,SAAS,IAC9B,CAACA,EAAQ,EAAE;AAAA,YAAA;AAAA,UACf,GAEK2E,IAAQH,EAAM,SAAS;AAAA,YAC5B,CAACxE,MAAY,CAAC0E,EAAM,IAAI1E,EAAQ,EAAE;AAAA,UAAA;AAEnC,iBAAO2E,EAAM,SAAS,IAAI,CAAC,GAAGA,GAAO,GAAGF,CAAQ,IAAIA;AAAA,QACrD,CAAC;AAAA,MACF,SAASG,GAAc;AAItB,QAAA9D;AAAA,UACC8D,aAAwB,QACrBA,IACA,IAAI,MAAM,OAAOA,CAAY,CAAC;AAAA,QAAA;AAAA,MAEnC,UAAA;AACC,QAAA7B,EAAoB,UAAU,IAC9BX,EAAoB,EAAK;AAAA,MAC1B;AAAA,IACD,GAAA;AAAA,EACD,GAAG,CAACY,GAAeX,GAAgBvB,GAAS4C,CAAe,CAAC;AAI5D,EAAAM,EAAU,MAAM;AACf,IAAInD,KACEgE,GAAA;AAAA,EAEP,GAAG,CAAChE,CAAO,CAAC,GAGZmD,EAAU,MAAM,MAAMrB,EAAS,UAAA,GAAa,CAAA,CAAE;AAE9C,QAAMmC,IAAwB7B;AAAA,IAC7B,CAAC8B,MAAyD;AACzD,YAAMC,IAActC,EAAe;AAEnC,MADAA,EAAe,UAAU,MACpBsC,KAGLhC;AAAA,QAAc,CAACyB,MACdA,EACE,IAAI,CAACzE,MAAY;AACjB,cAAIA,EAAQ,OAAOgF;AAClB,mBAAOhF;AAER,gBAAMiF,IAA0B;AAAA,YAC/B,GAAGjF;AAAA,YACH,aAAa;AAAA,UAAA;AAEd,iBAAO+E,IAASA,EAAOE,CAAO,IAAIA;AAAA,QACnC,CAAC,EAKA;AAAA,UACA,CAACjF,MACAA,EAAQ,OAAOgF,KACfhF,EAAQ,QAAQ,SAAS,KACzBA,EAAQ,mBAAmB;AAAA,QAAA;AAAA,MAC7B;AAAA,IAEH;AAAA,IACA,CAACgD,CAAa;AAAA,EAAA,GAGTkC,KAAcjC;AAAA,IACnB,CAACkC,MAA8B;AAC9B,YAAMH,IAActC,EAAe;AAEnC,UAAIyC,EAAM,SAAS,UAAU;AAC5B,cAAMC,IAAQC,EAAwBF,CAAK,EAAE;AAC7C,YAAI,CAACH,KAAe,CAACI;AACpB;AAED,QAAApC;AAAA,UAAc,CAACyB,MACdA,EAAS;AAAA,YAAI,CAACzE,MACbA,EAAQ,OAAOgF,IACZ;AAAA,cACA,GAAGhF;AAAA,cACH,SAASA,EAAQ,UAAUoF;AAAA,cAC3B,WAAWD,EAAM,aAAanF,EAAQ;AAAA,YAAA,IAEtCA;AAAA,UAAA;AAAA,QACJ;AAED;AAAA,MACD;AAEA,UAAImF,EAAM,SAAS,QAAQ;AAK1B,cAAM;AAAA,UACL,MAAMG;AAAA,UACN,WAAAC;AAAA,UACA,aAAAC;AAAA,UACA,YAAAnC;AAAA,QAAA,IACGgC,EAAwBF,CAAK;AACjC,QAAAL,EAAsB,CAAC9E,OAAa;AAAA,UACnC,GAAGA;AAAA,UACH,SAASsF;AAAA,UACT,WAAWH,EAAM,aAAanF,EAAQ;AAAA,UACtC,GAAIuF,IAAY,EAAE,WAAAA,EAAA,IAAc,CAAA;AAAA;AAAA;AAAA,UAGhC,GAAIC,IAAc,EAAE,aAAAA,MAAgB,CAAA;AAAA,QAAC,EACpC,GACFpC,EAAoBC,CAAU,GAC9BC,EAAA,GACAvC,IAAqB;AAAA,UACpB,MAAMuE;AAAA,UACN,YAAAjC;AAAA,UACA,WAAAkC;AAAA,QAAA,CACA;AACD;AAAA,MACD;AAEA,MAAIJ,EAAM,SAAS,YAClBnD,EAASqD,EAAwBF,CAAK,EAAE,QAAQtF,EAAa,GAC7DiF,EAAA,GACAxB,EAAA;AAAA,IAKF;AAAA,IACA;AAAA,MACCN;AAAA,MACA8B;AAAA,MACA/D;AAAA,MACAuC;AAAA,MACAF;AAAA,IAAA;AAAA,EACD,GAGKqC,IAAcxC;AAAA,IACnB,CAACjD,MAAoB;AACpB,YAAM0F,IAAa1F,EAAQ,KAAA,GACrBuD,IAAKX,EAAa;AACxB,UAAI,CAAC8C,KAAc,CAACnC,KAAM5B;AACzB;AAGD,MAAAK,EAAS,MAAS;AAClB,YAAM2D,IAAM,KAAK,IAAA,GACXC,IAAoB,aAAaD,CAAG;AAC1C,MAAAjD,EAAe,UAAUkD,GAEzB5C,EAAc,CAACyB,MAAa;AAAA,QAC3B,GAAGA;AAAA,QACH;AAAA,UACC,IAAI,aAAakB,CAAG;AAAA,UACpB,MAAM;AAAA,UACN,SAASD;AAAA,UACT,WAAWC;AAAA,QAAA;AAAA,QAEZ;AAAA,UACC,IAAIC;AAAA,UACJ,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAWD,IAAM;AAAA,UACjB,aAAa;AAAA,QAAA;AAAA,MACd,CACA,GACD/D,EAAe,EAAI,GACnB0B,EAAA,GAEAX,EAAS,UAAUkD;AAAA,QAClB;AAAA,UACC,SAAA5E;AAAA,UACA,cAAAC;AAAA,UACA,SAAAC;AAAA,UACA,WAAAC;AAAA,UACA,cAAAC;AAAA,UACA,WAAAC;AAAA,UACA,SAAApB;AAAA,UACA,OAAAC;AAAA,UACA,OAAAE;AAAA,UACA,YAAAqF;AAAA,UACA,WAAWnC;AAAA,UACX,oBAAoBd,EAAsB;AAAA,UAC1C,cAAA9B;AAAA,QAAA;AAAA,QAED;AAAA,UACC,SAASuE;AAAA,UACT,YAAY,MAAM;AAGjB,YAAAJ,EAAA,GACAlD,EAAe,EAAK,GACpBe,EAAS,UAAU,MACnBW,EAAA;AAAA,UACD;AAAA,UACA,SAAS,CAACwC,MAAgB;AACzB,YAAA9D,EAAS8D,EAAY,WAAWjG,EAAa,GAC7CiF,EAAA,GACAlD,EAAe,EAAK,GACpBe,EAAS,UAAU,MACnBW,EAAA,GACAxC,IAAUgF,CAAW;AAAA,UACtB;AAAA,UACA,SAAS,MAAM;AACd,YAAAhB,EAAA,GACAlD,EAAe,EAAK,GACpBe,EAAS,UAAU,MACnBW,EAAA;AAAA,UACD;AAAA,QAAA;AAAA,MACD;AAAA,IAEF;AAAA,IACA;AAAA,MACCN;AAAA,MACA5B;AAAA,MACAH;AAAA,MACAC;AAAA,MACAI;AAAA,MACAnB;AAAA,MACA2E;AAAA,MACAzD;AAAA,MACA6D;AAAA,MACA/D;AAAA,MACAQ;AAAA,MACAb;AAAA,MACAT;AAAA,MACAiD;AAAA,MACApD;AAAA,MACAS;AAAA,IAAA;AAAA,EACD,GAGKoF,KAAa9C,EAAY,MAAM;AAIpC,IAHiBV,EAAY,QAAQ;AAAA,MACpC,CAACvC,MAAYA,EAAQ,SAAS,eAAeA,EAAQ,QAAQ,SAAS;AAAA,IAAA,KAKvEyF,EAAYO,EAAyB;AAAA,EACtC,GAAG,CAACP,CAAW,CAAC,GAYVQ,KAAiBhD;AAAA,IACtB,CACCiD,GACAC,GACAC,MACI;AACJ,YAAMxC,IAAYH,EAAa,SACzBF,IAAKX,EAAa;AACxB,UAAI,CAACW;AACJ;AAID,YAAM8C,IAAQ9D,EAAY,QAAQ;AAAA,QACjC,CAACvC,OAAaA,EAAQ,aAAaA,EAAQ,QAAQkG;AAAA,MAAA;AAEpD,MAAKI,GAAoB;AAAA,QACxB,SAAS1C,EAAU;AAAA,QACnB,cAAcA,EAAU;AAAA,QACxB,SAASA,EAAU;AAAA,QACnB,WAAWA,EAAU;AAAA,QACrB,cAAcA,EAAU;AAAA,QACxB,WAAWA,EAAU;AAAA,QACrB,SAASA,EAAU;AAAA,QACnB,WAAWL;AAAA,QACX,WAAA2C;AAAA,QACA,UAAAC;AAAA,QACA,OAAOtD,EAAS;AAAA,QAChB,OAAOwD,GAAO;AAAA,QACd,MAAMzC,EAAU;AAAA,QAChB,SAASwC,GAAQ;AAAA,QACjB,SAASA,GAAQ;AAAA,MAAA,CACjB,EAAE,MAAM,CAACG,MAAkB;AAC3B,QAAAzF;AAAA,UACCyF,aAAyB,QACtBA,IACA,IAAI,MAAM,OAAOA,CAAa,CAAC;AAAA,QAAA;AAAA,MAEpC,CAAC;AAAA,IACF;AAAA,IACA,CAACzF,CAAO;AAAA,EAAA,GAGH0F,KAAgBvD,EAAY,MAAM;AACvC,QAAI,CAACN,EAAS;AACb;AAKD,UAAMqC,IAActC,EAAe;AACnC,IAAIsC,KACHhC;AAAA,MAAc,CAACyB,MACdA,EAAS;AAAA,QAAI,CAACzE,MACbA,EAAQ,OAAOgF,IACZ,EAAE,GAAGhF,GAAS,gBAAgB,OAC9BA;AAAA,MAAA;AAAA,IACJ,GAGF2C,EAAS,QAAA,GACTA,EAAS,UAAU;AAAA,EACpB,GAAG,CAACK,CAAa,CAAC,GAEZyD,KAAuBxD,EAAY,MAAM;AAC9C,IAAAN,EAAS,UAAA,GACTA,EAAS,UAAU,MACnBD,EAAe,UAAU,MACzBd,EAAe,EAAK,GACpBI,EAAS,MAAS,GAGlBc,EAAmB,UAAU,GAC7BC,EAAoB,UAAU,IAC9BX,EAAoB,EAAK,GACzBE,EAAkB,EAAK;AAGvB,UAAMoE,IAAY9D,EAAa,SAEzB+D,IAAS/F,KAAmBgG,GAAoB,EAAE,SAAA1G,GAAS;AACjE,IAAA0C,EAAa,UAAU+D,GACvBjF,GAAaiF,CAAM,GACnBpE,EAAY,UAAU,CAAA,GACtBhB,EAAY,CAAA,CAAE,GACd6B,EAAoB,MAAS,GAOzBvC,KAAW6F,KACTG,GAAqBH,CAAS,GAEpC1F,IAAoB2F,CAAM;AAAA,EAC3B,GAAG;AAAA,IACF3F;AAAA,IACAH;AAAA,IACAD;AAAA,IACAwC;AAAA,IACAlD;AAAA,EAAA,CACA,GAIK4G,KAAaC;AAAA,IAClB,MACCpF,KACA,CAAC5B,EAAS,KAAK,CAACC,MAAYA,EAAQ,eAAeA,EAAQ,OAAO;AAAA,IACnE,CAAC2B,GAAa5B,CAAQ;AAAA,EAAA;AAGvB,SAAO;AAAA,IACN,UAAAA;AAAA,IACA,WAAA0B;AAAA,IACA,oBAAAQ;AAAA,IACA,aAAAN;AAAA,IACA,YAAAmF;AAAA,IACA,aAAAjF;AAAA,IACA,kBAAAM;AAAA,IACA,gBAAAE;AAAA,IACA,OAAAN;AAAA,IACA,aAAA0D;AAAA,IACA,YAAAM;AAAA,IACA,gBAAAE;AAAA,IACA,mBAAA1B;AAAA,IACA,eAAAiC;AAAA,IACA,sBAAAC;AAAA,EAAA;AAEF;"}
@@ -1,35 +1,34 @@
1
1
  import { jsx as t, jsxs as j } from "react/jsx-runtime";
2
2
  import v, { useState as z, useEffect as p } from "react";
3
3
  import { ZeroState as A } from "../zeroState/ZeroState.js";
4
- import { COLORS as L } from "../../constants/Theme.js";
5
- import { SearchBox as M } from "../dropdown/OpenedDropdown/components/searchbox/SearchBox.js";
6
- import { MenuList as _ } from "./MenuList.js";
7
- import { DropdownContainer as q, OptionsContainer as B, NoResultsContainer as H, FooterContainer as I } from "./MultiLevelDropdown.styled.js";
8
- import { Floater as T } from "../floater/floater.js";
9
- const W = ({
4
+ import { COLORS as S } from "../../constants/Theme.js";
5
+ import { SearchBox as F } from "../dropdown/OpenedDropdown/components/searchbox/SearchBox.js";
6
+ import { MenuList as M } from "./MenuList.js";
7
+ import { DropdownContainer as _, OptionsContainer as q, NoResultsContainer as B } from "./MultiLevelDropdown.styled.js";
8
+ import { Floater as H } from "../floater/floater.js";
9
+ const U = ({
10
10
  options: l,
11
11
  width: i,
12
- isSearchable: b,
13
- onDropdownItemClick: C,
12
+ isSearchable: L,
13
+ onDropdownItemClick: b,
14
14
  refElement: w,
15
- topOffset: R,
16
- leftOffset: E,
17
- isDropdownOpen: d,
15
+ topOffset: C,
16
+ leftOffset: R,
17
+ isDropdownOpen: u,
18
18
  onDropdownOutsideClick: o,
19
- allowParentSelection: F,
19
+ allowParentSelection: E,
20
20
  maxLevels: N,
21
21
  hideGroupLabel: O,
22
- version: n = "1.0",
23
- footer: m
22
+ version: n = "1.0"
24
23
  }) => {
25
- const u = v.useRef(null), [a, x] = z(l), g = (f) => {
26
- const c = Array.isArray(l) ? [...l] : [], S = [];
24
+ const d = v.useRef(null), [f, m] = z(l), x = (a) => {
25
+ const c = Array.isArray(l) ? [...l] : [], y = [];
27
26
  for (; c.length > 0; ) {
28
27
  const e = c.shift();
29
- e && e.label.toLowerCase().includes(f.toLowerCase()) && S.push(e), e && "children" in e && e.children ? c.push(...e.children) : e && "options" in e && e.options && c.push(...e.options);
28
+ e && e.label.toLowerCase().includes(a.toLowerCase()) && y.push(e), e && "children" in e && e.children ? c.push(...e.children) : e && "options" in e && e.options && c.push(...e.options);
30
29
  }
31
30
  const h = (e) => e.map((r) => {
32
- if (S.includes(r))
31
+ if (y.includes(r))
33
32
  return r;
34
33
  if ("children" in r && r.children) {
35
34
  const s = h(
@@ -47,36 +46,36 @@ const W = ({
47
46
  }
48
47
  return null;
49
48
  }).filter((r) => r !== null);
50
- x(h(l));
51
- }, y = (f) => {
52
- u.current && !u.current.contains(f.target) ? o && o(!0) : o && o(!1);
49
+ m(h(l));
50
+ }, g = (a) => {
51
+ d.current && !d.current.contains(a.target) ? o && o(!0) : o && o(!1);
53
52
  };
54
53
  return p(() => {
55
- d && g("");
56
- }, [d]), p(() => (document.addEventListener("mousedown", y), () => {
57
- document.removeEventListener("mousedown", y);
54
+ u && x("");
55
+ }, [u]), p(() => (document.addEventListener("mousedown", g), () => {
56
+ document.removeEventListener("mousedown", g);
58
57
  }), []), p(() => {
59
- x(l);
58
+ m(l);
60
59
  }, [l]), /* @__PURE__ */ t(
61
- T,
60
+ H,
62
61
  {
63
62
  refElement: w,
64
- topOffset: R,
65
- leftOffset: E,
66
- children: d && /* @__PURE__ */ t(
63
+ topOffset: C,
64
+ leftOffset: R,
65
+ children: u && /* @__PURE__ */ t(
67
66
  "div",
68
67
  {
69
- ref: u,
68
+ ref: d,
70
69
  style: {
71
- backgroundColor: L.surface.standard,
70
+ backgroundColor: S.surface.standard,
72
71
  zIndex: 99999,
73
72
  borderRadius: n === "3.0" ? "4px" : "8px",
74
73
  overflow: "hidden",
75
74
  boxShadow: "0 2px 8px 0 rgba(0, 0, 0, 0.12)",
76
75
  whiteSpace: "normal"
77
76
  },
78
- children: /* @__PURE__ */ j(q, { width: i, version: n, children: [
79
- b && /* @__PURE__ */ t(
77
+ children: /* @__PURE__ */ j(_, { width: i, version: n, children: [
78
+ L && /* @__PURE__ */ t(
80
79
  "div",
81
80
  {
82
81
  style: {
@@ -84,30 +83,30 @@ const W = ({
84
83
  width: i ?? "200px"
85
84
  },
86
85
  children: /* @__PURE__ */ t(
87
- M,
86
+ F,
88
87
  {
89
- onSearch: g,
88
+ onSearch: x,
90
89
  version: n === "3.0" ? "3.0" : "2.0"
91
90
  }
92
91
  )
93
92
  }
94
93
  ),
95
- /* @__PURE__ */ t(B, { width: i, version: n, children: (a ?? []).length > 0 && /* @__PURE__ */ t(
96
- _,
94
+ /* @__PURE__ */ t(q, { width: i, version: n, children: (f ?? []).length > 0 && /* @__PURE__ */ t(
95
+ M,
97
96
  {
98
97
  width: i ?? "200px",
99
- onDropdownItemClick: C,
100
- options: a,
98
+ onDropdownItemClick: b,
99
+ options: f,
101
100
  parents: [],
102
- allowParentSelection: F,
101
+ allowParentSelection: E,
103
102
  maxLevels: N,
104
103
  hideGroupLabel: O,
105
104
  currentLevel: 1,
106
105
  version: n
107
106
  }
108
107
  ) }),
109
- (a ?? []).length === 0 && /* @__PURE__ */ t(
110
- H,
108
+ (f ?? []).length === 0 && /* @__PURE__ */ t(
109
+ B,
111
110
  {
112
111
  style: { width: i ?? "200px" },
113
112
  version: n,
@@ -116,7 +115,7 @@ const W = ({
116
115
  {
117
116
  style: {
118
117
  fontSize: "12px",
119
- color: L.content.placeholder,
118
+ color: S.content.placeholder,
120
119
  lineHeight: "16px"
121
120
  },
122
121
  children: "No results found!"
@@ -129,8 +128,7 @@ const W = ({
129
128
  }
130
129
  )
131
130
  }
132
- ),
133
- m && /* @__PURE__ */ t(I, { children: m })
131
+ )
134
132
  ] })
135
133
  }
136
134
  )
@@ -138,6 +136,6 @@ const W = ({
138
136
  );
139
137
  };
140
138
  export {
141
- W as MultiLevelDropdown
139
+ U as MultiLevelDropdown
142
140
  };
143
141
  //# sourceMappingURL=MultiLevelDropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiLevelDropdown.js","sources":["../../../../src/components/multi-level-dropdown/MultiLevelDropdown.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\nimport { COLORS } from '@src/constants/Theme';\nimport { SearchBox } from '../dropdown/OpenedDropdown/components/searchbox/SearchBox';\nimport { Floater } from '../floater';\nimport { MenuList } from './MenuList';\nimport {\n\tDropdownContainer,\n\tFooterContainer,\n\tNoResultsContainer,\n\tOptionsContainer,\n} from './MultiLevelDropdown.styled';\nimport { MultiLevelDropdownOption, MultiLevelDropdownProps } from './type';\n\nexport const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({\n\toptions,\n\twidth,\n\tisSearchable,\n\tonDropdownItemClick,\n\trefElement,\n\ttopOffset,\n\tleftOffset,\n\tisDropdownOpen,\n\tonDropdownOutsideClick,\n\tallowParentSelection,\n\tmaxLevels,\n\thideGroupLabel,\n\tversion = '1.0',\n\tfooter,\n}) => {\n\tconst dropdownRef = React.useRef<HTMLDivElement>(null);\n\tconst [filteredOptions, setFilteredOptions] =\n\t\tuseState<MultiLevelDropdownOption[]>(options);\n\n\tconst search = (searchString: string) => {\n\t\tconst queue = Array.isArray(options) ? [...options] : [];\n\t\tconst result: MultiLevelDropdownOption[] = [];\n\n\t\twhile (queue.length > 0) {\n\t\t\tconst current = queue.shift();\n\t\t\tif (\n\t\t\t\tcurrent &&\n\t\t\t\tcurrent.label.toLowerCase().includes(searchString.toLowerCase())\n\t\t\t) {\n\t\t\t\tresult.push(current);\n\t\t\t}\n\t\t\tif (current && 'children' in current && current.children) {\n\t\t\t\tqueue.push(...current.children);\n\t\t\t} else if (current && 'options' in current && current.options) {\n\t\t\t\tqueue.push(...current.options);\n\t\t\t}\n\t\t}\n\n\t\tconst filterOptions = (options: MultiLevelDropdownOption[]) => {\n\t\t\treturn options\n\t\t\t\t.map((option: MultiLevelDropdownOption) => {\n\t\t\t\t\tif (result.includes(option)) {\n\t\t\t\t\t\treturn option;\n\t\t\t\t\t}\n\t\t\t\t\tif ('children' in option && option.children) {\n\t\t\t\t\t\tconst filteredChildren = filterOptions(\n\t\t\t\t\t\t\toption.children as MultiLevelDropdownOption[],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (filteredChildren.length > 0) {\n\t\t\t\t\t\t\treturn { ...option, children: filteredChildren };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ('options' in option && option.options) {\n\t\t\t\t\t\tconst filteredOptions = filterOptions(\n\t\t\t\t\t\t\toption.options as MultiLevelDropdownOption[],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (filteredOptions.length > 0) {\n\t\t\t\t\t\t\treturn { ...option, options: filteredOptions };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t})\n\t\t\t\t.filter((option) => option !== null);\n\t\t};\n\n\t\tsetFilteredOptions(filterOptions(options) as MultiLevelDropdownOption[]);\n\t};\n\n\tconst handleClickOutside = (event: MouseEvent) => {\n\t\tif (\n\t\t\tdropdownRef.current &&\n\t\t\t!dropdownRef.current.contains(event.target as Node)\n\t\t) {\n\t\t\tif (onDropdownOutsideClick) {\n\t\t\t\tonDropdownOutsideClick(true);\n\t\t\t}\n\t\t} else {\n\t\t\tif (onDropdownOutsideClick) {\n\t\t\t\tonDropdownOutsideClick(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tuseEffect(() => {\n\t\tif (isDropdownOpen) {\n\t\t\tsearch('');\n\t\t}\n\t}, [isDropdownOpen]);\n\n\tuseEffect(() => {\n\t\tdocument.addEventListener('mousedown', handleClickOutside);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', handleClickOutside);\n\t\t};\n\t}, []);\n\n\tuseEffect(() => {\n\t\tsetFilteredOptions(options);\n\t}, [options]);\n\n\treturn (\n\t\t<Floater\n\t\t\trefElement={refElement}\n\t\t\ttopOffset={topOffset}\n\t\t\tleftOffset={leftOffset}\n\t\t>\n\t\t\t{isDropdownOpen && (\n\t\t\t\t<div\n\t\t\t\t\tref={dropdownRef}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackgroundColor: COLORS.surface.standard,\n\t\t\t\t\t\tzIndex: 99999,\n\t\t\t\t\t\tborderRadius: version === '3.0' ? '4px' : '8px',\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tboxShadow: '0 2px 8px 0 rgba(0, 0, 0, 0.12)',\n\t\t\t\t\t\twhiteSpace: 'normal',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<DropdownContainer width={width} version={version}>\n\t\t\t\t\t\t{isSearchable && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tpadding: version === '3.0' ? '0px' : '4px',\n\t\t\t\t\t\t\t\t\twidth: width ?? '200px',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SearchBox\n\t\t\t\t\t\t\t\t\tonSearch={search}\n\t\t\t\t\t\t\t\t\tversion={version === '3.0' ? '3.0' : '2.0'}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<OptionsContainer width={width} version={version}>\n\t\t\t\t\t\t\t{(filteredOptions ?? []).length > 0 && (\n\t\t\t\t\t\t\t\t<MenuList\n\t\t\t\t\t\t\t\t\twidth={width ?? '200px'}\n\t\t\t\t\t\t\t\t\tonDropdownItemClick={onDropdownItemClick}\n\t\t\t\t\t\t\t\t\toptions={filteredOptions}\n\t\t\t\t\t\t\t\t\tparents={[]}\n\t\t\t\t\t\t\t\t\tallowParentSelection={allowParentSelection}\n\t\t\t\t\t\t\t\t\tmaxLevels={maxLevels}\n\t\t\t\t\t\t\t\t\thideGroupLabel={hideGroupLabel}\n\t\t\t\t\t\t\t\t\tcurrentLevel={1}\n\t\t\t\t\t\t\t\t\tversion={version}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</OptionsContainer>\n\n\t\t\t\t\t\t{(filteredOptions ?? []).length === 0 && (\n\t\t\t\t\t\t\t<NoResultsContainer\n\t\t\t\t\t\t\t\tstyle={{ width: width ?? '200px' }}\n\t\t\t\t\t\t\t\tversion={version}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{version === '3.0' ? (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: '12px',\n\t\t\t\t\t\t\t\t\t\t\tcolor: COLORS.content.placeholder,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight: '16px',\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tNo results found!\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<ZeroState\n\t\t\t\t\t\t\t\t\t\ttitle=\"No results found!\"\n\t\t\t\t\t\t\t\t\t\tsubTitle={`Sorry, we are unable to find any results for your search.`}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</NoResultsContainer>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{footer && <FooterContainer>{footer}</FooterContainer>}\n\t\t\t\t\t</DropdownContainer>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</Floater>\n\t);\n};\n"],"names":["MultiLevelDropdown","options","width","isSearchable","onDropdownItemClick","refElement","topOffset","leftOffset","isDropdownOpen","onDropdownOutsideClick","allowParentSelection","maxLevels","hideGroupLabel","version","footer","dropdownRef","React","filteredOptions","setFilteredOptions","useState","search","searchString","queue","result","current","filterOptions","option","filteredChildren","handleClickOutside","event","useEffect","jsx","Floater","COLORS","jsxs","DropdownContainer","SearchBox","OptionsContainer","MenuList","NoResultsContainer","ZeroState","FooterContainer"],"mappings":"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"}
1
+ {"version":3,"file":"MultiLevelDropdown.js","sources":["../../../../src/components/multi-level-dropdown/MultiLevelDropdown.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\nimport { COLORS } from '@src/constants/Theme';\nimport { SearchBox } from '../dropdown/OpenedDropdown/components/searchbox/SearchBox';\nimport { Floater } from '../floater';\nimport { MenuList } from './MenuList';\nimport {\n\tDropdownContainer,\n\tNoResultsContainer,\n\tOptionsContainer,\n} from './MultiLevelDropdown.styled';\nimport { MultiLevelDropdownOption, MultiLevelDropdownProps } from './type';\n\nexport const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({\n\toptions,\n\twidth,\n\tisSearchable,\n\tonDropdownItemClick,\n\trefElement,\n\ttopOffset,\n\tleftOffset,\n\tisDropdownOpen,\n\tonDropdownOutsideClick,\n\tallowParentSelection,\n\tmaxLevels,\n\thideGroupLabel,\n\tversion = '1.0',\n}) => {\n\tconst dropdownRef = React.useRef<HTMLDivElement>(null);\n\tconst [filteredOptions, setFilteredOptions] =\n\t\tuseState<MultiLevelDropdownOption[]>(options);\n\n\tconst search = (searchString: string) => {\n\t\tconst queue = Array.isArray(options) ? [...options] : [];\n\t\tconst result: MultiLevelDropdownOption[] = [];\n\n\t\twhile (queue.length > 0) {\n\t\t\tconst current = queue.shift();\n\t\t\tif (\n\t\t\t\tcurrent &&\n\t\t\t\tcurrent.label.toLowerCase().includes(searchString.toLowerCase())\n\t\t\t) {\n\t\t\t\tresult.push(current);\n\t\t\t}\n\t\t\tif (current && 'children' in current && current.children) {\n\t\t\t\tqueue.push(...current.children);\n\t\t\t} else if (current && 'options' in current && current.options) {\n\t\t\t\tqueue.push(...current.options);\n\t\t\t}\n\t\t}\n\n\t\tconst filterOptions = (options: MultiLevelDropdownOption[]) => {\n\t\t\treturn options\n\t\t\t\t.map((option: MultiLevelDropdownOption) => {\n\t\t\t\t\tif (result.includes(option)) {\n\t\t\t\t\t\treturn option;\n\t\t\t\t\t}\n\t\t\t\t\tif ('children' in option && option.children) {\n\t\t\t\t\t\tconst filteredChildren = filterOptions(\n\t\t\t\t\t\t\toption.children as MultiLevelDropdownOption[],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (filteredChildren.length > 0) {\n\t\t\t\t\t\t\treturn { ...option, children: filteredChildren };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ('options' in option && option.options) {\n\t\t\t\t\t\tconst filteredOptions = filterOptions(\n\t\t\t\t\t\t\toption.options as MultiLevelDropdownOption[],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (filteredOptions.length > 0) {\n\t\t\t\t\t\t\treturn { ...option, options: filteredOptions };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t})\n\t\t\t\t.filter((option) => option !== null);\n\t\t};\n\n\t\tsetFilteredOptions(filterOptions(options) as MultiLevelDropdownOption[]);\n\t};\n\n\tconst handleClickOutside = (event: MouseEvent) => {\n\t\tif (\n\t\t\tdropdownRef.current &&\n\t\t\t!dropdownRef.current.contains(event.target as Node)\n\t\t) {\n\t\t\tif (onDropdownOutsideClick) {\n\t\t\t\tonDropdownOutsideClick(true);\n\t\t\t}\n\t\t} else {\n\t\t\tif (onDropdownOutsideClick) {\n\t\t\t\tonDropdownOutsideClick(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tuseEffect(() => {\n\t\tif (isDropdownOpen) {\n\t\t\tsearch('');\n\t\t}\n\t}, [isDropdownOpen]);\n\n\tuseEffect(() => {\n\t\tdocument.addEventListener('mousedown', handleClickOutside);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', handleClickOutside);\n\t\t};\n\t}, []);\n\n\tuseEffect(() => {\n\t\tsetFilteredOptions(options);\n\t}, [options]);\n\n\treturn (\n\t\t<Floater\n\t\t\trefElement={refElement}\n\t\t\ttopOffset={topOffset}\n\t\t\tleftOffset={leftOffset}\n\t\t>\n\t\t\t{isDropdownOpen && (\n\t\t\t\t<div\n\t\t\t\t\tref={dropdownRef}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackgroundColor: COLORS.surface.standard,\n\t\t\t\t\t\tzIndex: 99999,\n\t\t\t\t\t\tborderRadius: version === '3.0' ? '4px' : '8px',\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tboxShadow: '0 2px 8px 0 rgba(0, 0, 0, 0.12)',\n\t\t\t\t\t\twhiteSpace: 'normal',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<DropdownContainer width={width} version={version}>\n\t\t\t\t\t\t{isSearchable && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tpadding: version === '3.0' ? '0px' : '4px',\n\t\t\t\t\t\t\t\t\twidth: width ?? '200px',\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SearchBox\n\t\t\t\t\t\t\t\t\tonSearch={search}\n\t\t\t\t\t\t\t\t\tversion={version === '3.0' ? '3.0' : '2.0'}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<OptionsContainer width={width} version={version}>\n\t\t\t\t\t\t\t{(filteredOptions ?? []).length > 0 && (\n\t\t\t\t\t\t\t\t<MenuList\n\t\t\t\t\t\t\t\t\twidth={width ?? '200px'}\n\t\t\t\t\t\t\t\t\tonDropdownItemClick={onDropdownItemClick}\n\t\t\t\t\t\t\t\t\toptions={filteredOptions}\n\t\t\t\t\t\t\t\t\tparents={[]}\n\t\t\t\t\t\t\t\t\tallowParentSelection={allowParentSelection}\n\t\t\t\t\t\t\t\t\tmaxLevels={maxLevels}\n\t\t\t\t\t\t\t\t\thideGroupLabel={hideGroupLabel}\n\t\t\t\t\t\t\t\t\tcurrentLevel={1}\n\t\t\t\t\t\t\t\t\tversion={version}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</OptionsContainer>\n\n\t\t\t\t\t\t{(filteredOptions ?? []).length === 0 && (\n\t\t\t\t\t\t\t<NoResultsContainer\n\t\t\t\t\t\t\t\tstyle={{ width: width ?? '200px' }}\n\t\t\t\t\t\t\t\tversion={version}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{version === '3.0' ? (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: '12px',\n\t\t\t\t\t\t\t\t\t\t\tcolor: COLORS.content.placeholder,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight: '16px',\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tNo results found!\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<ZeroState\n\t\t\t\t\t\t\t\t\t\ttitle=\"No results found!\"\n\t\t\t\t\t\t\t\t\t\tsubTitle={`Sorry, we are unable to find any results for your search.`}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</NoResultsContainer>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DropdownContainer>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</Floater>\n\t);\n};\n"],"names":["MultiLevelDropdown","options","width","isSearchable","onDropdownItemClick","refElement","topOffset","leftOffset","isDropdownOpen","onDropdownOutsideClick","allowParentSelection","maxLevels","hideGroupLabel","version","dropdownRef","React","filteredOptions","setFilteredOptions","useState","search","searchString","queue","result","current","filterOptions","option","filteredChildren","handleClickOutside","event","useEffect","jsx","Floater","COLORS","jsxs","DropdownContainer","SearchBox","OptionsContainer","MenuList","NoResultsContainer","ZeroState"],"mappings":";;;;;;;;AAaO,MAAMA,IAAwD,CAAC;AAAA,EACrE,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,SAAAC,IAAU;AACX,MAAM;AACL,QAAMC,IAAcC,EAAM,OAAuB,IAAI,GAC/C,CAACC,GAAiBC,CAAkB,IACzCC,EAAqCjB,CAAO,GAEvCkB,IAAS,CAACC,MAAyB;AACxC,UAAMC,IAAQ,MAAM,QAAQpB,CAAO,IAAI,CAAC,GAAGA,CAAO,IAAI,CAAA,GAChDqB,IAAqC,CAAA;AAE3C,WAAOD,EAAM,SAAS,KAAG;AACxB,YAAME,IAAUF,EAAM,MAAA;AACtB,MACCE,KACAA,EAAQ,MAAM,YAAA,EAAc,SAASH,EAAa,YAAA,CAAa,KAE/DE,EAAO,KAAKC,CAAO,GAEhBA,KAAW,cAAcA,KAAWA,EAAQ,WAC/CF,EAAM,KAAK,GAAGE,EAAQ,QAAQ,IACpBA,KAAW,aAAaA,KAAWA,EAAQ,WACrDF,EAAM,KAAK,GAAGE,EAAQ,OAAO;AAAA,IAE/B;AAEA,UAAMC,IAAgB,CAACvB,MACfA,EACL,IAAI,CAACwB,MAAqC;AAC1C,UAAIH,EAAO,SAASG,CAAM;AACzB,eAAOA;AAER,UAAI,cAAcA,KAAUA,EAAO,UAAU;AAC5C,cAAMC,IAAmBF;AAAA,UACxBC,EAAO;AAAA,QAAA;AAER,YAAIC,EAAiB,SAAS;AAC7B,iBAAO,EAAE,GAAGD,GAAQ,UAAUC,EAAA;AAAA,MAEhC;AACA,UAAI,aAAaD,KAAUA,EAAO,SAAS;AAC1C,cAAMT,IAAkBQ;AAAA,UACvBC,EAAO;AAAA,QAAA;AAER,YAAIT,EAAgB,SAAS;AAC5B,iBAAO,EAAE,GAAGS,GAAQ,SAAST,EAAAA;AAAAA,MAE/B;AACA,aAAO;AAAA,IACR,CAAC,EACA,OAAO,CAACS,MAAWA,MAAW,IAAI;AAGrC,IAAAR,EAAmBO,EAAcvB,CAAO,CAA+B;AAAA,EACxE,GAEM0B,IAAqB,CAACC,MAAsB;AACjD,IACCd,EAAY,WACZ,CAACA,EAAY,QAAQ,SAASc,EAAM,MAAc,IAE9CnB,KACHA,EAAuB,EAAI,IAGxBA,KACHA,EAAuB,EAAK;AAAA,EAG/B;AAEA,SAAAoB,EAAU,MAAM;AACf,IAAIrB,KACHW,EAAO,EAAE;AAAA,EAEX,GAAG,CAACX,CAAc,CAAC,GAEnBqB,EAAU,OACT,SAAS,iBAAiB,aAAaF,CAAkB,GAClD,MAAM;AACZ,aAAS,oBAAoB,aAAaA,CAAkB;AAAA,EAC7D,IACE,CAAA,CAAE,GAELE,EAAU,MAAM;AACf,IAAAZ,EAAmBhB,CAAO;AAAA,EAC3B,GAAG,CAACA,CAAO,CAAC,GAGX,gBAAA6B;AAAA,IAACC;AAAA,IAAA;AAAA,MACA,YAAA1B;AAAA,MACA,WAAAC;AAAA,MACA,YAAAC;AAAA,MAEC,UAAAC,KACA,gBAAAsB;AAAA,QAAC;AAAA,QAAA;AAAA,UACA,KAAKhB;AAAA,UACL,OAAO;AAAA,YACN,iBAAiBkB,EAAO,QAAQ;AAAA,YAChC,QAAQ;AAAA,YACR,cAAcnB,MAAY,QAAQ,QAAQ;AAAA,YAC1C,UAAU;AAAA,YACV,WAAW;AAAA,YACX,YAAY;AAAA,UAAA;AAAA,UAGb,UAAA,gBAAAoB,EAACC,GAAA,EAAkB,OAAAhC,GAAc,SAAAW,GAC/B,UAAA;AAAA,YAAAV,KACA,gBAAA2B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACA,OAAO;AAAA,kBACN,SAASjB,MAAY,QAAQ,QAAQ;AAAA,kBACrC,OAAOX,KAAS;AAAA,gBAAA;AAAA,gBAGjB,UAAA,gBAAA4B;AAAA,kBAACK;AAAA,kBAAA;AAAA,oBACA,UAAUhB;AAAA,oBACV,SAASN,MAAY,QAAQ,QAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACtC;AAAA,YAAA;AAAA,YAGF,gBAAAiB,EAACM,KAAiB,OAAAlC,GAAc,SAAAW,GAC7B,gBAAmB,CAAA,GAAI,SAAS,KACjC,gBAAAiB;AAAA,cAACO;AAAA,cAAA;AAAA,gBACA,OAAOnC,KAAS;AAAA,gBAChB,qBAAAE;AAAA,gBACA,SAASY;AAAA,gBACT,SAAS,CAAA;AAAA,gBACT,sBAAAN;AAAA,gBACA,WAAAC;AAAA,gBACA,gBAAAC;AAAA,gBACA,cAAc;AAAA,gBACd,SAAAC;AAAA,cAAA;AAAA,YAAA,GAGH;AAAA,aAEEG,KAAmB,CAAA,GAAI,WAAW,KACnC,gBAAAc;AAAA,cAACQ;AAAA,cAAA;AAAA,gBACA,OAAO,EAAE,OAAOpC,KAAS,QAAA;AAAA,gBACzB,SAAAW;AAAA,gBAEC,gBAAY,QACZ,gBAAAiB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACA,OAAO;AAAA,sBACN,UAAU;AAAA,sBACV,OAAOE,EAAO,QAAQ;AAAA,sBACtB,YAAY;AAAA,oBAAA;AAAA,oBAEb,UAAA;AAAA,kBAAA;AAAA,gBAAA,IAID,gBAAAF;AAAA,kBAACS;AAAA,kBAAA;AAAA,oBACA,OAAM;AAAA,oBACN,UAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACX;AAAA,YAAA;AAAA,UAEF,EAAA,CAEF;AAAA,QAAA;AAAA,MAAA;AAAA,IACD;AAAA,EAAA;AAIJ;"}
@@ -11,9 +11,6 @@ export declare const OptionsContainer: import('styled-components/dist/types').IS
11
11
  width?: string | undefined;
12
12
  version?: "1.0" | "2.0" | "3.0" | undefined;
13
13
  }>> & string;
14
- export declare const FooterContainer: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
15
- style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
16
- }> & string;
17
14
  export declare const NoResultsContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Merged<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
18
15
  style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
19
16
  }, {
@@ -15,29 +15,20 @@ const c = n.div`
15
15
  width: 0px;
16
16
  }
17
17
  `, l = n.div`
18
- /* Own stacking context, otherwise the option rows' text paints over the
19
- upward shadow and it disappears. */
20
- position: relative;
21
- z-index: 1;
22
- padding: 8px;
23
- background-color: ${e.surface.standard};
24
- border-top: 1px solid ${e.stroke.primary};
25
- box-shadow: 0 -2px 8px 0 rgba(0, 0, 0, 0.12);
26
- `, u = n.div`
27
18
  margin-top: ${({ version: t }) => t === "3.0" ? 0 : 64}px;
28
19
  height: ${({ version: t }) => t === "3.0" ? 236 : 200}px;
29
20
  width: ${({ width: t }) => t || "200px"};
30
21
  display: ${({ version: t }) => t === "3.0" ? "flex" : "block"};
31
22
  align-items: center;
32
23
  justify-content: center;
33
- `, g = n.div`
24
+ `, u = n.div`
34
25
  width: 100%;
35
26
  justify-content: center;
36
27
  cursor: pointer;
37
28
  align-items: center;
38
29
  justify-content: space-between;
39
30
  margin: ${({ version: t }) => t === "3.0" ? "0" : "4px 0"};
40
- `, h = n.div`
31
+ `, g = n.div`
41
32
  z-index: 1000;
42
33
  position: relative;
43
34
  margin: 0px;
@@ -52,7 +43,7 @@ const c = n.div`
52
43
  &:focus-within > .submenu {
53
44
  display: block;
54
45
  }
55
- `, f = n.div`
46
+ `, h = n.div`
56
47
  position: relative;
57
48
  padding: ${({ version: t }) => t === "3.0" ? "8px" : "4px 8px"};
58
49
  transition: background-color 0.2s;
@@ -74,7 +65,7 @@ const c = n.div`
74
65
  &:hover {
75
66
  background-color: ${({ isSelected: t, isDisabled: i, version: o }) => i ? e.surface.standard : t ? o === "3.0" ? e.background.brandLight : e.background.positive.light : e.surface.hovered};
76
67
  }
77
- `, v = n.div`
68
+ `, f = n.div`
78
69
  display: flex;
79
70
  align-items: center;
80
71
  gap: 8px;
@@ -95,7 +86,7 @@ const c = n.div`
95
86
  &::-webkit-scrollbar {
96
87
  display: none;
97
88
  }
98
- `, w = n.div`
89
+ `, v = n.div`
99
90
  width: 16px;
100
91
  height: 16px;
101
92
  display: flex;
@@ -109,26 +100,25 @@ const c = n.div`
109
100
  align-items: center;
110
101
  justify-content: center;
111
102
  margin-left: 4px;
112
- `, y = n.div`
103
+ `, w = n.div`
113
104
  width: ${(t) => t.width};
114
- `, k = n(p)`
105
+ `, y = n(p)`
115
106
  width: ${(t) => t.width};
116
107
  top: ${(t) => t.top}px;
117
108
  left: ${(t) => t.left}px;
118
109
  `;
119
110
  export {
120
- v as ContentContainer,
111
+ f as ContentContainer,
121
112
  c as DropdownContainer,
122
- l as FooterContainer,
123
- g as GroupedMenuListContainer,
124
- w as LeadingIconContainer,
125
- f as MenuItemContainer,
113
+ u as GroupedMenuListContainer,
114
+ v as LeadingIconContainer,
115
+ h as MenuItemContainer,
126
116
  b as MenuItemWrapper,
127
- u as NoResultsContainer,
117
+ l as NoResultsContainer,
128
118
  x as OptionsContainer,
129
- h as StyledMenuList,
130
- k as StyledSubMenuWrapper,
131
- y as SubMenuContainer,
119
+ g as StyledMenuList,
120
+ y as StyledSubMenuWrapper,
121
+ w as SubMenuContainer,
132
122
  m as SubMenuListContainer,
133
123
  p as SubMenuWrapper,
134
124
  $ as TrailingIconContainer
@@ -1 +1 @@
1
- {"version":3,"file":"MultiLevelDropdown.styled.js","sources":["../../../../src/components/multi-level-dropdown/MultiLevelDropdown.styled.tsx"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\n\nexport const DropdownContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tposition: relative;\n\tborder-radius: ${({ version }) => (version === '3.0' ? 4 : 8)}px;\n\tbox-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.12);\n\tpadding-bottom: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n`;\n\nexport const OptionsContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\twidth: ${({ width }) => (width ? width : '200px')};\n\tmax-width: 300px;\n\tmax-height: 280px;\n\toverflow-y: scroll;\n\tpadding: ${({ version }) => (version === '3.0' ? '0' : '4px 0 0')};\n\t&::-webkit-scrollbar {\n\t\twidth: 0px;\n\t}\n`;\n\n// Sits outside OptionsContainer so it stays put while the options scroll. The\n// upward shadow lifts it off the list the way the design's z1 elevation does.\nexport const FooterContainer = styled.div`\n\t/* Own stacking context, otherwise the option rows' text paints over the\n\t upward shadow and it disappears. */\n\tposition: relative;\n\tz-index: 1;\n\tpadding: 8px;\n\tbackground-color: ${COLORS.surface.standard};\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n\tbox-shadow: 0 -2px 8px 0 rgba(0, 0, 0, 0.12);\n`;\n\nexport const NoResultsContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tmargin-top: ${({ version }) => (version === '3.0' ? 0 : 64)}px;\n\theight: ${({ version }) => (version === '3.0' ? 236 : 200)}px;\n\twidth: ${({ width }) => (width ? width : '200px')};\n\tdisplay: ${({ version }) => (version === '3.0' ? 'flex' : 'block')};\n\talign-items: center;\n\tjustify-content: center;\n`;\n\nexport const GroupedMenuListContainer = styled.div<{\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\twidth: 100%;\n\tjustify-content: center;\n\tcursor: pointer;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin: ${({ version }) => (version === '3.0' ? '0' : '4px 0')};\n`;\n\nexport const StyledMenuList = styled.div`\n\tz-index: 1000;\n\tposition: relative;\n\tmargin: 0px;\n\tpadding: 0px;\n\twidth: 100%;\n`;\n\nexport const MenuItemWrapper = styled.div<{ version?: '1.0' | '2.0' | '3.0' }>`\n\tposition: relative;\n\tpadding: ${({ version }) => (version === '3.0' ? '0px' : '1px 4px')};\n\tcursor: pointer;\n\twidth: 100%;\n\t&:hover > .submenu,\n\t&:focus-within > .submenu {\n\t\tdisplay: block;\n\t}\n`;\n\nexport interface MenuItemContainerProps {\n\tisSelected?: boolean;\n\tisHovered?: boolean;\n\tisSubMenuOpen?: boolean;\n\tisDisabled?: boolean;\n\tversion?: '1.0' | '2.0' | '3.0';\n}\n\nexport const MenuItemContainer = styled.div<MenuItemContainerProps>`\n\tposition: relative;\n\tpadding: ${({ version }) => (version === '3.0' ? '8px' : '4px 8px')};\n\ttransition: background-color 0.2s;\n\twidth: 100%;\n\tborder-radius: ${({ version }) => (version === '3.0' ? 0 : 8)}px;\n\tjustify-content: center;\n\tbackground-color: ${({\n\t\tisSelected,\n\t\tisHovered,\n\t\tisSubMenuOpen,\n\t\tisDisabled,\n\t\tversion,\n\t}) =>\n\t\tisDisabled\n\t\t\t? COLORS.surface.standard\n\t\t\t: isSelected || isSubMenuOpen\n\t\t\t? version === '3.0'\n\t\t\t\t? COLORS.background.brandLight\n\t\t\t\t: COLORS.background.positive.light\n\t\t\t: isHovered\n\t\t\t? COLORS.surface.hovered\n\t\t\t: COLORS.surface.standard};\n\tcolor: ${({ isSelected, isSubMenuOpen, version }) =>\n\t\tisSelected || isSubMenuOpen\n\t\t\t? version === '3.0'\n\t\t\t\t? COLORS.text.primary\n\t\t\t\t: COLORS.content.positive\n\t\t\t: COLORS.content.primary};\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\n\t&:hover {\n\t\tbackground-color: ${({ isSelected, isDisabled, version }) =>\n\t\t\tisDisabled\n\t\t\t\t? COLORS.surface.standard\n\t\t\t\t: isSelected\n\t\t\t\t? version === '3.0'\n\t\t\t\t\t? COLORS.background.brandLight\n\t\t\t\t\t: COLORS.background.positive.light\n\t\t\t\t: COLORS.surface.hovered};\n\t}\n`;\n\nexport const ContentContainer = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nexport const SubMenuWrapper = styled.div`\n\tz-index: 1001;\n\tposition: fixed;\n\tborder-left: 4px solid transparent;\n`;\n\nexport const SubMenuListContainer = styled.div<{\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tmargin: 4px;\n\tbackground-color: ${COLORS.surface.standard};\n\tbox-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.12);\n\tborder-radius: ${({ version }) => (version === '3.0' ? 4 : 8)}px;\n\tpadding-top: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n\tmax-height: 480px;\n\tpadding-bottom: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n\toverflow-y: scroll;\n\n\t&::-webkit-scrollbar {\n\t\tdisplay: none;\n\t}\n`;\n\nexport const LeadingIconContainer = styled.div`\n\twidth: 16px;\n\theight: 16px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-right: 4px;\n`;\n\nexport const TrailingIconContainer = styled.div`\n\twidth: 16px;\n\theight: 16px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-left: 4px;\n`;\n\nexport const SubMenuContainer = styled.div<{ width: string }>`\n\twidth: ${(props) => props.width};\n`;\n\nexport const StyledSubMenuWrapper = styled(SubMenuWrapper)<{\n\twidth: string;\n\ttop: number;\n\tleft: number;\n}>`\n\twidth: ${(props) => props.width};\n\ttop: ${(props) => props.top}px;\n\tleft: ${(props) => props.left}px;\n`;\n"],"names":["DropdownContainer","styled","version","OptionsContainer","width","FooterContainer","COLORS","NoResultsContainer","GroupedMenuListContainer","StyledMenuList","MenuItemWrapper","MenuItemContainer","isSelected","isHovered","isSubMenuOpen","isDisabled","ContentContainer","SubMenuWrapper","SubMenuListContainer","LeadingIconContainer","TrailingIconContainer","SubMenuContainer","props","StyledSubMenuWrapper"],"mappings":"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"}
1
+ {"version":3,"file":"MultiLevelDropdown.styled.js","sources":["../../../../src/components/multi-level-dropdown/MultiLevelDropdown.styled.tsx"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\n\nexport const DropdownContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tposition: relative;\n\tborder-radius: ${({ version }) => (version === '3.0' ? 4 : 8)}px;\n\tbox-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.12);\n\tpadding-bottom: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n`;\n\nexport const OptionsContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\twidth: ${({ width }) => (width ? width : '200px')};\n\tmax-width: 300px;\n\tmax-height: 280px;\n\toverflow-y: scroll;\n\tpadding: ${({ version }) => (version === '3.0' ? '0' : '4px 0 0')};\n\t&::-webkit-scrollbar {\n\t\twidth: 0px;\n\t}\n`;\n\nexport const NoResultsContainer = styled.div<{\n\twidth?: string;\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tmargin-top: ${({ version }) => (version === '3.0' ? 0 : 64)}px;\n\theight: ${({ version }) => (version === '3.0' ? 236 : 200)}px;\n\twidth: ${({ width }) => (width ? width : '200px')};\n\tdisplay: ${({ version }) => (version === '3.0' ? 'flex' : 'block')};\n\talign-items: center;\n\tjustify-content: center;\n`;\n\nexport const GroupedMenuListContainer = styled.div<{\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\twidth: 100%;\n\tjustify-content: center;\n\tcursor: pointer;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin: ${({ version }) => (version === '3.0' ? '0' : '4px 0')};\n`;\n\nexport const StyledMenuList = styled.div`\n\tz-index: 1000;\n\tposition: relative;\n\tmargin: 0px;\n\tpadding: 0px;\n\twidth: 100%;\n`;\n\nexport const MenuItemWrapper = styled.div<{ version?: '1.0' | '2.0' | '3.0' }>`\n\tposition: relative;\n\tpadding: ${({ version }) => (version === '3.0' ? '0px' : '1px 4px')};\n\tcursor: pointer;\n\twidth: 100%;\n\t&:hover > .submenu,\n\t&:focus-within > .submenu {\n\t\tdisplay: block;\n\t}\n`;\n\nexport interface MenuItemContainerProps {\n\tisSelected?: boolean;\n\tisHovered?: boolean;\n\tisSubMenuOpen?: boolean;\n\tisDisabled?: boolean;\n\tversion?: '1.0' | '2.0' | '3.0';\n}\n\nexport const MenuItemContainer = styled.div<MenuItemContainerProps>`\n\tposition: relative;\n\tpadding: ${({ version }) => (version === '3.0' ? '8px' : '4px 8px')};\n\ttransition: background-color 0.2s;\n\twidth: 100%;\n\tborder-radius: ${({ version }) => (version === '3.0' ? 0 : 8)}px;\n\tjustify-content: center;\n\tbackground-color: ${({\n\t\tisSelected,\n\t\tisHovered,\n\t\tisSubMenuOpen,\n\t\tisDisabled,\n\t\tversion,\n\t}) =>\n\t\tisDisabled\n\t\t\t? COLORS.surface.standard\n\t\t\t: isSelected || isSubMenuOpen\n\t\t\t? version === '3.0'\n\t\t\t\t? COLORS.background.brandLight\n\t\t\t\t: COLORS.background.positive.light\n\t\t\t: isHovered\n\t\t\t? COLORS.surface.hovered\n\t\t\t: COLORS.surface.standard};\n\tcolor: ${({ isSelected, isSubMenuOpen, version }) =>\n\t\tisSelected || isSubMenuOpen\n\t\t\t? version === '3.0'\n\t\t\t\t? COLORS.text.primary\n\t\t\t\t: COLORS.content.positive\n\t\t\t: COLORS.content.primary};\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\n\t&:hover {\n\t\tbackground-color: ${({ isSelected, isDisabled, version }) =>\n\t\t\tisDisabled\n\t\t\t\t? COLORS.surface.standard\n\t\t\t\t: isSelected\n\t\t\t\t? version === '3.0'\n\t\t\t\t\t? COLORS.background.brandLight\n\t\t\t\t\t: COLORS.background.positive.light\n\t\t\t\t: COLORS.surface.hovered};\n\t}\n`;\n\nexport const ContentContainer = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n`;\n\nexport const SubMenuWrapper = styled.div`\n\tz-index: 1001;\n\tposition: fixed;\n\tborder-left: 4px solid transparent;\n`;\n\nexport const SubMenuListContainer = styled.div<{\n\tversion?: '1.0' | '2.0' | '3.0';\n}>`\n\tmargin: 4px;\n\tbackground-color: ${COLORS.surface.standard};\n\tbox-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.12);\n\tborder-radius: ${({ version }) => (version === '3.0' ? 4 : 8)}px;\n\tpadding-top: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n\tmax-height: 480px;\n\tpadding-bottom: ${({ version }) => (version === '3.0' ? 0 : 4)}px;\n\toverflow-y: scroll;\n\n\t&::-webkit-scrollbar {\n\t\tdisplay: none;\n\t}\n`;\n\nexport const LeadingIconContainer = styled.div`\n\twidth: 16px;\n\theight: 16px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-right: 4px;\n`;\n\nexport const TrailingIconContainer = styled.div`\n\twidth: 16px;\n\theight: 16px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-left: 4px;\n`;\n\nexport const SubMenuContainer = styled.div<{ width: string }>`\n\twidth: ${(props) => props.width};\n`;\n\nexport const StyledSubMenuWrapper = styled(SubMenuWrapper)<{\n\twidth: string;\n\ttop: number;\n\tleft: number;\n}>`\n\twidth: ${(props) => props.width};\n\ttop: ${(props) => props.top}px;\n\tleft: ${(props) => props.left}px;\n`;\n"],"names":["DropdownContainer","styled","version","OptionsContainer","width","NoResultsContainer","GroupedMenuListContainer","StyledMenuList","MenuItemWrapper","MenuItemContainer","isSelected","isHovered","isSubMenuOpen","isDisabled","COLORS","ContentContainer","SubMenuWrapper","SubMenuListContainer","LeadingIconContainer","TrailingIconContainer","SubMenuContainer","props","StyledSubMenuWrapper"],"mappings":";;AAGO,MAAMA,IAAoBC,EAAO;AAAA;AAAA,kBAKtB,CAAC,EAAE,SAAAC,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA;AAAA,mBAE3C,CAAC,EAAE,SAAAA,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA,GAGlDC,IAAmBF,EAAO;AAAA,UAI7B,CAAC,EAAE,OAAAG,EAAA,MAAaA,KAAgB,OAAQ;AAAA;AAAA;AAAA;AAAA,YAItC,CAAC,EAAE,SAAAF,EAAA,MAAeA,MAAY,QAAQ,MAAM,SAAU;AAAA;AAAA;AAAA;AAAA,GAMrDG,IAAqBJ,EAAO;AAAA,eAI1B,CAAC,EAAE,SAAAC,EAAA,MAAeA,MAAY,QAAQ,IAAI,EAAG;AAAA,WACjD,CAAC,EAAE,SAAAA,EAAA,MAAeA,MAAY,QAAQ,MAAM,GAAI;AAAA,UACjD,CAAC,EAAE,OAAAE,EAAA,MAAaA,KAAgB,OAAQ;AAAA,YACtC,CAAC,EAAE,SAAAF,EAAA,MAAeA,MAAY,QAAQ,SAAS,OAAQ;AAAA;AAAA;AAAA,GAKtDI,IAA2BL,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAQpC,CAAC,EAAE,SAAAC,EAAA,MAAeA,MAAY,QAAQ,MAAM,OAAQ;AAAA,GAGlDK,IAAiBN,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQxBO,IAAkBP,EAAO;AAAA;AAAA,YAE1B,CAAC,EAAE,SAAAC,EAAA,MAAeA,MAAY,QAAQ,QAAQ,SAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAiBvDO,IAAoBR,EAAO;AAAA;AAAA,YAE5B,CAAC,EAAE,SAAAC,EAAA,MAAeA,MAAY,QAAQ,QAAQ,SAAU;AAAA;AAAA;AAAA,kBAGlD,CAAC,EAAE,SAAAA,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA;AAAA,qBAEzC,CAAC;AAAA,EACpB,YAAAQ;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAX;AACD,MACCW,IACGC,EAAO,QAAQ,WACfJ,KAAcE,IACdV,MAAY,QACXY,EAAO,WAAW,aAClBA,EAAO,WAAW,SAAS,QAC5BH,IACAG,EAAO,QAAQ,UACfA,EAAO,QAAQ,QAAQ;AAAA,UAClB,CAAC,EAAE,YAAAJ,GAAY,eAAAE,GAAe,SAAAV,EAAA,MACtCQ,KAAcE,IACXV,MAAY,QACXY,EAAO,KAAK,UACZA,EAAO,QAAQ,WAChBA,EAAO,QAAQ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAML,CAAC,EAAE,YAAAJ,GAAY,YAAAG,GAAY,SAAAX,QAC9CW,IACGC,EAAO,QAAQ,WACfJ,IACAR,MAAY,QACXY,EAAO,WAAW,aAClBA,EAAO,WAAW,SAAS,QAC5BA,EAAO,QAAQ,OAAO;AAAA;AAAA,GAIfC,IAAmBd,EAAO;AAAA;AAAA;AAAA;AAAA,GAM1Be,IAAiBf,EAAO;AAAA;AAAA;AAAA;AAAA,GAMxBgB,IAAuBhB,EAAO;AAAA;AAAA,qBAItBa,EAAO,QAAQ,QAAQ;AAAA;AAAA,kBAE1B,CAAC,EAAE,SAAAZ,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA,gBAC9C,CAAC,EAAE,SAAAA,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA;AAAA,mBAEzC,CAAC,EAAE,SAAAA,EAAA,MAAeA,MAAY,QAAQ,IAAI,CAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQlDgB,IAAuBjB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAS9BkB,IAAwBlB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAS/BmB,IAAmBnB,EAAO;AAAA,UAC7B,CAACoB,MAAUA,EAAM,KAAK;AAAA,GAGnBC,IAAuBrB,EAAOe,CAAc;AAAA,UAK/C,CAACK,MAAUA,EAAM,KAAK;AAAA,QACxB,CAACA,MAAUA,EAAM,GAAG;AAAA,SACnB,CAACA,MAAUA,EAAM,IAAI;AAAA;"}
@@ -9,11 +9,6 @@ export interface MultiLevelDropdownProps extends FloaterProps {
9
9
  maxLevels?: number;
10
10
  hideGroupLabel?: boolean;
11
11
  version?: '1.0' | '2.0' | '3.0';
12
- /**
13
- * Pinned below the options list, outside the scroll area — for actions that
14
- * must stay reachable however long the list is, e.g. "+ New label".
15
- */
16
- footer?: ReactNode;
17
12
  onDropdownOutsideClick?: (isOutsideClick: any) => void;
18
13
  onDropdownItemClick?: (option: MultiLevelDropdownOption, parents: MultiLevelDropdownOption[]) => void;
19
14
  }