From 7c4f8e5261dddb9c3cda5cf193ca339a5ede3a8a Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Tue, 24 Jun 2025 15:07:10 +0200 Subject: [PATCH 01/19] feat: add new searchbox - initial setup --- .../components/Common/Search/index.module.css | 53 +++ apps/site/components/Common/Search/index.tsx | 430 ++++++++++++++++-- .../components/Common/SearchOld/index.tsx | 145 ++++++ .../Common/{Search => SearchOld}/utils.ts | 0 apps/site/package.json | 2 + pnpm-lock.yaml | 95 +++- 6 files changed, 659 insertions(+), 66 deletions(-) create mode 100644 apps/site/components/Common/Search/index.module.css create mode 100644 apps/site/components/Common/SearchOld/index.tsx rename apps/site/components/Common/{Search => SearchOld}/utils.ts (100%) diff --git a/apps/site/components/Common/Search/index.module.css b/apps/site/components/Common/Search/index.module.css new file mode 100644 index 0000000000000..a2e9f378d7276 --- /dev/null +++ b/apps/site/components/Common/Search/index.module.css @@ -0,0 +1,53 @@ +@reference "../../../styles/index.css"; + +.searchButton { + @apply text-accent1-100 + dark:text-accent1-100 + flex + grow + cursor-pointer + items-center + justify-center + gap-1; +} + +.searchButtonContent { + @apply flex + flex-nowrap + items-center + gap-2 + text-sm; +} + +.modalWrapper { + @apply fixed + left-0 + top-0 + z-50 + flex + h-full + w-full + bg-white/70 + dark:bg-neutral-950/70; +} + +.modalInner { + @apply inset-0 + flex + flex-col + justify-between + bg-neutral-100 + sm:bottom-auto + sm:top-[5vh] + sm:mx-auto + sm:max-h-[70vh] + sm:min-h-[200px] + sm:w-[80%] + sm:max-w-[720px] + sm:rounded-xl + sm:border + sm:border-neutral-200 + sm:p-0 + dark:bg-neutral-950 + sm:dark:border-neutral-900; +} diff --git a/apps/site/components/Common/Search/index.tsx b/apps/site/components/Common/Search/index.tsx index 0c12664b61826..4e63670824367 100644 --- a/apps/site/components/Common/Search/index.tsx +++ b/apps/site/components/Common/Search/index.tsx @@ -1,27 +1,48 @@ 'use client'; -import { OramaSearchBox, OramaSearchButton } from '@orama/react-components'; -import { useTranslations, useLocale } from 'next-intl'; -import { useTheme } from 'next-themes'; -import type { FC } from 'react'; - -import { useRouter } from '#site/navigation.mjs'; +import { ArrowUpIcon, ClipboardDocumentIcon } from '@heroicons/react/20/solid'; +import { ArrowLeftIcon } from '@heroicons/react/24/outline'; import { - ORAMA_CLOUD_ENDPOINT, - ORAMA_CLOUD_API_KEY, - DEFAULT_ORAMA_QUERY_PARAMS, - DEFAULT_ORAMA_SUGGESTIONS, - BASE_URL, -} from '#site/next.constants.mjs'; - -type ResultMapDescription = { - path: string; - pageSectionTitle: string; -}; + ArrowDownIcon, + CircleStackIcon, + MagnifyingGlassIcon, + PauseCircleIcon, +} from '@heroicons/react/24/solid'; +import { CollectionManager } from '@orama/core'; +import ChatInteractions from '@orama/ui/components/ChatInteractions'; +import ChatRoot from '@orama/ui/components/ChatRoot'; +import FacetTabs from '@orama/ui/components/FacetTabs'; +import Modal from '@orama/ui/components/Modal'; +import PromptTextArea from '@orama/ui/components/PromptTextArea'; +import SearchInput from '@orama/ui/components/SearchInput'; +import SearchResults from '@orama/ui/components/SearchResults'; +import SearchRoot from '@orama/ui/components/SearchRoot'; +import { SlidingPanel } from '@orama/ui/components/SlidingPanel'; +import Suggestions from '@orama/ui/components/Suggestions'; +import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; +import classNames from 'classnames'; +import { useTranslations } from 'next-intl'; +// import { useTheme } from 'next-themes'; +import { Fragment, useState, type FC, type PropsWithChildren } from 'react'; + +// import { useRouter } from '#site/navigation.mjs'; +// import { +// ORAMA_CLOUD_ENDPOINT, +// ORAMA_CLOUD_API_KEY, +// DEFAULT_ORAMA_QUERY_PARAMS, +// DEFAULT_ORAMA_SUGGESTIONS, +// BASE_URL, +// } from '#site/next.constants.mjs'; + +import styles from './index.module.css'; -type ResultMapPath = { path: string; siteSection: string }; +const oramaClient = new CollectionManager({ + url: 'https://staging.collections.orama.com', + collectionID: 'dpygf82gs9bvtf6o85fjuj40', + readAPIKey: '2pj8SUaPGbakScglDBHfJbV5aIuWmT7y', +}); -import { themeConfig, translationKeys } from './utils'; +// import { themeConfig, translationKeys } from './utils'; const uppercaseFirst = (word: string) => word.charAt(0).toUpperCase() + word.slice(1); @@ -35,40 +56,164 @@ const getFormattedPath = (path: string, title: string) => .filter(Boolean) .join(' > ')} — ${title}`; -const SearchButton: FC = () => { - const { resolvedTheme } = useTheme(); - const t = useTranslations(); - const locale = useLocale(); - const colorScheme = resolvedTheme as 'light' | 'dark'; - const router = useRouter(); - - const sourceMap = { - title: 'pageSectionTitle', - description: 'formattedPath', - path: 'path', - }; +const InnerSearchBox: FC = () => { + // const { resolvedTheme } = useTheme(); + // const t = useTranslations(); + // const locale = useLocale(); + // const colorScheme = resolvedTheme as 'light' | 'dark'; + // const router = useRouter(); + const [displayChat, setDisplayChat] = useState(false); + const { + containerRef, + showGoToBottomButton, + scrollToBottom, + recalculateGoToBottomButton, + } = useScrollableContainer(); - const resultMap = { - ...sourceMap, - description: ({ path, pageSectionTitle }: ResultMapDescription) => - getFormattedPath(path, pageSectionTitle), - path: ({ path, siteSection }: ResultMapPath) => - siteSection.toLowerCase() === 'docs' ? `/${path}` : `/${locale}/${path}`, - section: 'siteSection', - }; + // const sourceMap = { + // title: 'pageSectionTitle', + // description: 'formattedPath', + // path: 'path', + // }; + + // const resultMap = { + // ...sourceMap, + // description: ({ path, pageSectionTitle }: ResultMapDescription) => + // getFormattedPath(path, pageSectionTitle), + // path: ({ path, siteSection }: ResultMapPath) => + // siteSection.toLowerCase() === 'docs' ? `/${path}` : `/${locale}/${path}`, + // section: 'siteSection', + // }; return ( <> - + + + + - + + {(group, isSelected) => ( + + {group.name} ({group.count}) + + )} + + + + + {searchTerm => ( + <> + {searchTerm ? ( +

+ {`No results found for "${searchTerm}". Please try a different search term.`} +

