diff --git a/apps/mobile/app/components/list-items/search-result/index.tsx b/apps/mobile/app/components/list-items/search-result/index.tsx new file mode 100644 index 000000000..93657b636 --- /dev/null +++ b/apps/mobile/app/components/list-items/search-result/index.tsx @@ -0,0 +1,181 @@ +/* +This file is part of the Notesnook project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +import React from "react"; +import { HighlightedResult } from "@notesnook/core"; +import { View } from "react-native"; +import { Pressable } from "../../ui/pressable"; +import Paragraph from "../../ui/typography/paragraph"; +import { useThemeColors } from "@notesnook/theme"; +import { DefaultAppStyles } from "../../../utils/styles"; +import Heading from "../../ui/typography/heading"; +import { AppFontSize } from "../../../utils/size"; +import { Properties } from "../../properties"; +import { db } from "../../../common/database"; +import { eSendEvent } from "../../../services/event-manager"; +import { eOnLoadNote } from "../../../utils/events"; +import { IconButton } from "../../ui/icon-button"; +import { fluidTabsRef } from "../../../utils/global-refs"; +type SearchResultProps = { + item: HighlightedResult; +}; + +export const SearchResult = (props: SearchResultProps) => { + const [expanded, setExpanded] = React.useState(true); + const { colors } = useThemeColors(); + + const openNote = async (index?: number) => { + const note = await db.notes.note(props.item.id); + eSendEvent(eOnLoadNote, { + item: { + ...note, + content: props.item.rawContent + ? { + data: props.item.rawContent || "", + type: "tiptap" + } + : undefined + }, + searchResultIndex: index + }); + fluidTabsRef.current?.goToPage("editor"); + }; + + return ( + { + const note = await db.notes.note(props.item.id); + Properties.present(note); + }} + onPress={async () => openNote()} + > + + + {props.item.content?.length ? ( + setExpanded((prev) => !prev)} + size={AppFontSize.md + 2} + color={colors.secondary.icon} + style={{ + width: 23, + height: 23 + }} + /> + ) : null} + + {props.item.title.map((title) => ( + <> + {title.prefix} + + {title.match} + + {title.suffix} + + ))} + + + {props.item.content?.length ? ( + + {props.item.content.length} + + ) : null} + + + {expanded && + props.item.content.map((content, index) => ( + { + const note = await db.notes.note(props.item.id); + Properties.present(note); + }} + onPress={() => { + let activeIndex = 0; + for (let i = 0; i <= index; i++) { + activeIndex += props.item.content[i].length; + } + console.log(activeIndex); + openNote(activeIndex); + }} + > + + {content.map((match) => ( + <> + {match.prefix} + + {match.match} + + {match.suffix} + + ))} + + + ))} + + ); +}; diff --git a/apps/mobile/app/components/list/index.tsx b/apps/mobile/app/components/list/index.tsx index 3933a4b38..675017a8d 100644 --- a/apps/mobile/app/components/list/index.tsx +++ b/apps/mobile/app/components/list/index.tsx @@ -150,7 +150,7 @@ export default function List(props: ListProps) { flex: 1 }} > - {props.data?.placeholders?.length === 0 ? ( + {props.data?.placeholders?.length === 0 || !props.data ? ( <> {props.CustomLisHeader ? ( props.CustomLisHeader diff --git a/apps/mobile/app/components/list/list-item.wrapper.tsx b/apps/mobile/app/components/list/list-item.wrapper.tsx index 9a816d4ca..b91904477 100644 --- a/apps/mobile/app/components/list/list-item.wrapper.tsx +++ b/apps/mobile/app/components/list/list-item.wrapper.tsx @@ -27,6 +27,7 @@ import { GroupHeader, GroupOptions, GroupingKey, + HighlightedResult, Item, ItemType, Note, @@ -49,6 +50,7 @@ import { NoteWrapper } from "../list-items/note/wrapper"; import { NotebookWrapper } from "../list-items/notebook/wrapper"; import ReminderItem from "../list-items/reminder"; import TagItem from "../list-items/tag"; +import { SearchResult } from "../list-items/search-result"; type ListItemWrapperProps = { group?: GroupingKey; @@ -153,7 +155,9 @@ export function ListItemWrapper(props: ListItemWrapperProps) { }, items?.cacheItem(index) ? 100 : 0 ); - } catch (e) {} + } catch (e) { + /** empty */ + } })(); }, [index, items, refreshItem]); @@ -196,7 +200,7 @@ export function ListItemWrapper(props: ListItemWrapperProps) { notebooks={notebooks.current} reminder={reminder.current} attachmentsCount={attachmentsCount.current} - date={getDate(item, group)} + date={getDate(item as Note, group)} isRenderedInActionSheet={isSheet} index={index} locked={locked.current} @@ -227,7 +231,7 @@ export function ListItemWrapper(props: ListItemWrapperProps) { @@ -285,12 +289,34 @@ export function ListItemWrapper(props: ListItemWrapperProps) { /> ); + case "searchResult": + return ( + <> + {groupHeader && previousIndex.current === index && !isSheet ? ( + { + eSendEvent(eOpenJumpToDialog, { + ref: props.scrollRef, + data: items + }); + }} + /> + ) : null} + + + ); default: return null; } } -function getDate(item: Item, groupType?: GroupingKey): number { +function getDate(item: Notebook | Note, groupType?: GroupingKey): number { return ( getSortValue( groupType diff --git a/apps/mobile/app/screens/editor/tiptap/commands.ts b/apps/mobile/app/screens/editor/tiptap/commands.ts index ae5eada47..aaa1782e9 100644 --- a/apps/mobile/app/screens/editor/tiptap/commands.ts +++ b/apps/mobile/app/screens/editor/tiptap/commands.ts @@ -236,6 +236,11 @@ class Commands { const tabId = useTabStore.getState().currentTab; return this.sendCommand("scrollIntoViewById", id, tabId); }; + + scrollToSearchResult = (index: number) => { + const tabId = useTabStore.getState().currentTab; + return this.sendCommand("scrollToSearchResult", index, tabId); + }; } export default Commands; diff --git a/apps/mobile/app/screens/editor/tiptap/use-editor.ts b/apps/mobile/app/screens/editor/tiptap/use-editor.ts index 0c475e7da..ad2be7f8e 100644 --- a/apps/mobile/app/screens/editor/tiptap/use-editor.ts +++ b/apps/mobile/app/screens/editor/tiptap/use-editor.ts @@ -469,8 +469,7 @@ export const useEditor = ( } ) => { currentNotes.current[note.id] = note; - const locked = note && (await db.vaults.itemExists(note)); - if ((locked || note.content) && note.content?.data) { + if (note.content && note.content?.data) { currentContents.current[note.id] = { data: note.content?.data, type: note.content?.type || "tiptap", @@ -498,6 +497,7 @@ export const useEditor = ( session?: TabSessionItem; newTab?: boolean; refresh?: boolean; + searchResultIndex?: number; }) => { loadNoteMutex.runExclusive(async () => { if (!event) return; @@ -683,13 +683,17 @@ export const useEditor = ( { data: currentContents.current[item.id]?.data || "", scrollTop: tab?.session?.scrollTop, - selection: tab?.session?.selection + selection: tab?.session?.selection, + searchResultIndex: event.searchResultIndex }, tabId, 10000 ); setTimeout(() => { + if (event.searchResultIndex !== undefined) { + commands.scrollToSearchResult(event.searchResultIndex); + } if (blockIdRef.current) { commands.scrollIntoViewById(blockIdRef.current); blockIdRef.current = undefined; diff --git a/apps/mobile/app/screens/search/index.tsx b/apps/mobile/app/screens/search/index.tsx index 8075accd3..c63c24674 100644 --- a/apps/mobile/app/screens/search/index.tsx +++ b/apps/mobile/app/screens/search/index.tsx @@ -17,7 +17,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { Item, Note, VirtualizedGrouping } from "@notesnook/core"; +import { + FilteredSelector, + Item, + Note, + VirtualizedGrouping +} from "@notesnook/core"; +import { strings } from "@notesnook/intl"; import React, { useEffect, useRef, useState } from "react"; import { DatabaseLogger, db } from "../../common/database"; import List from "../../components/list"; @@ -28,20 +34,20 @@ import { NavigationProps } from "../../services/navigation"; import useNavigationStore from "../../stores/use-navigation-store"; import { eGroupOptionsUpdated, eOnRefreshSearch } from "../../utils/events"; import { SearchBar } from "./search-bar"; -import { FilteredSelector } from "@notesnook/core"; -import { strings } from "@notesnook/intl"; export const Search = ({ route, navigation }: NavigationProps<"Search">) => { const [results, setResults] = useState>(); const [loading, setLoading] = useState(false); const [searchStatus, setSearchStatus] = useState(); const currentQuery = useRef(); const timer = useRef(); - const isFocused = useNavigationFocus(navigation, { + useNavigationFocus(navigation, { onFocus: (prev) => { useNavigationStore.getState().setFocusedRouteId(route.name); return !prev?.current; }, - onBlur: () => false + onBlur: () => { + return false; + } }); const onSearch = React.useCallback( @@ -57,12 +63,14 @@ export const Search = ({ route, navigation }: NavigationProps<"Search">) => { setLoading(true); let results: VirtualizedGrouping | undefined; const groupOptions = db.settings.getGroupOptions("search"); - switch (route.params.type) { case "note": - results = await db.lookup - .notes(query, route.params.items as FilteredSelector) - .sorted(groupOptions); + results = await db.lookup.notes( + query, + groupOptions, + route.params.items as FilteredSelector + ); + break; case "notebook": results = await db.lookup.notebooks(query).sorted(groupOptions); @@ -143,7 +151,7 @@ export const Search = ({ route, navigation }: NavigationProps<"Search">) => { clearTimeout(timer.current); timer.current = setTimeout(() => { onSearch(query); - }, 300); + }, 500); }} loading={loading} /> diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index c5fc321cd..91a9e1e9c 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -1,12 +1,12 @@ { "name": "@notesnook/mobile", - "version": "3.1.0-beta.2", + "version": "3.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@notesnook/mobile", - "version": "3.1.0-beta.2", + "version": "3.1.1", "hasInstallScript": true, "license": "GPL-3.0-or-later", "workspaces": [ @@ -1069,8 +1069,7 @@ "prismjs": "^1.29.0", "qclone": "^1.2.0", "rfdc": "^1.3.0", - "spark-md5": "^3.0.2", - "sqlite-better-trigram": "0.0.2" + "spark-md5": "^3.0.2" }, "devDependencies": { "@notesnook/crypto": "file:../crypto", @@ -1096,6 +1095,8 @@ "nanoid": "5.0.7", "otplib": "^12.0.1", "refractor": "^4.8.1", + "sqlite-better-trigram": "^0.0.3", + "sqlite3-fts5-html": "^0.0.3", "vitest": "2.1.8", "vitest-fetch-mock": "^0.2.2", "ws": "^8.13.0" @@ -3727,7 +3728,7 @@ "hasInstallScript": true, "license": "GPL-3.0-or-later", "dependencies": { - "@notesnook-importer/core": "^2.1.1", + "@notesnook-importer/core": "^2.2.2", "@notesnook/common": "file:../common", "@notesnook/intl": "file:../intl", "@notesnook/theme": "file:../theme", diff --git a/packages/common/package-lock.json b/packages/common/package-lock.json index 6a0daf84b..39df12c1f 100644 --- a/packages/common/package-lock.json +++ b/packages/common/package-lock.json @@ -83,7 +83,7 @@ "otplib": "^12.0.1", "refractor": "^4.8.1", "sqlite-better-trigram": "^0.0.3", - "sqlite3-fts5-html": "^0.0.2", + "sqlite3-fts5-html": "^0.0.3", "vitest": "2.1.8", "vitest-fetch-mock": "^0.2.2", "ws": "^8.13.0" diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index f924ea390..2f4fdf3a0 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -93,7 +93,7 @@ export type Collections = { export type CollectionType = keyof Collections; -export type ItemType = ValueOf; +export type ItemType = ValueOf | "searchResult"; export type Item = ValueOf; export type GroupableItem = ValueOf< @@ -130,6 +130,7 @@ export type ItemMap = { sessioncontent: SessionContentItem; settingitem: SettingItem; vault: Vault; + searchResult: HighlightedResult; /** * @deprecated only kept here for migration purposes @@ -493,9 +494,8 @@ export type Match = { match: string; suffix: string; }; -export interface HighlightedResult { - type: "searchResult"; - id: string; + +export interface HighlightedResult extends BaseItem<"searchResult"> { rawContent?: string; title: Match[]; content: Match[][]; diff --git a/packages/editor-mobile/package-lock.json b/packages/editor-mobile/package-lock.json index eb6859d79..6c0bd8ba5 100644 --- a/packages/editor-mobile/package-lock.json +++ b/packages/editor-mobile/package-lock.json @@ -63,7 +63,7 @@ "hasInstallScript": true, "license": "GPL-3.0-or-later", "dependencies": { - "@notesnook-importer/core": "^2.1.1", + "@notesnook-importer/core": "^2.2.2", "@notesnook/common": "file:../common", "@notesnook/intl": "file:../intl", "@notesnook/theme": "file:../theme", diff --git a/packages/editor-mobile/src/components/editor.tsx b/packages/editor-mobile/src/components/editor.tsx index f9a0e01be..68ca24539 100644 --- a/packages/editor-mobile/src/components/editor.tsx +++ b/packages/editor-mobile/src/components/editor.tsx @@ -201,6 +201,9 @@ const Tiptap = ({ copyToClipboard: (text) => { globalThis.editorControllers[tab.id]?.copyToClipboard(text); }, + onFocus: () => { + getContentDiv().classList.remove("searching"); + }, onSelectionUpdate: () => { if (tabRef.current.session?.noteId) { clearTimeout(noteStateUpdateTimer.current); @@ -245,7 +248,11 @@ const Tiptap = ({ ]); const update = useCallback( - (scrollTop?: number, selection?: { to: number; from: number }) => { + ( + scrollTop?: number, + selection?: { to: number; from: number }, + searchResultIndex?: number + ) => { setTick((tick) => tick + 1); globalThis.editorControllers[tabRef.current.id]?.setTitlePlaceholder( strings.noteTitle() @@ -253,7 +260,13 @@ const Tiptap = ({ setTimeout(() => { editorControllers[tabRef.current.id]?.setLoading(false); setTimeout(() => { - restoreNoteSelection(scrollTop, selection); + if (searchResultIndex !== undefined) { + globalThis.editorControllers[ + tabRef.current.id + ]?.scrollToSearchResult(searchResultIndex); + } else { + restoreNoteSelection(scrollTop, selection); + } }, 300); }, 1); }, @@ -270,6 +283,9 @@ const Tiptap = ({ scrollTop: () => containerRef.current?.scrollTop || 0, scrollTo: (top) => { containerRef.current?.scrollTo({ top, behavior: "auto" }); + }, + getContentDiv() { + return getContentDiv(); } }); const controllerRef = useRef(controller); @@ -888,7 +904,7 @@ const TiptapProvider = (): JSX.Element => { return contentRef.current; } const editorContainer = document.createElement("div"); - editorContainer.classList.add("selectable", "main-editor"); + editorContainer.classList.add("selectable", "main-editor", "searching"); editorContainer.style.flex = "1"; editorContainer.style.cursor = "text"; editorContainer.style.padding = "0px 12px"; @@ -897,6 +913,7 @@ const TiptapProvider = (): JSX.Element => { editorContainer.style.fontFamily = getFontById(settings.fontFamily)?.font || "sans-serif"; contentRef.current = editorContainer; + return editorContainer; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/packages/editor-mobile/src/hooks/useEditorController.ts b/packages/editor-mobile/src/hooks/useEditorController.ts index aca0e3a44..169b5d6fc 100644 --- a/packages/editor-mobile/src/hooks/useEditorController.ts +++ b/packages/editor-mobile/src/hooks/useEditorController.ts @@ -101,20 +101,25 @@ export type EditorController = { passwordInputRef: MutableRefObject; focusPassInput: () => void; blurPassInput: () => void; + scrollToSearchResult: (index: number) => void; + getContentDiv: () => HTMLElement | null; }; export function useEditorController({ update, getTableOfContents, scrollTo, - scrollTop + scrollTop, + getContentDiv }: { update: ( scrollTop?: number, - selection?: { to: number; from: number } + selection?: { to: number; from: number }, + searchResultIndex?: number ) => void; getTableOfContents: () => any[]; scrollTo: (top: number) => void; scrollTop: () => number; + getContentDiv: () => HTMLElement | null; }): EditorController { const passwordInputRef = useRef(null); const tab = useTabContext(); @@ -360,7 +365,7 @@ export function useEditorController({ htmlContentRef.current = value.data; logger("info", "LOADING NOTE HTML"); if (!editor) break; - update(value.scrollTop, value.selection); + update(value.scrollTop, value.selection, value.searchResultIndex); setTimeout(() => { countWords(0); }, 300); @@ -449,9 +454,23 @@ export function useEditorController({ }); }; + const scrollToSearchResult = useCallback((index: number) => { + const marks = document.getElementsByTagName("nn-search-result"); + if (marks.length > index) { + const mark = marks[index]; + if (mark) { + mark.scrollIntoView({ + behavior: "instant", + block: "start" + }); + } + } + }, []); + return { getTableOfContents: getTableOfContents, scrollIntoView: (id: string) => scrollIntoViewById(id), + scrollToSearchResult: scrollToSearchResult, contentChange, selectionChange, titleChange, @@ -471,6 +490,7 @@ export function useEditorController({ countWords, copyToClipboard, getAttachmentData, + getContentDiv, updateTab: () => { // When the tab is focused, we apply any updates to content that were recieved when // the tab was not focused. diff --git a/packages/editor-mobile/src/utils/commands.ts b/packages/editor-mobile/src/utils/commands.ts index 7f20313bc..c30cf4626 100644 --- a/packages/editor-mobile/src/utils/commands.ts +++ b/packages/editor-mobile/src/utils/commands.ts @@ -196,5 +196,9 @@ globalThis.commands = { scrollIntoViewById: (id: string, tabId: string) => { return editorControllers[tabId]?.scrollIntoView(id) || []; + }, + scrollToSearchResult: (index: number, tabId: string) => { + editorControllers[tabId]?.getContentDiv()?.classList.add("searching"); + editorControllers[tabId]?.scrollToSearchResult(index); } }; diff --git a/packages/theme/package-lock.json b/packages/theme/package-lock.json index a3cb3913e..5d610a1ca 100644 --- a/packages/theme/package-lock.json +++ b/packages/theme/package-lock.json @@ -529,39 +529,6 @@ "polished": "^4.0.5" } }, - "node_modules/@theme-ui/color-modes": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.16.2.tgz", - "integrity": "sha512-jWEWx53lxNgWCT38i/kwLV2rsvJz8lVZgi5oImnVwYba9VejXD23q1ckbNFJHosQ8KKXY87ht0KPC6BQFIiHtQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/core": "^0.16.2", - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, - "node_modules/@theme-ui/color-modes/node_modules/@theme-ui/core": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz", - "integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, "node_modules/@theme-ui/components": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/@theme-ui/components/-/components-0.16.1.tgz", @@ -610,39 +577,6 @@ "@emotion/react": "^11.11.1" } }, - "node_modules/@theme-ui/theme-provider": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.16.2.tgz", - "integrity": "sha512-LRnVevODcGqO0JyLJ3wht+PV3ZoZcJ7XXLJAJWDoGeII4vZcPQKwVy4Lpz/juHsZppQxKcB3U+sQDGBnP25irQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/color-modes": "^0.16.2", - "@theme-ui/core": "^0.16.2", - "@theme-ui/css": "^0.16.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, - "node_modules/@theme-ui/theme-provider/node_modules/@theme-ui/core": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz", - "integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, "node_modules/@trpc/server": { "version": "10.45.2", "resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.45.2.tgz", diff --git a/packages/ui/package-lock.json b/packages/ui/package-lock.json index 47560617b..b90838f12 100644 --- a/packages/ui/package-lock.json +++ b/packages/ui/package-lock.json @@ -560,39 +560,6 @@ "@styled-system/css": "^5.1.5" } }, - "node_modules/@theme-ui/color-modes": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.16.2.tgz", - "integrity": "sha512-jWEWx53lxNgWCT38i/kwLV2rsvJz8lVZgi5oImnVwYba9VejXD23q1ckbNFJHosQ8KKXY87ht0KPC6BQFIiHtQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/core": "^0.16.2", - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, - "node_modules/@theme-ui/color-modes/node_modules/@theme-ui/core": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz", - "integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, "node_modules/@theme-ui/components": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/@theme-ui/components/-/components-0.16.1.tgz", @@ -641,39 +608,6 @@ "@emotion/react": "^11.11.1" } }, - "node_modules/@theme-ui/theme-provider": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.16.2.tgz", - "integrity": "sha512-LRnVevODcGqO0JyLJ3wht+PV3ZoZcJ7XXLJAJWDoGeII4vZcPQKwVy4Lpz/juHsZppQxKcB3U+sQDGBnP25irQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/color-modes": "^0.16.2", - "@theme-ui/core": "^0.16.2", - "@theme-ui/css": "^0.16.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, - "node_modules/@theme-ui/theme-provider/node_modules/@theme-ui/core": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@theme-ui/core/-/core-0.16.2.tgz", - "integrity": "sha512-bBd/ltbwO9vIUjF1jtlOX6XN0IIOdf1vzBp2JCKsSOqdfn84m+XL8OogIe/zOhQ+aM94Nrq4+32tFJc8sFav4Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@theme-ui/css": "^0.16.2", - "deepmerge": "^4.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.11.1", - "react": ">=18" - } - }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",