@servicetitan/anvil2-ext-atlas 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/{artifact-card-up-tMTrn.js → artifact-card-CviyzgR9.js} +23 -3
- package/dist/artifact-card-CviyzgR9.js.map +1 -0
- package/dist/artifact-card.js +1 -1
- package/dist/artifact-panel-CNzdjBT8.js.map +1 -1
- package/dist/artifact-panel-layout-sm-DM-lO.js.map +1 -1
- package/dist/atlas-header-DtYEZIyx.js.map +1 -1
- package/dist/chat-composer-rich-BXkSuUJL.js.map +1 -1
- package/dist/chat-composer-rich.css +2 -3
- package/dist/chat-window-Eh0GzLcm.js.map +1 -1
- package/dist/content-DGEN1Tcq.js.map +1 -1
- package/dist/header-CZ2pSpzC.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infinite-content-CUXfEs3y.js.map +1 -1
- package/dist/loader-Cj2z0xxN.js.map +1 -1
- package/dist/markdown-text-BcCCdMfH.js.map +1 -1
- package/dist/notification-card-DizmzaUo.js.map +1 -1
- package/dist/pulse-loader-DcrQsZeD.js.map +1 -1
- package/dist/single-recommendation-card-BPbfhvu_.js.map +1 -1
- package/dist/suggestion-BQxfnBot.js.map +1 -1
- package/dist/toolbox-2IgmOZuu.js.map +1 -1
- package/dist/user-message-D1KrKgfD.js.map +1 -1
- package/dist/welcome-aZxbV1rc.js.map +1 -1
- package/package.json +5 -5
- package/dist/artifact-card-up-tMTrn.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-panel-layout-sm-DM-lO.js","sources":["../src/components/artifact-panel-layout/artifact-panel-layout.tsx"],"sourcesContent":["import {\n ComponentPropsWithoutRef,\n ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { useMergeRefs } from \"@servicetitan/anvil2\";\n\nimport { getRemInPx } from \"../../utils/get-rem-in-px\";\nimport {\n ArtifactPanelLayoutModeContext,\n ArtifactPanelLayoutRegistrationContext,\n ArtifactPanelMode,\n RegisteredPanel,\n} from \"./context\";\nimport styles from \"./artifact-panel-layout.module.scss\";\n\n/**\n * Minimum width the chat content needs to remain usable. Below this threshold,\n * panels switch from inline to overlay mode so the chat keeps room.\n */\nconst CHAT_MIN_REM = 20;\n\n/**\n * Props for the ArtifactPanelLayout component\n * @property {ReactNode} children - The chat content and any nested ArtifactPanel components.\n * @extends ComponentPropsWithoutRef<\"div\">\n */\nexport type ArtifactPanelLayoutProps = ComponentPropsWithoutRef<\"div\"> & {\n children: ReactNode;\n};\n\n/**\n * ArtifactPanelLayout is the row container that orchestrates the responsive\n * behavior of nested ArtifactPanel components. It establishes the\n * positioning context and decides whether each registered panel sits inline\n * (as a flex sibling of the chat content) or floats as an overlay when there\n * is not enough room.\n *\n * Features:\n * - Establishes a positioned flex row that holds chat content and ArtifactPanel siblings\n * - Tracks each registered panel's width via context so the layout can react to drag-to-resize and multi-panel scenarios as they land\n * - Observes its own width via ResizeObserver and recomputes modes when the available space changes\n * - Reverse-engineers the threshold from a chat-content minimum width: panels go inline only when the chat would still have at least 20rem of room\n *\n * @example\n * <ArtifactPanelLayout>\n * <Content itemsLength={messages.length}>{messages}</Content>\n * <ArtifactPanel\n * isOpen={open}\n * onOpenChange={setOpen}\n * title=\"Supplemental info\"\n * >\n * {content}\n * </ArtifactPanel>\n * </ArtifactPanelLayout>\n */\nexport const ArtifactPanelLayout = forwardRef<\n HTMLDivElement,\n ArtifactPanelLayoutProps\n>(function ArtifactPanelLayoutInner(props, ref) {\n const { children, className, ...rest } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRef = useMergeRefs([ref, containerRef]);\n\n const [containerWidth, setContainerWidth] = useState(0);\n const [panels, setPanels] = useState<Record<string, RegisteredPanel>>({});\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n setContainerWidth(el.clientWidth);\n const observer = new ResizeObserver(([entry]) => {\n setContainerWidth(entry.contentRect.width);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n const registerPanel = useCallback((id: string, panel: RegisteredPanel) => {\n setPanels((prev) => ({ ...prev, [id]: panel }));\n }, []);\n\n const unregisterPanel = useCallback((id: string) => {\n setPanels((prev) => {\n if (!(id in prev)) return prev;\n const next = { ...prev };\n delete next[id];\n return next;\n });\n }, []);\n\n const modes = useMemo<Record<string, ArtifactPanelMode>>(() => {\n const chatMinPx = CHAT_MIN_REM * getRemInPx();\n const totalInlineWidth = Object.values(panels).reduce(\n (sum, p) => sum + p.width,\n 0,\n );\n const allInlineFits = containerWidth - totalInlineWidth >= chatMinPx;\n const result: Record<string, ArtifactPanelMode> = {};\n if (allInlineFits) {\n Object.keys(panels).forEach((id) => {\n result[id] = \"inline\";\n });\n return result;\n }\n // Per-panel decision when not all panels fit inline together. Each panel\n // goes overlay if it alone would push the chat below the threshold. Once\n // a left panel ships, this is the place to add a collapse priority so a\n // single panel can overlay first instead of collapsing both.\n Object.entries(panels).forEach(([id, panel]) => {\n result[id] =\n containerWidth - panel.width >= chatMinPx ? \"inline\" : \"overlay\";\n });\n return result;\n }, [containerWidth, panels]);\n\n // Registration API is stable across renders so panels can safely depend on\n // it in a useEffect without triggering re-registration loops when the\n // mode-context value updates.\n const registrationValue = useMemo(\n () => ({ registerPanel, unregisterPanel }),\n [registerPanel, unregisterPanel],\n );\n\n // Mode API updates whenever the computed modes map changes. Panels reading\n // from this context re-render to pick up their new mode.\n const modeValue = useMemo(\n () => ({\n getMode: (id: string): ArtifactPanelMode => modes[id] ?? \"inline\",\n }),\n [modes],\n );\n\n const layoutClassName = classNames(styles.layout, className);\n\n return (\n <ArtifactPanelLayoutRegistrationContext.Provider value={registrationValue}>\n <ArtifactPanelLayoutModeContext.Provider value={modeValue}>\n <div ref={mergedRef} className={layoutClassName} {...rest}>\n {children}\n </div>\n </ArtifactPanelLayoutModeContext.Provider>\n </ArtifactPanelLayoutRegistrationContext.Provider>\n );\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"artifact-panel-layout-sm-DM-lO.js","sources":["../src/components/artifact-panel-layout/artifact-panel-layout.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { useMergeRefs } from \"@servicetitan/anvil2\";\n\nimport { getRemInPx } from \"../../utils/get-rem-in-px\";\nimport {\n ArtifactPanelLayoutModeContext,\n ArtifactPanelLayoutRegistrationContext,\n type ArtifactPanelMode,\n type RegisteredPanel,\n} from \"./context\";\nimport styles from \"./artifact-panel-layout.module.scss\";\n\n/**\n * Minimum width the chat content needs to remain usable. Below this threshold,\n * panels switch from inline to overlay mode so the chat keeps room.\n */\nconst CHAT_MIN_REM = 20;\n\n/**\n * Props for the ArtifactPanelLayout component\n * @property {ReactNode} children - The chat content and any nested ArtifactPanel components.\n * @extends ComponentPropsWithoutRef<\"div\">\n */\nexport type ArtifactPanelLayoutProps = ComponentPropsWithoutRef<\"div\"> & {\n children: ReactNode;\n};\n\n/**\n * ArtifactPanelLayout is the row container that orchestrates the responsive\n * behavior of nested ArtifactPanel components. It establishes the\n * positioning context and decides whether each registered panel sits inline\n * (as a flex sibling of the chat content) or floats as an overlay when there\n * is not enough room.\n *\n * Features:\n * - Establishes a positioned flex row that holds chat content and ArtifactPanel siblings\n * - Tracks each registered panel's width via context so the layout can react to drag-to-resize and multi-panel scenarios as they land\n * - Observes its own width via ResizeObserver and recomputes modes when the available space changes\n * - Reverse-engineers the threshold from a chat-content minimum width: panels go inline only when the chat would still have at least 20rem of room\n *\n * @example\n * <ArtifactPanelLayout>\n * <Content itemsLength={messages.length}>{messages}</Content>\n * <ArtifactPanel\n * isOpen={open}\n * onOpenChange={setOpen}\n * title=\"Supplemental info\"\n * >\n * {content}\n * </ArtifactPanel>\n * </ArtifactPanelLayout>\n */\nexport const ArtifactPanelLayout = forwardRef<\n HTMLDivElement,\n ArtifactPanelLayoutProps\n>(function ArtifactPanelLayoutInner(props, ref) {\n const { children, className, ...rest } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRef = useMergeRefs([ref, containerRef]);\n\n const [containerWidth, setContainerWidth] = useState(0);\n const [panels, setPanels] = useState<Record<string, RegisteredPanel>>({});\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n setContainerWidth(el.clientWidth);\n const observer = new ResizeObserver(([entry]) => {\n setContainerWidth(entry.contentRect.width);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n const registerPanel = useCallback((id: string, panel: RegisteredPanel) => {\n setPanels((prev) => ({ ...prev, [id]: panel }));\n }, []);\n\n const unregisterPanel = useCallback((id: string) => {\n setPanels((prev) => {\n if (!(id in prev)) return prev;\n const next = { ...prev };\n delete next[id];\n return next;\n });\n }, []);\n\n const modes = useMemo<Record<string, ArtifactPanelMode>>(() => {\n const chatMinPx = CHAT_MIN_REM * getRemInPx();\n const totalInlineWidth = Object.values(panels).reduce(\n (sum, p) => sum + p.width,\n 0,\n );\n const allInlineFits = containerWidth - totalInlineWidth >= chatMinPx;\n const result: Record<string, ArtifactPanelMode> = {};\n if (allInlineFits) {\n Object.keys(panels).forEach((id) => {\n result[id] = \"inline\";\n });\n return result;\n }\n // Per-panel decision when not all panels fit inline together. Each panel\n // goes overlay if it alone would push the chat below the threshold. Once\n // a left panel ships, this is the place to add a collapse priority so a\n // single panel can overlay first instead of collapsing both.\n Object.entries(panels).forEach(([id, panel]) => {\n result[id] =\n containerWidth - panel.width >= chatMinPx ? \"inline\" : \"overlay\";\n });\n return result;\n }, [containerWidth, panels]);\n\n // Registration API is stable across renders so panels can safely depend on\n // it in a useEffect without triggering re-registration loops when the\n // mode-context value updates.\n const registrationValue = useMemo(\n () => ({ registerPanel, unregisterPanel }),\n [registerPanel, unregisterPanel],\n );\n\n // Mode API updates whenever the computed modes map changes. Panels reading\n // from this context re-render to pick up their new mode.\n const modeValue = useMemo(\n () => ({\n getMode: (id: string): ArtifactPanelMode => modes[id] ?? \"inline\",\n }),\n [modes],\n );\n\n const layoutClassName = classNames(styles.layout, className);\n\n return (\n <ArtifactPanelLayoutRegistrationContext.Provider value={registrationValue}>\n <ArtifactPanelLayoutModeContext.Provider value={modeValue}>\n <div ref={mergedRef} className={layoutClassName} {...rest}>\n {children}\n </div>\n </ArtifactPanelLayoutModeContext.Provider>\n </ArtifactPanelLayoutRegistrationContext.Provider>\n );\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atlas-header-DtYEZIyx.js","sources":["../src/components/atlas-header/atlas-header.tsx"],"sourcesContent":["import { FC } from \"react\";\nimport { Flex, Icon, Svg, Text } from \"@servicetitan/anvil2\";\nimport IconAtlasLogo from \"@servicetitan/anvil2/assets/icons/st/atlas_logo.svg\";\nimport { PulseLoader } from \"../loader\";\n\nexport interface AtlasHeaderProps {\n /**\n * Custom icon to display instead of the default Atlas logo\n */\n svgIcon?: Svg;\n /**\n * Custom assistant name to display instead of \"Atlas\"\n */\n assistant?: string;\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * Whether the loading animation is active\n */\n loading?: boolean;\n /**\n * Status message shown while loading. Defaults to \"Thinking...\"\n */\n statusMessage?: string;\n}\n\n/**\n * Shared component that displays the Atlas logo and name header.\n * When loading is true, the icon pulses and shows the statusMessage with a gradient sweep animation.\n * Used across all message types and recommendation cards.\n */\nexport const AtlasHeader: FC<AtlasHeaderProps> = ({\n svgIcon,\n assistant = \"Atlas\",\n className,\n loading = false,\n statusMessage = \"Thinking...\",\n}) => {\n if (loading) {\n return (\n <PulseLoader\n className={className}\n statusMessage={statusMessage}\n svgIcon={svgIcon}\n />\n );\n }\n\n return (\n <Flex className={className} alignItems=\"flex-start\" gap={3}>\n <div\n style={{\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n marginTop: \"3px\",\n }}\n >\n <Icon svg={svgIcon ?? IconAtlasLogo} size=\"medium\" inherit />\n </div>\n <Text inline>\n <b>{assistant}</b>\n </Text>\n </Flex>\n );\n};\n"],"names":["IconAtlasLogo"],"mappings":";;;;AAiCO,MAAM,cAAoC,CAAC;AAAA,EAChD,OAAA;AAAA,EACA,SAAA,GAAY,OAAA;AAAA,EACZ,SAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,aAAA,GAAgB;AAClB,CAAA,KAAM;AACJ,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACE,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,4BACG,IAAA,EAAA,EAAK,SAAA,EAAsB,UAAA,EAAW,YAAA,EAAa,KAAK,CAAA,EACvD,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,UAAA,EAAY,CAAA;AAAA,UACZ,OAAA,EAAS,MAAA;AAAA,UACT,UAAA,EAAY,QAAA;AAAA,UACZ,SAAA,EAAW;AAAA,SACb;AAAA,QAEA,QAAA,kBAAA,GAAA,CAAC,QAAK,GAAA,EAAK,OAAA,IAAWA,cAAe,IAAA,EAAK,QAAA,EAAS,SAAO,IAAA,EAAC;AAAA;AAAA,KAC7D;AAAA,wBACC,IAAA,EAAA,EAAK,MAAA,EAAM,MACV,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAG,qBAAU,CAAA,EAChB;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"atlas-header-DtYEZIyx.js","sources":["../src/components/atlas-header/atlas-header.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { Flex, Icon, type Svg, Text } from \"@servicetitan/anvil2\";\nimport IconAtlasLogo from \"@servicetitan/anvil2/assets/icons/st/atlas_logo.svg\";\nimport { PulseLoader } from \"../loader\";\n\nexport interface AtlasHeaderProps {\n /**\n * Custom icon to display instead of the default Atlas logo\n */\n svgIcon?: Svg;\n /**\n * Custom assistant name to display instead of \"Atlas\"\n */\n assistant?: string;\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * Whether the loading animation is active\n */\n loading?: boolean;\n /**\n * Status message shown while loading. Defaults to \"Thinking...\"\n */\n statusMessage?: string;\n}\n\n/**\n * Shared component that displays the Atlas logo and name header.\n * When loading is true, the icon pulses and shows the statusMessage with a gradient sweep animation.\n * Used across all message types and recommendation cards.\n */\nexport const AtlasHeader: FC<AtlasHeaderProps> = ({\n svgIcon,\n assistant = \"Atlas\",\n className,\n loading = false,\n statusMessage = \"Thinking...\",\n}) => {\n if (loading) {\n return (\n <PulseLoader\n className={className}\n statusMessage={statusMessage}\n svgIcon={svgIcon}\n />\n );\n }\n\n return (\n <Flex className={className} alignItems=\"flex-start\" gap={3}>\n <div\n style={{\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n marginTop: \"3px\",\n }}\n >\n <Icon svg={svgIcon ?? IconAtlasLogo} size=\"medium\" inherit />\n </div>\n <Text inline>\n <b>{assistant}</b>\n </Text>\n </Flex>\n );\n};\n"],"names":["IconAtlasLogo"],"mappings":";;;;AAiCO,MAAM,cAAoC,CAAC;AAAA,EAChD,OAAA;AAAA,EACA,SAAA,GAAY,OAAA;AAAA,EACZ,SAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,aAAA,GAAgB;AAClB,CAAA,KAAM;AACJ,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACE,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,4BACG,IAAA,EAAA,EAAK,SAAA,EAAsB,UAAA,EAAW,YAAA,EAAa,KAAK,CAAA,EACvD,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,UAAA,EAAY,CAAA;AAAA,UACZ,OAAA,EAAS,MAAA;AAAA,UACT,UAAA,EAAY,QAAA;AAAA,UACZ,SAAA,EAAW;AAAA,SACb;AAAA,QAEA,QAAA,kBAAA,GAAA,CAAC,QAAK,GAAA,EAAK,OAAA,IAAWA,cAAe,IAAA,EAAK,QAAA,EAAS,SAAO,IAAA,EAAC;AAAA;AAAA,KAC7D;AAAA,wBACC,IAAA,EAAA,EAAK,MAAA,EAAM,MACV,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAG,qBAAU,CAAA,EAChB;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-composer-rich-BXkSuUJL.js","sources":["../../anvil2/dist/assets/icons/material/round/add.svg","../../anvil2/dist/assets/icons/material/round/mic.svg","../../anvil2/dist/assets/icons/material/round/send.svg","../../anvil2/dist/assets/icons/st/attach_file.svg","../src/components/chat-composer-rich/chat-composer-rich.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgAdd = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M18 13h-5v5c0 .55-.45 1-1 1s-1-.45-1-1v-5H6c-.55 0-1-.45-1-1s.45-1 1-1h5V6c0-.55.45-1 1-1s1 .45 1 1v5h5c.55 0 1 .45 1 1s-.45 1-1 1z\" }));\nexport default SvgAdd;\n","import * as React from \"react\";\nconst SvgMic = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.91-3c-.49 0-.9.36-.98.85C16.52 14.2 14.47 16 12 16s-4.52-1.8-4.93-4.15a.998.998 0 0 0-.98-.85c-.61 0-1.09.54-1 1.14.49 3 2.89 5.35 5.91 5.78V20c0 .55.45 1 1 1s1-.45 1-1v-2.08a6.993 6.993 0 0 0 5.91-5.78c.1-.6-.39-1.14-1-1.14z\" }));\nexport default SvgMic;\n","import * as React from \"react\";\nconst SvgSend = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"m3.4 20.4 17.45-7.48a1 1 0 0 0 0-1.84L3.4 3.6a.993.993 0 0 0-1.39.91L2 9.12c0 .5.37.93.87.99L17 12 2.87 13.88c-.5.07-.87.5-.87 1l.01 4.61c0 .71.73 1.2 1.39.91z\" }));\nexport default SvgSend;\n","import * as React from \"react\";\nconst SvgAttachFile = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M17.5 15.438q0 2.382-1.673 4.056t-4.056 1.673q-2.384 0-4.056-1.673-1.674-1.674-1.673-4.056v-8.48q0-1.718 1.203-2.922 1.203-1.203 2.922-1.203t2.922 1.203q1.203 1.205 1.203 2.922v8.021q0 1.055-.734 1.788a2.43 2.43 0 0 1-1.787.733 2.43 2.43 0 0 1-1.788-.733 2.43 2.43 0 0 1-.733-1.788V7.417q0-.39.264-.653a.9.9 0 0 1 .653-.264q.39 0 .653.264a.9.9 0 0 1 .263.653v7.562a.67.67 0 0 0 .688.688.67.67 0 0 0 .687-.688V6.96a2.32 2.32 0 0 0-.676-1.628q-.653-.664-1.615-.664-.963 0-1.627.664a2.2 2.2 0 0 0-.665 1.627v8.48q-.023 1.627 1.123 2.761t2.773 1.134q1.604 0 2.727-1.134t1.169-2.762v-8.02q0-.39.263-.653a.9.9 0 0 1 .653-.264q.39 0 .653.264a.9.9 0 0 1 .264.653z\" }));\nexport default SvgAttachFile;\n","import { KeyboardEvent, useEffect, useRef, useState } from \"react\";\nimport classNames from \"classnames\";\nimport { Button, Menu } from \"@servicetitan/anvil2\";\nimport IconPlus from \"@servicetitan/anvil2/assets/icons/material/round/add.svg\";\nimport IconMic from \"@servicetitan/anvil2/assets/icons/material/round/mic.svg\";\nimport IconSend from \"@servicetitan/anvil2/assets/icons/material/round/send.svg\";\nimport IconAttachFile from \"@servicetitan/anvil2/assets/icons/st/attach_file.svg\";\n\nimport styles from \"./chat-composer-rich.module.scss\";\n\nexport interface ChatComposerRichProps {\n message?: string;\n /** Callback when user submits a message */\n onSend?: (text: string) => void;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Whether the composer is disabled */\n disabled?: boolean;\n /** Additional CSS class name */\n className?: string;\n onChange: (text: string) => void;\n /** Callback when upload file is selected from menu */\n onUploadFile?: () => void;\n /** Callback when dictate message is selected from menu */\n onDictateMessage?: () => void;\n /** ID for the menu button */\n menuButtonId?: string;\n /** ID for the send icon button */\n sendIconId?: string;\n /** ID for the message input area */\n messageInputId?: string;\n}\n\nexport const ChatComposerRich = ({\n message,\n onSend,\n onChange,\n placeholder = \"Ask anything...\",\n disabled = false,\n className,\n onUploadFile,\n onDictateMessage,\n messageInputId,\n sendIconId,\n}: ChatComposerRichProps) => {\n const [isEmpty, setIsEmpty] = useState(true);\n const editorRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (editorRef.current && message) {\n editorRef.current.innerText = message;\n }\n }, [message]);\n\n const handleInput = () => {\n const text = editorRef.current?.innerText.trim() ?? \"\";\n setIsEmpty(text.length === 0);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const handleSubmit = () => {\n if (disabled) {\n return;\n }\n\n const text = editorRef.current?.innerText.trim() ?? \"\";\n onChange(text);\n if (!text) {\n return;\n }\n\n onSend?.(text);\n\n if (editorRef.current) {\n // Clear content while preserving the element structure\n editorRef.current.innerText = \"\";\n // Keep focus in the input for smooth conversation flow\n editorRef.current.focus();\n }\n setIsEmpty(true);\n };\n\n useEffect(() => {\n // Ensure empty placeholder is visible on mount\n setIsEmpty(!editorRef.current?.innerText.trim());\n }, []);\n\n return (\n <div className={classNames(styles[\"composer-wrapper\"], className)}>\n <form\n onSubmit={(e) => e.preventDefault()}\n className={styles[\"composer-form\"]}\n >\n {onDictateMessage || onUploadFile ? (\n <Menu\n id=\"\"\n trigger={(props) => (\n <Button\n {...props}\n type=\"button\"\n aria-label=\"Open menu\"\n disabled={disabled}\n className={styles[\"icon-button\"]}\n icon={IconPlus}\n size=\"small\"\n />\n )}\n disabled={disabled}\n >\n <Menu.Item\n label=\"Upload file\"\n icon={IconAttachFile}\n onClick={onUploadFile}\n />\n <Menu.Item\n label=\"Dictate message\"\n icon={IconMic}\n onClick={onDictateMessage}\n />\n </Menu>\n ) : (\n <div />\n )}\n\n <div className={styles[\"input-wrapper\"]}>\n <div\n id={messageInputId}\n ref={editorRef}\n contentEditable=\"plaintext-only\"\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={placeholder}\n data-placeholder={placeholder}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n className={styles[\"input\"]}\n tabIndex={0}\n />\n {isEmpty && (\n <span className={styles[\"placeholder\"]}>{placeholder}</span>\n )}\n </div>\n\n <Button\n id={sendIconId}\n size=\"small\"\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || isEmpty}\n className={styles[\"send-button\"]}\n aria-label=\"Send message\"\n appearance=\"ghost\"\n icon={IconSend}\n />\n </form>\n </div>\n );\n};\n"],"names":["IconPlus","IconAttachFile","IconMic","IconSend"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-composer-rich-BXkSuUJL.js","sources":["../../anvil2/dist/assets/icons/material/round/add.svg","../../anvil2/dist/assets/icons/material/round/mic.svg","../../anvil2/dist/assets/icons/material/round/send.svg","../../anvil2/dist/assets/icons/st/attach_file.svg","../src/components/chat-composer-rich/chat-composer-rich.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgAdd = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M18 13h-5v5c0 .55-.45 1-1 1s-1-.45-1-1v-5H6c-.55 0-1-.45-1-1s.45-1 1-1h5V6c0-.55.45-1 1-1s1 .45 1 1v5h5c.55 0 1 .45 1 1s-.45 1-1 1z\" }));\nexport default SvgAdd;\n","import * as React from \"react\";\nconst SvgMic = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.91-3c-.49 0-.9.36-.98.85C16.52 14.2 14.47 16 12 16s-4.52-1.8-4.93-4.15a.998.998 0 0 0-.98-.85c-.61 0-1.09.54-1 1.14.49 3 2.89 5.35 5.91 5.78V20c0 .55.45 1 1 1s1-.45 1-1v-2.08a6.993 6.993 0 0 0 5.91-5.78c.1-.6-.39-1.14-1-1.14z\" }));\nexport default SvgMic;\n","import * as React from \"react\";\nconst SvgSend = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"m3.4 20.4 17.45-7.48a1 1 0 0 0 0-1.84L3.4 3.6a.993.993 0 0 0-1.39.91L2 9.12c0 .5.37.93.87.99L17 12 2.87 13.88c-.5.07-.87.5-.87 1l.01 4.61c0 .71.73 1.2 1.39.91z\" }));\nexport default SvgSend;\n","import * as React from \"react\";\nconst SvgAttachFile = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M17.5 15.438q0 2.382-1.673 4.056t-4.056 1.673q-2.384 0-4.056-1.673-1.674-1.674-1.673-4.056v-8.48q0-1.718 1.203-2.922 1.203-1.203 2.922-1.203t2.922 1.203q1.203 1.205 1.203 2.922v8.021q0 1.055-.734 1.788a2.43 2.43 0 0 1-1.787.733 2.43 2.43 0 0 1-1.788-.733 2.43 2.43 0 0 1-.733-1.788V7.417q0-.39.264-.653a.9.9 0 0 1 .653-.264q.39 0 .653.264a.9.9 0 0 1 .263.653v7.562a.67.67 0 0 0 .688.688.67.67 0 0 0 .687-.688V6.96a2.32 2.32 0 0 0-.676-1.628q-.653-.664-1.615-.664-.963 0-1.627.664a2.2 2.2 0 0 0-.665 1.627v8.48q-.023 1.627 1.123 2.761t2.773 1.134q1.604 0 2.727-1.134t1.169-2.762v-8.02q0-.39.263-.653a.9.9 0 0 1 .653-.264q.39 0 .653.264a.9.9 0 0 1 .264.653z\" }));\nexport default SvgAttachFile;\n","import { type KeyboardEvent, useEffect, useRef, useState } from \"react\";\nimport classNames from \"classnames\";\nimport { Button, Menu } from \"@servicetitan/anvil2\";\nimport IconPlus from \"@servicetitan/anvil2/assets/icons/material/round/add.svg\";\nimport IconMic from \"@servicetitan/anvil2/assets/icons/material/round/mic.svg\";\nimport IconSend from \"@servicetitan/anvil2/assets/icons/material/round/send.svg\";\nimport IconAttachFile from \"@servicetitan/anvil2/assets/icons/st/attach_file.svg\";\n\nimport styles from \"./chat-composer-rich.module.scss\";\n\nexport interface ChatComposerRichProps {\n message?: string;\n /** Callback when user submits a message */\n onSend?: (text: string) => void;\n /** Placeholder text for the input */\n placeholder?: string;\n /** Whether the composer is disabled */\n disabled?: boolean;\n /** Additional CSS class name */\n className?: string;\n onChange: (text: string) => void;\n /** Callback when upload file is selected from menu */\n onUploadFile?: () => void;\n /** Callback when dictate message is selected from menu */\n onDictateMessage?: () => void;\n /** ID for the menu button */\n menuButtonId?: string;\n /** ID for the send icon button */\n sendIconId?: string;\n /** ID for the message input area */\n messageInputId?: string;\n}\n\nexport const ChatComposerRich = ({\n message,\n onSend,\n onChange,\n placeholder = \"Ask anything...\",\n disabled = false,\n className,\n onUploadFile,\n onDictateMessage,\n messageInputId,\n sendIconId,\n}: ChatComposerRichProps) => {\n const [isEmpty, setIsEmpty] = useState(true);\n const editorRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (editorRef.current && message) {\n editorRef.current.innerText = message;\n }\n }, [message]);\n\n const handleInput = () => {\n const text = editorRef.current?.innerText.trim() ?? \"\";\n setIsEmpty(text.length === 0);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const handleSubmit = () => {\n if (disabled) {\n return;\n }\n\n const text = editorRef.current?.innerText.trim() ?? \"\";\n onChange(text);\n if (!text) {\n return;\n }\n\n onSend?.(text);\n\n if (editorRef.current) {\n // Clear content while preserving the element structure\n editorRef.current.innerText = \"\";\n // Keep focus in the input for smooth conversation flow\n editorRef.current.focus();\n }\n setIsEmpty(true);\n };\n\n useEffect(() => {\n // Ensure empty placeholder is visible on mount\n setIsEmpty(!editorRef.current?.innerText.trim());\n }, []);\n\n return (\n <div className={classNames(styles[\"composer-wrapper\"], className)}>\n <form\n onSubmit={(e) => e.preventDefault()}\n className={styles[\"composer-form\"]}\n >\n {onDictateMessage || onUploadFile ? (\n <Menu\n id=\"\"\n trigger={(props) => (\n <Button\n {...props}\n type=\"button\"\n aria-label=\"Open menu\"\n disabled={disabled}\n className={styles[\"icon-button\"]}\n icon={IconPlus}\n size=\"small\"\n />\n )}\n disabled={disabled}\n >\n <Menu.Item\n label=\"Upload file\"\n icon={IconAttachFile}\n onClick={onUploadFile}\n />\n <Menu.Item\n label=\"Dictate message\"\n icon={IconMic}\n onClick={onDictateMessage}\n />\n </Menu>\n ) : (\n <div />\n )}\n\n <div className={styles[\"input-wrapper\"]}>\n <div\n id={messageInputId}\n ref={editorRef}\n contentEditable=\"plaintext-only\"\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={placeholder}\n data-placeholder={placeholder}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n className={styles[\"input\"]}\n tabIndex={0}\n />\n {isEmpty && (\n <span className={styles[\"placeholder\"]}>{placeholder}</span>\n )}\n </div>\n\n <Button\n id={sendIconId}\n size=\"small\"\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || isEmpty}\n className={styles[\"send-button\"]}\n aria-label=\"Send message\"\n appearance=\"ghost\"\n icon={IconSend}\n />\n </form>\n </div>\n );\n};\n"],"names":["IconPlus","IconAttachFile","IconMic","IconSend"],"mappings":"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"}
|
|
@@ -47,9 +47,8 @@
|
|
|
47
47
|
transform: translateY(-50%);
|
|
48
48
|
color: var(--a2-foreground-color-subdued, #737475);
|
|
49
49
|
pointer-events: none;
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
user-select: none;
|
|
50
|
+
-moz-user-select: none;
|
|
51
|
+
user-select: none;
|
|
53
52
|
font-size: 1rem;
|
|
54
53
|
}
|
|
55
54
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-window-Eh0GzLcm.js","sources":["../src/components/chat/chat-window.tsx"],"sourcesContent":["import { ReactNode } from \"react\";\nimport classNames from \"classnames\";\nimport { motion } from \"framer-motion\";\n\nimport styles from \"./styles.module.scss\";\n\ninterface ChatWindowProps {\n open: boolean;\n position?: { x: number; y: number };\n isDragging?: boolean;\n fullscreen?: boolean;\n children: ReactNode;\n}\n\nexport const ChatWindow = ({\n open,\n position,\n isDragging,\n fullscreen = false,\n children,\n}: ChatWindowProps) => {\n const isFullscreenOpen = fullscreen && open;\n\n const className = classNames({\n [styles[\"chat-window-expanded\"]]: isFullscreenOpen,\n [styles[\"chat-window\"]]: !isFullscreenOpen,\n [styles[\"open\"]]: !isFullscreenOpen && open,\n [styles[\"closed\"]]: !isFullscreenOpen && !open,\n [styles[\"positioned\"]]: !isFullscreenOpen && position,\n [styles[\"relative\"]]: !isFullscreenOpen && !position,\n });\n\n const getPositionStyles = () => {\n if (isFullscreenOpen) {\n return {};\n }\n\n return position\n ? {\n left: position.x,\n top: position.y,\n }\n : {};\n };\n\n return (\n <motion.div\n layout={!isDragging}\n initial={{\n opacity: isFullscreenOpen ? 0 : 1,\n x: !isFullscreenOpen && !open ? 0 : -25,\n }}\n animate={{\n x: isFullscreenOpen ? 0 : open ? -25 : 0,\n }}\n transition={{\n type: isFullscreenOpen ? \"tween\" : \"spring\",\n ease: isFullscreenOpen ? \"easeInOut\" : undefined,\n stiffness: 300,\n damping: 35,\n duration: 0.3,\n }}\n className={className}\n style={getPositionStyles()}\n >\n <motion.div\n layout={!isDragging ? \"position\" : undefined}\n style={{ width: \"100%\", height: \"100%\" }}\n >\n {children}\n </motion.div>\n </motion.div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcO,MAAM,aAAa,CAAC;AAAA,EACzB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb;AACF,CAAA,KAAuB;AACrB,EAAA,MAAM,mBAAmB,UAAA,IAAc,IAAA;AAEvC,EAAA,MAAM,YAAY,UAAA,CAAW;AAAA,IAC3B,CAAC,MAAA,CAAO,sBAAsB,CAAC,GAAG,gBAAA;AAAA,IAClC,CAAC,MAAA,CAAO,aAAa,CAAC,GAAG,CAAC,gBAAA;AAAA,IAC1B,CAAC,MAAA,CAAO,MAAM,CAAC,GAAG,CAAC,gBAAA,IAAoB,IAAA;AAAA,IACvC,CAAC,MAAA,CAAO,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAA;AAAA,IAC1C,CAAC,MAAA,CAAO,YAAY,CAAC,GAAG,CAAC,gBAAA,IAAoB,QAAA;AAAA,IAC7C,CAAC,MAAA,CAAO,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC;AAAA,GAC7C,CAAA;AAED,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,IAAI,gBAAA,EAAkB;AACpB,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,OAAO,QAAA,GACH;AAAA,MACE,MAAM,QAAA,CAAS,CAAA;AAAA,MACf,KAAK,QAAA,CAAS;AAAA,QAEhB,EAAC;AAAA,EACP,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA,CAAO,GAAA;AAAA,IAAP;AAAA,MACC,QAAQ,CAAC,UAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,mBAAmB,CAAA,GAAI,CAAA;AAAA,QAChC,CAAA,EAAG,CAAC,gBAAA,IAAoB,CAAC,OAAO,CAAA,GAAI;AAAA,OACtC;AAAA,MACA,OAAA,EAAS;AAAA,QACP,CAAA,EAAG,gBAAA,GAAmB,CAAA,GAAI,IAAA,GAAO,GAAA,GAAM;AAAA,OACzC;AAAA,MACA,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,mBAAmB,OAAA,GAAU,QAAA;AAAA,QACnC,IAAA,EAAM,mBAAmB,WAAA,GAAc,MAAA;AAAA,QACvC,SAAA,EAAW,GAAA;AAAA,QACX,OAAA,EAAS,EAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,SAAA;AAAA,MACA,OAAO,iBAAA,EAAkB;AAAA,MAEzB,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UACC,MAAA,EAAQ,CAAC,UAAA,GAAa,UAAA,GAAa,MAAA;AAAA,UACnC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,UAEtC;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"chat-window-Eh0GzLcm.js","sources":["../src/components/chat/chat-window.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport classNames from \"classnames\";\nimport { motion } from \"framer-motion\";\n\nimport styles from \"./styles.module.scss\";\n\ninterface ChatWindowProps {\n open: boolean;\n position?: { x: number; y: number };\n isDragging?: boolean;\n fullscreen?: boolean;\n children: ReactNode;\n}\n\nexport const ChatWindow = ({\n open,\n position,\n isDragging,\n fullscreen = false,\n children,\n}: ChatWindowProps) => {\n const isFullscreenOpen = fullscreen && open;\n\n const className = classNames({\n [styles[\"chat-window-expanded\"]]: isFullscreenOpen,\n [styles[\"chat-window\"]]: !isFullscreenOpen,\n [styles[\"open\"]]: !isFullscreenOpen && open,\n [styles[\"closed\"]]: !isFullscreenOpen && !open,\n [styles[\"positioned\"]]: !isFullscreenOpen && position,\n [styles[\"relative\"]]: !isFullscreenOpen && !position,\n });\n\n const getPositionStyles = () => {\n if (isFullscreenOpen) {\n return {};\n }\n\n return position\n ? {\n left: position.x,\n top: position.y,\n }\n : {};\n };\n\n return (\n <motion.div\n layout={!isDragging}\n initial={{\n opacity: isFullscreenOpen ? 0 : 1,\n x: !isFullscreenOpen && !open ? 0 : -25,\n }}\n animate={{\n x: isFullscreenOpen ? 0 : open ? -25 : 0,\n }}\n transition={{\n type: isFullscreenOpen ? \"tween\" : \"spring\",\n ease: isFullscreenOpen ? \"easeInOut\" : undefined,\n stiffness: 300,\n damping: 35,\n duration: 0.3,\n }}\n className={className}\n style={getPositionStyles()}\n >\n <motion.div\n layout={!isDragging ? \"position\" : undefined}\n style={{ width: \"100%\", height: \"100%\" }}\n >\n {children}\n </motion.div>\n </motion.div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcO,MAAM,aAAa,CAAC;AAAA,EACzB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb;AACF,CAAA,KAAuB;AACrB,EAAA,MAAM,mBAAmB,UAAA,IAAc,IAAA;AAEvC,EAAA,MAAM,YAAY,UAAA,CAAW;AAAA,IAC3B,CAAC,MAAA,CAAO,sBAAsB,CAAC,GAAG,gBAAA;AAAA,IAClC,CAAC,MAAA,CAAO,aAAa,CAAC,GAAG,CAAC,gBAAA;AAAA,IAC1B,CAAC,MAAA,CAAO,MAAM,CAAC,GAAG,CAAC,gBAAA,IAAoB,IAAA;AAAA,IACvC,CAAC,MAAA,CAAO,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAA;AAAA,IAC1C,CAAC,MAAA,CAAO,YAAY,CAAC,GAAG,CAAC,gBAAA,IAAoB,QAAA;AAAA,IAC7C,CAAC,MAAA,CAAO,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC;AAAA,GAC7C,CAAA;AAED,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,IAAI,gBAAA,EAAkB;AACpB,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,OAAO,QAAA,GACH;AAAA,MACE,MAAM,QAAA,CAAS,CAAA;AAAA,MACf,KAAK,QAAA,CAAS;AAAA,QAEhB,EAAC;AAAA,EACP,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA,CAAO,GAAA;AAAA,IAAP;AAAA,MACC,QAAQ,CAAC,UAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,mBAAmB,CAAA,GAAI,CAAA;AAAA,QAChC,CAAA,EAAG,CAAC,gBAAA,IAAoB,CAAC,OAAO,CAAA,GAAI;AAAA,OACtC;AAAA,MACA,OAAA,EAAS;AAAA,QACP,CAAA,EAAG,gBAAA,GAAmB,CAAA,GAAI,IAAA,GAAO,GAAA,GAAM;AAAA,OACzC;AAAA,MACA,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,mBAAmB,OAAA,GAAU,QAAA;AAAA,QACnC,IAAA,EAAM,mBAAmB,WAAA,GAAc,MAAA;AAAA,QACvC,SAAA,EAAW,GAAA;AAAA,QACX,OAAA,EAAS,EAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,SAAA;AAAA,MACA,OAAO,iBAAA,EAAkB;AAAA,MAEzB,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UACC,MAAA,EAAQ,CAAC,UAAA,GAAa,UAAA,GAAa,MAAA;AAAA,UACnC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,UAEtC;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-DGEN1Tcq.js","sources":["../src/components/content/content.tsx"],"sourcesContent":["import { FC
|
|
1
|
+
{"version":3,"file":"content-DGEN1Tcq.js","sources":["../src/components/content/content.tsx"],"sourcesContent":["import {\n type FC,\n type PropsWithChildren,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { Grid } from \"@servicetitan/anvil2\";\n\nimport { Spinner } from \"../spinner\";\n\nimport styles from \"./content.module.scss\";\n\nexport interface ContentProps {\n itemsLength: number;\n loading?: boolean;\n className?: string;\n}\n\nexport const Content: FC<PropsWithChildren<ContentProps>> = ({\n children,\n itemsLength,\n loading = false,\n className,\n}) => {\n const chatEndRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isInitialLoad, setIsInitialLoad] = useState(true);\n const [previousMessageCount, setPreviousMessageCount] = useState(0);\n\n const scrollToBottom = (smooth = true) => {\n if (smooth) {\n chatEndRef.current?.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\n } else {\n chatEndRef.current?.scrollIntoView({ behavior: \"auto\", block: \"end\" });\n }\n };\n\n useEffect(() => {\n if (isInitialLoad && itemsLength > 0) {\n // Initial load: scroll to bottom without smooth animation\n scrollToBottom(false);\n setIsInitialLoad(false);\n setPreviousMessageCount(itemsLength);\n } else if (!isInitialLoad && itemsLength > previousMessageCount) {\n // New messages added: scroll to bottom with smooth animation\n scrollToBottom(true);\n setPreviousMessageCount(itemsLength);\n } else if (!isInitialLoad && itemsLength !== previousMessageCount) {\n // Message count changed but not increased (e.g., conversation switched)\n // Just update the count without scrolling\n setPreviousMessageCount(itemsLength);\n }\n }, [itemsLength, isInitialLoad, previousMessageCount]);\n\n return (\n <Grid\n className={classNames(styles[\"chat-content\"], className)}\n ref={containerRef}\n gridColumn=\"1 / 13\"\n >\n {loading ? <Spinner /> : children}\n <div ref={chatEndRef} />\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAoBO,MAAM,UAA+C,CAAC;AAAA,EAC3D,QAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,IAAI,CAAA;AACvD,EAAA,MAAM,CAAC,oBAAA,EAAsB,uBAAuB,CAAA,GAAI,SAAS,CAAC,CAAA;AAElE,EAAA,MAAM,cAAA,GAAiB,CAAC,MAAA,GAAS,IAAA,KAAS;AACxC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,UAAA,CAAW,SAAS,cAAA,CAAe,EAAE,UAAU,QAAA,EAAU,KAAA,EAAO,OAAO,CAAA;AAAA,IACzE,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,SAAS,cAAA,CAAe,EAAE,UAAU,MAAA,EAAQ,KAAA,EAAO,OAAO,CAAA;AAAA,IACvE;AAAA,EACF,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,aAAA,IAAiB,cAAc,CAAA,EAAG;AAEpC,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,MAAA,uBAAA,CAAwB,WAAW,CAAA;AAAA,IACrC,CAAA,MAAA,IAAW,CAAC,aAAA,IAAiB,WAAA,GAAc,oBAAA,EAAsB;AAE/D,MAAA,cAAA,CAAe,IAAI,CAAA;AACnB,MAAA,uBAAA,CAAwB,WAAW,CAAA;AAAA,IACrC,CAAA,MAAA,IAAW,CAAC,aAAA,IAAiB,WAAA,KAAgB,oBAAA,EAAsB;AAGjE,MAAA,uBAAA,CAAwB,WAAW,CAAA;AAAA,IACrC;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,aAAA,EAAe,oBAAoB,CAAC,CAAA;AAErD,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAA,CAAW,MAAA,CAAO,cAAc,GAAG,SAAS,CAAA;AAAA,MACvD,GAAA,EAAK,YAAA;AAAA,MACL,UAAA,EAAW,QAAA;AAAA,MAEV,QAAA,EAAA;AAAA,QAAA,OAAA,mBAAU,GAAA,CAAC,WAAQ,CAAA,GAAK,QAAA;AAAA,wBACzB,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,UAAA,EAAY;AAAA;AAAA;AAAA,GACxB;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header-CZ2pSpzC.js","sources":["../../anvil2/dist/assets/icons/material/round/arrow_back_ios.svg","../../anvil2/dist/assets/icons/material/round/drag_indicator.svg","../../anvil2/dist/assets/icons/material/round/inbox.svg","../../anvil2/dist/assets/icons/material/round/mode_edit.svg","../../anvil2/dist/assets/icons/material/round/open_in_full.svg","../src/components/header/header.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgArrowBackIos = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M16.62 2.99a1.25 1.25 0 0 0-1.77 0L6.54 11.3a.996.996 0 0 0 0 1.41l8.31 8.31c.49.49 1.28.49 1.77 0s.49-1.28 0-1.77L9.38 12l7.25-7.25c.48-.48.48-1.28-.01-1.76z\" }));\nexport default SvgArrowBackIos;\n","import * as React from \"react\";\nconst SvgDragIndicator = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" }));\nexport default SvgDragIndicator;\n","import * as React from \"react\";\nconst SvgInbox = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v9h-3.56c-.36 0-.68.19-.86.5-.52.9-1.47 1.5-2.58 1.5s-2.06-.6-2.58-1.5a1 1 0 0 0-.86-.5H5V5h14z\" }));\nexport default SvgInbox;\n","import * as React from \"react\";\nconst SvgModeEdit = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 5.63l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83a.996.996 0 0 0 0-1.41z\" }));\nexport default SvgModeEdit;\n","import * as React from \"react\";\nconst SvgOpenInFull = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M21 8.59V4c0-.55-.45-1-1-1h-4.59c-.89 0-1.34 1.08-.71 1.71l1.59 1.59-10 10-1.59-1.59c-.62-.63-1.7-.19-1.7.7V20c0 .55.45 1 1 1h4.59c.89 0 1.34-1.08.71-1.71L7.71 17.7l10-10 1.59 1.59c.62.63 1.7.19 1.7-.7z\" }));\nexport default SvgOpenInFull;\n","import { Fragment, MouseEvent } from \"react\";\nimport classNames from \"classnames\";\nimport { observer } from \"mobx-react\";\nimport {\n Badge,\n Button,\n Flex,\n OverflowText,\n Text,\n Tooltip,\n} from \"@servicetitan/anvil2\";\nimport IconArrowBackIos from \"@servicetitan/anvil2/assets/icons/material/round/arrow_back_ios.svg\";\nimport IconClose from \"@servicetitan/anvil2/assets/icons/material/round/close.svg\";\nimport IconDragIndicator from \"@servicetitan/anvil2/assets/icons/material/round/drag_indicator.svg\";\nimport IconInbox from \"@servicetitan/anvil2/assets/icons/material/round/inbox.svg\";\nimport IconModeEdit from \"@servicetitan/anvil2/assets/icons/material/round/mode_edit.svg\";\nimport IconOpenInFull from \"@servicetitan/anvil2/assets/icons/material/round/open_in_full.svg\";\n\nimport styles from \"./header.module.scss\";\n\nexport interface HeaderProps {\n title?: string;\n onMouseDown?: (e: MouseEvent) => void;\n isDragging?: boolean;\n isDraggable?: boolean;\n isExpanded?: boolean;\n disabledChatsIcon?: boolean;\n historyCount?: number;\n titleBadge?: string | number;\n className?: string;\n onBack?: () => void;\n onClose?: () => void;\n onViewHistory?: () => void;\n onFullscreen?: () => void;\n onCreateNewChat?: () => void;\n backButtonId?: string;\n viewHistoryButtonId?: string;\n fullscreenButtonId?: string;\n newChatButtonId?: string;\n closeButtonId?: string;\n}\n\nexport const Header = observer(\n ({\n title = \"Atlas\",\n onMouseDown,\n isDraggable,\n isDragging,\n onFullscreen,\n onViewHistory,\n isExpanded,\n historyCount,\n titleBadge,\n disabledChatsIcon,\n onClose,\n onBack,\n className = \"\",\n onCreateNewChat,\n backButtonId,\n viewHistoryButtonId,\n fullscreenButtonId,\n newChatButtonId,\n closeButtonId,\n }: HeaderProps) => {\n return (\n <Flex className={classNames(styles[\"chat-header\"], className)}>\n <Flex gap={1} style={{ marginInlineEnd: \"var(--a2-size-1)\" }}>\n {isDraggable && !isExpanded && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n className=\"cursor-grab\"\n onMouseDown={onMouseDown ?? undefined}\n style={{\n position: \"relative\",\n cursor: isDragging ? \"grabbing\" : \"grab\",\n }}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconDragIndicator}\n aria-label=\"drag\"\n />\n </Tooltip.Trigger>\n {isDragging ? null : (\n <Tooltip.Content>Drag to Adjust</Tooltip.Content>\n )}\n </Tooltip>\n )}\n {onBack && (\n <Button\n id={backButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconArrowBackIos}\n onClick={onBack}\n />\n )}\n </Flex>\n <Flex grow={1}>\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <OverflowText rows={1} className={styles[\"chat-header-title\"]}>\n <Text\n el=\"h4\"\n size=\"small\"\n variant=\"headline\"\n style={{ marginBlockEnd: \"0\", paddingBlockEnd: \"0\" }}\n >\n {title}\n </Text>\n {!!titleBadge && (\n <Badge\n offset={{\n x: \"12px\",\n y: \"0.5rem\",\n }}\n >\n {titleBadge}\n </Badge>\n )}\n </OverflowText>\n </Tooltip.Trigger>\n <Tooltip.Content>{title}</Tooltip.Content>\n </Tooltip>\n </Flex>\n <Flex gap={1}>\n {onViewHistory && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger style={{ position: \"relative\" }}>\n <Fragment>\n <Button\n id={viewHistoryButtonId}\n style={{ position: \"relative\" }}\n disabled={disabledChatsIcon}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconInbox}\n aria-label=\"chats\"\n onClick={onViewHistory}\n />\n {!!historyCount && <Badge>{historyCount}</Badge>}\n </Fragment>\n </Tooltip.Trigger>\n <Tooltip.Content>View All Chats</Tooltip.Content>\n </Tooltip>\n )}\n {onFullscreen && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={fullscreenButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconOpenInFull}\n aria-label=\"fullscreen\"\n onClick={onFullscreen}\n />\n </Tooltip.Trigger>\n <Tooltip.Content>\n {isExpanded ? \"Minimize Window\" : \"Expand Window\"}\n </Tooltip.Content>\n </Tooltip>\n )}\n {onCreateNewChat && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={newChatButtonId}\n size=\"small\"\n icon={IconModeEdit}\n aria-label=\"new chat\"\n onClick={onCreateNewChat}\n >\n New Chat\n </Button>\n </Tooltip.Trigger>\n <Tooltip.Content>New Chat</Tooltip.Content>\n </Tooltip>\n )}\n {onClose && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={closeButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconClose}\n aria-label=\"close\"\n onClick={onClose}\n />\n </Tooltip.Trigger>\n <Tooltip.Content>Hide Window</Tooltip.Content>\n </Tooltip>\n )}\n </Flex>\n </Flex>\n );\n },\n);\n"],"names":["IconDragIndicator","IconArrowBackIos","IconInbox","IconOpenInFull","IconModeEdit","IconClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"header-CZ2pSpzC.js","sources":["../../anvil2/dist/assets/icons/material/round/arrow_back_ios.svg","../../anvil2/dist/assets/icons/material/round/drag_indicator.svg","../../anvil2/dist/assets/icons/material/round/inbox.svg","../../anvil2/dist/assets/icons/material/round/mode_edit.svg","../../anvil2/dist/assets/icons/material/round/open_in_full.svg","../src/components/header/header.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgArrowBackIos = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M16.62 2.99a1.25 1.25 0 0 0-1.77 0L6.54 11.3a.996.996 0 0 0 0 1.41l8.31 8.31c.49.49 1.28.49 1.77 0s.49-1.28 0-1.77L9.38 12l7.25-7.25c.48-.48.48-1.28-.01-1.76z\" }));\nexport default SvgArrowBackIos;\n","import * as React from \"react\";\nconst SvgDragIndicator = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" }));\nexport default SvgDragIndicator;\n","import * as React from \"react\";\nconst SvgInbox = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v9h-3.56c-.36 0-.68.19-.86.5-.52.9-1.47 1.5-2.58 1.5s-2.06-.6-2.58-1.5a1 1 0 0 0-.86-.5H5V5h14z\" }));\nexport default SvgInbox;\n","import * as React from \"react\";\nconst SvgModeEdit = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 5.63l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83a.996.996 0 0 0 0-1.41z\" }));\nexport default SvgModeEdit;\n","import * as React from \"react\";\nconst SvgOpenInFull = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M21 8.59V4c0-.55-.45-1-1-1h-4.59c-.89 0-1.34 1.08-.71 1.71l1.59 1.59-10 10-1.59-1.59c-.62-.63-1.7-.19-1.7.7V20c0 .55.45 1 1 1h4.59c.89 0 1.34-1.08.71-1.71L7.71 17.7l10-10 1.59 1.59c.62.63 1.7.19 1.7-.7z\" }));\nexport default SvgOpenInFull;\n","import { Fragment, type MouseEvent } from \"react\";\nimport classNames from \"classnames\";\nimport { observer } from \"mobx-react\";\nimport {\n Badge,\n Button,\n Flex,\n OverflowText,\n Text,\n Tooltip,\n} from \"@servicetitan/anvil2\";\nimport IconArrowBackIos from \"@servicetitan/anvil2/assets/icons/material/round/arrow_back_ios.svg\";\nimport IconClose from \"@servicetitan/anvil2/assets/icons/material/round/close.svg\";\nimport IconDragIndicator from \"@servicetitan/anvil2/assets/icons/material/round/drag_indicator.svg\";\nimport IconInbox from \"@servicetitan/anvil2/assets/icons/material/round/inbox.svg\";\nimport IconModeEdit from \"@servicetitan/anvil2/assets/icons/material/round/mode_edit.svg\";\nimport IconOpenInFull from \"@servicetitan/anvil2/assets/icons/material/round/open_in_full.svg\";\n\nimport styles from \"./header.module.scss\";\n\nexport interface HeaderProps {\n title?: string;\n onMouseDown?: (e: MouseEvent) => void;\n isDragging?: boolean;\n isDraggable?: boolean;\n isExpanded?: boolean;\n disabledChatsIcon?: boolean;\n historyCount?: number;\n titleBadge?: string | number;\n className?: string;\n onBack?: () => void;\n onClose?: () => void;\n onViewHistory?: () => void;\n onFullscreen?: () => void;\n onCreateNewChat?: () => void;\n backButtonId?: string;\n viewHistoryButtonId?: string;\n fullscreenButtonId?: string;\n newChatButtonId?: string;\n closeButtonId?: string;\n}\n\nexport const Header = observer(\n ({\n title = \"Atlas\",\n onMouseDown,\n isDraggable,\n isDragging,\n onFullscreen,\n onViewHistory,\n isExpanded,\n historyCount,\n titleBadge,\n disabledChatsIcon,\n onClose,\n onBack,\n className = \"\",\n onCreateNewChat,\n backButtonId,\n viewHistoryButtonId,\n fullscreenButtonId,\n newChatButtonId,\n closeButtonId,\n }: HeaderProps) => {\n return (\n <Flex className={classNames(styles[\"chat-header\"], className)}>\n <Flex gap={1} style={{ marginInlineEnd: \"var(--a2-size-1)\" }}>\n {isDraggable && !isExpanded && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n className=\"cursor-grab\"\n onMouseDown={onMouseDown ?? undefined}\n style={{\n position: \"relative\",\n cursor: isDragging ? \"grabbing\" : \"grab\",\n }}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconDragIndicator}\n aria-label=\"drag\"\n />\n </Tooltip.Trigger>\n {isDragging ? null : (\n <Tooltip.Content>Drag to Adjust</Tooltip.Content>\n )}\n </Tooltip>\n )}\n {onBack && (\n <Button\n id={backButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconArrowBackIos}\n onClick={onBack}\n />\n )}\n </Flex>\n <Flex grow={1}>\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <OverflowText rows={1} className={styles[\"chat-header-title\"]}>\n <Text\n el=\"h4\"\n size=\"small\"\n variant=\"headline\"\n style={{ marginBlockEnd: \"0\", paddingBlockEnd: \"0\" }}\n >\n {title}\n </Text>\n {!!titleBadge && (\n <Badge\n offset={{\n x: \"12px\",\n y: \"0.5rem\",\n }}\n >\n {titleBadge}\n </Badge>\n )}\n </OverflowText>\n </Tooltip.Trigger>\n <Tooltip.Content>{title}</Tooltip.Content>\n </Tooltip>\n </Flex>\n <Flex gap={1}>\n {onViewHistory && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger style={{ position: \"relative\" }}>\n <Fragment>\n <Button\n id={viewHistoryButtonId}\n style={{ position: \"relative\" }}\n disabled={disabledChatsIcon}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconInbox}\n aria-label=\"chats\"\n onClick={onViewHistory}\n />\n {!!historyCount && <Badge>{historyCount}</Badge>}\n </Fragment>\n </Tooltip.Trigger>\n <Tooltip.Content>View All Chats</Tooltip.Content>\n </Tooltip>\n )}\n {onFullscreen && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={fullscreenButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconOpenInFull}\n aria-label=\"fullscreen\"\n onClick={onFullscreen}\n />\n </Tooltip.Trigger>\n <Tooltip.Content>\n {isExpanded ? \"Minimize Window\" : \"Expand Window\"}\n </Tooltip.Content>\n </Tooltip>\n )}\n {onCreateNewChat && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={newChatButtonId}\n size=\"small\"\n icon={IconModeEdit}\n aria-label=\"new chat\"\n onClick={onCreateNewChat}\n >\n New Chat\n </Button>\n </Tooltip.Trigger>\n <Tooltip.Content>New Chat</Tooltip.Content>\n </Tooltip>\n )}\n {onClose && (\n <Tooltip placement=\"bottom\">\n <Tooltip.Trigger>\n <Button\n id={closeButtonId}\n appearance=\"ghost\"\n size=\"small\"\n icon={IconClose}\n aria-label=\"close\"\n onClick={onClose}\n />\n </Tooltip.Trigger>\n <Tooltip.Content>Hide Window</Tooltip.Content>\n </Tooltip>\n )}\n </Flex>\n </Flex>\n );\n },\n);\n"],"names":["IconDragIndicator","IconArrowBackIos","IconInbox","IconOpenInFull","IconModeEdit","IconClose"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ArtifactCard } from './artifact-card-
|
|
1
|
+
export { A as ArtifactCard } from './artifact-card-CviyzgR9.js';
|
|
2
2
|
export { A as ArtifactPanel } from './artifact-panel-CNzdjBT8.js';
|
|
3
3
|
export { A as ArtifactPanelLayout } from './artifact-panel-layout-sm-DM-lO.js';
|
|
4
4
|
export { A as AtlasHeader } from './atlas-header-DtYEZIyx.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/hooks/use-draggable.ts"],"sourcesContent":["import { MouseEvent, useCallback, useEffect, useState } from \"react\";\n\nexport interface UseDraggableProps {\n initialX?: number;\n initialY?: number;\n minVisibleHorizontal?: number;\n minVisibleVertical?: number;\n width?: number;\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\nexport const useDraggable = ({\n initialX = window.innerWidth - 390,\n initialY = 64,\n minVisibleHorizontal = 390,\n minVisibleVertical = 56,\n width = 390,\n}: UseDraggableProps = {}) => {\n const [position, setPosition] = useState<Position>({\n x: initialX,\n y: initialY,\n });\n const [isDragging, setIsDragging] = useState(false);\n const [dragOffset, setDragOffset] = useState<Position>({ x: 0, y: 0 });\n\n // Function to ensure position is within viewport boundaries\n const ensurePositionInViewport = useCallback(\n (pos: Position): Position => {\n const maxX = window.innerWidth - minVisibleHorizontal;\n const minX = -width + minVisibleHorizontal;\n const maxY = window.innerHeight - minVisibleVertical;\n return {\n x: Math.min(Math.max(pos.x, minX), maxX),\n y: Math.min(Math.max(pos.y, minVisibleVertical), maxY),\n };\n },\n [minVisibleHorizontal, minVisibleVertical, width],\n );\n\n // Function to recalculate initial position based on current viewport\n const recalculateInitialPosition = useCallback((): Position => {\n const newInitialX = window.innerWidth - width;\n return { x: newInitialX, y: initialY };\n }, [width, initialY]);\n\n const resetPosition = useCallback(() => {\n const newInitialPos = recalculateInitialPosition();\n setPosition(newInitialPos);\n }, [recalculateInitialPosition]);\n\n const handleMouseDown = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n setIsDragging(true);\n\n setDragOffset({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n },\n [position],\n );\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging) {\n return;\n }\n\n const newX = e.clientX - dragOffset.x;\n const newY = e.clientY - dragOffset.y;\n\n const constrainedPosition = ensurePositionInViewport({\n x: newX,\n y: newY,\n });\n setPosition(constrainedPosition);\n },\n [isDragging, dragOffset, ensurePositionInViewport],\n );\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n // Handle viewport resize\n const handleResize = useCallback(() => {\n const constrainedPosition = ensurePositionInViewport(position);\n setPosition(constrainedPosition);\n }, [position, ensurePositionInViewport]);\n\n useEffect(() => {\n if (isDragging) {\n // Prevent text selection while dragging\n document.body.style.userSelect = \"none\";\n document.body.style.webkitUserSelect = \"none\";\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n }\n\n return () => {\n // Restore text selection\n document.body.style.userSelect = \"\";\n document.body.style.webkitUserSelect = \"\";\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [isDragging, handleMouseMove, handleMouseUp]);\n\n // Add resize listener\n useEffect(() => {\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [handleResize]);\n\n return {\n position,\n isDragging,\n handleMouseDown,\n resetPosition,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/hooks/use-draggable.ts"],"sourcesContent":["import { type MouseEvent, useCallback, useEffect, useState } from \"react\";\n\nexport interface UseDraggableProps {\n initialX?: number;\n initialY?: number;\n minVisibleHorizontal?: number;\n minVisibleVertical?: number;\n width?: number;\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\nexport const useDraggable = ({\n initialX = window.innerWidth - 390,\n initialY = 64,\n minVisibleHorizontal = 390,\n minVisibleVertical = 56,\n width = 390,\n}: UseDraggableProps = {}) => {\n const [position, setPosition] = useState<Position>({\n x: initialX,\n y: initialY,\n });\n const [isDragging, setIsDragging] = useState(false);\n const [dragOffset, setDragOffset] = useState<Position>({ x: 0, y: 0 });\n\n // Function to ensure position is within viewport boundaries\n const ensurePositionInViewport = useCallback(\n (pos: Position): Position => {\n const maxX = window.innerWidth - minVisibleHorizontal;\n const minX = -width + minVisibleHorizontal;\n const maxY = window.innerHeight - minVisibleVertical;\n return {\n x: Math.min(Math.max(pos.x, minX), maxX),\n y: Math.min(Math.max(pos.y, minVisibleVertical), maxY),\n };\n },\n [minVisibleHorizontal, minVisibleVertical, width],\n );\n\n // Function to recalculate initial position based on current viewport\n const recalculateInitialPosition = useCallback((): Position => {\n const newInitialX = window.innerWidth - width;\n return { x: newInitialX, y: initialY };\n }, [width, initialY]);\n\n const resetPosition = useCallback(() => {\n const newInitialPos = recalculateInitialPosition();\n setPosition(newInitialPos);\n }, [recalculateInitialPosition]);\n\n const handleMouseDown = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n setIsDragging(true);\n\n setDragOffset({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n },\n [position],\n );\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging) {\n return;\n }\n\n const newX = e.clientX - dragOffset.x;\n const newY = e.clientY - dragOffset.y;\n\n const constrainedPosition = ensurePositionInViewport({\n x: newX,\n y: newY,\n });\n setPosition(constrainedPosition);\n },\n [isDragging, dragOffset, ensurePositionInViewport],\n );\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n // Handle viewport resize\n const handleResize = useCallback(() => {\n const constrainedPosition = ensurePositionInViewport(position);\n setPosition(constrainedPosition);\n }, [position, ensurePositionInViewport]);\n\n useEffect(() => {\n if (isDragging) {\n // Prevent text selection while dragging\n document.body.style.userSelect = \"none\";\n document.body.style.webkitUserSelect = \"none\";\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n }\n\n return () => {\n // Restore text selection\n document.body.style.userSelect = \"\";\n document.body.style.webkitUserSelect = \"\";\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [isDragging, handleMouseMove, handleMouseUp]);\n\n // Add resize listener\n useEffect(() => {\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [handleResize]);\n\n return {\n position,\n isDragging,\n handleMouseDown,\n resetPosition,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infinite-content-CUXfEs3y.js","sources":["../src/components/infinite-content/hooks/use-infinite-scroll.ts","../src/components/infinite-content/hooks/use-scroll-callback.ts","../src/components/infinite-content/infinite-content.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseInfiniteScrollOptions {\n hasMore: boolean;\n isLoading: boolean;\n onLoadMore: () => void;\n rootMargin?: string;\n threshold?: number;\n}\n\nexport const useInfiniteScroll = ({\n hasMore,\n isLoading,\n onLoadMore,\n rootMargin = \"100px\",\n threshold = 0.1,\n}: UseInfiniteScrollOptions) => {\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n const handleIntersection = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n const [entry] = entries;\n\n if (entry.isIntersecting && hasMore && !isLoading) {\n onLoadMore();\n }\n },\n [hasMore, isLoading, onLoadMore],\n );\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel) {\n return;\n }\n\n const observer = new IntersectionObserver(handleIntersection, {\n rootMargin,\n threshold,\n });\n\n observer.observe(sentinel);\n\n return () => {\n observer.unobserve(sentinel);\n observer.disconnect();\n };\n }, [handleIntersection, rootMargin, threshold]);\n\n return {\n sentinelRef,\n };\n};\n","import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseScrollCallbackOptions {\n onScrollDown?: () => void;\n onScrollTop?: () => void;\n threshold?: number;\n element?: HTMLElement | null;\n}\n\nexport const useScrollCallback = ({\n onScrollDown,\n onScrollTop,\n threshold = 50,\n element,\n}: UseScrollCallbackOptions = {}) => {\n const lastScrollTop = useRef(0);\n const hasTriggeredScrollDown = useRef(false);\n\n const handleScroll = useCallback(() => {\n const scrollTop = element\n ? element.scrollTop\n : window.scrollY || document.documentElement.scrollTop;\n\n // Check if scrolled down past threshold\n if (scrollTop >= threshold && !hasTriggeredScrollDown.current) {\n hasTriggeredScrollDown.current = true;\n onScrollDown?.();\n }\n\n // Check if scrolled back to top\n if (scrollTop === 0 && hasTriggeredScrollDown.current) {\n hasTriggeredScrollDown.current = false;\n onScrollTop?.();\n }\n\n lastScrollTop.current = scrollTop;\n }, [onScrollDown, onScrollTop, threshold, element]);\n\n useEffect(() => {\n if (!element) {\n return;\n }\n\n const targetElement = element;\n\n targetElement.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => {\n targetElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll, element]);\n\n return {\n lastScrollTop: lastScrollTop.current,\n hasTriggeredScrollDown: hasTriggeredScrollDown.current,\n };\n};\n","import {\n FC,\n Fragment,\n PropsWithChildren,\n ReactNode,\n RefObject,\n useRef,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { Flex } from \"@servicetitan/anvil2\";\n\nimport { Spinner } from \"../spinner\";\n\nimport { useInfiniteScroll } from \"./hooks/use-infinite-scroll\";\nimport { useScrollCallback } from \"./hooks/use-scroll-callback\";\n\nimport styles from \"./infinite-content.module.scss\";\n\nexport interface InfiniteContentProps {\n loading?: boolean;\n className?: string;\n hasMore?: boolean;\n onLoadMore?: () => void;\n loadingMore?: boolean;\n rootMargin?: string;\n threshold?: number;\n renderLoadingMore?: () => ReactNode;\n renderEndMessage?: () => ReactNode;\n onScrollDown?: () => void;\n onScrollTop?: () => void;\n scrollThreshold?: number;\n scrollContainerRef?: RefObject<HTMLElement>;\n}\n\nexport const InfiniteContent: FC<PropsWithChildren<InfiniteContentProps>> = ({\n children,\n loading = false,\n className,\n hasMore = false,\n onLoadMore = () => {},\n loadingMore = false,\n rootMargin = \"200px\",\n threshold = 0.1,\n renderLoadingMore,\n renderEndMessage,\n onScrollDown,\n onScrollTop,\n scrollThreshold = 50,\n scrollContainerRef,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const { sentinelRef } = useInfiniteScroll({\n hasMore,\n isLoading: loadingMore,\n onLoadMore: () => {\n onLoadMore();\n },\n rootMargin,\n threshold,\n });\n\n useScrollCallback({\n onScrollDown,\n onScrollTop,\n threshold: scrollThreshold,\n element: scrollContainerRef?.current ?? containerRef.current,\n });\n\n // Show initial loading state only when there are no messages yet\n const showInitialLoading =\n loading &&\n (!children || (Array.isArray(children) && children.length === 0));\n\n return (\n <Flex\n ref={containerRef}\n className={classNames(styles[\"infinite-content\"], className)}\n >\n {showInitialLoading ? (\n <Spinner />\n ) : (\n <Fragment>\n {children}\n\n {/* Loading more indicator */}\n {loadingMore && hasMore && (\n <div className={styles[\"loading-more\"]}>\n {renderLoadingMore ? renderLoadingMore() : <Spinner />}\n </div>\n )}\n\n {/* Infinite scroll sentinel - invisible trigger element */}\n {hasMore && (\n <div\n ref={sentinelRef}\n className={styles[\"sentinel\"]}\n aria-hidden=\"true\"\n />\n )}\n\n {/* End of list indicator */}\n {!hasMore && children && (\n <div>{renderEndMessage ? renderEndMessage() : null}</div>\n )}\n </Fragment>\n )}\n </Flex>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"infinite-content-CUXfEs3y.js","sources":["../src/components/infinite-content/hooks/use-infinite-scroll.ts","../src/components/infinite-content/hooks/use-scroll-callback.ts","../src/components/infinite-content/infinite-content.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseInfiniteScrollOptions {\n hasMore: boolean;\n isLoading: boolean;\n onLoadMore: () => void;\n rootMargin?: string;\n threshold?: number;\n}\n\nexport const useInfiniteScroll = ({\n hasMore,\n isLoading,\n onLoadMore,\n rootMargin = \"100px\",\n threshold = 0.1,\n}: UseInfiniteScrollOptions) => {\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n const handleIntersection = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n const [entry] = entries;\n\n if (entry.isIntersecting && hasMore && !isLoading) {\n onLoadMore();\n }\n },\n [hasMore, isLoading, onLoadMore],\n );\n\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel) {\n return;\n }\n\n const observer = new IntersectionObserver(handleIntersection, {\n rootMargin,\n threshold,\n });\n\n observer.observe(sentinel);\n\n return () => {\n observer.unobserve(sentinel);\n observer.disconnect();\n };\n }, [handleIntersection, rootMargin, threshold]);\n\n return {\n sentinelRef,\n };\n};\n","import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseScrollCallbackOptions {\n onScrollDown?: () => void;\n onScrollTop?: () => void;\n threshold?: number;\n element?: HTMLElement | null;\n}\n\nexport const useScrollCallback = ({\n onScrollDown,\n onScrollTop,\n threshold = 50,\n element,\n}: UseScrollCallbackOptions = {}) => {\n const lastScrollTop = useRef(0);\n const hasTriggeredScrollDown = useRef(false);\n\n const handleScroll = useCallback(() => {\n const scrollTop = element\n ? element.scrollTop\n : window.scrollY || document.documentElement.scrollTop;\n\n // Check if scrolled down past threshold\n if (scrollTop >= threshold && !hasTriggeredScrollDown.current) {\n hasTriggeredScrollDown.current = true;\n onScrollDown?.();\n }\n\n // Check if scrolled back to top\n if (scrollTop === 0 && hasTriggeredScrollDown.current) {\n hasTriggeredScrollDown.current = false;\n onScrollTop?.();\n }\n\n lastScrollTop.current = scrollTop;\n }, [onScrollDown, onScrollTop, threshold, element]);\n\n useEffect(() => {\n if (!element) {\n return;\n }\n\n const targetElement = element;\n\n targetElement.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => {\n targetElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll, element]);\n\n return {\n lastScrollTop: lastScrollTop.current,\n hasTriggeredScrollDown: hasTriggeredScrollDown.current,\n };\n};\n","import {\n type FC,\n Fragment,\n type PropsWithChildren,\n type ReactNode,\n type RefObject,\n useRef,\n} from \"react\";\nimport classNames from \"classnames\";\nimport { Flex } from \"@servicetitan/anvil2\";\n\nimport { Spinner } from \"../spinner\";\n\nimport { useInfiniteScroll } from \"./hooks/use-infinite-scroll\";\nimport { useScrollCallback } from \"./hooks/use-scroll-callback\";\n\nimport styles from \"./infinite-content.module.scss\";\n\nexport interface InfiniteContentProps {\n loading?: boolean;\n className?: string;\n hasMore?: boolean;\n onLoadMore?: () => void;\n loadingMore?: boolean;\n rootMargin?: string;\n threshold?: number;\n renderLoadingMore?: () => ReactNode;\n renderEndMessage?: () => ReactNode;\n onScrollDown?: () => void;\n onScrollTop?: () => void;\n scrollThreshold?: number;\n scrollContainerRef?: RefObject<HTMLElement>;\n}\n\nexport const InfiniteContent: FC<PropsWithChildren<InfiniteContentProps>> = ({\n children,\n loading = false,\n className,\n hasMore = false,\n onLoadMore = () => {},\n loadingMore = false,\n rootMargin = \"200px\",\n threshold = 0.1,\n renderLoadingMore,\n renderEndMessage,\n onScrollDown,\n onScrollTop,\n scrollThreshold = 50,\n scrollContainerRef,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const { sentinelRef } = useInfiniteScroll({\n hasMore,\n isLoading: loadingMore,\n onLoadMore: () => {\n onLoadMore();\n },\n rootMargin,\n threshold,\n });\n\n useScrollCallback({\n onScrollDown,\n onScrollTop,\n threshold: scrollThreshold,\n element: scrollContainerRef?.current ?? containerRef.current,\n });\n\n // Show initial loading state only when there are no messages yet\n const showInitialLoading =\n loading &&\n (!children || (Array.isArray(children) && children.length === 0));\n\n return (\n <Flex\n ref={containerRef}\n className={classNames(styles[\"infinite-content\"], className)}\n >\n {showInitialLoading ? (\n <Spinner />\n ) : (\n <Fragment>\n {children}\n\n {/* Loading more indicator */}\n {loadingMore && hasMore && (\n <div className={styles[\"loading-more\"]}>\n {renderLoadingMore ? renderLoadingMore() : <Spinner />}\n </div>\n )}\n\n {/* Infinite scroll sentinel - invisible trigger element */}\n {hasMore && (\n <div\n ref={sentinelRef}\n className={styles[\"sentinel\"]}\n aria-hidden=\"true\"\n />\n )}\n\n {/* End of list indicator */}\n {!hasMore && children && (\n <div>{renderEndMessage ? renderEndMessage() : null}</div>\n )}\n </Fragment>\n )}\n </Flex>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-Cj2z0xxN.js","sources":["../src/components/loader/loader.tsx"],"sourcesContent":["import { FC } from \"react\";\nimport { easeInOut, motion } from \"framer-motion\";\nimport { Flex } from \"@servicetitan/anvil2\";\n\nconst dotVariants = {\n bounce: (i: number) => ({\n y: [0, -15, 0],\n transition: {\n duration: 1.2,\n ease: easeInOut,\n repeat: Infinity,\n delay: i * 0.15,\n },\n }),\n};\n\nexport const Loader: FC = () => {\n return (\n <Flex\n role=\"status\"\n aria-label=\"Loading message\"\n style={{\n paddingBlockStart: \"var(--a2-size-2)\",\n marginBlockStart: \"var(--a2-size-3)\",\n }}\n data-chromatic=\"ignore\"\n >\n {[0, 1, 2].map((i) => (\n <motion.div\n key={i}\n custom={i}\n variants={dotVariants}\n animate=\"bounce\"\n data-chromatic=\"ignore\"\n style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n background: \"var(--a2-foreground-color-primary)\",\n }}\n />\n ))}\n </Flex>\n );\n};\n"],"names":[],"mappings":";;;;AAIA,MAAM,WAAA,GAAc;AAAA,EAClB,MAAA,EAAQ,CAAC,CAAA,MAAe;AAAA,IACtB,CAAA,EAAG,CAAC,CAAA,EAAG,GAAA,EAAK,CAAC,CAAA;AAAA,IACb,UAAA,EAAY;AAAA,MACV,QAAA,EAAU,GAAA;AAAA,MACV,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ,QAAA;AAAA,MACR,OAAO,CAAA,GAAI;AAAA;AACb,GACF;AACF,CAAA;AAEO,MAAM,SAAa,MAAM;AAC9B,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,YAAA,EAAW,iBAAA;AAAA,MACX,KAAA,EAAO;AAAA,QACL,iBAAA,EAAmB,kBAAA;AAAA,QACnB,gBAAA,EAAkB;AAAA,OACpB;AAAA,MACA,gBAAA,EAAe,QAAA;AAAA,MAEd,WAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,qBACd,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UAEC,MAAA,EAAQ,CAAA;AAAA,UACR,QAAA,EAAU,WAAA;AAAA,UACV,OAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAe,QAAA;AAAA,UACf,KAAA,EAAO;AAAA,YACL,KAAA,EAAO,KAAA;AAAA,YACP,MAAA,EAAQ,KAAA;AAAA,YACR,YAAA,EAAc,KAAA;AAAA,YACd,UAAA,EAAY;AAAA;AACd,SAAA;AAAA,QAVK;AAAA,OAYR;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"loader-Cj2z0xxN.js","sources":["../src/components/loader/loader.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { easeInOut, motion } from \"framer-motion\";\nimport { Flex } from \"@servicetitan/anvil2\";\n\nconst dotVariants = {\n bounce: (i: number) => ({\n y: [0, -15, 0],\n transition: {\n duration: 1.2,\n ease: easeInOut,\n repeat: Infinity,\n delay: i * 0.15,\n },\n }),\n};\n\nexport const Loader: FC = () => {\n return (\n <Flex\n role=\"status\"\n aria-label=\"Loading message\"\n style={{\n paddingBlockStart: \"var(--a2-size-2)\",\n marginBlockStart: \"var(--a2-size-3)\",\n }}\n data-chromatic=\"ignore\"\n >\n {[0, 1, 2].map((i) => (\n <motion.div\n key={i}\n custom={i}\n variants={dotVariants}\n animate=\"bounce\"\n data-chromatic=\"ignore\"\n style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n background: \"var(--a2-foreground-color-primary)\",\n }}\n />\n ))}\n </Flex>\n );\n};\n"],"names":[],"mappings":";;;;AAIA,MAAM,WAAA,GAAc;AAAA,EAClB,MAAA,EAAQ,CAAC,CAAA,MAAe;AAAA,IACtB,CAAA,EAAG,CAAC,CAAA,EAAG,GAAA,EAAK,CAAC,CAAA;AAAA,IACb,UAAA,EAAY;AAAA,MACV,QAAA,EAAU,GAAA;AAAA,MACV,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ,QAAA;AAAA,MACR,OAAO,CAAA,GAAI;AAAA;AACb,GACF;AACF,CAAA;AAEO,MAAM,SAAa,MAAM;AAC9B,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,YAAA,EAAW,iBAAA;AAAA,MACX,KAAA,EAAO;AAAA,QACL,iBAAA,EAAmB,kBAAA;AAAA,QACnB,gBAAA,EAAkB;AAAA,OACpB;AAAA,MACA,gBAAA,EAAe,QAAA;AAAA,MAEd,WAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,qBACd,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UAEC,MAAA,EAAQ,CAAA;AAAA,UACR,QAAA,EAAU,WAAA;AAAA,UACV,OAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAe,QAAA;AAAA,UACf,KAAA,EAAO;AAAA,YACL,KAAA,EAAO,KAAA;AAAA,YACP,MAAA,EAAQ,KAAA;AAAA,YACR,YAAA,EAAc,KAAA;AAAA,YACd,UAAA,EAAY;AAAA;AACd,SAAA;AAAA,QAVK;AAAA,OAYR;AAAA;AAAA,GACH;AAEJ;;;;"}
|