+ ) : ( + +

+ Suggestions +

+ + setDisplayChat(true)} + className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" + itemClassName="cursor-pointer" + > + How to install Node.js? + + setDisplayChat(true)} + className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" + itemClassName="cursor-pointer" + > + How to create an HTTP server? + + setDisplayChat(true)} + className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" + itemClassName="cursor-pointer" + > + Upgrading Node.js version + + +
+ )} + + )} +
+ +
+ + {group => ( +
+

+ {group.name} +

+ + {hit => ( + + {/* CUSTOM ITEM CONTENT */} + {typeof hit.document?.pageSectionTitle === 'string' && ( +

+ {hit.document?.pageSectionTitle} +

+ )} + {typeof hit.document?.pageSectionTitle === 'string' && + typeof hit.document?.path === 'string' && ( +

+ {getFormattedPath( + hit.document?.path, + hit.document?.pageSectionTitle + )} +

+ )} +
+ )} +
+
+ )} +
+
+ {/* { // result.path already contains LOCALE. Locale is set to undefined here so router does not add it once again. router.push(fullURLObject.href, { locale: undefined }); }} - /> + /> */} + setDisplayChat(false)} + > + + +
+
+ +
+ +
+ scrollToBottom({ animated: true })} + className="relative h-full items-start overflow-y-auto" + > + {(interaction, index, totalInteractions) => ( + <> + +

{interaction.query}

+
+ {interaction.loading && + !interaction.response && ( // TODO; use theme +
+
+
+
+ )} + + {(document, index: number) => ( +
+
+ + {document?.title as string} + + + {typeof document?.content === 'string' + ? document.content.substring(0, 40) + : ''} + ... + +
+
+ )} +
+ + + {interaction.response} + + + {interaction.response && !interaction.loading && ( +
+ + {index === totalInteractions && ( +
+ + Reset all + +
+ )} +
+
    + {index === totalInteractions && ( +
  • + + + +
  • + )} +
  • + + } + > + {/* */} + Copy + +
  • +
+
+ )} + + )} +
+
+
+ {showGoToBottomButton && ( + + )} + + + } + className={`cursor-pointer rounded-lg p-2 text-white transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-50`} + > + + + +
+
+
+
+ + ); +}; + +const OramaSearch: FC = () => { + const [open, setOpen] = useState(false); + const t = useTranslations(); + + const openSearchBox = (): void => { + setOpen(true); + }; + return ( + <> + + + setOpen(false)} + closeOnOutsideClick={true} + closeOnEscape={true} + className={styles.modalWrapper} + > + + + + + + + + + + ); }; -export default SearchButton; +export default OramaSearch; diff --git a/apps/site/components/Common/SearchOld/index.tsx b/apps/site/components/Common/SearchOld/index.tsx new file mode 100644 index 0000000000000..0c12664b61826 --- /dev/null +++ b/apps/site/components/Common/SearchOld/index.tsx @@ -0,0 +1,145 @@ +'use client'; + +import { OramaSearchBox, OramaSearchButton } from '@orama/react-components'; +import { useTranslations, useLocale } from 'next-intl'; +import { useTheme } from 'next-themes'; +import type { FC } from 'react'; + +import { useRouter } from '#site/navigation.mjs'; +import { + ORAMA_CLOUD_ENDPOINT, + ORAMA_CLOUD_API_KEY, + DEFAULT_ORAMA_QUERY_PARAMS, + DEFAULT_ORAMA_SUGGESTIONS, + BASE_URL, +} from '#site/next.constants.mjs'; + +type ResultMapDescription = { + path: string; + pageSectionTitle: string; +}; + +type ResultMapPath = { path: string; siteSection: string }; + +import { themeConfig, translationKeys } from './utils'; + +const uppercaseFirst = (word: string) => + word.charAt(0).toUpperCase() + word.slice(1); + +const getFormattedPath = (path: string, title: string) => + `${path + .replace(/#.+$/, '') + .split('/') + .map(element => element.replaceAll('-', ' ')) + .map(element => uppercaseFirst(element)) + .filter(Boolean) + .join(' > ')} — ${title}`; + +const SearchButton: FC = () => { + const { resolvedTheme } = useTheme(); + const t = useTranslations(); + const locale = useLocale(); + const colorScheme = resolvedTheme as 'light' | 'dark'; + const router = useRouter(); + + const sourceMap = { + title: 'pageSectionTitle', + description: 'formattedPath', + path: 'path', + }; + + const resultMap = { + ...sourceMap, + description: ({ path, pageSectionTitle }: ResultMapDescription) => + getFormattedPath(path, pageSectionTitle), + path: ({ path, siteSection }: ResultMapPath) => + siteSection.toLowerCase() === 'docs' ? `/${path}` : `/${locale}/${path}`, + section: 'siteSection', + }; + + return ( + <> + + {t('components.search.searchPlaceholder')} + + + [key, t(`components.search.${key}`)]) + )} + searchParams={DEFAULT_ORAMA_QUERY_PARAMS} + suggestions={DEFAULT_ORAMA_SUGGESTIONS} + chatMarkdownLinkHref={({ href }) => { + if (!href) { + return href; + } + + const baseURLObject = new URL(BASE_URL); + const baseURLHostName = baseURLObject.hostname; + + const searchBoxURLObject = new URL(href); + const searchBoxURLHostName = searchBoxURLObject.hostname; + const serachBoxURLPathName = searchBoxURLObject.pathname; + + // We do not want to add the locale to the url for external links and docs links + if ( + baseURLHostName !== searchBoxURLHostName || + serachBoxURLPathName.startsWith('/docs/') + ) { + return href; + } + + const URLWithLocale = new URL( + `${locale}${searchBoxURLObject.pathname}`, + searchBoxURLObject.origin + ); + + return URLWithLocale.href; + }} + onAnswerSourceClick={event => { + event.preventDefault(); + + const baseURLObject = new URL(BASE_URL); + + const { path } = event.detail.source; + + const finalPath = path.startsWith('docs/') + ? path + : `${locale}/${path}`; + + const finalURL = new URL(finalPath, baseURLObject); + + window.open(finalURL, '_blank'); + }} + onSearchResultClick={event => { + event.preventDefault(); + + const fullURLObject = new URL(event.detail.result.path, BASE_URL); + + // result.path already contains LOCALE. Locale is set to undefined here so router does not add it once again. + router.push(fullURLObject.href, { locale: undefined }); + }} + /> + + ); +}; + +export default SearchButton; diff --git a/apps/site/components/Common/Search/utils.ts b/apps/site/components/Common/SearchOld/utils.ts similarity index 100% rename from apps/site/components/Common/Search/utils.ts rename to apps/site/components/Common/SearchOld/utils.ts diff --git a/apps/site/package.json b/apps/site/package.json index bdd04d21b59d5..6d9db7fe0545c 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -42,6 +42,8 @@ "@opentelemetry/sdk-logs": "~0.202.0", "@orama/react-components": "^0.8.1", "@oramacloud/client": "^2.1.4", + "@orama/ui": "^0.0.4", + "@orama/core": "^0.1.10", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-toast": "^1.2.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b3dfd68b48b0..8705bf7cd5bee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,9 +99,15 @@ importers: '@opentelemetry/sdk-logs': specifier: ~0.202.0 version: 0.202.0(@opentelemetry/api@1.9.0) + '@orama/core': + specifier: ^0.1.10 + version: 0.1.10 '@orama/react-components': - specifier: ^0.8.1 - version: 0.8.1(@stencil/core@4.30.0)(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^0.8.0 + version: 0.8.0(@stencil/core@4.30.0)(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@orama/ui': + specifier: ^0.0.4 + version: 0.0.4(@orama/core@0.1.10)(@types/react@19.1.6)(react@19.1.0) '@oramacloud/client': specifier: ^2.1.4 version: 2.1.4 @@ -1927,8 +1933,8 @@ packages: resolution: {integrity: sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==} engines: {node: '>=14'} - '@orama/core@0.1.11': - resolution: {integrity: sha512-cxs2ZrPlL0qCO91ba1FkFg/CX569v6Pqbo0e7EEvRVObBSOI1N1PIYAQ7lTXBUN7mDjpqHvPgOJ0mUuvotSl+Q==} + '@orama/core@0.1.10': + resolution: {integrity: sha512-Sqmdg61fE0D1yzKhqosjasgxqP7/9W5uBz9GRFPkt4Q0qTJ3rxm8hCfhFkPbLWNZAZuOANuzXiU3h8nzaFquww==} '@orama/cuid2@2.2.3': resolution: {integrity: sha512-Lcak3chblMejdlSHgYU2lS2cdOhDpU6vkfIJH4m+YKvqQyLqs1bB8+w6NT1MG5bO12NUK2GFc34Mn2xshMIQ1g==} @@ -1957,8 +1963,14 @@ packages: '@orama/orama': 3.1.9 '@oramacloud/client': ^2.1.1 - '@orama/wc-components@0.8.1': - resolution: {integrity: sha512-VLNIbPu9bOwr6bQgvpEmZvifaExf6disF8+zz1f/ipjmcNpZZL+0CWRmkvf5FNg1PHN3WvJrdulrfP01QwLljQ==} + '@orama/ui@0.0.4': + resolution: {integrity: sha512-dWxTgsY4nm9ytGjuFflz1W8XTcJqZ71FxRsMZmj5qaK+/wdpBbcD8n+FlkWkiULLnAuEnVQ97wTX/RSE+siMrg==} + peerDependencies: + '@orama/core': ^0.1.8 + react: ^19 + + '@orama/wc-components@0.8.0': + resolution: {integrity: sha512-G0PUACezU7atmD8BlydqqUtIznOSfZ2rzf2oJ9jDfTtx4Nrzuo4mWdAOTqcsEZRxzIOjzgZkjLPJLFsOugfjqQ==} '@oramacloud/client@2.1.4': resolution: {integrity: sha512-uNPFs4wq/iOPbggCwTkVNbIr64Vfd7ZS/h+cricXVnzXWocjDTfJ3wLL4lr0qiSu41g8z+eCAGBqJ30RO2O4AA==} @@ -5028,6 +5040,9 @@ packages: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -6467,6 +6482,11 @@ packages: printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + prism-react-renderer@1.3.5: + resolution: {integrity: sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==} + peerDependencies: + react: '>=0.14.9' + proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -6549,6 +6569,12 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-markdown@10.1.0: + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + react-property@2.0.2: resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==} @@ -9916,7 +9942,7 @@ snapshots: '@opentelemetry/semantic-conventions@1.34.0': {} - '@orama/core@0.1.11': + '@orama/core@0.1.10': dependencies: '@orama/cuid2': 2.2.3 dedent: 1.5.3 @@ -9946,18 +9972,29 @@ snapshots: - '@types/react' - babel-plugin-macros - '@orama/switch@3.1.9(@orama/core@0.1.11)(@orama/orama@3.1.9)(@oramacloud/client@2.1.4)': + '@orama/switch@3.1.6(@orama/core@0.1.10)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4)': dependencies: - '@orama/core': 0.1.11 - '@orama/orama': 3.1.9 + '@orama/core': 0.1.10 + '@orama/orama': 3.1.6 '@oramacloud/client': 2.1.4 - '@orama/wc-components@0.8.1': + '@orama/ui@0.0.4(@orama/core@0.1.10)(@types/react@19.1.6)(react@19.1.0)': dependencies: - '@orama/core': 0.1.11 + '@orama/core': 0.1.10 + prism-react-renderer: 1.3.5(react@19.1.0) + react: 19.1.0 + react-markdown: 10.1.0(@types/react@19.1.6)(react@19.1.0) + remark-gfm: 4.0.1 + transitivePeerDependencies: + - '@types/react' + - supports-color + + '@orama/wc-components@0.8.0': + dependencies: + '@orama/core': 0.1.10 '@orama/highlight': 0.1.9 - '@orama/orama': 3.1.9 - '@orama/switch': 3.1.9(@orama/core@0.1.11)(@orama/orama@3.1.9)(@oramacloud/client@2.1.4) + '@orama/orama': 3.1.6 + '@orama/switch': 3.1.6(@orama/core@0.1.10)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4) '@oramacloud/client': 2.1.4 '@phosphor-icons/webcomponents': 2.1.5 '@stencil/core': 4.30.0 @@ -12866,14 +12903,14 @@ snapshots: - bluebird - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) + eslint-import-resolver-typescript: 4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -12906,7 +12943,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -13650,6 +13687,8 @@ snapshots: html-tags@3.3.1: {} + html-url-attributes@3.0.1: {} + html-void-elements@3.0.0: {} html-webpack-plugin@5.6.3(webpack@5.99.9(@swc/core@1.11.24)(esbuild@0.25.5)): @@ -15322,6 +15361,10 @@ snapshots: printable-characters@1.0.42: {} + prism-react-renderer@1.3.5(react@19.1.0): + dependencies: + react: 19.1.0 + proc-log@4.2.0: {} promise-inflight@1.0.1: {} @@ -15403,6 +15446,24 @@ snapshots: react-is@17.0.2: {} + react-markdown@10.1.0(@types/react@19.1.6)(react@19.1.0): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 19.1.6 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.0 + react: 19.1.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + react-property@2.0.2: {} react-remove-scroll-bar@2.3.8(@types/react@19.1.8)(react@19.1.0): From e4d0c1dc3d0035b8699a6c4b33e6eddc0ae15182 Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Tue, 24 Jun 2025 18:57:54 +0200 Subject: [PATCH 02/19] style: search button --- .../components/Common/Search/index.module.css | 45 ++++- apps/site/components/Common/Search/index.tsx | 154 ++++-------------- 2 files changed, 66 insertions(+), 133 deletions(-) diff --git a/apps/site/components/Common/Search/index.module.css b/apps/site/components/Common/Search/index.module.css index a2e9f378d7276..86095bf964951 100644 --- a/apps/site/components/Common/Search/index.module.css +++ b/apps/site/components/Common/Search/index.module.css @@ -1,24 +1,55 @@ @reference "../../../styles/index.css"; -.searchButton { - @apply text-accent1-100 - dark:text-accent1-100 +.searchWrapper { + @apply relative flex + w-full + flex-shrink-0; +} + +.searchButton { + @apply flex grow cursor-pointer items-center - justify-center - gap-1; + justify-between + gap-1 + rounded-xl + border + border-neutral-300 + bg-white + p-2 + text-neutral-900 + transition-colors + duration-300 + hover:bg-neutral-100 + dark:border-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200 + hover:dark:bg-neutral-900; } .searchButtonContent { @apply flex flex-nowrap items-center - gap-2 + gap-1 text-sm; } +.searchButtonShortcut { + @apply hidden + rounded-md + bg-neutral-300 + px-2 + py-1 + text-sm + text-neutral-800 + sm:inline + dark:bg-neutral-900 + dark:text-neutral-400; +} + .modalWrapper { @apply fixed left-0 @@ -28,7 +59,7 @@ h-full w-full bg-white/70 - dark:bg-neutral-950/70; + dark:bg-neutral-950/85; } .modalInner { diff --git a/apps/site/components/Common/Search/index.tsx b/apps/site/components/Common/Search/index.tsx index 4e63670824367..2883217bd0677 100644 --- a/apps/site/components/Common/Search/index.tsx +++ b/apps/site/components/Common/Search/index.tsx @@ -21,19 +21,11 @@ import { SlidingPanel } from '@orama/ui/components/SlidingPanel'; import Suggestions from '@orama/ui/components/Suggestions'; import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; import classNames from 'classnames'; +import Link from 'next/link'; +import { useLocale } from 'next-intl'; import { useTranslations } from 'next-intl'; -// import { useTheme } from 'next-themes'; import { Fragment, useState, type FC, type PropsWithChildren } from 'react'; -// import { useRouter } from '#site/navigation.mjs'; -// import { -// ORAMA_CLOUD_ENDPOINT, -// ORAMA_CLOUD_API_KEY, -// DEFAULT_ORAMA_QUERY_PARAMS, -// DEFAULT_ORAMA_SUGGESTIONS, -// BASE_URL, -// } from '#site/next.constants.mjs'; - import styles from './index.module.css'; const oramaClient = new CollectionManager({ @@ -42,8 +34,6 @@ const oramaClient = new CollectionManager({ readAPIKey: '2pj8SUaPGbakScglDBHfJbV5aIuWmT7y', }); -// import { themeConfig, translationKeys } from './utils'; - const uppercaseFirst = (word: string) => word.charAt(0).toUpperCase() + word.slice(1); @@ -57,11 +47,7 @@ const getFormattedPath = (path: string, title: string) => .join(' > ')} — ${title}`; const InnerSearchBox: FC = () => { - // const { resolvedTheme } = useTheme(); - // const t = useTranslations(); - // const locale = useLocale(); - // const colorScheme = resolvedTheme as 'light' | 'dark'; - // const router = useRouter(); + const locale = useLocale(); const [displayChat, setDisplayChat] = useState(false); const { containerRef, @@ -70,24 +56,9 @@ const InnerSearchBox: FC = () => { recalculateGoToBottomButton, } = useScrollableContainer(); - // const sourceMap = { - // title: 'pageSectionTitle', - // description: 'formattedPath', - // path: 'path', - // }; - - // const resultMap = { - // ...sourceMap, - // description: ({ path, pageSectionTitle }: ResultMapDescription) => - // getFormattedPath(path, pageSectionTitle), - // path: ({ path, siteSection }: ResultMapPath) => - // siteSection.toLowerCase() === 'docs' ? `/${path}` : `/${locale}/${path}`, - // section: 'siteSection', - // }; - return ( <> - + = () => { {hit => ( - - {/* CUSTOM ITEM CONTENT */} - {typeof hit.document?.pageSectionTitle === 'string' && ( -

- {hit.document?.pageSectionTitle} -

- )} - {typeof hit.document?.pageSectionTitle === 'string' && - typeof hit.document?.path === 'string' && ( -

- {getFormattedPath( - hit.document?.path, - hit.document?.pageSectionTitle - )} -

+ + + {typeof hit.document?.pageSectionTitle === 'string' && ( +

+ {hit.document?.pageSectionTitle} +

)} + {typeof hit.document?.pageSectionTitle === 'string' && + typeof hit.document?.path === 'string' && ( +

+ {getFormattedPath( + hit.document?.path, + hit.document?.pageSectionTitle + )} +

+ )} +
)}
@@ -213,76 +184,6 @@ const InnerSearchBox: FC = () => { )} - {/* [key, t(`components.search.${key}`)]) - )} - searchParams={DEFAULT_ORAMA_QUERY_PARAMS} - suggestions={DEFAULT_ORAMA_SUGGESTIONS} - chatMarkdownLinkHref={({ href }) => { - if (!href) { - return href; - } - - const baseURLObject = new URL(BASE_URL); - const baseURLHostName = baseURLObject.hostname; - - const searchBoxURLObject = new URL(href); - const searchBoxURLHostName = searchBoxURLObject.hostname; - const serachBoxURLPathName = searchBoxURLObject.pathname; - - // We do not want to add the locale to the url for external links and docs links - if ( - baseURLHostName !== searchBoxURLHostName || - serachBoxURLPathName.startsWith('/docs/') - ) { - return href; - } - - const URLWithLocale = new URL( - `${locale}${searchBoxURLObject.pathname}`, - searchBoxURLObject.origin - ); - - return URLWithLocale.href; - }} - onAnswerSourceClick={event => { - event.preventDefault(); - - const baseURLObject = new URL(BASE_URL); - - const { path } = event.detail.source; - - const finalPath = path.startsWith('docs/') - ? path - : `${locale}/${path}`; - - const finalURL = new URL(finalPath, baseURLObject); - - window.open(finalURL, '_blank'); - }} - onSearchResultClick={event => { - event.preventDefault(); - - const fullURLObject = new URL(event.detail.result.path, BASE_URL); - - // result.path already contains LOCALE. Locale is set to undefined here so router does not add it once again. - router.push(fullURLObject.href, { locale: undefined }); - }} - /> */} setDisplayChat(false)} @@ -451,6 +352,7 @@ const OramaSearch: FC = () => { {t('components.search.searchPlaceholder')} + ⌘ K Date: Wed, 25 Jun 2025 12:24:17 +0200 Subject: [PATCH 03/19] style: searchbox empty state --- .../components/Common/Search/index.module.css | 84 ---- apps/site/components/Common/Search/index.tsx | 379 ------------------ .../site/components/Common/Searchbox/Chat.tsx | 199 +++++++++ .../components/Common/Searchbox/Search.tsx | 170 ++++++++ .../Common/Searchbox/index.module.css | 194 +++++++++ .../components/Common/Searchbox/index.tsx | 78 ++++ apps/site/components/withNavBar.tsx | 15 +- apps/site/package.json | 2 +- 8 files changed, 651 insertions(+), 470 deletions(-) delete mode 100644 apps/site/components/Common/Search/index.module.css delete mode 100644 apps/site/components/Common/Search/index.tsx create mode 100644 apps/site/components/Common/Searchbox/Chat.tsx create mode 100644 apps/site/components/Common/Searchbox/Search.tsx create mode 100644 apps/site/components/Common/Searchbox/index.module.css create mode 100644 apps/site/components/Common/Searchbox/index.tsx diff --git a/apps/site/components/Common/Search/index.module.css b/apps/site/components/Common/Search/index.module.css deleted file mode 100644 index 86095bf964951..0000000000000 --- a/apps/site/components/Common/Search/index.module.css +++ /dev/null @@ -1,84 +0,0 @@ -@reference "../../../styles/index.css"; - -.searchWrapper { - @apply relative - flex - w-full - flex-shrink-0; -} - -.searchButton { - @apply flex - grow - cursor-pointer - items-center - justify-between - gap-1 - rounded-xl - border - border-neutral-300 - bg-white - p-2 - text-neutral-900 - transition-colors - duration-300 - hover:bg-neutral-100 - dark:border-neutral-900 - dark:bg-neutral-950 - dark:text-neutral-200 - hover:dark:bg-neutral-900; -} - -.searchButtonContent { - @apply flex - flex-nowrap - items-center - gap-1 - text-sm; -} - -.searchButtonShortcut { - @apply hidden - rounded-md - bg-neutral-300 - px-2 - py-1 - text-sm - text-neutral-800 - sm:inline - dark:bg-neutral-900 - dark:text-neutral-400; -} - -.modalWrapper { - @apply fixed - left-0 - top-0 - z-50 - flex - h-full - w-full - bg-white/70 - dark:bg-neutral-950/85; -} - -.modalInner { - @apply inset-0 - flex - flex-col - justify-between - bg-neutral-100 - sm:bottom-auto - sm:top-[5vh] - sm:mx-auto - sm:max-h-[70vh] - sm:min-h-[200px] - sm:w-[80%] - sm:max-w-[720px] - sm:rounded-xl - sm:border - sm:border-neutral-200 - sm:p-0 - dark:bg-neutral-950 - sm:dark:border-neutral-900; -} diff --git a/apps/site/components/Common/Search/index.tsx b/apps/site/components/Common/Search/index.tsx deleted file mode 100644 index 2883217bd0677..0000000000000 --- a/apps/site/components/Common/Search/index.tsx +++ /dev/null @@ -1,379 +0,0 @@ -'use client'; - -import { ArrowUpIcon, ClipboardDocumentIcon } from '@heroicons/react/20/solid'; -import { ArrowLeftIcon } from '@heroicons/react/24/outline'; -import { - ArrowDownIcon, - CircleStackIcon, - MagnifyingGlassIcon, - PauseCircleIcon, -} from '@heroicons/react/24/solid'; -import { CollectionManager } from '@orama/core'; -import ChatInteractions from '@orama/ui/components/ChatInteractions'; -import ChatRoot from '@orama/ui/components/ChatRoot'; -import FacetTabs from '@orama/ui/components/FacetTabs'; -import Modal from '@orama/ui/components/Modal'; -import PromptTextArea from '@orama/ui/components/PromptTextArea'; -import SearchInput from '@orama/ui/components/SearchInput'; -import SearchResults from '@orama/ui/components/SearchResults'; -import SearchRoot from '@orama/ui/components/SearchRoot'; -import { SlidingPanel } from '@orama/ui/components/SlidingPanel'; -import Suggestions from '@orama/ui/components/Suggestions'; -import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; -import classNames from 'classnames'; -import Link from 'next/link'; -import { useLocale } from 'next-intl'; -import { useTranslations } from 'next-intl'; -import { Fragment, useState, type FC, type PropsWithChildren } from 'react'; - -import styles from './index.module.css'; - -const oramaClient = new CollectionManager({ - url: 'https://staging.collections.orama.com', - collectionID: 'dpygf82gs9bvtf6o85fjuj40', - readAPIKey: '2pj8SUaPGbakScglDBHfJbV5aIuWmT7y', -}); - -const uppercaseFirst = (word: string) => - word.charAt(0).toUpperCase() + word.slice(1); - -const getFormattedPath = (path: string, title: string) => - `${path - .replace(/#.+$/, '') - .split('/') - .map(element => element.replaceAll('-', ' ')) - .map(element => uppercaseFirst(element)) - .filter(Boolean) - .join(' > ')} — ${title}`; - -const InnerSearchBox: FC = () => { - const locale = useLocale(); - const [displayChat, setDisplayChat] = useState(false); - const { - containerRef, - showGoToBottomButton, - scrollToBottom, - recalculateGoToBottomButton, - } = useScrollableContainer(); - - return ( - <> - - - - - - - - - {(group, isSelected) => ( - - {group.name} ({group.count}) - - )} - - - - - {searchTerm => ( - <> - {searchTerm ? ( -

- {`No results found for "${searchTerm}". Please try a different search term.`} -

- ) : ( - -

- Suggestions -

- - setDisplayChat(true)} - className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" - itemClassName="cursor-pointer" - > - How to install Node.js? - - setDisplayChat(true)} - className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" - itemClassName="cursor-pointer" - > - How to create an HTTP server? - - setDisplayChat(true)} - className="cursor-pointer text-sm text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200" - itemClassName="cursor-pointer" - > - Upgrading Node.js version - - -
- )} - - )} -
- -
- - {group => ( -
-

- {group.name} -

- - {hit => ( - - - {typeof hit.document?.pageSectionTitle === 'string' && ( -

- {hit.document?.pageSectionTitle} -

- )} - {typeof hit.document?.pageSectionTitle === 'string' && - typeof hit.document?.path === 'string' && ( -

- {getFormattedPath( - hit.document?.path, - hit.document?.pageSectionTitle - )} -

- )} - -
- )} -
-
- )} -
-
- setDisplayChat(false)} - > - - -
-
- -
- -
- scrollToBottom({ animated: true })} - className="relative h-full items-start overflow-y-auto" - > - {(interaction, index, totalInteractions) => ( - <> - -

{interaction.query}

-
- {interaction.loading && - !interaction.response && ( // TODO; use theme -
-
-
-
- )} - - {(document, index: number) => ( -
-
- - {document?.title as string} - - - {typeof document?.content === 'string' - ? document.content.substring(0, 40) - : ''} - ... - -
-
- )} -
- - - {interaction.response} - - - {interaction.response && !interaction.loading && ( -
- - {index === totalInteractions && ( -
- - Reset all - -
- )} -
-
    - {index === totalInteractions && ( -
  • - - - -
  • - )} -
  • - - } - > - {/* */} - Copy - -
  • -
-
- )} - - )} -
-
-
- {showGoToBottomButton && ( - - )} - - - } - className={`cursor-pointer rounded-lg p-2 text-white transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-50`} - > - - - -
-
-
-
- - ); -}; - -const OramaSearch: FC = () => { - const [open, setOpen] = useState(false); - const t = useTranslations(); - - const openSearchBox = (): void => { - setOpen(true); - }; - return ( - <> - - - setOpen(false)} - closeOnOutsideClick={true} - closeOnEscape={true} - className={styles.modalWrapper} - > - - - - - - - - - - - - ); -}; - -export default OramaSearch; diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat.tsx new file mode 100644 index 0000000000000..26f4b4831ada2 --- /dev/null +++ b/apps/site/components/Common/Searchbox/Chat.tsx @@ -0,0 +1,199 @@ +'use client'; + +import { ArrowUpIcon, ClipboardDocumentIcon } from '@heroicons/react/20/solid'; +import { ArrowLeftIcon } from '@heroicons/react/24/outline'; +import { + ArrowDownIcon, + CircleStackIcon, + PauseCircleIcon, +} from '@heroicons/react/24/solid'; +import ChatInteractions from '@orama/ui/components/ChatInteractions'; +import PromptTextArea from '@orama/ui/components/PromptTextArea'; +import { SlidingPanel } from '@orama/ui/components/SlidingPanel'; +import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; +// import classNames from 'classnames'; +// import Link from 'next/link'; +// import { useLocale } from 'next-intl'; +// import { useTranslations } from 'next-intl'; +import { Fragment, type FC, type PropsWithChildren } from 'react'; + +// import styles from './index.module.css'; + +type SlidingChatPanelProps = PropsWithChildren & { + open: boolean; + onClose: () => void; +}; + +// const uppercaseFirst = (word: string) => +// word.charAt(0).toUpperCase() + word.slice(1); + +// const getFormattedPath = (path: string, title: string) => +// `${path +// .replace(/#.+$/, '') +// .split('/') +// .map(element => element.replaceAll('-', ' ')) +// .map(element => uppercaseFirst(element)) +// .filter(Boolean) +// .join(' > ')} — ${title}`; + +export const SlidingChatPanel: FC = ({ + open, + onClose, +}) => { + // const locale = useLocale(); + // const t = useTranslations(); + const { + containerRef, + showGoToBottomButton, + scrollToBottom, + recalculateGoToBottomButton, + } = useScrollableContainer(); + + return ( + <> + + + +
+
+ +
+ +
+ scrollToBottom({ animated: true })} + className="relative h-full items-start overflow-y-auto" + > + {(interaction, index, totalInteractions) => ( + <> + +

{interaction.query}

+
+ {interaction.loading && + !interaction.response && ( // TODO; use theme +
+
+
+
+ )} + + {(document, index: number) => ( +
+
+ + {document?.title as string} + + + {typeof document?.content === 'string' + ? document.content.substring(0, 40) + : ''} + ... + +
+
+ )} +
+ + + {interaction.response} + + + {interaction.response && !interaction.loading && ( +
+ + {index === totalInteractions && ( +
+ + Reset all + +
+ )} +
+
    + {index === totalInteractions && ( +
  • + + + +
  • + )} +
  • + + } + > + {/* */} + Copy + +
  • +
+
+ )} + + )} +
+
+
+ {showGoToBottomButton && ( + + )} + + + } + className={`cursor-pointer rounded-lg p-2 text-white transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-50`} + > + + + +
+
+
+
+ + ); +}; diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx new file mode 100644 index 0000000000000..af637a26fabcc --- /dev/null +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -0,0 +1,170 @@ +'use client'; + +import { SparklesIcon } from '@heroicons/react/24/outline'; +import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; +import FacetTabs from '@orama/ui/components/FacetTabs'; +import SearchInput from '@orama/ui/components/SearchInput'; +import SearchResults from '@orama/ui/components/SearchResults'; +import Suggestions from '@orama/ui/components/Suggestions'; +import classNames from 'classnames'; +import Link from 'next/link'; +import { useLocale } from 'next-intl'; +import { useTranslations } from 'next-intl'; +import { type FC, type PropsWithChildren } from 'react'; + +import styles from './index.module.css'; + +type SearchProps = PropsWithChildren & { + onChatTrigger: () => void; +}; + +const uppercaseFirst = (word: string) => + word.charAt(0).toUpperCase() + word.slice(1); + +const getFormattedPath = (path: string, title: string) => + `${path + .replace(/#.+$/, '') + .split('/') + .map(element => element.replaceAll('-', ' ')) + .map(element => uppercaseFirst(element)) + .filter(Boolean) + .join(' > ')} — ${title}`; + +export const Search: FC = ({ onChatTrigger }) => { + const locale = useLocale(); + const t = useTranslations(); + + return ( + <> + + + + + +
+ +
+ +
+ + + {(group, isSelected) => ( + + {group.name} ({group.count}) + + )} + + + + + {searchTerm => ( + <> + {searchTerm ? ( +

+ {`No results found for "${searchTerm}". Please try a different search term.`} +

+ ) : ( + +

Suggestions

+ + + + How to install Node.js? + + + + How to create an HTTP server? + + + + Upgrading Node.js version + + +
+ )} + + )} +
+ +
+ + {group => ( +
+

+ {group.name} +

+ + {hit => ( + + + {typeof hit.document?.pageSectionTitle === 'string' && ( +

+ {hit.document?.pageSectionTitle} +

+ )} + {typeof hit.document?.pageSectionTitle === 'string' && + typeof hit.document?.path === 'string' && ( +

+ {getFormattedPath( + hit.document?.path, + hit.document?.pageSectionTitle + )} +

+ )} + +
+ )} +
+
+ )} +
+
+
+ + ); +}; diff --git a/apps/site/components/Common/Searchbox/index.module.css b/apps/site/components/Common/Searchbox/index.module.css new file mode 100644 index 0000000000000..ca84b440f2c79 --- /dev/null +++ b/apps/site/components/Common/Searchbox/index.module.css @@ -0,0 +1,194 @@ +@reference "../../../styles/index.css"; + +.searchWrapper { + @apply relative + flex + w-full + flex-shrink-0; +} + +.searchButton { + @apply flex + grow + cursor-pointer + items-center + justify-between + gap-1 + rounded-xl + border + border-neutral-300 + bg-white + p-2 + text-neutral-900 + transition-colors + duration-300 + hover:bg-neutral-100 + dark:border-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200 + hover:dark:bg-neutral-900; +} + +.searchButtonContent { + @apply relative + flex + flex-nowrap + items-center + gap-1 + text-sm; +} + +.searchButtonShortcut { + @apply hidden + rounded-md + bg-neutral-300 + px-2 + py-1 + text-sm + text-neutral-800 + sm:inline + dark:bg-neutral-900 + dark:text-neutral-400; +} + +.modalWrapper { + @apply fixed + left-0 + top-0 + z-50 + flex + h-full + w-full + bg-white/70 + dark:bg-neutral-950/85; +} + +.modalInner { + @apply inset-0 + flex + flex-col + justify-between + bg-neutral-100 + sm:bottom-auto + sm:top-[5vh] + sm:mx-auto + sm:max-h-[70vh] + sm:min-h-[200px] + sm:w-[80%] + sm:max-w-[720px] + sm:rounded-xl + sm:border + sm:border-neutral-200 + sm:p-0 + dark:bg-neutral-950 + sm:dark:border-neutral-900; + + > section { + @apply h-full; + } +} + +.modalContent { + @apply flex + flex-col; +} + +.searchInputWrapper { + @apply relative; + + svg { + @apply absolute + left-3 + top-1/2 + h-4 + w-4 + -translate-y-1/2 + text-neutral-500 + dark:text-neutral-600; + } +} + +.searchInput { + @apply w-full + border-0 + border-b + border-neutral-200 + bg-transparent + py-4 + pl-9 + pr-4 + text-sm + text-neutral-900 + placeholder:text-neutral-500 + focus:outline-none + dark:border-neutral-900 + dark:text-neutral-200 + dark:placeholder:text-neutral-600; +} + +.chatButtonWrapper { + @apply border-b + border-neutral-200 + p-2 + dark:border-neutral-900; +} + +.chatButton { + @apply flex + w-full + cursor-pointer + items-center + gap-2 + rounded-lg + border + border-transparent + bg-transparent + p-3 + text-sm + transition-colors + duration-300 + hover:bg-neutral-300 + dark:hover:bg-neutral-900; +} + +.suggestionsWrapper { + @apply flex + min-h-0 + flex-1 + flex-col + overflow-y-auto + text-neutral-900 + dark:text-neutral-200; +} + +.suggestionsTitle { + @apply mb-3 + mt-3 + text-xs + font-semibold + uppercase + text-neutral-700 + dark:text-neutral-500; +} + +.suggestionItem { + @apply flex + cursor-pointer + items-center + gap-2 + py-2 + text-sm + text-green-600 + dark:text-green-400; +} + +.searchResultsWrapper { + @apply h-full + flex-1 + overflow-y-auto + px-5 + pb-6 + pt-4 + text-neutral-900 + dark:text-neutral-200; +} diff --git a/apps/site/components/Common/Searchbox/index.tsx b/apps/site/components/Common/Searchbox/index.tsx new file mode 100644 index 0000000000000..c8a8214b23395 --- /dev/null +++ b/apps/site/components/Common/Searchbox/index.tsx @@ -0,0 +1,78 @@ +'use client'; + +import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; +import { CollectionManager } from '@orama/core'; +import ChatRoot from '@orama/ui/components/ChatRoot'; +import Modal from '@orama/ui/components/Modal'; +import SearchRoot from '@orama/ui/components/SearchRoot'; +import { useTranslations } from 'next-intl'; +import { useState, type FC, type PropsWithChildren } from 'react'; + +import { SlidingChatPanel } from './Chat'; +import styles from './index.module.css'; +import { Search } from './Search'; + +const oramaClient = new CollectionManager({ + url: 'https://atlantis.cluster.staging.oramacore.com', + collectionID: 'dpygf82gs9bvtf6o85fjuj40', + readAPIKey: '2pj8SUaPGbakScglDBHfJbV5aIuWmT7y', +}); + +const InnerSearchBox: FC = () => { + const [displayChat, setDisplayChat] = useState(false); + + return ( + <> + setDisplayChat(true)} /> + setDisplayChat(false)} + /> + + ); +}; + +const OramaSearch: FC = () => { + const [open, setOpen] = useState(false); + const t = useTranslations(); + + const openSearchBox = (): void => { + setOpen(true); + }; + + return ( + <> + + + setOpen(false)} + closeOnOutsideClick={true} + closeOnEscape={true} + className={styles.modalWrapper} + > + + + + + + + + + + + + ); +}; + +export default OramaSearch; diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index 8cab6b824c919..f25218903ca91 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -20,12 +20,15 @@ import { useSiteNavigation } from '#site/hooks'; import { useRouter, usePathname } from '#site/navigation.mjs'; import { availableLocales } from '#site/next.locales.mjs'; -const SearchButton = dynamic(() => import('#site/components/Common/Search'), { - ssr: false, - loading: () => ( - - ), -}); +const SearchButton = dynamic( + () => import('#site/components/Common/Searchbox'), + { + ssr: false, + loading: () => ( + + ), + } +); const WithNavBar: FC = () => { const { navigationItems } = useSiteNavigation(); diff --git a/apps/site/package.json b/apps/site/package.json index 6d9db7fe0545c..5260697d860c3 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -43,7 +43,7 @@ "@orama/react-components": "^0.8.1", "@oramacloud/client": "^2.1.4", "@orama/ui": "^0.0.4", - "@orama/core": "^0.1.10", + "@orama/core": "^0.1.11", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-toast": "^1.2.14", From 8451f807dfd5f9b2c0146e022428df3eebb7d38f Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Wed, 25 Jun 2025 16:01:22 +0200 Subject: [PATCH 04/19] style: modal search --- .../components/Common/Searchbox/Search.tsx | 151 ++++++++++++------ .../Common/Searchbox/index.module.css | 146 ++++++++++++++++- 2 files changed, 251 insertions(+), 46 deletions(-) diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index af637a26fabcc..b3423add8cf4e 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -1,15 +1,23 @@ 'use client'; -import { SparklesIcon } from '@heroicons/react/24/outline'; -import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; +import { SparklesIcon, DocumentTextIcon } from '@heroicons/react/24/outline'; +import { + MagnifyingGlassIcon, + ArrowTurnDownLeftIcon, + ArrowDownIcon, + ArrowUpIcon, +} from '@heroicons/react/24/solid'; import FacetTabs from '@orama/ui/components/FacetTabs'; import SearchInput from '@orama/ui/components/SearchInput'; import SearchResults from '@orama/ui/components/SearchResults'; import Suggestions from '@orama/ui/components/Suggestions'; +import { useSearchContext } from '@orama/ui/context/SearchContext'; import classNames from 'classnames'; +import Image from 'next/image'; import Link from 'next/link'; import { useLocale } from 'next-intl'; import { useTranslations } from 'next-intl'; +import { useTheme } from 'next-themes'; import { type FC, type PropsWithChildren } from 'react'; import styles from './index.module.css'; @@ -32,7 +40,11 @@ const getFormattedPath = (path: string, title: string) => export const Search: FC = ({ onChatTrigger }) => { const locale = useLocale(); + const { resolvedTheme } = useTheme(); const t = useTranslations(); + const { searchTerm } = useSearchContext(); + + const oramaLogo = `https://website-assets.oramasearch.com/orama-when-${resolvedTheme}.svg`; return ( <> @@ -53,30 +65,34 @@ export const Search: FC = ({ onChatTrigger }) => {
- - + + {(group, isSelected) => ( - {group.name} ({group.count}) + {group.name} + {group.count} )} @@ -86,12 +102,16 @@ export const Search: FC = ({ onChatTrigger }) => { {searchTerm => ( <> {searchTerm ? ( -

- {`No results found for "${searchTerm}". Please try a different search term.`} -

+
+

+ {t('components.search.noResultsFoundFor')} "{searchTerm}" +

+
) : ( -

Suggestions

+

+ {t('components.search.suggestions')} +

= ({ onChatTrigger }) => { )} -
- - {group => ( -
-

- {group.name} -

- - {hit => ( - - + + {group => ( +
+

{group.name}

+ + {hit => ( + + + +
{typeof hit.document?.pageSectionTitle === 'string' && ( -

+

{hit.document?.pageSectionTitle}

)} {typeof hit.document?.pageSectionTitle === 'string' && typeof hit.document?.path === 'string' && ( -

+

{getFormattedPath( hit.document?.path, hit.document?.pageSectionTitle )}

)} - - - )} - -
- )} - +
+ +
+ )} +
+
+ )} +
+
+ + {/* FOOTER */} +
+
+
+ + + + to select +
+
+ + + + + + + to navigate +
+
+ esc + to close +
+
+
diff --git a/apps/site/components/Common/Searchbox/index.module.css b/apps/site/components/Common/Searchbox/index.module.css index ca84b440f2c79..f327ac86b23fb 100644 --- a/apps/site/components/Common/Searchbox/index.module.css +++ b/apps/site/components/Common/Searchbox/index.module.css @@ -131,6 +131,11 @@ border-neutral-200 p-2 dark:border-neutral-900; + + svg { + @apply h-4 + w-4; + } } .chatButton { @@ -151,6 +156,11 @@ dark:hover:bg-neutral-900; } +.chatButtonWithSearch { + @apply bg-neutral-300 + dark:bg-neutral-900; +} + .suggestionsWrapper { @apply flex min-h-0 @@ -188,7 +198,141 @@ overflow-y-auto px-5 pb-6 - pt-4 + pt-3 text-neutral-900 dark:text-neutral-200; } + +.noResultsWrapper { + @apply flex + h-full + items-center + justify-center + py-10 + text-sm + text-neutral-700 + dark:text-neutral-500; +} + +.facetTabItem { + @apply flex + cursor-pointer + items-center + gap-2 + rounded-3xl + border + border-neutral-200 + px-3 + py-1 + text-sm + transition-colors + duration-300 + dark:border-neutral-900; +} + +.facetTabItemSelected { + @apply border-green-600 + dark:border-green-400; +} + +.facetTabsWrapper { + @apply mb-4; +} + +.facetTabsList { + @apply flex + items-center + gap-2; +} + +.facetTabItemCount { + @apply text-neutral-700 + dark:text-neutral-700; +} + +.searchResultsGroupTitle { + @apply my-2 + pl-2 + text-sm + text-neutral-600 + dark:text-neutral-700; +} + +.searchResultsItem { + > a { + @apply flex + items-center + gap-4 + rounded-lg + px-2 + py-4 + text-sm + outline-none + transition-colors + duration-300 + hover:bg-neutral-300 + focus:bg-white + dark:border-neutral-900 + dark:bg-neutral-950 + dark:hover:bg-neutral-900 + dark:focus:bg-neutral-900; + } + + svg { + @apply h-5 + w-5; + } +} + +.searchResultsItemDescription { + @apply text-sm + text-neutral-600 + dark:text-neutral-700; +} + +.footer { + @apply flex + items-center + justify-between + rounded-b-xl + border-t + border-neutral-200 + bg-neutral-100 + p-4 + dark:border-neutral-900 + dark:bg-neutral-950; +} + +.poweredByLink { + @apply flex + items-center + gap-2 + text-sm + text-neutral-700 + dark:text-neutral-400; +} + +.shortcutWrapper { + @apply flex + items-center + gap-2; +} + +.shortcutItem { + @apply flex + items-center + gap-2 + text-xs + text-neutral-700 + dark:text-neutral-700; +} + +.shortcutKey { + @apply rounded-md + bg-neutral-300 + p-1 + font-mono + text-xs + font-semibold + dark:bg-neutral-900; +} From 8ecdf9e0f9a7e7e8a960d03747ade16e79b1ac30 Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Thu, 26 Jun 2025 11:55:08 +0200 Subject: [PATCH 05/19] style: prompt wrapper --- .../site/components/Common/Searchbox/Chat.tsx | 163 +++++++-------- .../components/Common/Searchbox/Search.tsx | 22 ++- .../Common/Searchbox/index.module.css | 185 +++++++++++++++++- .../components/Common/Searchbox/index.tsx | 4 +- apps/site/package.json | 2 +- packages/i18n/src/locales/en.json | 3 +- pnpm-lock.yaml | 32 +-- 7 files changed, 285 insertions(+), 126 deletions(-) diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat.tsx index 26f4b4831ada2..fd835026d9e13 100644 --- a/apps/site/components/Common/Searchbox/Chat.tsx +++ b/apps/site/components/Common/Searchbox/Chat.tsx @@ -1,23 +1,26 @@ 'use client'; -import { ArrowUpIcon, ClipboardDocumentIcon } from '@heroicons/react/20/solid'; -import { ArrowLeftIcon } from '@heroicons/react/24/outline'; +import { ArrowUpIcon } from '@heroicons/react/20/solid'; import { - ArrowDownIcon, - CircleStackIcon, - PauseCircleIcon, -} from '@heroicons/react/24/solid'; -import ChatInteractions from '@orama/ui/components/ChatInteractions'; -import PromptTextArea from '@orama/ui/components/PromptTextArea'; -import { SlidingPanel } from '@orama/ui/components/SlidingPanel'; -import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; + ArrowPathRoundedSquareIcon, + ClipboardIcon, + DocumentCheckIcon, +} from '@heroicons/react/24/outline'; +import { ArrowDownIcon, PauseCircleIcon } from '@heroicons/react/24/solid'; +import Skeleton from '@node-core/ui-components/Common/Skeleton'; +import { + ChatInteractions, + PromptTextArea, + SlidingPanel, +} from '@orama/ui/components'; +import { useScrollableContainer } from '@orama/ui/hooks'; // import classNames from 'classnames'; // import Link from 'next/link'; // import { useLocale } from 'next-intl'; // import { useTranslations } from 'next-intl'; -import { Fragment, type FC, type PropsWithChildren } from 'react'; +import { type FC, type PropsWithChildren } from 'react'; -// import styles from './index.module.css'; +import styles from './index.module.css'; type SlidingChatPanelProps = PropsWithChildren & { open: boolean; @@ -52,43 +55,28 @@ export const SlidingChatPanel: FC = ({ return ( <> - - -
-
- -
- -
+ +
+
scrollToBottom({ animated: true })} - className="relative h-full items-start overflow-y-auto" + className={styles.chatInteractionsWrapper} > {(interaction, index, totalInteractions) => ( - <> +
-

{interaction.query}

+

{interaction.query}

- {interaction.loading && - !interaction.response && ( // TODO; use theme -
-
-
-
- )} + + {interaction.loading && !interaction.response && ( + + )} + = ({ : [] } className={`mb-1 mt-2 flex flex-row gap-1 overflow-x-auto`} - itemClassName={''} > {(document, index: number) => (
= ({ >
- {document?.title as string} - - - {typeof document?.content === 'string' - ? document.content.substring(0, 40) - : ''} - ... + {document?.pageSectionTitle as string}
)}
- - {interaction.response} - +
+ + {interaction.response} + - {interaction.response && !interaction.loading && ( -
- - {index === totalInteractions && ( -
- - Reset all - -
- )} -
-
    - {index === totalInteractions && ( + {interaction.response && !interaction.loading && ( +
    +
      + {index === totalInteractions && ( +
    • + + + +
    • + )}
    • - - - + + } + > + +
    • - )} -
    • - - } - > - {/* */} - Copy - -
    • -
    -
    - )} - +
+
+ )} +
+
)}
-
+
{showGoToBottomButton && ( )} - + } - className={`cursor-pointer rounded-lg p-2 text-white transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-50`} + className={styles.promptTextAreaButton} > +
+ + AI summaries can make mistakes. Please verify the information. + +
diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index b3423add8cf4e..df99f7737f991 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -7,10 +7,12 @@ import { ArrowDownIcon, ArrowUpIcon, } from '@heroicons/react/24/solid'; -import FacetTabs from '@orama/ui/components/FacetTabs'; -import SearchInput from '@orama/ui/components/SearchInput'; -import SearchResults from '@orama/ui/components/SearchResults'; -import Suggestions from '@orama/ui/components/Suggestions'; +import { + SearchInput, + FacetTabs, + SearchResults, + Suggestions, +} from '@orama/ui/components'; import { useSearchContext } from '@orama/ui/context/SearchContext'; import classNames from 'classnames'; import Image from 'next/image'; @@ -71,7 +73,7 @@ export const Search: FC = ({ onChatTrigger }) => { )} data-focus-on-arrow-nav > - + {searchTerm ? `${searchTerm} - ` : ''} {t('components.search.chatButtonLabel')} @@ -86,6 +88,7 @@ export const Search: FC = ({ onChatTrigger }) => { = ({ onChatTrigger }) => {
- + to select
- + - + to navigate
@@ -215,11 +218,12 @@ export const Search: FC = ({ onChatTrigger }) => { target="_blank" rel="noopener noreferrer" className={styles.poweredByLink} + data-focus-on-arrow-nav > Powered by Powered by Orama diff --git a/apps/site/components/Common/Searchbox/index.module.css b/apps/site/components/Common/Searchbox/index.module.css index f327ac86b23fb..c73b61f0e5588 100644 --- a/apps/site/components/Common/Searchbox/index.module.css +++ b/apps/site/components/Common/Searchbox/index.module.css @@ -271,7 +271,7 @@ transition-colors duration-300 hover:bg-neutral-300 - focus:bg-white + focus:bg-neutral-300 dark:border-neutral-900 dark:bg-neutral-950 dark:hover:bg-neutral-900 @@ -329,10 +329,189 @@ .shortcutKey { @apply rounded-md - bg-neutral-300 + bg-neutral-200 p-1 font-mono text-xs - font-semibold dark:bg-neutral-900; + + svg { + @apply h-4 + w-4; + } +} + +.slidingPanelContent { + @apply overflow-hidden + rounded-tl-3xl + rounded-tr-3xl + bg-neutral-100 + shadow-lg + md:max-w-none + dark:bg-gray-950; +} + +.slidingPanelTop { + @apply mx-auto + flex + h-full + max-w-4xl + flex-col + justify-between + gap-2; +} + +.slidingPanelBottom { + @apply relative + flex-shrink-0; +} + +.chatContainer { + @apply flex + min-h-0 + flex-1 + flex-col; +} + +.chatInteractionsWrapper { + @apply relative + h-full + items-start + overflow-y-auto + px-8 + antialiased + md:subpixel-antialiased; +} + +.chatInteraction { + @apply pb-4; +} + +.chatUserPrompt { + @apply mb-4 + text-base + text-neutral-900 + dark:text-neutral-200; +} + +.chatAssistantMessage { + @apply my-6 + max-w-full + rounded-xl + bg-neutral-100 + px-6 + py-4 + text-base + text-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200; + + p { + @apply font-sm-line-height + mb-3; + } + + li > pre { + @apply my-4; + + > div { + @apply rounded-lg + p-3 + text-sm; + } + } +} + +.chatLoader { + @apply my-4; +} + +.chatActionsContainer { + @apply flex + items-center + justify-end + pt-2; +} + +.chatActionsList { + @apply flex + items-center + gap-4; +} + +.chatAction { + @apply cursor-pointer; + + svg { + @apply h-5 + w-5; + } +} + +.chatActionIconSelected { + @apply text-green-600 + dark:text-green-400; +} + +.promptTextAreaWrapper { + @apply relative + mx-8 + flex + items-center + space-x-2 + rounded-2xl + border + border-neutral-200 + bg-transparent + py-1 + text-base + text-neutral-900 + placeholder:text-neutral-500 + focus:outline-none + dark:border-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200 + dark:placeholder:text-neutral-600; +} + +.promptTextAreaButton { + @apply absolute + right-2 + top-1/2 + -translate-y-1/2 + cursor-pointer + rounded-lg + bg-neutral-300 + p-2 + text-neutral-800 + transition-colors + duration-300 + hover:bg-neutral-400 + disabled:cursor-not-allowed + disabled:bg-neutral-200 + disabled:text-neutral-500 + dark:bg-green-400 + dark:text-white + dark:hover:bg-green-400 + dark:disabled:bg-neutral-800 + dark:disabled:text-neutral-500; +} + +.promptTextAreaField { + @apply w-full + resize-none + border-0 + bg-transparent + px-4 + py-2 + focus:outline-none; +} + +.slidingPanelFooter { + @apply flex + items-center + justify-center + pt-2 + text-neutral-700 + dark:text-neutral-700; } diff --git a/apps/site/components/Common/Searchbox/index.tsx b/apps/site/components/Common/Searchbox/index.tsx index c8a8214b23395..b0c6b733ff325 100644 --- a/apps/site/components/Common/Searchbox/index.tsx +++ b/apps/site/components/Common/Searchbox/index.tsx @@ -2,9 +2,7 @@ import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; import { CollectionManager } from '@orama/core'; -import ChatRoot from '@orama/ui/components/ChatRoot'; -import Modal from '@orama/ui/components/Modal'; -import SearchRoot from '@orama/ui/components/SearchRoot'; +import { SearchRoot, ChatRoot, Modal } from '@orama/ui/components'; import { useTranslations } from 'next-intl'; import { useState, type FC, type PropsWithChildren } from 'react'; diff --git a/apps/site/package.json b/apps/site/package.json index 5260697d860c3..e8667c11181c0 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -42,7 +42,7 @@ "@opentelemetry/sdk-logs": "~0.202.0", "@orama/react-components": "^0.8.1", "@oramacloud/client": "^2.1.4", - "@orama/ui": "^0.0.4", + "@orama/ui": "^0.0.5", "@orama/core": "^0.1.11", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index 064b82e74f790..efc88fd839147 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -252,7 +252,8 @@ "initErrorSearch": "Unable to initialize search service", "initErrorChat": "Unable to initialize chat service", "chatButtonLabel": "Get an AI summary", - "searchButtonLabel": "Search" + "searchButtonLabel": "Search", + "poweredBy": "Powered by {provider}" }, "blog": { "blogHeader": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8705bf7cd5bee..fe4131f62f3c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,14 +100,14 @@ importers: specifier: ~0.202.0 version: 0.202.0(@opentelemetry/api@1.9.0) '@orama/core': - specifier: ^0.1.10 - version: 0.1.10 + specifier: ^0.1.11 + version: 0.1.11 '@orama/react-components': specifier: ^0.8.0 version: 0.8.0(@stencil/core@4.30.0)(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@orama/ui': - specifier: ^0.0.4 - version: 0.0.4(@orama/core@0.1.10)(@types/react@19.1.6)(react@19.1.0) + specifier: ^0.0.5 + version: 0.0.5(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0) '@oramacloud/client': specifier: ^2.1.4 version: 2.1.4 @@ -1933,8 +1933,8 @@ packages: resolution: {integrity: sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==} engines: {node: '>=14'} - '@orama/core@0.1.10': - resolution: {integrity: sha512-Sqmdg61fE0D1yzKhqosjasgxqP7/9W5uBz9GRFPkt4Q0qTJ3rxm8hCfhFkPbLWNZAZuOANuzXiU3h8nzaFquww==} + '@orama/core@0.1.11': + resolution: {integrity: sha512-cxs2ZrPlL0qCO91ba1FkFg/CX569v6Pqbo0e7EEvRVObBSOI1N1PIYAQ7lTXBUN7mDjpqHvPgOJ0mUuvotSl+Q==} '@orama/cuid2@2.2.3': resolution: {integrity: sha512-Lcak3chblMejdlSHgYU2lS2cdOhDpU6vkfIJH4m+YKvqQyLqs1bB8+w6NT1MG5bO12NUK2GFc34Mn2xshMIQ1g==} @@ -1963,10 +1963,10 @@ packages: '@orama/orama': 3.1.9 '@oramacloud/client': ^2.1.1 - '@orama/ui@0.0.4': - resolution: {integrity: sha512-dWxTgsY4nm9ytGjuFflz1W8XTcJqZ71FxRsMZmj5qaK+/wdpBbcD8n+FlkWkiULLnAuEnVQ97wTX/RSE+siMrg==} + '@orama/ui@0.0.5': + resolution: {integrity: sha512-ddK9Jh666ps6/NuQtZTR4pgSI/eKTLK/3UllU22PbQh2/XN0WQPuh3iEe2xIbhC1YEancpUiZZHB2KhzPXs4Hw==} peerDependencies: - '@orama/core': ^0.1.8 + '@orama/core': ^0.1.11 react: ^19 '@orama/wc-components@0.8.0': @@ -9942,7 +9942,7 @@ snapshots: '@opentelemetry/semantic-conventions@1.34.0': {} - '@orama/core@0.1.10': + '@orama/core@0.1.11': dependencies: '@orama/cuid2': 2.2.3 dedent: 1.5.3 @@ -9972,15 +9972,15 @@ snapshots: - '@types/react' - babel-plugin-macros - '@orama/switch@3.1.6(@orama/core@0.1.10)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4)': + '@orama/switch@3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4)': dependencies: - '@orama/core': 0.1.10 + '@orama/core': 0.1.11 '@orama/orama': 3.1.6 '@oramacloud/client': 2.1.4 - '@orama/ui@0.0.4(@orama/core@0.1.10)(@types/react@19.1.6)(react@19.1.0)': + '@orama/ui@0.0.5(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0)': dependencies: - '@orama/core': 0.1.10 + '@orama/core': 0.1.11 prism-react-renderer: 1.3.5(react@19.1.0) react: 19.1.0 react-markdown: 10.1.0(@types/react@19.1.6)(react@19.1.0) @@ -9991,10 +9991,10 @@ snapshots: '@orama/wc-components@0.8.0': dependencies: - '@orama/core': 0.1.10 + '@orama/core': 0.1.11 '@orama/highlight': 0.1.9 '@orama/orama': 3.1.6 - '@orama/switch': 3.1.6(@orama/core@0.1.10)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4) + '@orama/switch': 3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4) '@oramacloud/client': 2.1.4 '@phosphor-icons/webcomponents': 2.1.5 '@stencil/core': 4.30.0 From 6ac3d65585f76fd0f3fa7fa54f8667443739fa89 Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Thu, 26 Jun 2025 13:11:54 +0200 Subject: [PATCH 06/19] fix: layout sliding panel --- .../site/components/Common/Searchbox/Chat.tsx | 24 ++++++----- .../components/Common/Searchbox/Search.tsx | 2 +- .../Common/Searchbox/index.module.css | 40 +++++++++++-------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat.tsx index fd835026d9e13..2a69a3024b6de 100644 --- a/apps/site/components/Common/Searchbox/Chat.tsx +++ b/apps/site/components/Common/Searchbox/Chat.tsx @@ -13,7 +13,7 @@ import { PromptTextArea, SlidingPanel, } from '@orama/ui/components'; -import { useScrollableContainer } from '@orama/ui/hooks'; +import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; // import classNames from 'classnames'; // import Link from 'next/link'; // import { useLocale } from 'next-intl'; @@ -52,12 +52,18 @@ export const SlidingChatPanel: FC = ({ recalculateGoToBottomButton, } = useScrollableContainer(); + if (!open) { + return null; + } + + console.log('SlidingChatPanel rendered', containerRef, showGoToBottomButton); + return ( <> -
-
+
+
= ({ className={styles.chatInteractionsWrapper} > {(interaction, index, totalInteractions) => ( -
+ <> @@ -77,7 +83,7 @@ export const SlidingChatPanel: FC = ({ )} - = ({
)} - + */}
@@ -133,11 +139,11 @@ export const SlidingChatPanel: FC = ({
)}
-
+ )}
-
+
{showGoToBottomButton && ( )} @@ -160,10 +167,10 @@ export const SlidingChatPanel: FC = ({ className={styles.promptTextAreaField} /> } + abortContent={} className={styles.promptTextAreaButton} > - +
diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index 2a95ebb449820..8b074e4c67dfe 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -22,7 +22,7 @@ import { useTranslations } from 'next-intl'; import { useTheme } from 'next-themes'; import { type FC, type PropsWithChildren } from 'react'; -import styles from './index.module.css'; +import styles from './search.module.css'; import { getFormattedPath } from './utils'; type SearchProps = PropsWithChildren & { @@ -104,27 +104,27 @@ export const Search: FC = ({ onChatTrigger }) => {

{t('components.search.suggestions')}

- + - - How to install Node.js? + + {t('components.search.suggestionOne')} - - How to create an HTTP server? + + {t('components.search.suggestionTwo')} - - Upgrading Node.js version + + {t('components.search.suggestionThree')} @@ -178,14 +178,15 @@ export const Search: FC = ({ onChatTrigger }) => {
- {/* FOOTER */}
- to select + + {t('components.search.keyboardShortcuts.select')} +
@@ -194,11 +195,15 @@ export const Search: FC = ({ onChatTrigger }) => { - to navigate + + {t('components.search.keyboardShortcuts.navigate')} +
esc - to close + + {t('components.search.keyboardShortcuts.close')} +
@@ -209,12 +214,12 @@ export const Search: FC = ({ onChatTrigger }) => { className={styles.poweredByLink} data-focus-on-arrow-nav > - Powered by + {t('components.search.poweredBy')} {t('components.search.poweredBy',
diff --git a/apps/site/components/Common/Searchbox/chat.module.css b/apps/site/components/Common/Searchbox/chat.module.css new file mode 100644 index 0000000000000..370fda1895db0 --- /dev/null +++ b/apps/site/components/Common/Searchbox/chat.module.css @@ -0,0 +1,288 @@ +@reference "../../../styles/index.css"; + +.slidingPanelContent { + @apply overflow-hidden + rounded-tl-3xl + rounded-tr-3xl + bg-neutral-100 + shadow-lg + md:max-w-none + dark:bg-gray-950; + + > div { + @apply h-full + overflow-y-auto + p-6; + } +} + +.slidingPanelInner { + @apply mx-auto + flex + h-full + max-w-4xl + flex-col + justify-between + gap-2; +} + +.slidingPanelTop { + @apply flex + min-h-0 + flex-1 + flex-col + pb-6; +} + +.slidingPanelBottom { + @apply relative + flex-shrink-0; +} + +.chatInteractionsWrapper { + @apply relative + h-full + items-start + overflow-y-auto + px-8; + + > div { + @apply h-full; + } +} + +.chatUserPrompt { + @apply mb-4 + text-base + text-neutral-900 + dark:text-neutral-200; +} + +.chatSources { + @apply mb-4 + flex + flex-nowrap + items-center + gap-3 + overflow-x-scroll + scroll-smooth + [scrollbar-width:none] + [&::-webkit-scrollbar]:hidden; +} + +.chatSource { + @apply flex + max-w-xs + items-center + gap-2 + text-base; +} + +.chatSourceLink { + @apply rounded-xl + bg-neutral-100 + px-4 + py-2 + text-neutral-900 + transition-colors + duration-300 + hover:bg-neutral-200 + focus:bg-neutral-200 + dark:bg-neutral-950 + dark:text-neutral-200 + hover:dark:bg-neutral-900 + focus:dark:bg-neutral-900; +} + +.chatSourceTitle { + @apply max-w-full + overflow-hidden + truncate + text-ellipsis + whitespace-nowrap + text-sm + font-semibold; +} + +.chatAssistantMessageWrapper { + @apply my-4 + mb-6 + max-w-full + rounded-xl + bg-neutral-100 + px-6 + py-4 + text-base + text-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200; +} + +.chatAssistantMessage { + p { + @apply font-sm-line-height + mb-3; + } + + pre:not([class*='language-']) { + @apply my-4; + + > div { + @apply rounded-lg + p-3 + text-sm; + } + } + + ul { + @apply list-disc + pl-6; + + li { + @apply mb-2; + } + } + + strong { + @apply font-bold; + } + + h3 { + @apply mb-2 + text-lg + font-bold; + } +} + +.chatLoader { + @apply my-4; +} + +.chatActionsContainer { + @apply flex + items-center + justify-end + pt-2; +} + +.chatActionsList { + @apply flex + list-none + items-center + gap-2 + p-0; +} + +.chatAction { + @apply cursor-pointer + rounded-full + p-2 + text-neutral-800 + transition-colors + duration-300 + hover:bg-neutral-300 + dark:text-neutral-400 + dark:hover:bg-neutral-900; + + svg { + @apply h-4 + w-4; + } +} + +.chatActionIconSelected { + @apply text-green-600 + dark:text-green-400; +} + +.promptTextAreaWrapper { + @apply relative + mx-8 + flex + items-center + space-x-2 + rounded-2xl + border + border-neutral-200 + bg-transparent + py-1 + text-base + text-neutral-900 + placeholder:text-neutral-500 + focus:outline-none + dark:border-neutral-900 + dark:bg-neutral-950 + dark:text-neutral-200 + dark:placeholder:text-neutral-600; + + svg { + @apply h-4 + w-4; + } +} + +.scrollDownButton { + @apply absolute + -top-8 + left-1/2 + -translate-x-1/2 + -translate-y-1/2 + cursor-pointer + rounded-lg + bg-neutral-300 + p-2 + text-neutral-800 + transition-colors + duration-300 + hover:bg-neutral-400 + dark:bg-neutral-900 + dark:text-white + dark:hover:bg-neutral-800; + + svg { + @apply h-4 + w-4; + } +} + +.promptTextAreaButton { + @apply absolute + right-2 + top-1/2 + -translate-y-1/2 + cursor-pointer + rounded-lg + bg-neutral-300 + p-2 + text-neutral-800 + transition-colors + duration-300 + hover:bg-neutral-400 + disabled:cursor-not-allowed + disabled:bg-neutral-200 + disabled:text-neutral-500 + dark:bg-green-400 + dark:text-white + dark:hover:bg-green-400 + dark:disabled:bg-neutral-900 + dark:disabled:text-neutral-700; +} + +.promptTextAreaField { + @apply w-full + resize-none + border-0 + bg-transparent + px-4 + py-2 + focus:outline-none; +} + +.slidingPanelFooter { + @apply flex + items-center + justify-center + pt-2 + text-neutral-700 + dark:text-neutral-700; +} diff --git a/apps/site/components/Common/Searchbox/index.module.css b/apps/site/components/Common/Searchbox/index.module.css index d366ba6147691..1bd5eabe5474a 100644 --- a/apps/site/components/Common/Searchbox/index.module.css +++ b/apps/site/components/Common/Searchbox/index.module.css @@ -1,11 +1,11 @@ @reference "../../../styles/index.css"; -.searchWrapper { +/* .searchWrapper { @apply relative flex w-full flex-shrink-0; -} +} */ .searchButton { @apply flex @@ -38,6 +38,11 @@ items-center gap-1 text-sm; + + svg { + @apply h-4 + w-4; + } } .searchButtonShortcut { @@ -96,7 +101,7 @@ flex-col; } -.searchInputWrapper { +/* .searchInputWrapper { @apply relative; svg { @@ -174,6 +179,11 @@ dark:text-neutral-200; } +.suggestionsList { + @apply mt-1 + space-y-1; +} + .suggestionsTitle { @apply mb-3 mt-3 @@ -193,6 +203,11 @@ text-sm text-green-600 dark:text-green-400; + + svg { + @apply h-5 + w-5; + } } .searchResultsWrapper { @@ -414,10 +429,6 @@ [&::-webkit-scrollbar]:hidden; } -/* .chatSourceItem { - @apply bg-accent1-300; -} */ - .chatSource { @apply flex max-w-xs @@ -562,6 +573,11 @@ dark:bg-neutral-950 dark:text-neutral-200 dark:placeholder:text-neutral-600; + + svg { + @apply h-4 + w-4; + } } .scrollDownButton { @@ -628,4 +644,4 @@ pt-2 text-neutral-700 dark:text-neutral-700; -} +} */ diff --git a/apps/site/components/Common/Searchbox/index.tsx b/apps/site/components/Common/Searchbox/index.tsx index b0c6b733ff325..7f14e36d78e0a 100644 --- a/apps/site/components/Common/Searchbox/index.tsx +++ b/apps/site/components/Common/Searchbox/index.tsx @@ -10,22 +10,24 @@ import { SlidingChatPanel } from './Chat'; import styles from './index.module.css'; import { Search } from './Search'; +// TODO: test collection, replace with production collection and env variables const oramaClient = new CollectionManager({ - url: 'https://atlantis.cluster.staging.oramacore.com', - collectionID: 'dpygf82gs9bvtf6o85fjuj40', - readAPIKey: '2pj8SUaPGbakScglDBHfJbV5aIuWmT7y', + url: 'https://atlantis.cluster.oramacore.com', + collectionID: 'si0xduw9p7z52s5q91d45d82', + readAPIKey: '6O3o7uKE3aoHN6RUWLtKKQbMNNikAupR', }); const InnerSearchBox: FC = () => { - const [displayChat, setDisplayChat] = useState(false); + const [isChatOpen, setIsChatOpen] = useState(false); + + const toggleChatPanel = (): void => { + setIsChatOpen(!isChatOpen); + }; return ( <> - setDisplayChat(true)} /> - setDisplayChat(false)} - /> + + ); }; @@ -34,19 +36,19 @@ const OramaSearch: FC = () => { const [open, setOpen] = useState(false); const t = useTranslations(); - const openSearchBox = (): void => { - setOpen(true); + const toggleSearchBox = (): void => { + setOpen(!open); }; return ( <> )} = ({
- - AI summaries can make mistakes. Please verify the information. - + {t('components.search.disclaimer')}
diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index 8b074e4c67dfe..bd4efac86c4be 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -17,8 +17,7 @@ import { useSearchContext } from '@orama/ui/contexts'; import classNames from 'classnames'; import Image from 'next/image'; import Link from 'next/link'; -import { useLocale } from 'next-intl'; -import { useTranslations } from 'next-intl'; +import { useLocale, useTranslations } from 'next-intl'; import { useTheme } from 'next-themes'; import { type FC, type PropsWithChildren } from 'react'; diff --git a/apps/site/components/Common/Searchbox/chat.module.css b/apps/site/components/Common/Searchbox/chat.module.css index 370fda1895db0..eb12b023f4591 100644 --- a/apps/site/components/Common/Searchbox/chat.module.css +++ b/apps/site/components/Common/Searchbox/chat.module.css @@ -10,7 +10,8 @@ dark:bg-gray-950; > div { - @apply h-full + @apply relative + h-full overflow-y-auto p-6; } @@ -39,6 +40,27 @@ flex-shrink-0; } +.slidingPanelCloseButton { + @apply absolute + right-4 + top-4 + z-10 + cursor-pointer + rounded-full + p-2 + text-neutral-800 + transition-colors + duration-300 + hover:bg-neutral-300 + dark:text-neutral-400 + dark:hover:bg-neutral-900; + + svg { + @apply h-5 + w-5; + } +} + .chatInteractionsWrapper { @apply relative h-full diff --git a/apps/site/package.json b/apps/site/package.json index e8667c11181c0..a5371eee7e4f7 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -42,7 +42,7 @@ "@opentelemetry/sdk-logs": "~0.202.0", "@orama/react-components": "^0.8.1", "@oramacloud/client": "^2.1.4", - "@orama/ui": "^0.0.5", + "@orama/ui": "^0.0.6", "@orama/core": "^0.1.11", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index c6d3ee574bb7b..1f7f47189a85e 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -257,6 +257,8 @@ "suggestionOne": "How to install Node.js?", "suggestionTwo": "How to create an HTTP server?", "suggestionThree": "Upgrading Node.js version", + "scrollToBottom": "Scroll to bottom", + "closeChat": "Close chat", "keyboardShortcuts": { "select": "to select", "navigate": "to navigate", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe4131f62f3c6..9e466eaf960a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,8 +106,8 @@ importers: specifier: ^0.8.0 version: 0.8.0(@stencil/core@4.30.0)(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@orama/ui': - specifier: ^0.0.5 - version: 0.0.5(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0) + specifier: ^0.0.6 + version: 0.0.6(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0) '@oramacloud/client': specifier: ^2.1.4 version: 2.1.4 @@ -1963,8 +1963,8 @@ packages: '@orama/orama': 3.1.9 '@oramacloud/client': ^2.1.1 - '@orama/ui@0.0.5': - resolution: {integrity: sha512-ddK9Jh666ps6/NuQtZTR4pgSI/eKTLK/3UllU22PbQh2/XN0WQPuh3iEe2xIbhC1YEancpUiZZHB2KhzPXs4Hw==} + '@orama/ui@0.0.6': + resolution: {integrity: sha512-aRpCXl+4VECVkkyv3kxd8+FUAFhXfp5G/E93ztfo5jCkNfnPTVI03SUWWUbPiehjtMbzut+P0VkKmG3n0neyhg==} peerDependencies: '@orama/core': ^0.1.11 react: ^19 @@ -9978,7 +9978,7 @@ snapshots: '@orama/orama': 3.1.6 '@oramacloud/client': 2.1.4 - '@orama/ui@0.0.5(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0)': + '@orama/ui@0.0.6(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0)': dependencies: '@orama/core': 0.1.11 prism-react-renderer: 1.3.5(react@19.1.0) @@ -13628,7 +13628,7 @@ snapshots: mdast-util-mdx-expression: 2.0.1 mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.0.0 + property-information: 7.1.0 space-separated-tokens: 2.0.2 style-to-js: 1.1.16 unist-util-position: 5.0.0 From 31e2db8c3b1b3e5029da2b21a8118f542ff01ecd Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Date: Wed, 9 Jul 2025 11:48:51 -0600 Subject: [PATCH 10/19] update orama core and update logo --- .../components/Common/Searchbox/Search.tsx | 15 +++---- .../components/Common/Searchbox/index.tsx | 14 +++--- apps/site/package.json | 2 +- .../public/static/logos/orama-logo-icon.svg | 40 +++++++++++++++++ apps/site/public/static/logos/orama-logo.svg | 14 ++++++ pnpm-lock.yaml | 43 +++++++++++-------- 6 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 apps/site/public/static/logos/orama-logo-icon.svg create mode 100644 apps/site/public/static/logos/orama-logo.svg diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index bd4efac86c4be..cd9416187f854 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -18,7 +18,6 @@ import classNames from 'classnames'; import Image from 'next/image'; import Link from 'next/link'; import { useLocale, useTranslations } from 'next-intl'; -import { useTheme } from 'next-themes'; import { type FC, type PropsWithChildren } from 'react'; import styles from './search.module.css'; @@ -30,12 +29,9 @@ type SearchProps = PropsWithChildren & { export const Search: FC = ({ onChatTrigger }) => { const locale = useLocale(); - const { resolvedTheme } = useTheme(); const t = useTranslations(); const { searchTerm } = useSearchContext(); - const oramaLogo = `https://website-assets.oramasearch.com/orama-when-${resolvedTheme}.svg`; - return ( <> @@ -45,9 +41,6 @@ export const Search: FC = ({ onChatTrigger }) => { ariaLabel={t('components.search.searchPlaceholder')} placeholder={t('components.search.searchPlaceholder')} className={styles.searchInput} - searchParams={{ - groupBy: 'siteSection', - }} /> @@ -215,7 +208,13 @@ export const Search: FC = ({ onChatTrigger }) => { > {t('components.search.poweredBy')} {t('components.search.poweredBy') + {t('components.search.poweredBy') = () => { @@ -63,8 +65,8 @@ const OramaSearch: FC = () => { > - - + + diff --git a/apps/site/package.json b/apps/site/package.json index a5371eee7e4f7..0e21cb0524035 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -43,7 +43,7 @@ "@orama/react-components": "^0.8.1", "@oramacloud/client": "^2.1.4", "@orama/ui": "^0.0.6", - "@orama/core": "^0.1.11", + "@orama/core": "^1.0.0-rc.3", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-toast": "^1.2.14", diff --git a/apps/site/public/static/logos/orama-logo-icon.svg b/apps/site/public/static/logos/orama-logo-icon.svg new file mode 100644 index 0000000000000..06a6cdb2e2771 --- /dev/null +++ b/apps/site/public/static/logos/orama-logo-icon.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/static/logos/orama-logo.svg b/apps/site/public/static/logos/orama-logo.svg new file mode 100644 index 0000000000000..cab830769adce --- /dev/null +++ b/apps/site/public/static/logos/orama-logo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e466eaf960a6..a851cdc94f61b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,14 +100,14 @@ importers: specifier: ~0.202.0 version: 0.202.0(@opentelemetry/api@1.9.0) '@orama/core': - specifier: ^0.1.11 - version: 0.1.11 + specifier: ^1.0.0-rc.3 + version: 1.0.0-rc.3 '@orama/react-components': specifier: ^0.8.0 version: 0.8.0(@stencil/core@4.30.0)(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@orama/ui': specifier: ^0.0.6 - version: 0.0.6(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0) + version: 0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.6)(react@19.1.0) '@oramacloud/client': specifier: ^2.1.4 version: 2.1.4 @@ -1936,6 +1936,9 @@ packages: '@orama/core@0.1.11': resolution: {integrity: sha512-cxs2ZrPlL0qCO91ba1FkFg/CX569v6Pqbo0e7EEvRVObBSOI1N1PIYAQ7lTXBUN7mDjpqHvPgOJ0mUuvotSl+Q==} + '@orama/core@1.0.0-rc.3': + resolution: {integrity: sha512-sqYHKgUCjbGFdiB28jvXYAowNlYSN5c1/U3VidbGSUJON/77TA08oVSf1CPwLMhm1tA0OSRAvlFAp4WNPJy+3Q==} + '@orama/cuid2@2.2.3': resolution: {integrity: sha512-Lcak3chblMejdlSHgYU2lS2cdOhDpU6vkfIJH4m+YKvqQyLqs1bB8+w6NT1MG5bO12NUK2GFc34Mn2xshMIQ1g==} @@ -9951,6 +9954,12 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros + '@orama/core@1.0.0-rc.3': + dependencies: + '@orama/cuid2': 2.2.3 + zod: 3.24.3 + zod-to-json-schema: 3.24.5(zod@3.24.3) + '@orama/cuid2@2.2.3': dependencies: '@noble/hashes': 1.8.0 @@ -9978,9 +9987,9 @@ snapshots: '@orama/orama': 3.1.6 '@oramacloud/client': 2.1.4 - '@orama/ui@0.0.6(@orama/core@0.1.11)(@types/react@19.1.6)(react@19.1.0)': + '@orama/ui@0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.6)(react@19.1.0)': dependencies: - '@orama/core': 0.1.11 + '@orama/core': 1.0.0-rc.3 prism-react-renderer: 1.3.5(react@19.1.0) react: 19.1.0 react-markdown: 10.1.0(@types/react@19.1.6)(react@19.1.0) @@ -12822,11 +12831,11 @@ snapshots: '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-react: 7.37.5(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.30.1(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.28.0(jiti@2.4.2)) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -12860,8 +12869,8 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import-x: 4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -12876,8 +12885,8 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import-x: 4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -12903,7 +12912,7 @@ snapshots: - bluebird - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2)(eslint@9.28.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -12932,7 +12941,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12943,7 +12952,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2)(eslint@9.28.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 From 2a22940e25fd11ea5cbf110c5e346897cc582477 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Date: Wed, 9 Jul 2025 12:10:57 -0600 Subject: [PATCH 11/19] update sync --- .../scripts/orama-search/sync-orama-cloud.mjs | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/apps/site/scripts/orama-search/sync-orama-cloud.mjs b/apps/site/scripts/orama-search/sync-orama-cloud.mjs index 276d19c4e45ad..f0a4be60d0148 100644 --- a/apps/site/scripts/orama-search/sync-orama-cloud.mjs +++ b/apps/site/scripts/orama-search/sync-orama-cloud.mjs @@ -1,18 +1,19 @@ -import { CloudManager } from '@oramacloud/client'; +import { CollectionManager } from '@orama/core'; import { siteContent } from './get-documents.mjs'; import { ORAMA_SYNC_BATCH_SIZE } from '../../next.constants.mjs'; // The following follows the instructions at https://docs.orama.com/cloud/data-sources/custom-integrations/webhooks -const INDEX_ID = process.env.ORAMA_INDEX_ID; -const API_KEY = process.env.ORAMA_SECRET_KEY; - -const oramaCloudManager = new CloudManager({ - api_key: API_KEY, +const collectionManager = new CollectionManager({ + authJwtURL: 'https://staging.app.orama.com/api/user/jwt', + collectionID: '85f541b3-b691-4d3e-9874-e7b3b4630adb', + apiKey: 'p_JMpbuY216Pv0WCQFGijQLXwVIJzrf1dy55i3eCbNJDP', }); -const oramaIndex = oramaCloudManager.index(INDEX_ID); +const index = collectionManager.setIndex( + '55cdf5e4-63e3-4498-926a-ee6152a510cd' +); console.log(`Syncing ${siteContent.length} documents to Orama Cloud index`); @@ -30,18 +31,15 @@ const runUpdate = async () => { for (const batch of batches) { // In Orama, "update" is an upsert operation. - await oramaIndex.update(batch); + await index.upsertDocuments(batch); } }; -// Now we proceed to call the APIs in order: -// 1. Empty the index -// 2. Insert the documents -// 3. Trigger a deployment -// Once all these steps are done, the new documents will be available in the live index. -// Allow Orama up to 1 minute to distribute the documents to all the 300+ nodes worldwide. -await oramaIndex.empty(); +// Now we proceed to call the APIs in order. +// The previous implementation used to empty the index before inserting new documents +// to remove documents that are no longer in the source. +// The new API from @orama/core might have a different approach for full sync. +// Based on the provided examples, we are now only running the update. await runUpdate(); -await oramaIndex.deploy(); console.log('Orama Cloud sync completed successfully!'); From 65ecd9ff31187ac54da63bb5dd2a0cfdd225b577 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Date: Wed, 9 Jul 2025 12:12:46 -0600 Subject: [PATCH 12/19] update pnpm-lock --- pnpm-lock.yaml | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a851cdc94f61b..bc9f11917b197 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,11 +103,11 @@ importers: specifier: ^1.0.0-rc.3 version: 1.0.0-rc.3 '@orama/react-components': - specifier: ^0.8.0 - version: 0.8.0(@stencil/core@4.30.0)(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^0.8.1 + version: 0.8.1(@stencil/core@4.30.0)(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@orama/ui': specifier: ^0.0.6 - version: 0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.6)(react@19.1.0) + version: 0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.8)(react@19.1.0) '@oramacloud/client': specifier: ^2.1.4 version: 2.1.4 @@ -240,7 +240,7 @@ importers: version: 15.3.5(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint-import-resolver-typescript: specifier: ~4.4.4 - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)) eslint-plugin-mdx: specifier: ~3.6.0 version: 3.6.0(eslint@9.30.1(jiti@2.4.2))(remark-lint-file-extension@3.0.1) @@ -324,7 +324,7 @@ importers: devDependencies: eslint-import-resolver-typescript: specifier: ~4.4.4 - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)) typescript: specifier: 'catalog:' version: 5.8.3 @@ -1959,11 +1959,11 @@ packages: react: '>=17.0.0 <20.0.0' react-dom: '>=17.0.0 <20.0.0' - '@orama/switch@3.1.9': - resolution: {integrity: sha512-xOuhvg3e0SnJtYJMEwlKOEpOiuwqWsYanqqsiOWIJne+l+rKA1D1QPJUueN7Vb+IV+iG/1f/ueVVRw1H0ldb7Q==} + '@orama/switch@3.1.6': + resolution: {integrity: sha512-Swj9tQZWQ8tw44sAJmlF15xlJ5+h1GdgysvPGTe1NHJCcAOrX2qxp4OsWB+1vxmIxewP6brnP/U3nUehQNQi6g==} peerDependencies: '@orama/core': ^0.0.10 - '@orama/orama': 3.1.9 + '@orama/orama': 3.1.6 '@oramacloud/client': ^2.1.1 '@orama/ui@0.0.6': @@ -1972,8 +1972,8 @@ packages: '@orama/core': ^0.1.11 react: ^19 - '@orama/wc-components@0.8.0': - resolution: {integrity: sha512-G0PUACezU7atmD8BlydqqUtIznOSfZ2rzf2oJ9jDfTtx4Nrzuo4mWdAOTqcsEZRxzIOjzgZkjLPJLFsOugfjqQ==} + '@orama/wc-components@0.8.1': + resolution: {integrity: sha512-VLNIbPu9bOwr6bQgvpEmZvifaExf6disF8+zz1f/ipjmcNpZZL+0CWRmkvf5FNg1PHN3WvJrdulrfP01QwLljQ==} '@oramacloud/client@2.1.4': resolution: {integrity: sha512-uNPFs4wq/iOPbggCwTkVNbIr64Vfd7ZS/h+cricXVnzXWocjDTfJ3wLL4lr0qiSu41g8z+eCAGBqJ30RO2O4AA==} @@ -4478,8 +4478,8 @@ packages: remark-lint-file-extension: optional: true - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -4512,8 +4512,8 @@ packages: eslint-import-resolver-node: optional: true - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -9981,29 +9981,29 @@ snapshots: - '@types/react' - babel-plugin-macros - '@orama/switch@3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4)': + '@orama/switch@3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.9)(@oramacloud/client@2.1.4)': dependencies: '@orama/core': 0.1.11 - '@orama/orama': 3.1.6 + '@orama/orama': 3.1.9 '@oramacloud/client': 2.1.4 - '@orama/ui@0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.6)(react@19.1.0)': + '@orama/ui@0.0.6(@orama/core@1.0.0-rc.3)(@types/react@19.1.8)(react@19.1.0)': dependencies: '@orama/core': 1.0.0-rc.3 prism-react-renderer: 1.3.5(react@19.1.0) react: 19.1.0 - react-markdown: 10.1.0(@types/react@19.1.6)(react@19.1.0) + react-markdown: 10.1.0(@types/react@19.1.8)(react@19.1.0) remark-gfm: 4.0.1 transitivePeerDependencies: - '@types/react' - supports-color - '@orama/wc-components@0.8.0': + '@orama/wc-components@0.8.1': dependencies: '@orama/core': 0.1.11 '@orama/highlight': 0.1.9 - '@orama/orama': 3.1.6 - '@orama/switch': 3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.6)(@oramacloud/client@2.1.4) + '@orama/orama': 3.1.9 + '@orama/switch': 3.1.6(@orama/core@0.1.11)(@orama/orama@3.1.9)(@oramacloud/client@2.1.4) '@oramacloud/client': 2.1.4 '@phosphor-icons/webcomponents': 2.1.5 '@stencil/core': 4.30.0 @@ -12831,11 +12831,11 @@ snapshots: '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-react: 7.37.5(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.28.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.30.1(jiti@2.4.2)) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -12858,7 +12858,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 @@ -12869,12 +12869,12 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)): + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)): dependencies: debug: 4.4.1 eslint: 9.30.1(jiti@2.4.2) @@ -12885,8 +12885,8 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -12912,14 +12912,14 @@ snapshots: - bluebird - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2)(eslint@9.28.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 4.4.2(eslint-plugin-import-x@4.15.0(@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.30.1(jiti@2.4.2)))(eslint-plugin-import@2.31.0)(eslint@9.30.1(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -12941,7 +12941,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.1(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12952,7 +12952,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.2)(eslint@9.28.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -15455,11 +15455,11 @@ snapshots: react-is@17.0.2: {} - react-markdown@10.1.0(@types/react@19.1.6)(react@19.1.0): + react-markdown@10.1.0(@types/react@19.1.8)(react@19.1.0): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.1.6 + '@types/react': 19.1.8 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 @@ -16251,7 +16251,7 @@ snapshots: send@1.2.0: dependencies: - debug: 4.3.6 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 From 834636fd06418ff36ef39f188fc43fa1906615b4 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Lecuona Date: Wed, 9 Jul 2025 19:24:26 -0600 Subject: [PATCH 13/19] Update apps/site/components/Common/Searchbox/Chat.tsx Co-authored-by: Aviv Keller Signed-off-by: Aileen Villanueva Lecuona --- apps/site/components/Common/Searchbox/Chat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat.tsx index 711aba7ddcde4..16fec2d2a6c1c 100644 --- a/apps/site/components/Common/Searchbox/Chat.tsx +++ b/apps/site/components/Common/Searchbox/Chat.tsx @@ -20,7 +20,7 @@ import { import { useScrollableContainer } from '@orama/ui/hooks/useScrollableContainer'; import Link from 'next/link'; import { useLocale, useTranslations } from 'next-intl'; -import { type FC, type PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import styles from './chat.module.css'; From f088203fe8a5ea4c371849339bd4b6e552cf11a7 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Lecuona Date: Wed, 9 Jul 2025 19:24:37 -0600 Subject: [PATCH 14/19] Update apps/site/components/Common/Searchbox/Chat.tsx Co-authored-by: Aviv Keller Signed-off-by: Aileen Villanueva Lecuona --- apps/site/components/Common/Searchbox/Chat.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat.tsx index 16fec2d2a6c1c..9752bad132161 100644 --- a/apps/site/components/Common/Searchbox/Chat.tsx +++ b/apps/site/components/Common/Searchbox/Chat.tsx @@ -24,10 +24,10 @@ import type { FC, PropsWithChildren } from 'react'; import styles from './chat.module.css'; -type SlidingChatPanelProps = PropsWithChildren & { +type SlidingChatPanelProps = PropsWithChildren<{ open: boolean; onClose: () => void; -}; +}>; export const SlidingChatPanel: FC = ({ open, From 3d582dd2aa1326c0f5546dbb7e56e41371831506 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Lecuona Date: Wed, 9 Jul 2025 19:24:47 -0600 Subject: [PATCH 15/19] Update apps/site/components/Common/Searchbox/Search.tsx Co-authored-by: Aviv Keller Signed-off-by: Aileen Villanueva Lecuona --- apps/site/components/Common/Searchbox/Search.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index cd9416187f854..e9cee62f23a49 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -23,9 +23,9 @@ import { type FC, type PropsWithChildren } from 'react'; import styles from './search.module.css'; import { getFormattedPath } from './utils'; -type SearchProps = PropsWithChildren & { +type SearchProps = PropsWithChildren<{ onChatTrigger: () => void; -}; +}>; export const Search: FC = ({ onChatTrigger }) => { const locale = useLocale(); From b1fff6aaf683558cd8060cf5e0ab79444c67b1a3 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Lecuona Date: Wed, 9 Jul 2025 19:24:55 -0600 Subject: [PATCH 16/19] Update apps/site/components/Common/Searchbox/Search.tsx Co-authored-by: Aviv Keller Signed-off-by: Aileen Villanueva Lecuona --- apps/site/components/Common/Searchbox/Search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index e9cee62f23a49..2ad00446e8585 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -18,7 +18,7 @@ import classNames from 'classnames'; import Image from 'next/image'; import Link from 'next/link'; import { useLocale, useTranslations } from 'next-intl'; -import { type FC, type PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import styles from './search.module.css'; import { getFormattedPath } from './utils'; From e09fa328b7cd1802b342f5dd481ceb7980b99cdd Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Lecuona Date: Wed, 9 Jul 2025 19:25:18 -0600 Subject: [PATCH 17/19] Update apps/site/components/Common/Searchbox/Search.tsx Co-authored-by: Aviv Keller Signed-off-by: Aileen Villanueva Lecuona --- apps/site/components/Common/Searchbox/Search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index 2ad00446e8585..df89aa7b87aa8 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -50,7 +50,7 @@ export const Search: FC = ({ onChatTrigger }) => { onClick={onChatTrigger} className={classNames( styles.chatButton, - searchTerm ? styles.chatButtonWithSearch : '' + { [styles.chatButtonWithSearch]: searchTerm } )} data-focus-on-arrow-nav > From d37297f534ad00bdf480a6bf8937325220d22a2f Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Date: Wed, 9 Jul 2025 20:14:23 -0600 Subject: [PATCH 18/19] fix height and pr comments --- .../components/Common/SearchOld/index.tsx | 145 ------------ .../site/components/Common/SearchOld/utils.ts | 60 ----- .../components/Common/Searchbox/Search.tsx | 209 +++++++++--------- .../Common/Searchbox/index.module.css | 9 +- .../components/Common/Searchbox/index.tsx | 23 +- apps/site/components/withNavBar.tsx | 2 +- .../scripts/orama-search/sync-orama-cloud.mjs | 1 - packages/i18n/src/locales/en.json | 2 +- packages/i18n/src/locales/es.json | 2 +- packages/i18n/src/locales/tr.json | 2 +- 10 files changed, 133 insertions(+), 322 deletions(-) delete mode 100644 apps/site/components/Common/SearchOld/index.tsx delete mode 100644 apps/site/components/Common/SearchOld/utils.ts diff --git a/apps/site/components/Common/SearchOld/index.tsx b/apps/site/components/Common/SearchOld/index.tsx deleted file mode 100644 index 0c12664b61826..0000000000000 --- a/apps/site/components/Common/SearchOld/index.tsx +++ /dev/null @@ -1,145 +0,0 @@ -'use client'; - -import { OramaSearchBox, OramaSearchButton } from '@orama/react-components'; -import { useTranslations, useLocale } from 'next-intl'; -import { useTheme } from 'next-themes'; -import type { FC } from 'react'; - -import { useRouter } from '#site/navigation.mjs'; -import { - ORAMA_CLOUD_ENDPOINT, - ORAMA_CLOUD_API_KEY, - DEFAULT_ORAMA_QUERY_PARAMS, - DEFAULT_ORAMA_SUGGESTIONS, - BASE_URL, -} from '#site/next.constants.mjs'; - -type ResultMapDescription = { - path: string; - pageSectionTitle: string; -}; - -type ResultMapPath = { path: string; siteSection: string }; - -import { themeConfig, translationKeys } from './utils'; - -const uppercaseFirst = (word: string) => - word.charAt(0).toUpperCase() + word.slice(1); - -const getFormattedPath = (path: string, title: string) => - `${path - .replace(/#.+$/, '') - .split('/') - .map(element => element.replaceAll('-', ' ')) - .map(element => uppercaseFirst(element)) - .filter(Boolean) - .join(' > ')} — ${title}`; - -const SearchButton: FC = () => { - const { resolvedTheme } = useTheme(); - const t = useTranslations(); - const locale = useLocale(); - const colorScheme = resolvedTheme as 'light' | 'dark'; - const router = useRouter(); - - const sourceMap = { - title: 'pageSectionTitle', - description: 'formattedPath', - path: 'path', - }; - - const resultMap = { - ...sourceMap, - description: ({ path, pageSectionTitle }: ResultMapDescription) => - getFormattedPath(path, pageSectionTitle), - path: ({ path, siteSection }: ResultMapPath) => - siteSection.toLowerCase() === 'docs' ? `/${path}` : `/${locale}/${path}`, - section: 'siteSection', - }; - - return ( - <> - - {t('components.search.searchPlaceholder')} - - - [key, t(`components.search.${key}`)]) - )} - searchParams={DEFAULT_ORAMA_QUERY_PARAMS} - suggestions={DEFAULT_ORAMA_SUGGESTIONS} - chatMarkdownLinkHref={({ href }) => { - if (!href) { - return href; - } - - const baseURLObject = new URL(BASE_URL); - const baseURLHostName = baseURLObject.hostname; - - const searchBoxURLObject = new URL(href); - const searchBoxURLHostName = searchBoxURLObject.hostname; - const serachBoxURLPathName = searchBoxURLObject.pathname; - - // We do not want to add the locale to the url for external links and docs links - if ( - baseURLHostName !== searchBoxURLHostName || - serachBoxURLPathName.startsWith('/docs/') - ) { - return href; - } - - const URLWithLocale = new URL( - `${locale}${searchBoxURLObject.pathname}`, - searchBoxURLObject.origin - ); - - return URLWithLocale.href; - }} - onAnswerSourceClick={event => { - event.preventDefault(); - - const baseURLObject = new URL(BASE_URL); - - const { path } = event.detail.source; - - const finalPath = path.startsWith('docs/') - ? path - : `${locale}/${path}`; - - const finalURL = new URL(finalPath, baseURLObject); - - window.open(finalURL, '_blank'); - }} - onSearchResultClick={event => { - event.preventDefault(); - - const fullURLObject = new URL(event.detail.result.path, BASE_URL); - - // result.path already contains LOCALE. Locale is set to undefined here so router does not add it once again. - router.push(fullURLObject.href, { locale: undefined }); - }} - /> - - ); -}; - -export default SearchButton; diff --git a/apps/site/components/Common/SearchOld/utils.ts b/apps/site/components/Common/SearchOld/utils.ts deleted file mode 100644 index dca1281ad7154..0000000000000 --- a/apps/site/components/Common/SearchOld/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -export const themeConfig = { - typography: { - '--font-primary': 'var(--font-open-sans)', - }, - colors: { - light: { - '--text-color-primary': 'var(--color-neutral-900)', - '--text-color-accent': 'var(--color-green-600)', - '--background-color-secondary': 'var(--color-neutral-100)', - '--background-color-tertiary': 'var(--color-neutral-300)', - '--border-color-accent': 'var(--color-green-600)', - '--border-color-primary': 'var(--color-neutral-200)', - '--border-color-tertiary': 'var(--color-green-700)', - '--button-background-color-primary': 'var(--color-green-600)', - '--button-background-color-secondary': 'var(--color-white)', - '--button-background-color-secondary-hover': 'var(--color-neutral-100)', - '--button-border-color-secondary': 'var(--color-neutral-300)', - '--button-text-color-secondary': 'var(--color-neutral-900)', - '--chat-button-border-color-gradientThree': 'var(--color-green-400)', - '--chat-button-border-color-gradientFour': 'var(--color-green-700)', - '--chat-button-background-color-gradientOne': 'var(--color-green-600)', - '--chat-button-background-color-gradientTwo': 'var(--color-green-300)', - }, - dark: { - '--text-color-primary': 'var(--color-neutral-100)', - '--text-color-accent': 'var(--color-green-400)', - '--background-color-secondary': 'var(--color-neutral-950)', - '--background-color-tertiary': 'var(--color-neutral-900)', - '--border-color-accent': 'var(--color-green-400)', - '--border-color-primary': 'var(--color-neutral-900)', - '--border-color-tertiary': 'var(--color-green-300)', - '--button-background-color-primary': 'var(--color-green-400)', - '--button-background-color-secondary': 'var(--color-neutral-950)', - '--button-background-color-secondary-hover': 'var(--color-neutral-900)', - '--button-border-color-secondary': 'var(--color-neutral-900)', - '--button-text-color-secondary': 'var(--color-neutral-200)', - '--chat-button-border-color-gradientThree': 'var(--color-green-400)', - '--chat-button-border-color-gradientFour': 'var(--color-green-700)', - '--chat-button-background-color-gradientOne': 'var(--color-green-400)', - '--chat-button-background-color-gradientTwo': 'var(--color-green-800)', - }, - }, -}; - -export const translationKeys = [ - 'searchPlaceholder', - 'chatPlaceholder', - 'noResultsFoundFor', - 'suggestions', - 'seeAll', - 'addMore', - 'clearChat', - 'errorMessage', - 'disclaimer', - 'startYourSearch', - 'initErrorSearch', - 'initErrorChat', - 'chatButtonLabel', - 'searchButtonLabel', -] as const; diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search.tsx index cd9416187f854..48d19ab5ab7ab 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search.tsx @@ -63,111 +63,118 @@ export const Search: FC = ({ onChatTrigger }) => {
- - - {(group, isSelected) => ( - + + + {(group, isSelected) => ( + + {group.name} + + {group.count} + + + )} + + + + + {searchTerm => ( + <> + {searchTerm ? ( +
+

+ {t('components.search.noResultsFoundFor')} "{searchTerm}" +

+
+ ) : ( + +

+ {t('components.search.suggestions')} +

+ + + + {t('components.search.suggestionOne')} + + + + {t('components.search.suggestionTwo')} + + + + {t('components.search.suggestionThree')} + + +
)} - > - {group.name} - {group.count} -
+ )} -
-
- - - {searchTerm => ( - <> - {searchTerm ? ( -
-

- {t('components.search.noResultsFoundFor')} "{searchTerm}" -

-
- ) : ( - -

- {t('components.search.suggestions')} -

- - - - {t('components.search.suggestionOne')} - - - - {t('components.search.suggestionTwo')} - - - - {t('components.search.suggestionThree')} - - -
- )} - - )} -
+ - - {group => ( -
-

{group.name}

- - {hit => ( - - - -
- {typeof hit.document?.pageSectionTitle === 'string' && ( -

- {hit.document?.pageSectionTitle} -

- )} - {typeof hit.document?.pageSectionTitle === 'string' && - typeof hit.document?.path === 'string' && ( -

- {getFormattedPath( - hit.document?.path, - hit.document?.pageSectionTitle - )} -

+ + {group => ( +
+

{group.name}

+ + {hit => ( + + + +
+ {typeof hit.document?.pageSectionTitle === + 'string' && ( +

+ {hit.document?.pageSectionTitle} +

)} -
- -
- )} -
-
- )} -
+ {typeof hit.document?.pageSectionTitle === 'string' && + typeof hit.document?.path === 'string' && ( +

+ {getFormattedPath( + hit.document?.path, + hit.document?.pageSectionTitle + )} +

+ )} +
+ +
+ )} +
+
+ )} +
+
diff --git a/apps/site/components/Common/Searchbox/index.module.css b/apps/site/components/Common/Searchbox/index.module.css index 1bd5eabe5474a..dd86260379dfa 100644 --- a/apps/site/components/Common/Searchbox/index.module.css +++ b/apps/site/components/Common/Searchbox/index.module.css @@ -79,7 +79,6 @@ sm:bottom-auto sm:top-[5vh] sm:mx-auto - sm:max-h-[70vh] sm:min-h-[200px] sm:w-[80%] sm:max-w-[720px] @@ -90,9 +89,11 @@ dark:bg-neutral-950 sm:dark:border-neutral-900; - > section { - @apply h-full; - } + max-height: 28vh; +} + +.modalWrapper.modalWrapperWithResults .modalInner { + max-height: 70vh; } .modalContent { diff --git a/apps/site/components/Common/Searchbox/index.tsx b/apps/site/components/Common/Searchbox/index.tsx index 569088f9bc50f..c646a29130825 100644 --- a/apps/site/components/Common/Searchbox/index.tsx +++ b/apps/site/components/Common/Searchbox/index.tsx @@ -3,6 +3,8 @@ import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; import { CollectionManager } from '@orama/core'; import { SearchRoot, ChatRoot, Modal } from '@orama/ui/components'; +import { useSearchContext } from '@orama/ui/contexts'; +import classNames from 'classnames'; import { useTranslations } from 'next-intl'; import { useState, type FC, type PropsWithChildren } from 'react'; @@ -34,9 +36,10 @@ const InnerSearchBox: FC = () => { ); }; -const OramaSearch: FC = () => { +const SearchWithModal: FC = () => { const [open, setOpen] = useState(false); const t = useTranslations(); + const { searchTerm } = useSearchContext(); const toggleSearchBox = (): void => { setOpen(!open); @@ -61,15 +64,13 @@ const OramaSearch: FC = () => { onModalClosed={toggleSearchBox} closeOnOutsideClick={true} closeOnEscape={true} - className={styles.modalWrapper} + className={classNames(styles.modalWrapper, { + [styles.modalWrapperWithResults]: searchTerm, + })} > - - - - - + @@ -77,4 +78,12 @@ const OramaSearch: FC = () => { ); }; +const OramaSearch: FC = () => ( + + + + + +); + export default OramaSearch; diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index f25218903ca91..a264b9ec29aa2 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -21,7 +21,7 @@ import { useRouter, usePathname } from '#site/navigation.mjs'; import { availableLocales } from '#site/next.locales.mjs'; const SearchButton = dynamic( - () => import('#site/components/Common/Searchbox'), + () => import('#site/components/Common/SearchBox'), { ssr: false, loading: () => ( diff --git a/apps/site/scripts/orama-search/sync-orama-cloud.mjs b/apps/site/scripts/orama-search/sync-orama-cloud.mjs index f0a4be60d0148..e8c0740451f84 100644 --- a/apps/site/scripts/orama-search/sync-orama-cloud.mjs +++ b/apps/site/scripts/orama-search/sync-orama-cloud.mjs @@ -30,7 +30,6 @@ const runUpdate = async () => { console.log(`Sending ${batches.length} batches of ${batchSize} documents`); for (const batch of batches) { - // In Orama, "update" is an upsert operation. await index.upsertDocuments(batch); } }; diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index 1f7f47189a85e..719b28f77787e 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -253,7 +253,7 @@ "initErrorChat": "Unable to initialize chat service", "chatButtonLabel": "Get an AI summary", "searchButtonLabel": "Search", - "poweredBy": "Powered by", + "poweredBy": "Powered by Orama", "suggestionOne": "How to install Node.js?", "suggestionTwo": "How to create an HTTP server?", "suggestionThree": "Upgrading Node.js version", diff --git a/packages/i18n/src/locales/es.json b/packages/i18n/src/locales/es.json index dd15732fcecb6..15e2634f52cec 100644 --- a/packages/i18n/src/locales/es.json +++ b/packages/i18n/src/locales/es.json @@ -218,7 +218,7 @@ "text": "Ocurrió un error mientras se realizaba la búsqueda. Por favor, intenta nuevamente más tarde." }, "poweredBy": { - "text": "Impulsado por" + "text": "Impulsado por Orama" }, "noResults": { "text": "Lo sentimos, no hay resultados para {query}." diff --git a/packages/i18n/src/locales/tr.json b/packages/i18n/src/locales/tr.json index 41d9c8ff64e9f..2cfaa4053d1c6 100644 --- a/packages/i18n/src/locales/tr.json +++ b/packages/i18n/src/locales/tr.json @@ -220,7 +220,7 @@ "text": "Arama sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyin." }, "poweredBy": { - "text": "Tarafından desteklenmektedir" + "text": "Tarafından desteklenmektedir Orama" }, "noResults": { "text": "\"{query}\" için sonuç bulunamadı." From ff59f5b00ab84e9e90d18d951f84672780c1c190 Mon Sep 17 00:00:00 2001 From: Aileen Villanueva Date: Wed, 9 Jul 2025 21:25:49 -0600 Subject: [PATCH 19/19] fix import and add directories for Search and Chat --- .../Searchbox/{chat.module.css => Chat/index.module.css} | 0 .../Common/Searchbox/{Chat.tsx => Chat/index.tsx} | 2 +- .../{search.module.css => Search/index.module.css} | 2 +- .../Common/Searchbox/{Search.tsx => Search/index.tsx} | 9 ++++----- .../components/Common/Searchbox/{ => Search}/utils.ts | 0 apps/site/components/withNavBar.tsx | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) rename apps/site/components/Common/Searchbox/{chat.module.css => Chat/index.module.css} (100%) rename apps/site/components/Common/Searchbox/{Chat.tsx => Chat/index.tsx} (99%) rename apps/site/components/Common/Searchbox/{search.module.css => Search/index.module.css} (98%) rename apps/site/components/Common/Searchbox/{Search.tsx => Search/index.tsx} (97%) rename apps/site/components/Common/Searchbox/{ => Search}/utils.ts (100%) diff --git a/apps/site/components/Common/Searchbox/chat.module.css b/apps/site/components/Common/Searchbox/Chat/index.module.css similarity index 100% rename from apps/site/components/Common/Searchbox/chat.module.css rename to apps/site/components/Common/Searchbox/Chat/index.module.css diff --git a/apps/site/components/Common/Searchbox/Chat.tsx b/apps/site/components/Common/Searchbox/Chat/index.tsx similarity index 99% rename from apps/site/components/Common/Searchbox/Chat.tsx rename to apps/site/components/Common/Searchbox/Chat/index.tsx index 9752bad132161..7b2ee5f8b3534 100644 --- a/apps/site/components/Common/Searchbox/Chat.tsx +++ b/apps/site/components/Common/Searchbox/Chat/index.tsx @@ -22,7 +22,7 @@ import Link from 'next/link'; import { useLocale, useTranslations } from 'next-intl'; import type { FC, PropsWithChildren } from 'react'; -import styles from './chat.module.css'; +import styles from './index.module.css'; type SlidingChatPanelProps = PropsWithChildren<{ open: boolean; diff --git a/apps/site/components/Common/Searchbox/search.module.css b/apps/site/components/Common/Searchbox/Search/index.module.css similarity index 98% rename from apps/site/components/Common/Searchbox/search.module.css rename to apps/site/components/Common/Searchbox/Search/index.module.css index a8784ff4052c5..0b7a0707c4ace 100644 --- a/apps/site/components/Common/Searchbox/search.module.css +++ b/apps/site/components/Common/Searchbox/Search/index.module.css @@ -1,4 +1,4 @@ -@reference "../../../styles/index.css"; +@reference "../../../../styles/index.css"; .searchInputWrapper { @apply relative; diff --git a/apps/site/components/Common/Searchbox/Search.tsx b/apps/site/components/Common/Searchbox/Search/index.tsx similarity index 97% rename from apps/site/components/Common/Searchbox/Search.tsx rename to apps/site/components/Common/Searchbox/Search/index.tsx index feeb7440c403d..a90ecd479fd1e 100644 --- a/apps/site/components/Common/Searchbox/Search.tsx +++ b/apps/site/components/Common/Searchbox/Search/index.tsx @@ -20,7 +20,7 @@ import Link from 'next/link'; import { useLocale, useTranslations } from 'next-intl'; import type { FC, PropsWithChildren } from 'react'; -import styles from './search.module.css'; +import styles from './index.module.css'; import { getFormattedPath } from './utils'; type SearchProps = PropsWithChildren<{ @@ -48,10 +48,9 @@ export const Search: FC = ({ onChatTrigger }) => {