2021-03-01 17:27:09 +00:00
|
|
|
/*
|
2024-09-09 14:57:16 +01:00
|
|
|
Copyright 2024 New Vector Ltd.
|
2021-03-01 17:27:09 +00:00
|
|
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
2025-01-06 11:18:54 +00:00
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
2024-09-09 14:57:16 +01:00
|
|
|
Please see LICENSE files in the repository root for full details.
|
2021-03-01 17:27:09 +00:00
|
|
|
*/
|
|
|
|
|
|
2023-02-13 11:39:16 +00:00
|
|
|
import React, {
|
2025-02-05 13:25:06 +00:00
|
|
|
type ComponentProps,
|
|
|
|
|
type RefObject,
|
|
|
|
|
type SyntheticEvent,
|
|
|
|
|
type KeyboardEvent,
|
2023-02-13 11:39:16 +00:00
|
|
|
useContext,
|
|
|
|
|
useRef,
|
|
|
|
|
useState,
|
2025-02-05 13:25:06 +00:00
|
|
|
type ChangeEvent,
|
|
|
|
|
type ReactNode,
|
2023-08-21 10:39:20 +01:00
|
|
|
useEffect,
|
2023-02-13 11:39:16 +00:00
|
|
|
} from "react";
|
2023-08-15 16:00:17 +01:00
|
|
|
import {
|
|
|
|
|
RoomType,
|
|
|
|
|
HistoryVisibility,
|
|
|
|
|
Preset,
|
|
|
|
|
Visibility,
|
2025-02-05 13:25:06 +00:00
|
|
|
type MatrixClient,
|
|
|
|
|
type ICreateRoomOpts,
|
2023-08-15 16:00:17 +01:00
|
|
|
} from "matrix-js-sdk/src/matrix";
|
2021-10-22 17:23:32 -05:00
|
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
2026-01-08 11:20:55 +00:00
|
|
|
import { LockSolidIcon, PublicIcon, ChevronLeftIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
2021-03-01 17:27:09 +00:00
|
|
|
|
2021-06-29 13:11:58 +01:00
|
|
|
import { _t } from "../../../languageHandler";
|
2021-11-29 17:42:53 +00:00
|
|
|
import ContextMenu, { ChevronFace } from "../../structures/ContextMenu";
|
2025-02-05 13:25:06 +00:00
|
|
|
import createRoom, { type IOpts as ICreateOpts } from "../../../createRoom";
|
2023-05-30 10:36:34 +01:00
|
|
|
import MatrixClientContext, { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
2025-02-05 13:25:06 +00:00
|
|
|
import type SpaceBasicSettings from "./SpaceBasicSettings";
|
|
|
|
|
import { SpaceAvatar } from "./SpaceBasicSettings";
|
|
|
|
|
import AccessibleButton, { type ButtonEvent } from "../elements/AccessibleButton";
|
2021-05-10 14:39:10 +01:00
|
|
|
import Field from "../elements/Field";
|
|
|
|
|
import withValidation from "../elements/Validation";
|
2021-06-07 08:57:39 +01:00
|
|
|
import RoomAliasField from "../elements/RoomAliasField";
|
2022-02-28 17:05:52 +01:00
|
|
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
|
|
|
|
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
2023-08-21 10:39:20 +01:00
|
|
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
|
|
|
|
import { Action } from "../../../dispatcher/actions";
|
|
|
|
|
import { Filter } from "../dialogs/spotlight/Filter";
|
2025-02-05 13:25:06 +00:00
|
|
|
import { type OpenSpotlightPayload } from "../../../dispatcher/payloads/OpenSpotlightPayload.ts";
|
2025-09-08 14:53:13 +01:00
|
|
|
import { useSettingValue } from "../../../hooks/useSettings.ts";
|
|
|
|
|
import { UIFeature } from "../../../settings/UIFeature.ts";
|
2025-12-16 13:56:36 +00:00
|
|
|
import SpacePillButton from "../../structures/SpacePillButton.tsx";
|
2023-05-30 10:36:34 +01:00
|
|
|
|
2021-08-04 10:37:35 +01:00
|
|
|
export const createSpace = async (
|
2023-05-30 10:36:34 +01:00
|
|
|
client: MatrixClient,
|
2021-08-04 10:37:35 +01:00
|
|
|
name: string,
|
|
|
|
|
isPublic: boolean,
|
|
|
|
|
alias?: string,
|
|
|
|
|
topic?: string,
|
|
|
|
|
avatar?: string | File,
|
|
|
|
|
createOpts: Partial<ICreateRoomOpts> = {},
|
|
|
|
|
otherOpts: Partial<Omit<ICreateOpts, "createOpts">> = {},
|
2023-02-24 15:28:40 +00:00
|
|
|
): Promise<string | null> => {
|
2023-05-30 10:36:34 +01:00
|
|
|
return createRoom(client, {
|
2021-08-04 10:37:35 +01:00
|
|
|
createOpts: {
|
|
|
|
|
name,
|
|
|
|
|
preset: isPublic ? Preset.PublicChat : Preset.PrivateChat,
|
2022-07-27 20:10:37 +02:00
|
|
|
visibility:
|
2023-05-30 10:36:34 +01:00
|
|
|
isPublic && (await client.doesServerSupportUnstableFeature("org.matrix.msc3827.stable"))
|
2022-07-27 20:10:37 +02:00
|
|
|
? Visibility.Public
|
|
|
|
|
: Visibility.Private,
|
2021-08-04 10:37:35 +01:00
|
|
|
power_level_content_override: {
|
|
|
|
|
// Only allow Admins to write to the timeline to prevent hidden sync spam
|
|
|
|
|
events_default: 100,
|
2021-09-10 13:05:04 +01:00
|
|
|
invite: isPublic ? 0 : 50,
|
2021-08-04 10:37:35 +01:00
|
|
|
},
|
2022-04-14 09:52:42 +02:00
|
|
|
room_alias_name: isPublic && alias ? alias.substring(1, alias.indexOf(":")) : undefined,
|
2021-08-04 10:37:35 +01:00
|
|
|
topic,
|
|
|
|
|
...createOpts,
|
|
|
|
|
},
|
|
|
|
|
avatar,
|
|
|
|
|
roomType: RoomType.Space,
|
|
|
|
|
historyVisibility: isPublic ? HistoryVisibility.WorldReadable : HistoryVisibility.Invited,
|
|
|
|
|
spinner: false,
|
|
|
|
|
encryption: false,
|
|
|
|
|
andView: true,
|
|
|
|
|
inlineErrors: true,
|
|
|
|
|
...otherOpts,
|
|
|
|
|
});
|
|
|
|
|
};
|
2021-03-01 17:27:09 +00:00
|
|
|
|
2021-05-10 14:39:10 +01:00
|
|
|
const spaceNameValidator = withValidation({
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
key: "required",
|
|
|
|
|
test: async ({ value }) => !!value,
|
2023-09-19 17:16:38 +01:00
|
|
|
invalid: () => _t("create_space|name_required"),
|
2021-05-10 14:39:10 +01:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
|
2021-09-13 16:27:46 +01:00
|
|
|
const nameToLocalpart = (name: string): string => {
|
|
|
|
|
return name
|
|
|
|
|
.trim()
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.replace(/\s+/g, "-")
|
|
|
|
|
.replace(/[^a-z0-9_-]+/gi, "");
|
2021-06-07 08:57:39 +01:00
|
|
|
};
|
|
|
|
|
|
2021-08-04 10:37:35 +01:00
|
|
|
type BProps = Omit<ComponentProps<typeof SpaceBasicSettings>, "nameDisabled" | "topicDisabled" | "avatarDisabled">;
|
2021-07-23 08:46:20 +01:00
|
|
|
interface ISpaceCreateFormProps extends BProps {
|
|
|
|
|
busy: boolean;
|
|
|
|
|
alias: string;
|
2025-03-28 10:07:41 +00:00
|
|
|
nameFieldRef: RefObject<Field | null>;
|
|
|
|
|
aliasFieldRef: RefObject<RoomAliasField | null>;
|
2021-07-23 08:46:20 +01:00
|
|
|
showAliasField?: boolean;
|
2023-03-08 13:28:07 +00:00
|
|
|
children?: ReactNode;
|
2026-02-23 15:37:58 +00:00
|
|
|
onSubmit(this: void, e: SyntheticEvent): void;
|
|
|
|
|
setAlias(this: void, alias: string): void;
|
2021-07-23 08:46:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const SpaceCreateForm: React.FC<ISpaceCreateFormProps> = ({
|
|
|
|
|
busy,
|
|
|
|
|
onSubmit,
|
2021-08-04 10:37:35 +01:00
|
|
|
avatarUrl,
|
2021-07-23 08:46:20 +01:00
|
|
|
setAvatar,
|
|
|
|
|
name,
|
|
|
|
|
setName,
|
|
|
|
|
nameFieldRef,
|
|
|
|
|
alias,
|
|
|
|
|
aliasFieldRef,
|
|
|
|
|
setAlias,
|
|
|
|
|
showAliasField,
|
|
|
|
|
topic,
|
|
|
|
|
setTopic,
|
|
|
|
|
children,
|
|
|
|
|
}) => {
|
2021-03-01 17:27:09 +00:00
|
|
|
const cli = useContext(MatrixClientContext);
|
2023-02-24 15:28:40 +00:00
|
|
|
const domain = cli.getDomain() ?? undefined;
|
2021-07-23 08:46:20 +01:00
|
|
|
|
2023-01-12 13:25:14 +00:00
|
|
|
const onKeyDown = (ev: KeyboardEvent): void => {
|
2022-02-28 17:05:52 +01:00
|
|
|
const action = getKeyBindingsManager().getAccessibilityAction(ev);
|
|
|
|
|
switch (action) {
|
|
|
|
|
case KeyBindingAction.Enter:
|
|
|
|
|
onSubmit(ev);
|
|
|
|
|
break;
|
2021-09-03 13:34:09 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-07-23 08:46:20 +01:00
|
|
|
return (
|
|
|
|
|
<form className="mx_SpaceBasicSettings" onSubmit={onSubmit}>
|
2021-08-04 10:37:35 +01:00
|
|
|
<SpaceAvatar avatarUrl={avatarUrl} setAvatar={setAvatar} avatarDisabled={busy} />
|
2021-07-23 08:46:20 +01:00
|
|
|
|
|
|
|
|
<Field
|
|
|
|
|
name="spaceName"
|
2023-08-23 10:25:33 +01:00
|
|
|
label={_t("common|name")}
|
2021-07-23 08:46:20 +01:00
|
|
|
autoFocus={true}
|
|
|
|
|
value={name}
|
2023-02-13 11:39:16 +00:00
|
|
|
onChange={(ev: ChangeEvent<HTMLInputElement>) => {
|
2021-07-23 08:46:20 +01:00
|
|
|
const newName = ev.target.value;
|
2021-09-13 16:27:46 +01:00
|
|
|
if (!alias || alias === `#${nameToLocalpart(name)}:${domain}`) {
|
|
|
|
|
setAlias(`#${nameToLocalpart(newName)}:${domain}`);
|
2021-07-23 08:46:20 +01:00
|
|
|
aliasFieldRef.current?.validate({ allowEmpty: true });
|
|
|
|
|
}
|
2021-09-13 16:27:46 +01:00
|
|
|
setName(newName);
|
2021-07-23 08:46:20 +01:00
|
|
|
}}
|
2021-09-03 13:34:09 +01:00
|
|
|
onKeyDown={onKeyDown}
|
2021-07-23 08:46:20 +01:00
|
|
|
ref={nameFieldRef}
|
|
|
|
|
onValidate={spaceNameValidator}
|
|
|
|
|
disabled={busy}
|
2021-09-03 13:34:09 +01:00
|
|
|
autoComplete="off"
|
2021-07-23 08:46:20 +01:00
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{showAliasField ? (
|
|
|
|
|
<RoomAliasField
|
|
|
|
|
ref={aliasFieldRef}
|
|
|
|
|
onChange={setAlias}
|
|
|
|
|
domain={domain}
|
|
|
|
|
value={alias}
|
2023-09-26 13:04:17 +01:00
|
|
|
placeholder={name ? nameToLocalpart(name) : _t("create_space|address_placeholder")}
|
|
|
|
|
label={_t("create_space|address_label")}
|
2021-07-23 08:46:20 +01:00
|
|
|
disabled={busy}
|
2021-09-03 13:34:09 +01:00
|
|
|
onKeyDown={onKeyDown}
|
2021-07-23 08:46:20 +01:00
|
|
|
/>
|
2022-12-12 12:24:14 +01:00
|
|
|
) : null}
|
2021-07-23 08:46:20 +01:00
|
|
|
|
2022-12-12 12:24:14 +01:00
|
|
|
<Field
|
2021-08-04 10:37:35 +01:00
|
|
|
name="spaceTopic"
|
2021-07-23 08:46:20 +01:00
|
|
|
element="textarea"
|
2023-08-23 10:25:33 +01:00
|
|
|
label={_t("common|description")}
|
2023-02-24 15:28:40 +00:00
|
|
|
value={topic ?? ""}
|
2021-07-23 08:46:20 +01:00
|
|
|
onChange={(ev) => setTopic(ev.target.value)}
|
2022-12-12 12:24:14 +01:00
|
|
|
rows={3}
|
2021-07-23 08:46:20 +01:00
|
|
|
disabled={busy}
|
2022-12-12 12:24:14 +01:00
|
|
|
/>
|
|
|
|
|
|
2021-07-23 08:46:20 +01:00
|
|
|
{children}
|
|
|
|
|
</form>
|
|
|
|
|
);
|
2021-06-07 08:57:39 +01:00
|
|
|
};
|
|
|
|
|
|
2023-01-12 13:25:14 +00:00
|
|
|
const SpaceCreateMenu: React.FC<{
|
2026-02-23 15:37:58 +00:00
|
|
|
onFinished(this: void): void;
|
2023-01-12 13:25:14 +00:00
|
|
|
}> = ({ onFinished }) => {
|
2023-05-30 10:36:34 +01:00
|
|
|
const cli = useMatrixClientContext();
|
2025-09-08 14:53:13 +01:00
|
|
|
const settingAllowPublicSpaces = useSettingValue(UIFeature.AllowCreatingPublicSpaces);
|
|
|
|
|
const [visibility, setVisibility] = useState<Visibility | null>(
|
|
|
|
|
settingAllowPublicSpaces === false ? Visibility.Private : null,
|
|
|
|
|
);
|
2021-03-01 17:27:09 +00:00
|
|
|
const [busy, setBusy] = useState<boolean>(false);
|
|
|
|
|
|
2021-05-10 14:39:10 +01:00
|
|
|
const [name, setName] = useState("");
|
2023-04-17 09:25:00 +01:00
|
|
|
const spaceNameField = useRef<Field>(null);
|
2021-06-07 08:57:39 +01:00
|
|
|
const [alias, setAlias] = useState("");
|
2023-04-17 09:25:00 +01:00
|
|
|
const spaceAliasField = useRef<RoomAliasField>(null);
|
2023-02-16 17:21:44 +00:00
|
|
|
const [avatar, setAvatar] = useState<File | undefined>(undefined);
|
2021-05-10 14:39:10 +01:00
|
|
|
const [topic, setTopic] = useState<string>("");
|
|
|
|
|
|
2023-08-21 10:39:20 +01:00
|
|
|
const [supportsSpaceFiltering, setSupportsSpaceFiltering] = useState(true); // assume it does until we find out it doesn't
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
cli.isVersionSupported("v1.4")
|
|
|
|
|
.then((supported) => {
|
|
|
|
|
return supported || cli.doesServerSupportUnstableFeature("org.matrix.msc3827.stable");
|
|
|
|
|
})
|
|
|
|
|
.then((supported) => {
|
|
|
|
|
setSupportsSpaceFiltering(supported);
|
|
|
|
|
});
|
|
|
|
|
}, [cli]);
|
|
|
|
|
|
2023-01-12 13:25:14 +00:00
|
|
|
const onSpaceCreateClick = async (e: ButtonEvent): Promise<void> => {
|
2021-05-10 14:39:10 +01:00
|
|
|
e.preventDefault();
|
2021-03-01 17:27:09 +00:00
|
|
|
if (busy) return;
|
2021-05-10 14:39:10 +01:00
|
|
|
|
2021-03-01 17:27:09 +00:00
|
|
|
setBusy(true);
|
2021-05-10 14:39:10 +01:00
|
|
|
// require & validate the space name field
|
2023-02-24 15:28:40 +00:00
|
|
|
if (spaceNameField.current && !(await spaceNameField.current.validate({ allowEmpty: false }))) {
|
2021-05-10 14:39:10 +01:00
|
|
|
spaceNameField.current.focus();
|
|
|
|
|
spaceNameField.current.validate({ allowEmpty: false, focused: true });
|
|
|
|
|
setBusy(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-09-13 16:27:46 +01:00
|
|
|
|
2023-02-24 15:28:40 +00:00
|
|
|
if (
|
|
|
|
|
spaceAliasField.current &&
|
|
|
|
|
visibility === Visibility.Public &&
|
|
|
|
|
!(await spaceAliasField.current.validate({ allowEmpty: false }))
|
|
|
|
|
) {
|
2021-06-07 08:57:39 +01:00
|
|
|
spaceAliasField.current.focus();
|
2021-10-08 14:33:58 +01:00
|
|
|
spaceAliasField.current.validate({ allowEmpty: false, focused: true });
|
2021-06-07 08:57:39 +01:00
|
|
|
setBusy(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-05-10 14:39:10 +01:00
|
|
|
|
2021-03-01 17:27:09 +00:00
|
|
|
try {
|
2023-05-30 10:36:34 +01:00
|
|
|
await createSpace(cli, name, visibility === Visibility.Public, alias, topic, avatar);
|
2021-03-01 17:27:09 +00:00
|
|
|
|
|
|
|
|
onFinished();
|
|
|
|
|
} catch (e) {
|
2021-10-15 16:30:53 +02:00
|
|
|
logger.error(e);
|
2021-03-01 17:27:09 +00:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-08-21 10:39:20 +01:00
|
|
|
const onSearchClick = (): void => {
|
2024-11-05 18:34:47 +00:00
|
|
|
defaultDispatcher.dispatch<OpenSpotlightPayload>({
|
2023-08-21 10:39:20 +01:00
|
|
|
action: Action.OpenSpotlight,
|
|
|
|
|
initialFilter: Filter.PublicSpaces,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-01 17:27:09 +00:00
|
|
|
let body;
|
|
|
|
|
if (visibility === null) {
|
|
|
|
|
body = (
|
|
|
|
|
<React.Fragment>
|
2023-09-26 13:04:17 +01:00
|
|
|
<h2>{_t("create_space|label")}</h2>
|
2023-09-19 17:16:38 +01:00
|
|
|
<p>{_t("create_space|explainer")}</p>
|
2021-03-01 17:27:09 +00:00
|
|
|
|
2025-12-16 13:56:36 +00:00
|
|
|
<SpacePillButton
|
|
|
|
|
icon={<PublicIcon />}
|
2023-08-23 10:25:33 +01:00
|
|
|
title={_t("common|public")}
|
2023-09-19 17:16:38 +01:00
|
|
|
description={_t("create_space|public_description")}
|
2021-03-01 17:27:09 +00:00
|
|
|
onClick={() => setVisibility(Visibility.Public)}
|
|
|
|
|
/>
|
2025-12-16 13:56:36 +00:00
|
|
|
<SpacePillButton
|
|
|
|
|
icon={<LockSolidIcon />}
|
2023-08-23 10:25:33 +01:00
|
|
|
title={_t("common|private")}
|
2023-09-19 17:16:38 +01:00
|
|
|
description={_t("create_space|private_description")}
|
2021-03-01 17:27:09 +00:00
|
|
|
onClick={() => setVisibility(Visibility.Private)}
|
|
|
|
|
/>
|
|
|
|
|
|
2023-08-21 10:39:20 +01:00
|
|
|
{supportsSpaceFiltering && (
|
|
|
|
|
<AccessibleButton kind="primary_outline" onClick={onSearchClick}>
|
2023-09-19 17:16:38 +01:00
|
|
|
{_t("create_space|search_public_button")}
|
2023-08-21 10:39:20 +01:00
|
|
|
</AccessibleButton>
|
|
|
|
|
)}
|
2021-03-01 17:27:09 +00:00
|
|
|
</React.Fragment>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
body = (
|
|
|
|
|
<React.Fragment>
|
2025-09-08 14:53:13 +01:00
|
|
|
{settingAllowPublicSpaces && (
|
|
|
|
|
<AccessibleButton
|
|
|
|
|
className="mx_SpaceCreateMenu_back"
|
|
|
|
|
onClick={() => setVisibility(null)}
|
|
|
|
|
title={_t("action|go_back")}
|
2026-01-08 11:20:55 +00:00
|
|
|
>
|
|
|
|
|
<ChevronLeftIcon />
|
|
|
|
|
</AccessibleButton>
|
2025-09-08 14:53:13 +01:00
|
|
|
)}
|
2021-03-01 17:27:09 +00:00
|
|
|
|
2023-09-19 17:16:38 +01:00
|
|
|
<h2>
|
|
|
|
|
{visibility === Visibility.Public
|
|
|
|
|
? _t("create_space|public_heading")
|
2025-09-08 14:53:13 +01:00
|
|
|
: settingAllowPublicSpaces
|
|
|
|
|
? _t("create_space|private_heading")
|
|
|
|
|
: _t("create_space|private_only_heading")}
|
2023-09-19 17:16:38 +01:00
|
|
|
</h2>
|
2021-03-01 17:27:09 +00:00
|
|
|
<p>
|
2023-09-26 13:04:17 +01:00
|
|
|
{_t("create_space|add_details_prompt")} {_t("create_space|add_details_prompt_2")}
|
2021-03-01 17:27:09 +00:00
|
|
|
</p>
|
|
|
|
|
|
2021-07-23 08:46:20 +01:00
|
|
|
<SpaceCreateForm
|
|
|
|
|
busy={busy}
|
|
|
|
|
onSubmit={onSpaceCreateClick}
|
|
|
|
|
setAvatar={setAvatar}
|
|
|
|
|
name={name}
|
|
|
|
|
setName={setName}
|
|
|
|
|
nameFieldRef={spaceNameField}
|
|
|
|
|
topic={topic}
|
|
|
|
|
setTopic={setTopic}
|
|
|
|
|
alias={alias}
|
|
|
|
|
setAlias={setAlias}
|
|
|
|
|
showAliasField={visibility === Visibility.Public}
|
|
|
|
|
aliasFieldRef={spaceAliasField}
|
|
|
|
|
/>
|
2021-05-10 14:39:10 +01:00
|
|
|
|
|
|
|
|
<AccessibleButton kind="primary" onClick={onSpaceCreateClick} disabled={busy}>
|
2023-09-26 13:04:17 +01:00
|
|
|
{busy ? _t("create_space|creating") : _t("action|create")}
|
2021-03-24 13:15:31 +00:00
|
|
|
</AccessibleButton>
|
2021-03-01 17:27:09 +00:00
|
|
|
</React.Fragment>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ContextMenu
|
|
|
|
|
left={72}
|
|
|
|
|
top={62}
|
|
|
|
|
chevronOffset={0}
|
|
|
|
|
chevronFace={ChevronFace.None}
|
|
|
|
|
onFinished={onFinished}
|
|
|
|
|
wrapperClassName="mx_SpaceCreateMenu_wrapper"
|
|
|
|
|
managed={false}
|
2021-12-09 12:27:03 +00:00
|
|
|
focusLock={true}
|
2021-03-01 17:27:09 +00:00
|
|
|
>
|
2021-07-02 16:31:37 +01:00
|
|
|
{body}
|
2021-03-01 17:27:09 +00:00
|
|
|
</ContextMenu>
|
|
|
|
|
);
|
2021-06-29 13:11:58 +01:00
|
|
|
};
|
2021-03-01 17:27:09 +00:00
|
|
|
|
|
|
|
|
export default SpaceCreateMenu;
|