diff --git a/package-lock.json b/package-lock.json
index 9fa56de14..081f250f7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4727,10 +4727,9 @@
}
},
"node_modules/@leafygreen-ui/icon": {
- "version": "12.7.0",
- "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@leafygreen-ui/icon/-/icon-12.7.0.tgz",
- "integrity": "sha512-RM+ohvFLF9JCj1WumiqiKUSF7bvYNV4uNWgHCWeXFpydJC+j6wqGXpclIXMHYeP2/bl54aHOgmaY/1FKq7QvRA==",
- "license": "Apache-2.0",
+ "version": "12.8.0",
+ "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@leafygreen-ui/icon/-/icon-12.8.0.tgz",
+ "integrity": "sha512-LDYSFtdn+dX3/hyBJJw722grz98To+X9Nw/97F6MUk+D9eNdufzPFYQCd8iDsgUbfeSVJ/uw1PVr20QEJ7Xtcw==",
"dependencies": {
"@leafygreen-ui/emotion": "^4.0.8",
"lodash": "^4.17.21"
@@ -34783,9 +34782,9 @@
}
},
"@leafygreen-ui/icon": {
- "version": "12.7.0",
- "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@leafygreen-ui/icon/-/icon-12.7.0.tgz",
- "integrity": "sha512-RM+ohvFLF9JCj1WumiqiKUSF7bvYNV4uNWgHCWeXFpydJC+j6wqGXpclIXMHYeP2/bl54aHOgmaY/1FKq7QvRA==",
+ "version": "12.8.0",
+ "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@leafygreen-ui/icon/-/icon-12.8.0.tgz",
+ "integrity": "sha512-LDYSFtdn+dX3/hyBJJw722grz98To+X9Nw/97F6MUk+D9eNdufzPFYQCd8iDsgUbfeSVJ/uw1PVr20QEJ7Xtcw==",
"requires": {
"@leafygreen-ui/emotion": "^4.0.8",
"lodash": "^4.17.21"
diff --git a/src/components/ActionBar/ActionBar.js b/src/components/ActionBar/ActionBar.js
index 636043f55..baeb161dd 100644
--- a/src/components/ActionBar/ActionBar.js
+++ b/src/components/ActionBar/ActionBar.js
@@ -1,12 +1,18 @@
-import React, { useContext } from 'react';
+import React, { lazy, useState, useContext } from 'react';
import PropTypes from 'prop-types';
+import Button from '@leafygreen-ui/button';
import { cx } from '@leafygreen-ui/emotion';
import Icon from '@leafygreen-ui/icon';
import { Overline } from '@leafygreen-ui/typography';
+import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
+import IconButton from '@leafygreen-ui/icon-button';
+import { useSiteMetadata } from '../../hooks/use-site-metadata';
import { isBrowser } from '../../utils/is-browser';
import { getPlaintext } from '../../utils/get-plaintext';
import { getNestedValue } from '../../utils/get-nested-value';
import { isOfflineDocsBuild } from '../../utils/is-offline-docs-build';
+import { getCurrLocale } from '../../utils/locale';
+import { reportAnalytics } from '../../utils/report-analytics';
import useSnootyMetadata from '../../utils/use-snooty-metadata';
import { SidenavContext } from '../Sidenav';
import {
@@ -16,6 +22,7 @@ import {
useFeedbackData,
FeedbackContainer,
} from '../Widgets/FeedbackWidget';
+import { SuspenseHelper } from '../SuspenseHelper';
import DarkModeDropdown from './DarkModeDropdown';
import SearchInput from './SearchInput';
import {
@@ -25,13 +32,21 @@ import {
getContainerStyling,
offlineStyling,
overlineStyling,
+ chatbotButtonStyling,
+ chatbotMobileButtonStyling,
} from './styles';
+const Chatbot = lazy(() => import('mongodb-chatbot-ui'));
+const ChatbotModal = lazy(() => import('./ChatbotModal'));
+
export const DEPRECATED_PROJECTS = ['atlas-app-services', 'datalake', 'realm'];
+const CHATBOT_TEXT = 'Ask MongoDB AI';
const ActionBar = ({ template, slug, sidenav, ...props }) => {
const url = isBrowser ? window.location.href : null;
const metadata = useSnootyMetadata();
+ const [chatbotClicked, setChatbotClicked] = useState(false);
+ const locale = getCurrLocale();
const feedbackData = useFeedbackData({
slug,
url,
@@ -43,6 +58,16 @@ const ActionBar = ({ template, slug, sidenav, ...props }) => {
const { hideMobile, setHideMobile } = useContext(SidenavContext);
+ const openChatbot = () => {
+ reportAnalytics('Chatbot button clicked');
+ setChatbotClicked((currVal) => !currVal);
+ };
+ const { snootyEnv } = useSiteMetadata();
+ const { darkMode } = useDarkMode();
+ const CHATBOT_SERVER_BASE_URL = ['dotcomprd', 'production'].includes(snootyEnv)
+ ? 'https://knowledge.mongodb.com/api/v1'
+ : 'https://knowledge.staging.corp.mongodb.com/api/v1';
+
return (
{
{!isOfflineDocsBuild && (
- {template !== 'openapi' && }
+ }
+ aria-label={CHATBOT_TEXT}
+ variant={'primaryOutline'}
+ onClick={openChatbot}
+ >
+ {CHATBOT_TEXT}
+
+
+
+
+ {locale === 'en-us' && (
+
+
+
+
+
+ )}
+
{template !== 'errorpage' && !DEPRECATED_PROJECTS.includes(metadata.project) && (
@@ -68,6 +112,7 @@ const ActionBar = ({ template, slug, sidenav, ...props }) => {
)}
+ {template !== 'openapi' && }
)}
diff --git a/src/components/ActionBar/ChatbotControls.js b/src/components/ActionBar/ChatbotControls.js
deleted file mode 100644
index 9ae07352a..000000000
--- a/src/components/ActionBar/ChatbotControls.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { forwardRef, useCallback, useImperativeHandle } from 'react';
-import { useChatbotContext } from 'mongodb-chatbot-ui';
-import PropTypes from 'prop-types';
-
-// Using a forward ref and imperative handle
-// to expose lazy loaded child (chatbot) behaviors to parent (SearchInput)
-// https://react.dev/reference/react/useImperativeHandle
-const ChatbotControls = forwardRef(function ChatbotControls({ searchValue }, ref) {
- const { setInputText, handleSubmit, openChat } = useChatbotContext();
-
- const onClick = useCallback(async () => {
- await openChat();
- setInputText(searchValue);
- handleSubmit(searchValue);
- }, [handleSubmit, openChat, searchValue, setInputText]);
-
- useImperativeHandle(ref, () => {
- return {
- onClick,
- };
- });
-});
-
-export default ChatbotControls;
-
-ChatbotControls.propTypes = {
- searchValue: PropTypes.string.isRequired,
-};
diff --git a/src/components/ActionBar/ChatbotModal.js b/src/components/ActionBar/ChatbotModal.js
new file mode 100644
index 000000000..420c07ed6
--- /dev/null
+++ b/src/components/ActionBar/ChatbotModal.js
@@ -0,0 +1,37 @@
+import React, { useEffect } from 'react';
+import { useChatbotContext, ModalView, MongoDbLegalDisclosure, PoweredByAtlasVectorSearch } from 'mongodb-chatbot-ui';
+import { css } from '@leafygreen-ui/emotion';
+import { defaultSuggestedPrompts } from '../ChatbotUi';
+
+const ChatbotModal = ({ chatbotClicked, setChatbotClicked }) => {
+ const { openChat } = useChatbotContext();
+ useEffect(() => {
+ if (chatbotClicked) {
+ openChat();
+ setChatbotClicked(false);
+ }
+ }, [chatbotClicked, openChat, setChatbotClicked]);
+
+ return (
+
+
+
+ >
+ }
+ initialMessageText={'Welcome to MongoDB AI'}
+ initialMessageSuggestedPrompts={defaultSuggestedPrompts}
+ />
+ );
+};
+
+export default ChatbotModal;
diff --git a/src/components/ActionBar/SearchInput.js b/src/components/ActionBar/SearchInput.js
index 358f960d7..c5de7c917 100644
--- a/src/components/ActionBar/SearchInput.js
+++ b/src/components/ActionBar/SearchInput.js
@@ -1,112 +1,44 @@
-import React, { lazy, useCallback, useEffect, useRef, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { navigate } from 'gatsby';
import PropTypes from 'prop-types';
import { useLocation } from '@gatsbyjs/reach-router';
import { css, cx } from '@leafygreen-ui/emotion';
import IconButton from '@leafygreen-ui/icon-button';
import Icon from '@leafygreen-ui/icon';
-import { useBackdropClick } from '@leafygreen-ui/hooks';
-import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { SearchInput as LGSearchInput } from '@leafygreen-ui/search-input';
import { Link } from '@leafygreen-ui/typography';
+import { useAllDocsets } from '../../hooks/useAllDocsets';
import useScreenSize from '../../hooks/useScreenSize';
import { useSiteMetadata } from '../../hooks/use-site-metadata';
import { theme } from '../../theme/docsTheme';
-import debounce from '../../utils/debounce';
+import { assertTrailingSlash } from '../../utils/assert-trailing-slash';
import { isBrowser } from '../../utils/is-browser';
-import { SuspenseHelper } from '../SuspenseHelper';
-import { getCurrLocale } from '../../utils/locale';
+import { localizePath } from '../../utils/locale';
+import { reportAnalytics } from '../../utils/report-analytics';
import { searchIconStyling, searchInputStyling, StyledInputContainer, StyledSearchBoxRef } from './styles';
-import { ShortcutIcon, SparkleIcon } from './SparkIcon';
-const Chatbot = lazy(() => import('mongodb-chatbot-ui'));
-const SearchMenu = lazy(() => import('./SearchMenu'));
-export const PLACEHOLDER_TEXT = `Search MongoDB Docs or Ask MongoDB AI`;
-const PLACEHOLDER_TEXT_MOBILE = 'Search or AI';
-
-// taken from LG/lib - our library is out of date
-// https://github.com/mongodb/leafygreen-ui/blob/main/packages/lib/src/index.ts#L102
-const keyMap = {
- ArrowUp: 'ArrowUp',
- ArrowDown: 'ArrowDown',
- ArrowLeft: 'ArrowLeft',
- ArrowRight: 'ArrowRight',
- Backspace: 'Backspace',
- BracketLeft: '[',
- Delete: 'Delete',
- Enter: 'Enter',
- Escape: 'Escape',
- Space: ' ',
- Tab: 'Tab',
-};
-
-export const SEARCH_SUGGESTIONS = [
- {
- copy: 'Search',
- },
- {
- copy: 'Ask MongoDB AI',
- icon: ,
- shortcutIcon: ,
- },
-];
+export const PLACEHOLDER_TEXT = `Search MongoDB Docs`;
+const PLACEHOLDER_TEXT_MOBILE = 'Search';
const SearchInput = ({ className, slug }) => {
const [searchValue, setSearchValue] = useState('');
- const [isOpen, setIsOpen] = useState(false);
- const [isFocused, setIsFocused] = useState(false);
- const [selectedResult, setSelectedResult] = useState();
const searchBoxRef = useRef();
const inputRef = useRef();
- const menuRef = useRef();
- const metadata = useSiteMetadata();
- const { darkMode } = useDarkMode();
- const [selectedOption, setSelectedOption] = useState(0);
+ const { project, snootyEnv } = useSiteMetadata();
const [mobileSearchActive, setMobileSearchActive] = useState(false);
const { search } = useLocation();
- const locale = getCurrLocale();
- const [isChatbotAvail, setChatbotAvail] = useState(false);
- const isEnglish = locale === 'en-us';
-
- useBackdropClick(
- () => {
- setIsOpen(false);
- inputRef.current?.blur();
- },
- [searchBoxRef, menuRef],
- isOpen
- );
-
- useEffect(() => {
- if (!searchValue.length) {
- return setIsOpen(false);
+ const docsets = useAllDocsets();
+
+ const keyPressHandler = useCallback(async (event) => {
+ // cmd+k or ctrl+k focuses search bar,
+ // unless already focused on an input field
+ const holdingCtrlCmd = (navigator.userAgent.includes('Mac') && event.metaKey) || event.ctrlKey;
+ if (holdingCtrlCmd && event.key === 'k' && document.activeElement.tagName.toLowerCase() !== 'input') {
+ event.preventDefault();
+ inputRef.current?.focus();
+ return;
}
- const debounced = debounce(() => {
- setIsOpen(!!searchValue.length && document?.activeElement === inputRef.current);
- }, 500);
- return () => debounced();
- }, [searchValue]);
-
- const keyPressHandler = useCallback(
- async (event) => {
- // cmd+k or ctrl+k focuses search bar,
- // unless already focused on an input field
- const holdingCtrlCmd = (navigator.userAgent.includes('Mac') && event.metaKey) || event.ctrlKey;
- if (holdingCtrlCmd && event.key === 'k' && document.activeElement.tagName.toLowerCase() !== 'input') {
- event.preventDefault();
- inputRef.current?.focus();
- return;
- }
-
- // if currently focused on search input and on English site (therefore, chatbot is an option),
- // activates the chatbot modal
- if (event.target.isSameNode(inputRef.current) && event.key === '/' && isEnglish) {
- event.preventDefault();
- setIsOpen(false);
- setSelectedResult(1);
- }
- },
- [isEnglish]
- );
+ }, []);
// adding keyboard shortcuts document wide
useEffect(() => {
@@ -141,99 +73,48 @@ const SearchInput = ({ className, slug }) => {
}
}, [search]);
- // close menu when changing screen size
- useEffect(() => {
- function handleResize() {
- setIsOpen(false);
- }
- window.addEventListener('resize', handleResize);
- // Remove event listener on cleanup
- return () => window.removeEventListener('resize', handleResize);
- }, [isMobile, mobileSearchActive]);
-
- const handleSearchBoxKeyDown = (e) => {
- const isFocusInMenu = menuRef.current?.contains?.(document.activeElement);
- const isFocusOnSearchBox = searchBoxRef.current?.contains?.(document.activeElement);
- const isFocusInComponent = isFocusOnSearchBox || isFocusInMenu;
- const optionsCount = isChatbotAvail ? 2 : 1;
-
- if (!isFocusInComponent) {
- return;
- }
- switch (e.key) {
- case keyMap.Enter: {
- setSelectedResult(selectedOption);
- setIsOpen(false);
- break;
- }
-
- case keyMap.Escape: {
- setIsOpen(false);
- inputRef.current?.focus();
- break;
- }
-
- case keyMap.ArrowDown: {
- if (isOpen && isEnglish && isChatbotAvail) {
- setSelectedOption((selectedOption + 1) % optionsCount);
- inputRef.current?.focus();
- }
- e.preventDefault();
- break;
- }
-
- case keyMap.ArrowUp: {
- if (isOpen && isEnglish && isChatbotAvail) {
- setSelectedOption(Math.abs(selectedOption - (1 % optionsCount)));
- inputRef.current?.focus();
- }
- e.preventDefault();
- break;
- }
-
- case keyMap.Tab: {
- if (isOpen) {
- setIsOpen(false);
- }
- break;
- }
-
- default: {
- break;
- }
+ // get search url for staging and prod environments
+ // all other environments will fall back to prod
+ // considers localization as well
+ const fullSearchUrl = useMemo(() => {
+ const ENVS_WITH_SEARCH = ['dotcomstg', 'dotcomprd'];
+ const targetEnv = ENVS_WITH_SEARCH.includes(snootyEnv) ? snootyEnv : ENVS_WITH_SEARCH[1];
+ const landingDocset = docsets.find((d) => d.project === 'landing');
+ return (
+ assertTrailingSlash(landingDocset.url[targetEnv]) +
+ localizePath(assertTrailingSlash(landingDocset.prefix[targetEnv]) + 'search')
+ );
+ }, [docsets, snootyEnv]);
+
+ const onSubmit = () => {
+ reportAnalytics('Search bar used', {
+ type: 'docs-search',
+ query: searchValue,
+ });
+ inputRef.current?.blur();
+ if (project === 'landing' && slug === 'search') {
+ const newSearch = new URLSearchParams();
+ newSearch.set('q', searchValue);
+ return navigate(`?${newSearch.toString()}`, { state: { searchValue } });
}
+ return (window.location.href = `${fullSearchUrl}/?q=${searchValue}`);
};
- const CHATBOT_SERVER_BASE_URL = ['dotcomprd', 'production'].includes(metadata?.snootyEnv)
- ? 'https://knowledge.mongodb.com/api/v1'
- : 'https://knowledge.staging.corp.mongodb.com/api/v1';
-
return (
-
+
{
- setIsFocused(true);
setSearchValue(e.target.value);
}}
- onClick={() => {
- setIsOpen(!!searchValue.length);
- }}
- onSubmit={(e) => {
- inputRef.current?.blur();
- setIsOpen(false);
- }}
onFocus={() => {
- setIsFocused(true);
+ reportAnalytics('Search bar focused');
}}
+ onSubmit={onSubmit}
ref={inputRef}
/>
@@ -253,28 +134,11 @@ const SearchInput = ({ className, slug }) => {
Cancel
)}
-
-
-
-
-
{!mobileSearchActive && (
{
- setIsOpen(false);
setMobileSearchActive((state) => !state);
}}
>
diff --git a/src/components/ActionBar/SearchMenu.js b/src/components/ActionBar/SearchMenu.js
deleted file mode 100644
index a3e366fbd..000000000
--- a/src/components/ActionBar/SearchMenu.js
+++ /dev/null
@@ -1,155 +0,0 @@
-import React, { forwardRef, useEffect, useMemo, useState } from 'react';
-import { navigate } from 'gatsby';
-import { SearchResultsMenu, SearchResult } from '@leafygreen-ui/search-input';
-import { css, cx } from '@leafygreen-ui/emotion';
-import { ModalView, MongoDbLegalDisclosure, PoweredByAtlasVectorSearch, useChatbotContext } from 'mongodb-chatbot-ui';
-import PropTypes from 'prop-types';
-import { useAllDocsets } from '../../hooks/useAllDocsets';
-import { useSiteMetadata } from '../../hooks/use-site-metadata';
-import { assertTrailingSlash } from '../../utils/assert-trailing-slash';
-import { getCurrLocale, localizePath } from '../../utils/locale';
-import { reportAnalytics } from '../../utils/report-analytics';
-import useSnootyMetadata from '../../utils/use-snooty-metadata';
-import { suggestionStyling } from './styles';
-import { SEARCH_SUGGESTIONS } from './SearchInput';
-
-const SearchMenu = forwardRef(function SearchMenu(
- {
- searchValue,
- searchBoxRef,
- isOpen,
- selectedOption,
- slug,
- selectedResult,
- setSelectedResult,
- isFocused,
- setChatbotAvail,
- },
- ref
-) {
- const { handleSubmit, conversation } = useChatbotContext();
- const { project } = useSnootyMetadata();
- const docsets = useAllDocsets();
- const { snootyEnv } = useSiteMetadata();
- const locale = getCurrLocale();
- const [conversationInit, setConversationInit] = useState(false);
-
- // get search url for staging and prod environments
- // all other environments will fall back to prod
- // considers localization as well
- const fullSearchUrl = useMemo(() => {
- const ENVS_WITH_SEARCH = ['dotcomstg', 'dotcomprd'];
- const targetEnv = ENVS_WITH_SEARCH.includes(snootyEnv) ? snootyEnv : ENVS_WITH_SEARCH[1];
- const landingDocset = docsets.find((d) => d.project === 'landing');
- return (
- assertTrailingSlash(landingDocset.url[targetEnv]) +
- localizePath(assertTrailingSlash(landingDocset.prefix[targetEnv]) + 'search')
- );
- }, [docsets, snootyEnv]);
-
- const handleSearchResultClick = async (isChatbotRes) => {
- reportAnalytics('Search bar used', {
- type: isChatbotRes ? 'chatbot' : 'docs-search',
- query: searchValue,
- });
- setSelectedResult(undefined);
- if (isChatbotRes) {
- return handleSubmit(searchValue).catch((e) => console.error(e));
- }
- if (project === 'landing' && slug === 'search') {
- const newSearch = new URLSearchParams();
- newSearch.set('q', searchValue);
- return navigate(`?${newSearch.toString()}`, { state: { searchValue } });
- }
- return (window.location.href = `${fullSearchUrl}/?q=${searchValue}`);
- };
-
- useEffect(() => {
- if (!Number.isInteger(selectedResult)) {
- return;
- }
- handleSearchResultClick(selectedResult > 0);
- // NOTE: this effect should only run when selected result is changed
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [selectedResult]);
-
- // NOTE: conversation is updated in effect below
- useEffect(() => {
- if (!conversation.conversationId) {
- return;
- }
- setChatbotAvail(!conversation.error && !!conversation.conversationId);
- }, [conversation, setChatbotAvail]);
-
- useEffect(() => {
- if (!isFocused || conversationInit || conversation.conversationId) {
- return;
- }
- setConversationInit(true);
- // NOTE: createConversation does not resolve / throw errors.
- // updates conversation from useChatbotContext instead
- // https://github.com/mongodb/chatbot/blob/mongodb-chatbot-ui-v0.8.1/packages/mongodb-chatbot-ui/src/useConversation.tsx#L409
- conversation.createConversation().finally((e) => setConversationInit(false));
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isFocused]);
-
- const searchOptions = useMemo(() => {
- const useChatbot = !!conversation.conversationId && locale === 'en-us';
- return SEARCH_SUGGESTIONS.slice(0, useChatbot ? SEARCH_SUGGESTIONS.length : 1);
- }, [conversation, locale]);
-
- return (
- <>
-
- {searchOptions.map((suggestion, i) => {
- const { copy } = suggestion;
- const isChatbot = i === 1;
- return (
- setSelectedResult(i)}
- highlighted={selectedOption === i}
- >
- {!isChatbot && <>{searchValue}>}
- {isChatbot && (
- <>
- {suggestion.icon}
- {searchValue}
- {suggestion.shortcutIcon}
- >
- )}
-
- );
- })}
-
-
-
-
- >
- }
- />
- >
- );
-});
-
-export default SearchMenu;
-
-SearchMenu.propTypes = {
- searchValue: PropTypes.string.isRequired,
- searchBoxRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Element) })]),
- isOpen: PropTypes.bool,
- selectedOption: PropTypes.number,
- slug: PropTypes.string,
-};
diff --git a/src/components/ActionBar/styles.js b/src/components/ActionBar/styles.js
index 9486004ad..bd693169a 100644
--- a/src/components/ActionBar/styles.js
+++ b/src/components/ActionBar/styles.js
@@ -1,12 +1,11 @@
import styled from '@emotion/styled';
import { palette } from '@leafygreen-ui/palette';
import { css } from '@leafygreen-ui/emotion';
+import { gridStyling as landingTemplateGridStyling } from '../../templates/landing';
+import { gridStyling as centerGridStyling } from '../../templates/NotFound';
import { theme } from '../../theme/docsTheme';
-import { CONTENT_MAX_WIDTH } from '../../templates/product-landing';
import { displayNone } from '../../utils/display-none';
-const DESKTOP_DARK_MODE_AND_FEEDBACK_BUTTONS_WIDTH = '236px';
-
// default styling for all Action Bars
export const actionBarStyling = css`
display: flex;
@@ -41,10 +40,7 @@ export const actionBarStyling = css`
// used for :template: options - 'product-landing', 'changelog'
const gridStyling = css`
display: grid;
- grid-template-columns: minmax(${theme.size.xlarge}, 1fr) minmax(0, ${CONTENT_MAX_WIDTH}px) minmax(
- ${DESKTOP_DARK_MODE_AND_FEEDBACK_BUTTONS_WIDTH},
- 1fr
- );
+ grid-template-columns: minmax(${theme.size.xlarge}, 1fr) repeat(2, minmax(0, 600px)) minmax(${theme.size.xlarge}, 1fr);
@media ${theme.screenSize.upToLarge} {
grid-template-columns: ${theme.size.medium} 1fr fit-content(100%);
@@ -54,10 +50,7 @@ const gridStyling = css`
// use strictly for :template: landing
const landingGridStyling = css`
display: grid;
- grid-template-columns: minmax(${theme.size.xlarge}, 1fr) minmax(0, ${theme.breakpoints.xxLarge}px) minmax(
- ${DESKTOP_DARK_MODE_AND_FEEDBACK_BUTTONS_WIDTH},
- 1fr
- );
+ ${landingTemplateGridStyling}
@media ${theme.screenSize.upToLarge} {
grid-template-columns: ${theme.size.medium} 1fr fit-content(100%);
}
@@ -76,20 +69,40 @@ const flexStyling = css`
const middleAlignment = css`
display: grid;
- grid-template-columns: ${theme.size.xlarge} repeat(12, minmax(0, 1fr)) ${theme.size.xlarge};
+ ${centerGridStyling}
+
+ @media ${theme.screenSize.upToMedium} {
+ grid-template-columns: repeat(12, 1fr);
+ }
`;
-const centerInGrid = css`
+const leftInGrid = css`
grid-column: 2/-2;
@media ${theme.screenSize.upToLarge} {
- grid-column: 3/-3;
+ grid-column: 2/-3;
+ padding-right: 0;
}
@media ${theme.screenSize.largeAndUp} {
- grid-column: 4/-4;
+ grid-column: 2/-8;
}
@media ${theme.screenSize.xLargeAndUp} {
- grid-column: 6/-5;
+ grid-column: 2/-7;
+ }
+`;
+
+const centerInGrid = css`
+ grid-column: 6/-5;
+
+ @media ${theme.screenSize.upToXLarge} {
+ grid-column: 4/-6;
+ }
+
+ @media ${theme.screenSize.upToLarge} {
+ grid-column: 3/-8;
+ }
+ @media ${theme.screenSize.upToMedium} {
+ grid-column: 3/-2;
}
`;
@@ -97,6 +110,7 @@ export const getContainerStyling = (template) => {
let containerClassname,
searchContainerClassname,
fakeColumns = false;
+
switch (template) {
case 'product-landing':
containerClassname = gridStyling;
@@ -104,6 +118,7 @@ export const getContainerStyling = (template) => {
break;
case 'landing':
containerClassname = landingGridStyling;
+ searchContainerClassname = leftInGrid;
fakeColumns = true;
break;
case 'changelog':
@@ -134,6 +149,10 @@ export const ActionBarSearchContainer = styled.div`
width: 100%;
background: inherit;
+ @media ${theme.screenSize.mediumAndUp} {
+ padding-right: ${theme.size.default};
+ }
+
@media ${theme.screenSize.upToLarge} {
max-width: unset;
justify-content: space-between;
@@ -221,12 +240,13 @@ export const ActionsBox = styled('div')`
grid-column: -2/-1;
@media ${theme.screenSize.upToLarge} {
+ column-gap: 6px;
margin-right: ${theme.size.medium};
+ margin-left: ${theme.size.small};
}
@media ${theme.screenSize.upToMedium} {
- margin-left: ${theme.size.small};
- column-gap: ${theme.size.small};
+ margin-left: 1px;
}
`;
@@ -254,34 +274,33 @@ export const overlineStyling = css`
export const searchIconStyling = css`
${displayNone.onLargerThanMedium};
float: right;
+ justify-content: right;
`;
-// using content before/after to prevent event bubbling up from lg/search-input/search-result
-// package above gets all text inside node, and sets the value of Input node of all text within search result:
-// https://github.com/mongodb/leafygreen-ui/blob/%40leafygreen-ui/search-input%402.1.4/packages/search-input/src/SearchInput/SearchInput.tsx#L149-L155
-export const suggestionStyling = ({ copy }) => css`
- & > div:before {
- content: '${copy} "';
- }
-
- & > div:after {
- content: '"';
+export const offlineStyling = css`
+ @media ${theme.screenSize.largeAndUp} {
+ display: none;
}
+`;
- svg:first-of-type {
- float: left;
- margin-right: ${theme.size.tiny};
+const hideOnEnLang = `
+ &:not(:lang(EN)) {
+ display: none;
}
+`;
- padding: ${theme.fontSize.tiny} ${theme.size.medium};
-
- svg:last-of-type {
- float: right;
- }
+export const chatbotButtonStyling = css`
+ text-wrap-mode: nowrap;
+ ${displayNone.onMobileAndTablet};
+ ${hideOnEnLang}
`;
-export const offlineStyling = css`
- @media ${theme.screenSize.largeAndUp} {
- display: none;
+export const chatbotMobileButtonStyling = css`
+ ${displayNone.onLargerThanTablet}
+ ${hideOnEnLang}
+ color: ${palette.green.dark2};
+
+ .dark-theme & {
+ color: ${palette.green.dark1};
}
`;
diff --git a/src/components/Widgets/FeedbackWidget/FeedbackButton.js b/src/components/Widgets/FeedbackWidget/FeedbackButton.js
index 9a26fc141..850538ca6 100644
--- a/src/components/Widgets/FeedbackWidget/FeedbackButton.js
+++ b/src/components/Widgets/FeedbackWidget/FeedbackButton.js
@@ -10,19 +10,12 @@ import { useFeedbackContext } from './context';
import { FEEDBACK_BUTTON_TEXT } from './constants';
const darkModePrestyling = css`
- color: ${palette.green.dark2};
- border-color: ${palette.green.dark2};
-
- svg {
- color: ${palette.green.dark2};
- }
-
.dark-theme & {
- color: ${palette.green.base};
- border-color: ${palette.green.base};
+ color: ${palette.white};
+ border-color: ${palette.gray.base};
svg {
- color: ${palette.green.base};
+ color: ${palette.white};
}
}
`;
@@ -47,7 +40,7 @@ const FeedbackButton = () => {
`
)}
onClick={() => (!feedback ? initializeFeedback() : abandon())}
- variant={Variant.PrimaryOutline}
+ variant={Variant.Default}
leftGlyph={}
>
{FEEDBACK_BUTTON_TEXT}
diff --git a/src/templates/NotFound.js b/src/templates/NotFound.js
index 655064764..e59bb6388 100644
--- a/src/templates/NotFound.js
+++ b/src/templates/NotFound.js
@@ -135,8 +135,7 @@ export const NotFoundContainer = styled.div`
}
`;
-export const Wrapper = styled('main')`
- display: grid;
+export const gridStyling = `
@media ${theme.screenSize.mediumAndUp} {
grid-template-columns: ${`${theme.size.xlarge} repeat(12, minmax(0, 1fr)) ${theme.size.xlarge};`};
}
@@ -154,6 +153,11 @@ export const Wrapper = styled('main')`
}
`;
+export const Wrapper = styled('main')`
+ display: grid;
+ ${gridStyling}
+`;
+
const NotFound = () => {
return (
diff --git a/src/templates/landing.js b/src/templates/landing.js
index 95802ccfb..b4b461f47 100644
--- a/src/templates/landing.js
+++ b/src/templates/landing.js
@@ -4,9 +4,34 @@ import { useTheme, Global, css } from '@emotion/react';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { palette } from '@leafygreen-ui/palette';
import PropTypes from 'prop-types';
+import { theme } from '../theme/docsTheme';
const CONTENT_MAX_WIDTH = 1440;
+export const gridStyling = `
+
+// Use leftmost and rightmost grid columns as "margins" to allow the hero image
+// to span across the page while remaining as part of the document flow
+@media ${theme.screenSize.mediumAndUp} {
+ grid-template-columns: ${`minmax(${theme.size.xlarge}, 1fr) repeat(12, minmax(0, ${
+ CONTENT_MAX_WIDTH / 12
+ }px)) minmax(${theme.size.xlarge}, 1fr);`};
+}
+
+@media ${theme.screenSize.upToMedium} {
+ grid-template-columns: 48px repeat(12, 1fr) 48px;
+}
+
+@media ${theme.screenSize.upToSmall} {
+ grid-template-columns: ${theme.size.large} 1fr ${theme.size.large};
+}
+
+@media ${theme.screenSize.upToXSmall} {
+ grid-template-columns: ${theme.size.medium} 1fr ${theme.size.medium};
+}
+
+`;
+
const Wrapper = styled('main')`
margin: 0 auto;
width: 100%;
@@ -16,26 +41,7 @@ const Wrapper = styled('main')`
display: grid;
grid-column: 1 / -1;
- // Use leftmost and rightmost grid columns as "margins" to allow the hero image
- // to span across the page while remaining as part of the document flow
- @media ${({ theme }) => theme.screenSize.mediumAndUp} {
- grid-template-columns: ${({ theme }) =>
- `minmax(${theme.size.xlarge}, 1fr) repeat(12, minmax(0, ${CONTENT_MAX_WIDTH / 12}px)) minmax(${
- theme.size.xlarge
- }, 1fr);`};
- }
-
- @media ${({ theme }) => theme.screenSize.upToMedium} {
- grid-template-columns: 48px repeat(12, 1fr) 48px;
- }
-
- @media ${({ theme }) => theme.screenSize.upToSmall} {
- grid-template-columns: ${({ theme }) => theme.size.large} 1fr ${({ theme }) => theme.size.large};
- }
-
- @media ${({ theme }) => theme.screenSize.upToXSmall} {
- grid-template-columns: ${({ theme }) => theme.size.medium} 1fr ${({ theme }) => theme.size.medium};
- }
+ ${gridStyling};
& > .card-group {
@media ${({ theme }) => theme.screenSize.mediumAndUp} {