App Store Search (#5704)
Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Peer Richelsen <peer@cal.com>
This commit is contained in:
co-authored by
Alex van Andel
Peer Richelsen
Peer Richelsen
parent
ef3ad36c2c
commit
f1b92c49fc
@@ -38,7 +38,7 @@
|
||||
"@calcom/tsconfig": "*",
|
||||
"@calcom/ui": "*",
|
||||
"@daily-co/daily-js": "^0.26.0",
|
||||
"@formkit/auto-animate": "^1.0.0-beta.1",
|
||||
"@formkit/auto-animate": "^1.0.0-beta.5",
|
||||
"@glidejs/glide": "^3.5.2",
|
||||
"@heroicons/react": "^1.0.6",
|
||||
"@hookform/error-message": "^2.0.0",
|
||||
|
||||
@@ -1,21 +1,55 @@
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { InferGetStaticPropsType, NextPageContext } from "next";
|
||||
import { ChangeEventHandler, useState } from "react";
|
||||
|
||||
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { getSession } from "@calcom/lib/auth";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { AppCategories } from "@calcom/prisma/client";
|
||||
import { AllApps, AppsLayout, AppStoreCategories, TrendingAppsSlider } from "@calcom/ui";
|
||||
import { AllApps, AppsLayout, AppStoreCategories, Icon, TextField, TrendingAppsSlider } from "@calcom/ui";
|
||||
|
||||
import { ssgInit } from "@server/lib/ssg";
|
||||
|
||||
function AppsSearch({
|
||||
onChange,
|
||||
className,
|
||||
}: {
|
||||
onChange: ChangeEventHandler<HTMLInputElement>;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<TextField
|
||||
className="!border-gray-100 bg-gray-100 !pl-0 focus:!ring-offset-0"
|
||||
addOnLeading={<Icon.FiSearch className="h-4 w-4 text-gray-500" />}
|
||||
addOnClassname="!border-gray-100"
|
||||
containerClassName={classNames("focus:!ring-offset-0", className)}
|
||||
type="search"
|
||||
autoComplete="false"
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Apps({ appStore, categories }: InferGetStaticPropsType<typeof getServerSideProps>) {
|
||||
const { t } = useLocale();
|
||||
const [searchText, setSearchText] = useState<string | undefined>(undefined);
|
||||
|
||||
return (
|
||||
<AppsLayout isPublic heading={t("app_store")} subtitle={t("app_store_description")}>
|
||||
<AppStoreCategories categories={categories} />
|
||||
<TrendingAppsSlider items={appStore} />
|
||||
<AllApps apps={appStore} />
|
||||
<AppsLayout
|
||||
isPublic
|
||||
heading={t("app_store")}
|
||||
subtitle={t("app_store_description")}
|
||||
actions={(className) => (
|
||||
<AppsSearch className={className} onChange={(e) => setSearchText(e.target.value)} />
|
||||
)}>
|
||||
{!searchText && (
|
||||
<>
|
||||
<AppStoreCategories categories={categories} />
|
||||
<TrendingAppsSlider items={appStore} />
|
||||
</>
|
||||
)}
|
||||
<AllApps apps={appStore} searchText={searchText} />
|
||||
</AppsLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "An event is still waiting for approval",
|
||||
"event_is_still_waiting": "Event request is still waiting: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "No more results",
|
||||
"no_results": "No results",
|
||||
"load_more_results": "Load more results",
|
||||
"integration_meeting_id": "{{integrationName}} meeting ID: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Confirmed: {{eventType}} with {{name}} at {{date}}",
|
||||
|
||||
@@ -499,4 +499,8 @@ hr {
|
||||
.h-screen {
|
||||
height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export const CreateANewTeamForm = () => {
|
||||
className="mt-2"
|
||||
name="name"
|
||||
label={t("team_name")}
|
||||
value={value}
|
||||
defaultValue={value}
|
||||
onChange={(e) => {
|
||||
newTeamFormMethods.setValue("name", e?.target.value);
|
||||
if (newTeamFormMethods.formState.touchedFields["slug"] === undefined) {
|
||||
@@ -91,7 +91,7 @@ export const CreateANewTeamForm = () => {
|
||||
"http://",
|
||||
""
|
||||
)}/`}
|
||||
value={value}
|
||||
defaultValue={value}
|
||||
onChange={(e) => {
|
||||
newTeamFormMethods.setValue("slug", slugify(e?.target.value), {
|
||||
shouldTouch: true,
|
||||
|
||||
@@ -6,7 +6,7 @@ import classNames from "@calcom/lib/classNames";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
||||
import { Alert, showToast, Skeleton, Tooltip, UnstyledSelect } from "../../..";
|
||||
import { Alert, showToast, Icon, Skeleton, Tooltip, UnstyledSelect } from "../../..";
|
||||
import { HintsOrErrors } from "./HintOrErrors";
|
||||
import { Label } from "./Label";
|
||||
|
||||
@@ -44,9 +44,8 @@ type InputFieldProps = {
|
||||
addOnLeading?: ReactNode;
|
||||
addOnSuffix?: ReactNode;
|
||||
inputIsFullWidth?: boolean;
|
||||
/**@Default paddingX 12px */
|
||||
addOnPadding?: number;
|
||||
addOnFilled?: boolean;
|
||||
addOnClassname?: string;
|
||||
error?: string;
|
||||
labelSrOnly?: boolean;
|
||||
containerClassName?: string;
|
||||
@@ -61,13 +60,15 @@ type AddonProps = {
|
||||
isFilled?: boolean;
|
||||
className?: string;
|
||||
error?: boolean;
|
||||
paddingX?: number;
|
||||
};
|
||||
|
||||
const Addon = ({ isFilled, children, className, error, paddingX = 12 }: AddonProps) => (
|
||||
const Addon = ({ isFilled, children, className, error }: AddonProps) => (
|
||||
<div
|
||||
style={{ padding: `0 ${paddingX}px` }}
|
||||
className={classNames("addon-wrapper h-9 border border-gray-300", isFilled && "bg-gray-100", className)}>
|
||||
className={classNames(
|
||||
"addon-wrapper h-9 border border-gray-300 px-3",
|
||||
isFilled && "bg-gray-100",
|
||||
className
|
||||
)}>
|
||||
<div className={classNames("flex h-full flex-col justify-center text-sm", error && "text-red-900")}>
|
||||
<span className="whitespace-nowrap py-2.5">{children}</span>
|
||||
</div>
|
||||
@@ -88,9 +89,10 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
|
||||
addOnLeading,
|
||||
addOnSuffix,
|
||||
addOnFilled = true,
|
||||
addOnPadding,
|
||||
addOnClassname,
|
||||
inputIsFullWidth,
|
||||
hint,
|
||||
type,
|
||||
hintErrors,
|
||||
labelSrOnly,
|
||||
containerClassName,
|
||||
@@ -99,6 +101,8 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
|
||||
...passThrough
|
||||
} = props;
|
||||
|
||||
const [inputValue, setInputValue] = useState<string>("");
|
||||
|
||||
return (
|
||||
<div className={classNames(containerClassName)}>
|
||||
{!!name && (
|
||||
@@ -114,28 +118,45 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
|
||||
{addOnLeading || addOnSuffix ? (
|
||||
<div className="relative mb-1 flex items-center rounded-md focus-within:outline-none focus-within:ring-2 focus-within:ring-neutral-800 focus-within:ring-offset-1">
|
||||
{addOnLeading && (
|
||||
<Addon isFilled={addOnFilled} className="rounded-l-md border-r-0" paddingX={addOnPadding}>
|
||||
<Addon isFilled={addOnFilled} className={classNames("rounded-l-md border-r-0", addOnClassname)}>
|
||||
{addOnLeading}
|
||||
</Addon>
|
||||
)}
|
||||
<Input
|
||||
id={id}
|
||||
placeholder={placeholder}
|
||||
{...passThrough}
|
||||
{...(type == "search" && {
|
||||
onChange: (e) => {
|
||||
setInputValue(e.target.value);
|
||||
props.onChange && props.onChange(e);
|
||||
},
|
||||
value: inputValue,
|
||||
})}
|
||||
isFullWidth={inputIsFullWidth}
|
||||
className={classNames(
|
||||
className,
|
||||
addOnLeading && "rounded-l-none",
|
||||
addOnSuffix && "rounded-r-none",
|
||||
type === "search" && "pr-8",
|
||||
"!my-0 !ring-0"
|
||||
)}
|
||||
{...passThrough}
|
||||
ref={ref}
|
||||
/>
|
||||
{addOnSuffix && (
|
||||
<Addon isFilled={addOnFilled} className="rounded-r-md border-l-0" paddingX={addOnPadding}>
|
||||
<Addon isFilled={addOnFilled} className={classNames("rounded-r-md border-l-0", addOnClassname)}>
|
||||
{addOnSuffix}
|
||||
</Addon>
|
||||
)}
|
||||
{type === "search" && inputValue?.toString().length > 0 && (
|
||||
<Icon.FiX
|
||||
className="absolute right-2 top-2.5 h-4 w-4 cursor-pointer text-gray-500"
|
||||
onClick={(e) => {
|
||||
setInputValue("");
|
||||
props.onChange && props.onChange(e as unknown as React.ChangeEvent<HTMLInputElement>);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Input
|
||||
@@ -344,7 +365,7 @@ export const InputFieldWithSelect = forwardRef<
|
||||
ref={ref}
|
||||
{...props}
|
||||
inputIsFullWidth={false}
|
||||
addOnPadding={0}
|
||||
addOnClassname="!px-0"
|
||||
addOnSuffix={<UnstyledSelect {...props.selectProps} />}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"dependencies": {
|
||||
"@calcom/lib": "*",
|
||||
"@calcom/trpc": "*",
|
||||
"@formkit/auto-animate": "^1.0.0-beta.1",
|
||||
"@formkit/auto-animate": "^1.0.0-beta.5",
|
||||
"@radix-ui/react-dialog": "^1.0.0",
|
||||
"@radix-ui/react-portal": "^1.0.0",
|
||||
"@radix-ui/react-select": "^0.1.1",
|
||||
|
||||
@@ -183,6 +183,8 @@ type LayoutProps = {
|
||||
withoutMain?: boolean;
|
||||
// Gives you the option to skip HeadSEO and render your own.
|
||||
withoutSeo?: boolean;
|
||||
// Gives the ability to include actions to the right of the heading
|
||||
actions?: JSX.Element;
|
||||
};
|
||||
|
||||
const CustomBrandingContainer = () => {
|
||||
@@ -840,6 +842,7 @@ export function ShellMain(props: LayoutProps) {
|
||||
{props.CTA}
|
||||
</div>
|
||||
)}
|
||||
{props.actions && props.actions}
|
||||
</header>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -36,14 +36,15 @@ export function useShouldShowArrows() {
|
||||
return { ref, calculateScroll, leftVisible: showArrowScroll.left, rightVisible: showArrowScroll.right };
|
||||
}
|
||||
|
||||
type AllAppsPropsType = { apps: (App & { credentials: Credential[] | undefined })[] };
|
||||
type AllAppsPropsType = { apps: (App & { credentials: Credential[] | undefined })[]; searchText?: string };
|
||||
|
||||
interface CategoryTabProps {
|
||||
selectedCategory: string | null;
|
||||
categories: string[];
|
||||
searchText?: string;
|
||||
}
|
||||
|
||||
function CategoryTab({ selectedCategory, categories }: CategoryTabProps) {
|
||||
function CategoryTab({ selectedCategory, categories, searchText }: CategoryTabProps) {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
const { ref, calculateScroll, leftVisible, rightVisible } = useShouldShowArrows();
|
||||
@@ -60,12 +61,14 @@ function CategoryTab({ selectedCategory, categories }: CategoryTabProps) {
|
||||
};
|
||||
return (
|
||||
<div className="relative mb-4 flex flex-col justify-between lg:flex-row lg:items-center">
|
||||
<h2 className="text-lg font-semibold text-gray-900 ">
|
||||
{t("explore_apps", {
|
||||
category:
|
||||
(selectedCategory && selectedCategory[0].toUpperCase() + selectedCategory.slice(1)) ||
|
||||
t("all_apps"),
|
||||
})}
|
||||
<h2 className="hidden text-lg font-semibold text-gray-900 sm:block">
|
||||
{searchText
|
||||
? t("search")
|
||||
: t("explore_apps", {
|
||||
category:
|
||||
(selectedCategory && selectedCategory[0].toUpperCase() + selectedCategory.slice(1)) ||
|
||||
t("all_apps"),
|
||||
})}
|
||||
</h2>
|
||||
{leftVisible && (
|
||||
<button onClick={handleLeft} className="absolute top-9 flex md:left-1/2 md:-top-1">
|
||||
@@ -121,11 +124,11 @@ function CategoryTab({ selectedCategory, categories }: CategoryTabProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function AllApps({ apps }: AllAppsPropsType) {
|
||||
export default function AllApps({ apps, searchText }: AllAppsPropsType) {
|
||||
const router = useRouter();
|
||||
|
||||
const { t } = useLocale();
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
const [appsContainerRef] = useAutoAnimate<HTMLDivElement>();
|
||||
const [appsContainerRef, enableAnimation] = useAutoAnimate<HTMLDivElement>();
|
||||
|
||||
const categories = apps
|
||||
.map((app) => app.category)
|
||||
@@ -133,6 +136,10 @@ export default function AllApps({ apps }: AllAppsPropsType) {
|
||||
return self.indexOf(cat) === pos;
|
||||
});
|
||||
|
||||
if (searchText) {
|
||||
enableAnimation(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const queryCategory =
|
||||
typeof router.query.category === "string" && categories.includes(router.query.category)
|
||||
@@ -141,23 +148,27 @@ export default function AllApps({ apps }: AllAppsPropsType) {
|
||||
setSelectedCategory(queryCategory);
|
||||
}, [router.query.category]);
|
||||
|
||||
const filteredApps = apps
|
||||
.filter((app) =>
|
||||
selectedCategory !== null
|
||||
? app.categories
|
||||
? app.categories.includes(selectedCategory)
|
||||
: app.category === selectedCategory
|
||||
: true
|
||||
)
|
||||
.filter((app) => (searchText ? app.name.toLowerCase().includes(searchText.toLowerCase()) : true));
|
||||
|
||||
return (
|
||||
<div className="mb-16">
|
||||
<CategoryTab selectedCategory={selectedCategory} categories={categories} />
|
||||
<CategoryTab selectedCategory={selectedCategory} searchText={searchText} categories={categories} />
|
||||
<div
|
||||
className="grid gap-3 lg:grid-cols-4 [@media(max-width:1270px)]:grid-cols-3 [@media(max-width:730px)]:grid-cols-2 [@media(max-width:500px)]:grid-cols-1"
|
||||
ref={appsContainerRef}>
|
||||
{apps
|
||||
.filter((app) =>
|
||||
selectedCategory !== null
|
||||
? app.categories
|
||||
? app.categories.includes(selectedCategory)
|
||||
: app.category === selectedCategory
|
||||
: true
|
||||
)
|
||||
.map((app) => (
|
||||
<AppCard key={app.name} app={app} credentials={app.credentials} />
|
||||
))}
|
||||
{filteredApps.length
|
||||
? filteredApps.map((app) => (
|
||||
<AppCard key={app.name} app={app} searchText={searchText} credentials={app.credentials} />
|
||||
))
|
||||
: t("no_results")}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Credential } from "@prisma/client";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation";
|
||||
import { InstallAppButton } from "@calcom/app-store/components";
|
||||
@@ -12,9 +13,10 @@ import { showToast } from "../notifications";
|
||||
interface AppCardProps {
|
||||
app: App;
|
||||
credentials?: Credential[];
|
||||
searchText?: string;
|
||||
}
|
||||
|
||||
export default function AppCard({ app, credentials }: AppCardProps) {
|
||||
export default function AppCard({ app, credentials, searchText }: AppCardProps) {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
const mutation = useAddAppMutation(null, {
|
||||
@@ -31,6 +33,11 @@ export default function AppCard({ app, credentials }: AppCardProps) {
|
||||
|
||||
const allowedMultipleInstalls = app.categories && app.categories.indexOf("calendar") > -1;
|
||||
const appAdded = (credentials && credentials.length) || 0;
|
||||
const [searchTextIndex, setSearchTextIndex] = useState<number | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
setSearchTextIndex(searchText ? app.name.toLowerCase().indexOf(searchText.toLowerCase()) : undefined);
|
||||
}, [app.name, searchText]);
|
||||
|
||||
return (
|
||||
<div className="relative flex h-64 flex-col rounded-md border border-gray-300 p-5">
|
||||
@@ -38,7 +45,19 @@ export default function AppCard({ app, credentials }: AppCardProps) {
|
||||
<img src={app.logo} alt={app.name + " Logo"} className="mb-4 h-12 w-12 rounded-sm" />
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<h3 className="font-medium">{app.name}</h3>
|
||||
<h3 className="font-medium">
|
||||
{searchTextIndex != undefined && searchText ? (
|
||||
<>
|
||||
{app.name.substring(0, searchTextIndex)}
|
||||
<span className="bg-yellow-300">
|
||||
{app.name.substring(searchTextIndex, searchTextIndex + searchText.length)}
|
||||
</span>
|
||||
{app.name.substring(searchTextIndex + searchText.length)}
|
||||
</>
|
||||
) : (
|
||||
app.name
|
||||
)}
|
||||
</h3>
|
||||
</div>
|
||||
{/* TODO: add reviews <div className="flex text-sm text-gray-800">
|
||||
<span>{props.rating} stars</span> <StarIcon className="ml-1 mt-0.5 h-4 w-4 text-yellow-600" />
|
||||
|
||||
@@ -15,15 +15,17 @@ const tabs: HorizontalTabItemProps[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function AppsLayout({
|
||||
children,
|
||||
...rest
|
||||
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
|
||||
type AppsLayoutProps = {
|
||||
children: React.ReactNode;
|
||||
actions?: (className?: string) => JSX.Element;
|
||||
} & Omit<ComponentProps<typeof Shell>, "actions">;
|
||||
|
||||
export default function AppsLayout({ children, actions, ...rest }: AppsLayoutProps) {
|
||||
return (
|
||||
<Shell {...rest}>
|
||||
<div className="flex flex-col xl:flex-row ">
|
||||
<Shell {...rest} actions={actions?.("hidden sm:block")}>
|
||||
<div className="flex flex-col xl:flex-row">
|
||||
<div className="block lg:hidden">
|
||||
<HorizontalTabs tabs={tabs} />
|
||||
<HorizontalTabs tabs={tabs} actions={actions?.("ml-6 mr-4 mt-3 block sm:hidden")} />
|
||||
</div>
|
||||
<main className="w-full">{children}</main>
|
||||
</div>
|
||||
|
||||
@@ -5,9 +5,10 @@ export { HorizontalTabItem };
|
||||
export interface NavTabProps {
|
||||
tabs: HorizontalTabItemProps[];
|
||||
linkProps?: HorizontalTabItemProps["linkProps"];
|
||||
actions?: JSX.Element;
|
||||
}
|
||||
|
||||
const HorizontalTabs = function ({ tabs, linkProps, ...props }: NavTabProps) {
|
||||
const HorizontalTabs = function ({ tabs, linkProps, actions, ...props }: NavTabProps) {
|
||||
return (
|
||||
<div className="-mx-6 mb-2 w-[calc(100%+40px)]">
|
||||
<nav
|
||||
@@ -18,6 +19,7 @@ const HorizontalTabs = function ({ tabs, linkProps, ...props }: NavTabProps) {
|
||||
<HorizontalTabItem {...tab} key={idx} {...linkProps} />
|
||||
))}
|
||||
</nav>
|
||||
{actions && actions}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3839,10 +3839,10 @@
|
||||
intl-messageformat "9.13.0"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formkit/auto-animate@^1.0.0-beta.1":
|
||||
version "1.0.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-1.0.0-beta.1.tgz#aec5fd2ea5e499ceb7eb117c7fd1217a7f100748"
|
||||
integrity sha512-I3OWOBaPZKSJL4bsooXI8kC3q7bcgibD2oML0P/Lir6MnbvUe/0/7EH8br024juvM/Ulm9C9xGx9CJUQYrOWSA==
|
||||
"@formkit/auto-animate@^1.0.0-beta.5":
|
||||
version "1.0.0-beta.5"
|
||||
resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-1.0.0-beta.5.tgz#3fe4d520a82909cdcffa8854f26bc26ca4562045"
|
||||
integrity sha512-WoSwyhAZPOe6RB/IgicOtCHtrWwEpfKIZ/H/nxpKfnZL9CB6hhhBGU5bCdMRw7YpAUF2CDlQa+WWh+gCqz5lDg==
|
||||
|
||||
"@gar/promisify@^1.0.1":
|
||||
version "1.1.3"
|
||||
@@ -4593,6 +4593,158 @@
|
||||
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
|
||||
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
|
||||
|
||||
"@lexical/clipboard@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/clipboard/-/clipboard-0.5.0.tgz#3d835289c0e1543a13a5fd032294aa2614e4373a"
|
||||
integrity sha512-JFvdH4N/80GxC0jhaiO/fdUOeYcX8pMFrcrpBDeNIcBN/9eF8Rn/czvoPLLNB9Kcbz8d8XXqabKEGCz2hFL//w==
|
||||
dependencies:
|
||||
"@lexical/html" "0.5.0"
|
||||
"@lexical/list" "0.5.0"
|
||||
"@lexical/selection" "0.5.0"
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/code@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/code/-/code-0.5.0.tgz#05c92e3b077af3148a494b44f5663dea14f7631f"
|
||||
integrity sha512-GmqRaQ8EBtlu13ObSZYiGDzIsrkwRyyqI2HRVBrPo2iszLBpby+7uIncAVQVkxt1JNYOKE2n4JfxK8TSYyMtYQ==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
prismjs "^1.27.0"
|
||||
|
||||
"@lexical/dragon@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/dragon/-/dragon-0.5.0.tgz#54ec8812e3fb907af5913c5d0436b8d28fa4efe8"
|
||||
integrity sha512-Gf0jN8hjlF8E71wAsvbRpR1u9oS6RUjUw3VWp/Qa+IrtjBFFVzdTUloUs3cjMX9E/MFRJgt3wPsaKx2IuLBWQw==
|
||||
|
||||
"@lexical/hashtag@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/hashtag/-/hashtag-0.5.0.tgz#dfe39ea73d1c4658c724419ef1113e27fb75a7f3"
|
||||
integrity sha512-3MT72y72BmK4q7Rtb9gP3n83UL4vWC078T9io4zyPxKEI1Mh3UAVuRwh6Ypn0FeH94XvmuZAGVdoOC/nTd1now==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/history@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/history/-/history-0.5.0.tgz#5a13077e012f27f783beadca1c3fe545a2968f20"
|
||||
integrity sha512-DCQgh1aQ1KS5JVYPU6GYr52BN0MQqmoXfFtf5uYCX9CbSAC0hDSK8ZPqwFW7jINqe6GwXxy7bo32j7E0A5023A==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/html@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/html/-/html-0.5.0.tgz#5eb2ccb9ffb7c24fff097db369d81431d7a98833"
|
||||
integrity sha512-uJAof6gXTLOH9JnmPJ+wxILFtu7I/eCebFyVMjV53sqaeLsQ3pDfBTUe4RO+NciC+XBQ1WVpZgCM8Yx5c5cMmQ==
|
||||
dependencies:
|
||||
"@lexical/selection" "0.5.0"
|
||||
|
||||
"@lexical/link@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/link/-/link-0.5.0.tgz#fa5f3baa1122eb2a1be12ac7a30977eb4c557e1e"
|
||||
integrity sha512-XB8e+UPI9jeqsi7+Wr0n9SToljiS+gZmJ5gXANtR6lSZPtpcSUPs1iJZU2A2dNKXdvsZwSPCFdPL6ogFaaRvvQ==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/list@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/list/-/list-0.5.0.tgz#6ab4e1789d037af43f3d01012d2533c7c94daf15"
|
||||
integrity sha512-TYXe4FtNL7Lk3XDEhPyUbT0Pb1TU58qZywGCdrtuRjPnF4oDvRXgg9EhYWfHzYwdsyhNgaHId+Fq41CjrwTMYg==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/mark@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/mark/-/mark-0.5.0.tgz#59c2a2a9f0ecfa063d48ce6f4a50e6d8bc6fcae1"
|
||||
integrity sha512-leeqegWD4hqUdfYNsxB5iwsWozX2oc6mnJzcJfR4UB3Ksr0zH2xHc/z3Zp+CTeGuK5Tzppq5yGS+4cQ5xNpVgQ==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/markdown@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/markdown/-/markdown-0.5.0.tgz#3424a98e8600bc719f99bb4ab2484f0cf0e3c0f7"
|
||||
integrity sha512-02RLx7PdVzvYxvx65FTbXkW6KcjQZ1waAaMDNKdtBV9r9Mv2Y2XunCUjErYHQ1JN9JkGGv0+JuliRT7qZTsF+Q==
|
||||
dependencies:
|
||||
"@lexical/code" "0.5.0"
|
||||
"@lexical/link" "0.5.0"
|
||||
"@lexical/list" "0.5.0"
|
||||
"@lexical/rich-text" "0.5.0"
|
||||
"@lexical/text" "0.5.0"
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/offset@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/offset/-/offset-0.5.0.tgz#445aae1c74198dd4ed7d59669735925621139e0a"
|
||||
integrity sha512-ie4AFbvtt0CFBqaMcb0/gUuhoTt+YwbFXPFo1hW+oDVpmo3rJsEJKVsHhftBvHIP+/G5QlgPIhVmnlcSvEteTw==
|
||||
|
||||
"@lexical/overflow@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/overflow/-/overflow-0.5.0.tgz#70daabdb96a3de9bf2f052ab2e38917aaf6e3b18"
|
||||
integrity sha512-N+BQvgODU9lS7VK4FlxIRhGeASwsxfdkECtZ5iomHfqqNEI0WPLHbCTCkwS10rjfH1NrkXC314Y0SG2F7Ncv9Q==
|
||||
|
||||
"@lexical/plain-text@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/plain-text/-/plain-text-0.5.0.tgz#385ac7c67b34116578e45fe34cca41e9f62cbcad"
|
||||
integrity sha512-t1rnVnSXbPs9jLN/36/xZLNAlF9jwv8rSh6GHsjRIYiWX/MovNmgPmhNq/nkc+gRFZ2FKTFjdz3UeAUF4xQZMw==
|
||||
|
||||
"@lexical/react@^0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/react/-/react-0.5.0.tgz#f227dd71f95e49bf817d648b9ffd5a31850876bc"
|
||||
integrity sha512-bba0KXslxjf6M8XXJhx1rsrq9UV/6eo73WCZel2K+tGz8NEn1HCRTebQoebmRikzEQatEa3SoB6R47drMlk7Yw==
|
||||
dependencies:
|
||||
"@lexical/clipboard" "0.5.0"
|
||||
"@lexical/code" "0.5.0"
|
||||
"@lexical/dragon" "0.5.0"
|
||||
"@lexical/hashtag" "0.5.0"
|
||||
"@lexical/history" "0.5.0"
|
||||
"@lexical/link" "0.5.0"
|
||||
"@lexical/list" "0.5.0"
|
||||
"@lexical/mark" "0.5.0"
|
||||
"@lexical/markdown" "0.5.0"
|
||||
"@lexical/overflow" "0.5.0"
|
||||
"@lexical/plain-text" "0.5.0"
|
||||
"@lexical/rich-text" "0.5.0"
|
||||
"@lexical/selection" "0.5.0"
|
||||
"@lexical/table" "0.5.0"
|
||||
"@lexical/text" "0.5.0"
|
||||
"@lexical/utils" "0.5.0"
|
||||
"@lexical/yjs" "0.5.0"
|
||||
|
||||
"@lexical/rich-text@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/rich-text/-/rich-text-0.5.0.tgz#9b7ddacdd74a49761f15486ed2846c5117a55d14"
|
||||
integrity sha512-JhgMn70K410j3T/2WefPpEswZ+hWF3aJMNu7zkrCf2wB+KdrrGYoeNSZUzg2r4e6BuJgS117KlD99+MDnokCuw==
|
||||
|
||||
"@lexical/selection@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/selection/-/selection-0.5.0.tgz#fe94f06fb17d9f5848921a0bbce10774398d3486"
|
||||
integrity sha512-6I5qlqkYDIbDZPGwSOuvpWQUrqMY6URaKwrWsijQZMnNNKscGpC7IKb7sSDKn6YkLm7tuqig3hf2p+6hshkyWg==
|
||||
|
||||
"@lexical/table@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/table/-/table-0.5.0.tgz#cf33fac7c2e0b520ab4747f9322cce434d117cb6"
|
||||
integrity sha512-VNHWSsTFDSHNzLdQOR9qgKx4tvTuiDz6w0GfwBnMP4Ro2iKKtNowmZO4wDEZtVlUHvLMuOGuYqipOtKEDKbD4w==
|
||||
dependencies:
|
||||
"@lexical/utils" "0.5.0"
|
||||
|
||||
"@lexical/text@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/text/-/text-0.5.0.tgz#803e34d9b1e2430e8062d2db50c7452d4e03c86e"
|
||||
integrity sha512-RqhOBU2Ecg0WVW8p1d3OB2a8sQyvh3suADdr7We50+Dn/k1M+jhKVWiQnf07ve4/yqYTj6/9/8AAg7kuNS2P/A==
|
||||
|
||||
"@lexical/utils@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/utils/-/utils-0.5.0.tgz#4f03e8090e65cde5e81801ab08a2450e2e03733a"
|
||||
integrity sha512-FhQ+thPFTOyBxyRGcd3yJuYh/rvD8ro43DaelWD1KpSlwQ/YuWpdxsSuMqJ32ERpl+bmPPFP2kjkBofxSw1Quw==
|
||||
dependencies:
|
||||
"@lexical/list" "0.5.0"
|
||||
"@lexical/table" "0.5.0"
|
||||
|
||||
"@lexical/yjs@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@lexical/yjs/-/yjs-0.5.0.tgz#a6a6e12f5eceaa5a37ae7999b97ba8ce217987b6"
|
||||
integrity sha512-2io4GqnRoSh6Nu9bzsDOlwPFJYjXZ9SdgU4ZioH2VvyW4wVstd+ZF2QVcUJlhuwgQr6DzuvM/pqN914IufLzpw==
|
||||
dependencies:
|
||||
"@lexical/offset" "0.5.0"
|
||||
|
||||
"@lit-labs/react@^1.0.2":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@lit-labs/react/-/react-1.0.7.tgz#fbf7c129af701d74484c5dbc6f6ea97990b85e54"
|
||||
@@ -17945,6 +18097,11 @@ levn@~0.3.0:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lexical@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lexical/-/lexical-0.5.0.tgz#03a8abc816f6d922384ecd01bd14ed36a1ea4d63"
|
||||
integrity sha512-J0cFuNPQQY5P9W5XW2/xgqp5W0eEQ2rxShLf8eevLvxFWsPSY3zjg3RCzTHyheSiGBBjKDIaM4gxtO8eNeJr2A==
|
||||
|
||||
libphonenumber-js@^1.10.12:
|
||||
version "1.10.12"
|
||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.12.tgz#75ebe2f1887d12bbf45af5655fdb63f55f4ee05b"
|
||||
|
||||
Reference in New Issue
Block a user