Skip to content
11 changes: 11 additions & 0 deletions packages/compass-assistant/src/compass-assistant-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export const CompassAssistantDrawer: React.FunctionComponent<{
);
}

const appName = 'Compass'; // TODO

return (
<DrawerSection
id={ASSISTANT_DRAWER_ID}
Expand All @@ -92,6 +94,15 @@ export const CompassAssistantDrawer: React.FunctionComponent<{
label="MongoDB Assistant"
glyph="Sparkle"
autoOpen={autoOpen}
guideCue={{
cueId: 'assistant-drawer',
title: 'Introducing MongoDB Assistant',
description: `AI-powered assistant to intelligently guide you through your database tasks. Get expert MongoDB help and streamline your workflow directly within ${appName}`,
buttonText: 'Got it',
onPrimaryButtonClick: () => {},
tooltipAlign: 'left',
tooltipJustify: 'start',
}}
>
<AssistantChat
chat={chat}
Expand Down
59 changes: 45 additions & 14 deletions packages/compass-components/src/components/drawer-portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { css, cx } from '@leafygreen-ui/emotion';
import { isEqual } from 'lodash';
import { rafraf } from '../utils/rafraf';
import { GuideCue, type GuideCueProps } from './guide-cue/guide-cue';
import { BaseFontSize, fontWeights } from '@leafygreen-ui/tokens';

type ToolbarData = Required<DrawerLayoutProps>['toolbarData'];
Expand All @@ -37,6 +38,7 @@ type DrawerSectionProps = Omit<SectionData, 'content' | 'onClick'> & {
* provided will stay unordered at the bottom of the list
*/
order?: number;
guideCue?: GuideCueProps<HTMLButtonElement>;
};

type DrawerOpenStateContextValue = boolean;
Expand Down Expand Up @@ -271,21 +273,50 @@ export const DrawerAnchor: React.FunctionComponent = ({ children }) => {
return orderB < orderA ? 1 : orderB > orderA ? -1 : 0;
});
}, [drawerSectionItems]);

const [assistantNodes, setAssistantNodes] = useState<
Record<string, HTMLButtonElement | undefined>
>({});

useEffect(function () {
const nodes: Record<string, HTMLButtonElement | undefined> = {};
for (const [index, item] of toolbarData.entries()) {
const button = document.querySelector(
`[data-testid="lg-drawer-toolbar-icon_button-${index}"]`
);
nodes[item.id] = button ? (button as HTMLButtonElement) : undefined;
}
setAssistantNodes(nodes);
});

return (
<DrawerLayout
displayMode={DrawerDisplayMode.Embedded}
resizable
toolbarData={toolbarData}
className={cx(
drawerLayoutFixesStyles,
toolbarData.length === 0 && emptyDrawerLayoutFixesStyles,
// classname is the only property leafygreen passes over to the drawer
// wrapper component that would allow us to target it
'compass-drawer-anchor'
)}
>
<DrawerContextGrabber>{children}</DrawerContextGrabber>
</DrawerLayout>
<>
{toolbarData.map((item) => {
return (
assistantNodes[item.id] &&
item.guideCue && (
<GuideCue<HTMLButtonElement>
{...item.guideCue}
triggerNode={assistantNodes[item.id]}
/>
)
);
})}
<DrawerLayout
displayMode={DrawerDisplayMode.Embedded}
resizable
toolbarData={toolbarData}
className={cx(
drawerLayoutFixesStyles,
toolbarData.length === 0 && emptyDrawerLayoutFixesStyles,
// classname is the only property leafygreen passes over to the drawer
// wrapper component that would allow us to target it
'compass-drawer-anchor'
)}
>
<DrawerContextGrabber>{children}</DrawerContextGrabber>
</DrawerLayout>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,15 @@ export type GuideCueProps<T> = Omit<
GroupAndStep & {
cueId: string;
description: React.ReactChild;
trigger: ({ ref }: { ref: React.Ref<T> }) => React.ReactElement;
triggerNode?: T;
trigger?: ({ ref }: { ref: React.Ref<T> }) => React.ReactElement;
onOpenChange?: (isOpen: boolean) => void;
};

export const GuideCue = <T extends HTMLElement>({
description,
trigger,
triggerNode,
cueId,
groupId,
step,
Expand All @@ -106,7 +108,7 @@ export const GuideCue = <T extends HTMLElement>({
}: GuideCueProps<T>) => {
const [isCueOpen, setIsCueOpen] = useState(false);
const [isIntersecting, setIsIntersecting] = useState(true);
const refEl = useRef<T>(null);
const refEl = useRef<T>(triggerNode ?? null);
const [readyToRender, setReadyToRender] = useState(false);
const context = useContext(GuideCueContext);

Expand Down Expand Up @@ -276,7 +278,7 @@ export const GuideCue = <T extends HTMLElement>({
{description}
</LGGuideCue>
)}
{trigger({ ref: refEl })}
{trigger?.({ ref: refEl })}
</>
);
};