@valbuild/ui 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -3
- package/server/.tmp/assets/index-082e6676.css +1 -0
- package/server/.tmp/assets/index-3108ab2a.js +197 -0
- package/{index.html → server/.tmp/index.html} +3 -1
- package/.babelrc.json +0 -10
- package/.storybook/main.js +0 -25
- package/.storybook/preview-head.html +0 -6
- package/.storybook/preview.js +0 -33
- package/.storybook/theme.css +0 -34
- package/CHANGELOG.md +0 -0
- package/components.json +0 -16
- package/fix-server-hack.js +0 -54
- package/fullscreen.vite.config.ts +0 -9
- package/jest.config.js +0 -4
- package/postcss.config.js +0 -6
- package/rollup.config.js +0 -23
- package/server.vite.config.ts +0 -31
- package/src/App.tsx +0 -73
- package/src/assets/icons/Bold.tsx +0 -23
- package/src/assets/icons/Chevron.tsx +0 -28
- package/src/assets/icons/FontColor.tsx +0 -30
- package/src/assets/icons/ImageIcon.tsx +0 -29
- package/src/assets/icons/Italic.tsx +0 -24
- package/src/assets/icons/Logo.tsx +0 -103
- package/src/assets/icons/Section.tsx +0 -41
- package/src/assets/icons/Strikethrough.tsx +0 -22
- package/src/assets/icons/TextIcon.tsx +0 -20
- package/src/assets/icons/Underline.tsx +0 -22
- package/src/assets/icons/Undo.tsx +0 -20
- package/src/components/Button.tsx +0 -68
- package/src/components/Checkbox.tsx +0 -51
- package/src/components/DraggableList.stories.tsx +0 -20
- package/src/components/DraggableList.tsx +0 -95
- package/src/components/Dropdown.tsx +0 -101
- package/src/components/EditButton.tsx +0 -10
- package/src/components/ErrorText.tsx +0 -3
- package/src/components/ExpandLogo.tsx +0 -72
- package/src/components/Grid.stories.tsx +0 -43
- package/src/components/Grid.tsx +0 -139
- package/src/components/RichTextEditor/ContentEditable.tsx +0 -117
- package/src/components/RichTextEditor/Nodes/ImageNode.tsx +0 -100
- package/src/components/RichTextEditor/Plugins/AutoFocus.tsx +0 -12
- package/src/components/RichTextEditor/Plugins/ImagePlugin.tsx +0 -45
- package/src/components/RichTextEditor/Plugins/LinkEditorPlugin.tsx +0 -58
- package/src/components/RichTextEditor/Plugins/Toolbar.tsx +0 -412
- package/src/components/RichTextEditor/RichTextEditor.tsx +0 -105
- package/src/components/UploadModal.tsx +0 -109
- package/src/components/User.tsx +0 -17
- package/src/components/ValFormField.tsx +0 -574
- package/src/components/ValFullscreen.tsx +0 -1278
- package/src/components/ValMenu.tsx +0 -92
- package/src/components/ValOverlay.tsx +0 -488
- package/src/components/ValOverlayContext.tsx +0 -80
- package/src/components/ValWindow.stories.tsx +0 -146
- package/src/components/ValWindow.tsx +0 -220
- package/src/components/dashboard/DashboardButton.tsx +0 -25
- package/src/components/dashboard/DashboardDropdown.tsx +0 -59
- package/src/components/dashboard/Dropdown.stories.tsx +0 -11
- package/src/components/dashboard/Dropdown.tsx +0 -70
- package/src/components/dashboard/FormGroup.stories.tsx +0 -37
- package/src/components/dashboard/FormGroup.tsx +0 -42
- package/src/components/dashboard/Grid2.stories.tsx +0 -56
- package/src/components/dashboard/Grid2.tsx +0 -72
- package/src/components/dashboard/Tree.stories.tsx +0 -91
- package/src/components/dashboard/Tree.tsx +0 -72
- package/src/components/dashboard/ValDashboardEditor.tsx +0 -269
- package/src/components/dashboard/ValDashboardGrid.tsx +0 -142
- package/src/components/dashboard/ValTreeNavigator.tsx +0 -253
- package/src/components/forms/Form.tsx +0 -126
- package/src/components/forms/FormContainer.tsx +0 -24
- package/src/components/forms/ImageForm.tsx +0 -195
- package/src/components/forms/TextArea.tsx +0 -24
- package/src/components/ui/accordion.tsx +0 -58
- package/src/components/ui/alert-dialog.tsx +0 -139
- package/src/components/ui/avatar.tsx +0 -48
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/calendar.tsx +0 -62
- package/src/components/ui/card.tsx +0 -86
- package/src/components/ui/checkbox.tsx +0 -28
- package/src/components/ui/command.tsx +0 -153
- package/src/components/ui/dialog.tsx +0 -120
- package/src/components/ui/dropdown-menu.tsx +0 -198
- package/src/components/ui/form.tsx +0 -177
- package/src/components/ui/input.tsx +0 -24
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/popover.tsx +0 -29
- package/src/components/ui/progress.tsx +0 -26
- package/src/components/ui/radio-group.tsx +0 -42
- package/src/components/ui/scroll-area.tsx +0 -51
- package/src/components/ui/select.tsx +0 -119
- package/src/components/ui/switch.tsx +0 -27
- package/src/components/ui/tabs.tsx +0 -53
- package/src/components/ui/toggle.tsx +0 -43
- package/src/components/ui/tooltip.tsx +0 -28
- package/src/components/usePatch.ts +0 -86
- package/src/components/useTheme.ts +0 -45
- package/src/dto/SerializedSchema.ts +0 -69
- package/src/dto/Session.ts +0 -12
- package/src/dto/SessionMode.ts +0 -5
- package/src/dto/Tree.ts +0 -18
- package/src/exports.ts +0 -6
- package/src/index.css +0 -115
- package/src/index.tsx +0 -14
- package/src/lib/IValStore.ts +0 -6
- package/src/lib/utils.ts +0 -6
- package/src/main.jsx +0 -10
- package/src/richtext/conversion/conversion.test.ts +0 -146
- package/src/richtext/conversion/lexicalToRichTextSource.test.ts +0 -89
- package/src/richtext/conversion/lexicalToRichTextSource.ts +0 -285
- package/src/richtext/conversion/parseRichTextSource.test.ts +0 -469
- package/src/richtext/conversion/parseRichTextSource.ts +0 -233
- package/src/richtext/conversion/richTextSourceToLexical.test.ts +0 -381
- package/src/richtext/conversion/richTextSourceToLexical.ts +0 -293
- package/src/richtext/shadowRootPolyFill.js +0 -115
- package/src/server.ts +0 -70
- package/src/stories/Button.stories.tsx +0 -20
- package/src/stories/Checkbox.stories.tsx +0 -14
- package/src/stories/Dropdown.stories.tsx +0 -23
- package/src/stories/Introduction.mdx +0 -221
- package/src/stories/RichTextEditor.stories.tsx +0 -24
- package/src/stories/assets/code-brackets.svg +0 -1
- package/src/stories/assets/colors.svg +0 -1
- package/src/stories/assets/comments.svg +0 -1
- package/src/stories/assets/direction.svg +0 -1
- package/src/stories/assets/flow.svg +0 -1
- package/src/stories/assets/plugin.svg +0 -1
- package/src/stories/assets/repo.svg +0 -1
- package/src/stories/assets/stackalt.svg +0 -1
- package/src/utils/Remote.ts +0 -15
- package/src/utils/imageMimeType.ts +0 -23
- package/src/utils/readImage.ts +0 -54
- package/src/utils/resolvePath.ts +0 -32
- package/src/vite-env.d.ts +0 -1
- package/src/vite-index.tsx +0 -7
- package/src/vite-server.ts +0 -42
- package/tailwind.config.js +0 -83
- package/tsconfig.json +0 -19
- package/vite.config.ts +0 -43
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { useCallback, useState } from "react";
|
|
4
|
-
import "../../richtext/shadowRootPolyFill";
|
|
5
|
-
|
|
6
|
-
export type Props = {
|
|
7
|
-
ariaActiveDescendant?: React.AriaAttributes["aria-activedescendant"];
|
|
8
|
-
ariaAutoComplete?: React.AriaAttributes["aria-autocomplete"];
|
|
9
|
-
ariaControls?: React.AriaAttributes["aria-controls"];
|
|
10
|
-
ariaDescribedBy?: React.AriaAttributes["aria-describedby"];
|
|
11
|
-
ariaExpanded?: React.AriaAttributes["aria-expanded"];
|
|
12
|
-
ariaLabel?: React.AriaAttributes["aria-label"];
|
|
13
|
-
ariaLabelledBy?: React.AriaAttributes["aria-labelledby"];
|
|
14
|
-
ariaMultiline?: React.AriaAttributes["aria-multiline"];
|
|
15
|
-
ariaOwns?: React.AriaAttributes["aria-owns"];
|
|
16
|
-
ariaRequired?: React.AriaAttributes["aria-required"];
|
|
17
|
-
autoCapitalize?: HTMLDivElement["autocapitalize"];
|
|
18
|
-
"data-testid"?: string | null | undefined;
|
|
19
|
-
} & React.AllHTMLAttributes<HTMLDivElement>;
|
|
20
|
-
|
|
21
|
-
export function ContentEditable({
|
|
22
|
-
ariaActiveDescendant,
|
|
23
|
-
ariaAutoComplete,
|
|
24
|
-
ariaControls,
|
|
25
|
-
ariaDescribedBy,
|
|
26
|
-
ariaExpanded,
|
|
27
|
-
ariaLabel,
|
|
28
|
-
ariaLabelledBy,
|
|
29
|
-
ariaMultiline,
|
|
30
|
-
ariaOwns,
|
|
31
|
-
ariaRequired,
|
|
32
|
-
autoCapitalize,
|
|
33
|
-
className,
|
|
34
|
-
id,
|
|
35
|
-
role = "textbox",
|
|
36
|
-
spellCheck = true,
|
|
37
|
-
style,
|
|
38
|
-
tabIndex,
|
|
39
|
-
"data-testid": testid,
|
|
40
|
-
...rest
|
|
41
|
-
}: Props): JSX.Element {
|
|
42
|
-
const [editor] = useLexicalComposerContext();
|
|
43
|
-
const [isEditable, setEditable] = useState(false);
|
|
44
|
-
|
|
45
|
-
const ref = useCallback(
|
|
46
|
-
(rootElement: null | HTMLElement) => {
|
|
47
|
-
editor.setRootElement(rootElement);
|
|
48
|
-
const shadowRoot = document.getElementById("val-ui")?.shadowRoot;
|
|
49
|
-
if (!shadowRoot) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
// Lexical doesnt officially support shadow dom yet, but this is a workaround
|
|
53
|
-
// It happens to work in firefox since their document.getSelection pierces shadow dom
|
|
54
|
-
// Chrome does not do this,. but has getSelection on the shadowRoot
|
|
55
|
-
// Safari does not have getSelection on the shadowRoot, and document.getSelection does not pierce shadow dom
|
|
56
|
-
// So for Safari this is polyfilled in shadowRootPolyFill.js
|
|
57
|
-
// https://github.com/facebook/lexical/issues/2119
|
|
58
|
-
//
|
|
59
|
-
// In the code below we have a hack to override the window object on the editor with the shadowRoot
|
|
60
|
-
// then it will call getSelection on the shadowRoot instead of the document
|
|
61
|
-
if ("getSelection" in shadowRoot) {
|
|
62
|
-
// safari (if polyfilled) and chrome
|
|
63
|
-
editor._window = shadowRoot as unknown as Window;
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
[editor]
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
React.useLayoutEffect(() => {
|
|
71
|
-
setEditable(editor.isEditable());
|
|
72
|
-
return editor.registerEditableListener((currentIsEditable) => {
|
|
73
|
-
setEditable(currentIsEditable);
|
|
74
|
-
});
|
|
75
|
-
}, [editor]);
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<div
|
|
79
|
-
{...rest}
|
|
80
|
-
aria-activedescendant={!isEditable ? undefined : ariaActiveDescendant}
|
|
81
|
-
aria-autocomplete={!isEditable ? "none" : ariaAutoComplete}
|
|
82
|
-
aria-controls={!isEditable ? undefined : ariaControls}
|
|
83
|
-
aria-describedby={ariaDescribedBy}
|
|
84
|
-
aria-expanded={
|
|
85
|
-
!isEditable
|
|
86
|
-
? undefined
|
|
87
|
-
: role === "combobox"
|
|
88
|
-
? !!ariaExpanded
|
|
89
|
-
: undefined
|
|
90
|
-
}
|
|
91
|
-
aria-label={ariaLabel}
|
|
92
|
-
aria-labelledby={ariaLabelledBy}
|
|
93
|
-
aria-multiline={ariaMultiline}
|
|
94
|
-
aria-owns={!isEditable ? undefined : ariaOwns}
|
|
95
|
-
aria-readonly={!isEditable ? true : undefined}
|
|
96
|
-
aria-required={ariaRequired}
|
|
97
|
-
autoCapitalize={autoCapitalize}
|
|
98
|
-
className={className}
|
|
99
|
-
contentEditable={isEditable}
|
|
100
|
-
data-testid={testid}
|
|
101
|
-
id={id}
|
|
102
|
-
ref={ref}
|
|
103
|
-
role={role}
|
|
104
|
-
spellCheck={spellCheck}
|
|
105
|
-
style={style}
|
|
106
|
-
tabIndex={tabIndex}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default function LexicalContentEditable({
|
|
112
|
-
className,
|
|
113
|
-
}: {
|
|
114
|
-
className?: string;
|
|
115
|
-
}): JSX.Element {
|
|
116
|
-
return <ContentEditable className={className} />;
|
|
117
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DecoratorNode,
|
|
3
|
-
LexicalNode,
|
|
4
|
-
NodeKey,
|
|
5
|
-
SerializedLexicalNode,
|
|
6
|
-
Spread,
|
|
7
|
-
} from "lexical";
|
|
8
|
-
|
|
9
|
-
export type ImagePayload = {
|
|
10
|
-
src: string;
|
|
11
|
-
altText?: string;
|
|
12
|
-
height?: number;
|
|
13
|
-
width?: number;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type SerializedImageNode = Spread<ImagePayload, SerializedLexicalNode>;
|
|
17
|
-
|
|
18
|
-
export class ImageNode extends DecoratorNode<JSX.Element> {
|
|
19
|
-
__src: string;
|
|
20
|
-
__sha256?: string;
|
|
21
|
-
__imageFileExt?: string;
|
|
22
|
-
__altText?: string;
|
|
23
|
-
__width?: number;
|
|
24
|
-
__height?: number;
|
|
25
|
-
|
|
26
|
-
static getType(): string {
|
|
27
|
-
return "image";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static clone(node: ImageNode): ImageNode {
|
|
31
|
-
return new ImageNode({
|
|
32
|
-
src: node.__src,
|
|
33
|
-
altText: node.__altText,
|
|
34
|
-
width: node.__width,
|
|
35
|
-
height: node.__height,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
constructor(payload: ImagePayload, key?: NodeKey) {
|
|
40
|
-
super(key);
|
|
41
|
-
this.__src = payload.src;
|
|
42
|
-
this.__altText = payload.altText;
|
|
43
|
-
this.__width = payload.width;
|
|
44
|
-
this.__height = payload.height;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
exportJSON(): SerializedImageNode {
|
|
48
|
-
return {
|
|
49
|
-
altText: this.__altText,
|
|
50
|
-
height: this.__width,
|
|
51
|
-
src: this.__src,
|
|
52
|
-
type: "image",
|
|
53
|
-
version: 1,
|
|
54
|
-
width: this.__width,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static importJSON(serializedNode: SerializedImageNode): ImageNode {
|
|
59
|
-
return $createImageNode(serializedNode);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
createDOM(): HTMLElement {
|
|
63
|
-
return document.createElement("div");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
updateDOM(): false {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
decorate(): JSX.Element {
|
|
71
|
-
return (
|
|
72
|
-
<ImageComponent
|
|
73
|
-
src={this.__src}
|
|
74
|
-
altText={this.__altText}
|
|
75
|
-
empty={this.__empty}
|
|
76
|
-
height={this.__height}
|
|
77
|
-
nodeKey={this.getKey()}
|
|
78
|
-
/>
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function ImageComponent(props: {
|
|
84
|
-
empty: boolean;
|
|
85
|
-
altText?: string;
|
|
86
|
-
height?: number;
|
|
87
|
-
nodeKey?: NodeKey;
|
|
88
|
-
src: string;
|
|
89
|
-
width?: number;
|
|
90
|
-
}): JSX.Element {
|
|
91
|
-
return <img src={props.src}></img>;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function $createImageNode(payload: ImagePayload): ImageNode {
|
|
95
|
-
return new ImageNode(payload);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function $isImageNode(node: LexicalNode | null): boolean {
|
|
99
|
-
return node instanceof ImageNode;
|
|
100
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
|
-
|
|
4
|
-
export function AutoFocus() {
|
|
5
|
-
const [editor] = useLexicalComposerContext();
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
editor.focus();
|
|
9
|
-
}, [editor]);
|
|
10
|
-
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
2
|
-
import { $wrapNodeInElement, mergeRegister } from "@lexical/utils";
|
|
3
|
-
import {
|
|
4
|
-
$createParagraphNode,
|
|
5
|
-
$insertNodes,
|
|
6
|
-
$isRootOrShadowRoot,
|
|
7
|
-
COMMAND_PRIORITY_EDITOR,
|
|
8
|
-
createCommand,
|
|
9
|
-
LexicalCommand,
|
|
10
|
-
} from "lexical";
|
|
11
|
-
import { useEffect } from "react";
|
|
12
|
-
|
|
13
|
-
import { $createImageNode, ImageNode, ImagePayload } from "../Nodes/ImageNode";
|
|
14
|
-
|
|
15
|
-
export type InsertImagePayload = Readonly<ImagePayload>;
|
|
16
|
-
|
|
17
|
-
export const INSERT_IMAGE_COMMAND: LexicalCommand<InsertImagePayload> =
|
|
18
|
-
createCommand("INSERT_IMAGE_COMMAND");
|
|
19
|
-
|
|
20
|
-
export default function ImagesPlugin(): JSX.Element | null {
|
|
21
|
-
const [editor] = useLexicalComposerContext();
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (!editor.hasNodes([ImageNode])) {
|
|
25
|
-
throw new Error("ImagesPlugin: ImageNode not registered on editor");
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return mergeRegister(
|
|
29
|
-
editor.registerCommand<InsertImagePayload>(
|
|
30
|
-
INSERT_IMAGE_COMMAND,
|
|
31
|
-
(payload) => {
|
|
32
|
-
const imageNode = $createImageNode(payload);
|
|
33
|
-
$insertNodes([imageNode]);
|
|
34
|
-
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
35
|
-
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
},
|
|
39
|
-
COMMAND_PRIORITY_EDITOR
|
|
40
|
-
)
|
|
41
|
-
);
|
|
42
|
-
}, [editor]);
|
|
43
|
-
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { $isLinkNode } from "@lexical/link";
|
|
2
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
|
-
import { $isAtNodeEnd } from "@lexical/selection";
|
|
4
|
-
import { $findMatchingParent, mergeRegister } from "@lexical/utils";
|
|
5
|
-
import {
|
|
6
|
-
$getSelection,
|
|
7
|
-
$isRangeSelection,
|
|
8
|
-
CLICK_COMMAND,
|
|
9
|
-
COMMAND_PRIORITY_LOW,
|
|
10
|
-
ElementNode,
|
|
11
|
-
RangeSelection,
|
|
12
|
-
TextNode,
|
|
13
|
-
} from "lexical";
|
|
14
|
-
import { useEffect } from "react";
|
|
15
|
-
|
|
16
|
-
export function getSelectedNode(
|
|
17
|
-
selection: RangeSelection
|
|
18
|
-
): TextNode | ElementNode {
|
|
19
|
-
const anchor = selection.anchor;
|
|
20
|
-
const focus = selection.focus;
|
|
21
|
-
const anchorNode = selection.anchor.getNode();
|
|
22
|
-
const focusNode = selection.focus.getNode();
|
|
23
|
-
if (anchorNode === focusNode) {
|
|
24
|
-
return anchorNode;
|
|
25
|
-
}
|
|
26
|
-
const isBackward = selection.isBackward();
|
|
27
|
-
if (isBackward) {
|
|
28
|
-
return $isAtNodeEnd(focus) ? anchorNode : focusNode;
|
|
29
|
-
} else {
|
|
30
|
-
return $isAtNodeEnd(anchor) ? anchorNode : focusNode;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export default function LinkEditorPlugin() {
|
|
35
|
-
const [editor] = useLexicalComposerContext();
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
return mergeRegister(
|
|
39
|
-
editor.registerCommand(
|
|
40
|
-
CLICK_COMMAND,
|
|
41
|
-
(payload) => {
|
|
42
|
-
const selection = $getSelection();
|
|
43
|
-
if ($isRangeSelection(selection)) {
|
|
44
|
-
const node = getSelectedNode(selection);
|
|
45
|
-
const linkNode = $findMatchingParent(node, $isLinkNode);
|
|
46
|
-
if ($isLinkNode(linkNode) && (payload.metaKey || payload.ctrlKey)) {
|
|
47
|
-
window.open(linkNode.getURL(), "_blank");
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
},
|
|
53
|
-
COMMAND_PRIORITY_LOW
|
|
54
|
-
)
|
|
55
|
-
);
|
|
56
|
-
}, []);
|
|
57
|
-
return null;
|
|
58
|
-
}
|