roamjs-components 0.78.7 → 0.78.9

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.
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  declare type FilterOptions<T> = (options: T[], query: string) => T[];
3
3
  declare type OnNewItem<T> = (s: string) => T;
4
+ declare type ItemToQuery<T> = (t?: T) => string;
4
5
  export declare type AutocompleteInputProps<T = string> = {
5
6
  value?: T;
6
7
  setValue: (q: T) => void;
@@ -13,7 +14,7 @@ export declare type AutocompleteInputProps<T = string> = {
13
14
  multiline?: boolean;
14
15
  id?: string;
15
16
  filterOptions?: FilterOptions<T>;
16
- itemToQuery?: (item?: T) => string;
17
+ itemToQuery?: ItemToQuery<T>;
17
18
  renderItem?: (props: {
18
19
  item: T;
19
20
  onClick: () => void;
@@ -21,5 +22,5 @@ export declare type AutocompleteInputProps<T = string> = {
21
22
  }) => React.ReactElement;
22
23
  onNewItem?: OnNewItem<T>;
23
24
  };
24
- declare const AutocompleteInput: <T extends unknown = string>({ value, setValue, onBlur, onConfirm, showButton, options, placeholder, autoFocus, multiline, id, filterOptions: _filterOptions, itemToQuery, renderItem, onNewItem: _onNewItem, }: AutocompleteInputProps<T>) => React.ReactElement;
25
+ declare const AutocompleteInput: <T extends unknown = string>({ value, setValue, onBlur, onConfirm, showButton, options, placeholder, autoFocus, multiline, id, filterOptions: _filterOptions, itemToQuery: _itemToQuery, renderItem, onNewItem: _onNewItem, }: AutocompleteInputProps<T>) => React.ReactElement;
25
26
  export default AutocompleteInput;
@@ -6,8 +6,9 @@ const react_1 = tslib_1.__importStar(require("react"));
6
6
  const useArrowKeyDown_1 = tslib_1.__importDefault(require("../hooks/useArrowKeyDown"));
7
7
  const fuzzy_1 = tslib_1.__importDefault(require("fuzzy"));
8
8
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
9
- const AutocompleteInput = ({ value, setValue, onBlur, onConfirm, showButton, options = [], placeholder = "Enter value", autoFocus, multiline, id, filterOptions: _filterOptions, itemToQuery = (i) => `${i}`, renderItem, onNewItem: _onNewItem, }) => {
9
+ const AutocompleteInput = ({ value, setValue, onBlur, onConfirm, showButton, options = [], placeholder = "Enter value", autoFocus, multiline, id, filterOptions: _filterOptions, itemToQuery: _itemToQuery, renderItem, onNewItem: _onNewItem, }) => {
10
10
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
11
+ const itemToQuery = (0, react_1.useMemo)(() => _itemToQuery || ((s) => (s ? `${s}` : "")), [_onNewItem]);
11
12
  const [query, setQuery] = (0, react_1.useState)(() => itemToQuery(value));
12
13
  const open = (0, react_1.useCallback)(() => setIsOpen(true), [setIsOpen]);
13
14
  const close = (0, react_1.useCallback)(() => setIsOpen(false), [setIsOpen]);
@@ -48,6 +49,14 @@ const AutocompleteInput = ({ value, setValue, onBlur, onConfirm, showButton, opt
48
49
  if (query)
49
50
  setValue(items[activeIndex] || onNewItem(query));
50
51
  }, [setValue, activeIndex, items, onNewItem, query]);
52
+ (0, react_1.useEffect)(() => {
53
+ if (inputRef.current &&
54
+ inputRef.current === document.activeElement &&
55
+ value) {
56
+ const index = itemToQuery(value).length;
57
+ inputRef.current.setSelectionRange(index, index);
58
+ }
59
+ }, [inputRef]);
51
60
  const Input = (0, react_1.useMemo)(() => (multiline ? core_1.TextArea : core_1.InputGroup), [multiline]);
52
61
  return (react_1.default.createElement(core_1.Popover, { portalClassName: "roamjs-autocomplete-input", targetClassName: "roamjs-autocomplete-input-target", captureDismiss: true, isOpen: isOpen, onOpened: open, minimal: true, autoFocus: false, enforceFocus: false, position: core_1.PopoverPosition.BOTTOM_LEFT, modifiers: {
53
62
  flip: { enabled: false },
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteInput.js","sourceRoot":"","sources":["../../src/components/AutocompleteInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n InputGroup,\n Menu,\n MenuItem,\n PopoverPosition,\n Popover,\n Button,\n TextArea,\n} from \"@blueprintjs/core\";\nimport React, {\n useState,\n useCallback,\n useMemo,\n useRef,\n useEffect,\n} from \"react\";\nimport useArrowKeyDown from \"../hooks/useArrowKeyDown\";\nimport fuzzy from \"fuzzy\";\n\ntype FilterOptions<T> = (options: T[], query: string) => T[];\ntype OnNewItem<T> = (s: string) => T;\n\nexport type AutocompleteInputProps<T = string> = {\n value?: T;\n setValue: (q: T) => void;\n showButton?: boolean;\n onBlur?: (v: string) => void;\n onConfirm?: () => void;\n options?: T[];\n placeholder?: string;\n autoFocus?: boolean;\n multiline?: boolean;\n id?: string;\n filterOptions?: FilterOptions<T>;\n itemToQuery?: (item?: T) => string;\n renderItem?: (props: {\n item: T;\n onClick: () => void;\n active: boolean;\n }) => React.ReactElement;\n onNewItem?: OnNewItem<T>;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint\nconst AutocompleteInput = <T extends unknown = string>({\n value,\n setValue,\n onBlur,\n onConfirm,\n showButton,\n options = [],\n placeholder = \"Enter value\",\n autoFocus,\n multiline,\n id,\n filterOptions: _filterOptions,\n itemToQuery = (i) => `${i}`,\n renderItem,\n onNewItem: _onNewItem,\n}: AutocompleteInputProps<T>): React.ReactElement => {\n const [isOpen, setIsOpen] = useState(false);\n const [query, setQuery] = useState<string>(() => itemToQuery(value));\n const open = useCallback(() => setIsOpen(true), [setIsOpen]);\n const close = useCallback(() => setIsOpen(false), [setIsOpen]);\n const [isTyping, setIsTyping] = useState(false);\n const filterOptions = useMemo<FilterOptions<T>>(\n () =>\n _filterOptions ||\n ((o, q) =>\n typeof o[0] === \"string\"\n ? (fuzzy.filter(q, o).map((e) => e.string) as T[])\n : o),\n [_filterOptions]\n );\n const onNewItem = useMemo<OnNewItem<T>>(\n () => _onNewItem || ((s) => s as T),\n [_onNewItem]\n );\n\n const items = useMemo(\n () => (query ? filterOptions(options, query) : options),\n [query, options, filterOptions]\n );\n const menuRef = useRef<HTMLUListElement>(null);\n const inputRef = useRef<HTMLInputElement & HTMLTextAreaElement>(null);\n const onEnter = useCallback(\n (value?: T) => {\n if (isOpen && value) {\n setQuery(itemToQuery(value));\n setValue(value);\n setIsTyping(false);\n } else if (onConfirm) {\n onConfirm();\n } else {\n setIsOpen(true);\n }\n },\n [setValue, close, onConfirm, isOpen]\n );\n const { activeIndex, onKeyDown } = useArrowKeyDown({\n onEnter,\n results: items,\n menuRef,\n });\n useEffect(() => {\n if (!items.length || !isTyping) close();\n else open();\n }, [items, close, open, isTyping]);\n useEffect(() => {\n if (query) setValue(items[activeIndex] || onNewItem(query));\n }, [setValue, activeIndex, items, onNewItem, query]);\n const Input = useMemo(() => (multiline ? TextArea : InputGroup), [multiline]);\n return (\n <Popover\n portalClassName={\"roamjs-autocomplete-input\"}\n targetClassName={\"roamjs-autocomplete-input-target\"}\n captureDismiss={true}\n isOpen={isOpen}\n onOpened={open}\n minimal\n autoFocus={false}\n enforceFocus={false}\n position={PopoverPosition.BOTTOM_LEFT}\n modifiers={{\n flip: { enabled: false },\n preventOverflow: { enabled: false },\n }}\n content={\n <Menu className={\"max-h-64 overflow-auto max-w-md\"} ulRef={menuRef}>\n {items.map((t, i) => {\n const sharedProps = {\n onClick: () => {\n setIsTyping(false);\n setValue(t);\n setQuery(itemToQuery(t));\n inputRef.current?.focus();\n },\n active: activeIndex === i,\n };\n return renderItem ? (\n <React.Fragment key={i}>\n {renderItem?.({\n item: t,\n ...sharedProps,\n })}\n </React.Fragment>\n ) : (\n <MenuItem\n text={itemToQuery(t)}\n key={i}\n multiline\n {...sharedProps}\n />\n );\n })}\n </Menu>\n }\n target={\n <Input\n value={query}\n onChange={(e) => {\n setIsTyping(true);\n setQuery(e.target.value);\n }}\n autoFocus={autoFocus}\n placeholder={placeholder}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n close();\n } else {\n onKeyDown(e);\n }\n }}\n id={id}\n onClick={() => setIsTyping(true)}\n onBlur={(e) => {\n if (\n e.relatedTarget === null ||\n !(e.relatedTarget as HTMLElement).closest?.(\n \".roamjs-autocomplete-input\"\n )\n ) {\n setIsTyping(false);\n }\n if (onBlur) {\n onBlur(e.target.value);\n }\n }}\n inputRef={inputRef}\n {...(showButton\n ? {\n rightElement: (\n <Button icon={\"add\"} minimal onClick={() => onEnter()} />\n ),\n }\n : {})}\n />\n }\n />\n );\n};\n\nexport default AutocompleteInput;\n"]}
1
+ {"version":3,"file":"AutocompleteInput.js","sourceRoot":"","sources":["../../src/components/AutocompleteInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n InputGroup,\n Menu,\n MenuItem,\n PopoverPosition,\n Popover,\n Button,\n TextArea,\n} from \"@blueprintjs/core\";\nimport React, {\n useState,\n useCallback,\n useMemo,\n useRef,\n useEffect,\n} from \"react\";\nimport useArrowKeyDown from \"../hooks/useArrowKeyDown\";\nimport fuzzy from \"fuzzy\";\n\ntype FilterOptions<T> = (options: T[], query: string) => T[];\ntype OnNewItem<T> = (s: string) => T;\ntype ItemToQuery<T> = (t?: T) => string;\n\nexport type AutocompleteInputProps<T = string> = {\n value?: T;\n setValue: (q: T) => void;\n showButton?: boolean;\n onBlur?: (v: string) => void;\n onConfirm?: () => void;\n options?: T[];\n placeholder?: string;\n autoFocus?: boolean;\n multiline?: boolean;\n id?: string;\n filterOptions?: FilterOptions<T>;\n itemToQuery?: ItemToQuery<T>;\n renderItem?: (props: {\n item: T;\n onClick: () => void;\n active: boolean;\n }) => React.ReactElement;\n onNewItem?: OnNewItem<T>;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint\nconst AutocompleteInput = <T extends unknown = string>({\n value,\n setValue,\n onBlur,\n onConfirm,\n showButton,\n options = [],\n placeholder = \"Enter value\",\n autoFocus,\n multiline,\n id,\n filterOptions: _filterOptions,\n itemToQuery: _itemToQuery,\n renderItem,\n onNewItem: _onNewItem,\n}: AutocompleteInputProps<T>): React.ReactElement => {\n const [isOpen, setIsOpen] = useState(false);\n const itemToQuery = useMemo<ItemToQuery<T>>(\n () => _itemToQuery || ((s) => (s ? `${s}` : \"\")),\n [_onNewItem]\n );\n const [query, setQuery] = useState<string>(() => itemToQuery(value));\n const open = useCallback(() => setIsOpen(true), [setIsOpen]);\n const close = useCallback(() => setIsOpen(false), [setIsOpen]);\n const [isTyping, setIsTyping] = useState(false);\n const filterOptions = useMemo<FilterOptions<T>>(\n () =>\n _filterOptions ||\n ((o, q) =>\n typeof o[0] === \"string\"\n ? (fuzzy.filter(q, o).map((e) => e.string) as T[])\n : o),\n [_filterOptions]\n );\n const onNewItem = useMemo<OnNewItem<T>>(\n () => _onNewItem || ((s) => s as T),\n [_onNewItem]\n );\n\n const items = useMemo(\n () => (query ? filterOptions(options, query) : options),\n [query, options, filterOptions]\n );\n const menuRef = useRef<HTMLUListElement>(null);\n const inputRef = useRef<HTMLInputElement & HTMLTextAreaElement>(null);\n const onEnter = useCallback(\n (value?: T) => {\n if (isOpen && value) {\n setQuery(itemToQuery(value));\n setValue(value);\n setIsTyping(false);\n } else if (onConfirm) {\n onConfirm();\n } else {\n setIsOpen(true);\n }\n },\n [setValue, close, onConfirm, isOpen]\n );\n const { activeIndex, onKeyDown } = useArrowKeyDown({\n onEnter,\n results: items,\n menuRef,\n });\n useEffect(() => {\n if (!items.length || !isTyping) close();\n else open();\n }, [items, close, open, isTyping]);\n useEffect(() => {\n if (query) setValue(items[activeIndex] || onNewItem(query));\n }, [setValue, activeIndex, items, onNewItem, query]);\n useEffect(() => {\n if (\n inputRef.current &&\n inputRef.current === document.activeElement &&\n value\n ) {\n const index = itemToQuery(value).length;\n inputRef.current.setSelectionRange(index, index);\n }\n }, [inputRef]);\n const Input = useMemo(() => (multiline ? TextArea : InputGroup), [multiline]);\n return (\n <Popover\n portalClassName={\"roamjs-autocomplete-input\"}\n targetClassName={\"roamjs-autocomplete-input-target\"}\n captureDismiss={true}\n isOpen={isOpen}\n onOpened={open}\n minimal\n autoFocus={false}\n enforceFocus={false}\n position={PopoverPosition.BOTTOM_LEFT}\n modifiers={{\n flip: { enabled: false },\n preventOverflow: { enabled: false },\n }}\n content={\n <Menu className={\"max-h-64 overflow-auto max-w-md\"} ulRef={menuRef}>\n {items.map((t, i) => {\n const sharedProps = {\n onClick: () => {\n setIsTyping(false);\n setValue(t);\n setQuery(itemToQuery(t));\n inputRef.current?.focus();\n },\n active: activeIndex === i,\n };\n return renderItem ? (\n <React.Fragment key={i}>\n {renderItem?.({\n item: t,\n ...sharedProps,\n })}\n </React.Fragment>\n ) : (\n <MenuItem\n text={itemToQuery(t)}\n key={i}\n multiline\n {...sharedProps}\n />\n );\n })}\n </Menu>\n }\n target={\n <Input\n value={query}\n onChange={(e) => {\n setIsTyping(true);\n setQuery(e.target.value);\n }}\n autoFocus={autoFocus}\n placeholder={placeholder}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n close();\n } else {\n onKeyDown(e);\n }\n }}\n id={id}\n onClick={() => setIsTyping(true)}\n onBlur={(e) => {\n if (\n e.relatedTarget === null ||\n !(e.relatedTarget as HTMLElement).closest?.(\n \".roamjs-autocomplete-input\"\n )\n ) {\n setIsTyping(false);\n }\n if (onBlur) {\n onBlur(e.target.value);\n }\n }}\n inputRef={inputRef}\n {...(showButton\n ? {\n rightElement: (\n <Button icon={\"add\"} minimal onClick={() => onEnter()} />\n ),\n }\n : {})}\n />\n }\n />\n );\n};\n\nexport default AutocompleteInput;\n"]}
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import type { RoamOverlayProps } from "../util/renderOverlay";
3
+ import { InputTextNode } from "../types";
3
4
  declare type Props<T> = {
4
5
  title?: React.ReactNode;
5
6
  content?: React.ReactNode;
@@ -24,10 +25,11 @@ declare type Props<T> = {
24
25
  defaultValue?: boolean;
25
26
  type: "flag";
26
27
  } | {
27
- defaultValue?: string;
28
+ defaultValue?: InputTextNode[];
28
29
  type: "embed";
29
30
  }) & {
30
31
  label?: string;
32
+ conditional?: string;
31
33
  }>;
32
34
  };
33
35
  declare const FormDialog: <T extends Record<string, unknown>>({ title, content, isOpen, onClose, onSubmit, fields, }: RoamOverlayProps<Props<T>>) => JSX.Element;
@@ -11,28 +11,25 @@ const MenuItemSelect_1 = tslib_1.__importDefault(require("./MenuItemSelect"));
11
11
  const PageInput_1 = tslib_1.__importDefault(require("./PageInput"));
12
12
  const nanoid_1 = tslib_1.__importDefault(require("nanoid"));
13
13
  const dom_1 = require("../dom");
14
- const EmbedInput = ({ defaultValue = "", onChange, autoFocus, }) => {
14
+ const getFullTreeByParentUid_1 = tslib_1.__importDefault(require("../queries/getFullTreeByParentUid"));
15
+ const createPage_1 = tslib_1.__importDefault(require("../writes/createPage"));
16
+ const EmbedInput = ({ defaultValue, onChange, autoFocus, }) => {
17
+ const defaultEmbed = (0, react_1.useMemo)(() => defaultValue || [], [defaultValue]);
15
18
  const elRef = (0, react_1.useRef)(null);
16
19
  (0, react_1.useEffect)(() => {
17
20
  const el = elRef.current;
18
21
  if (el) {
19
22
  const uid = window.roamAlphaAPI.util.generateUID();
20
23
  const parentUid = window.roamAlphaAPI.util.generateUID();
21
- window.roamAlphaAPI.createPage({
22
- page: { uid: parentUid, title: (0, nanoid_1.default)() },
23
- });
24
- window.roamAlphaAPI
25
- .createBlock({
26
- location: {
27
- "parent-uid": parentUid,
28
- order: 0,
29
- },
30
- block: { uid, string: defaultValue },
31
- })
32
- .then(() => {
33
- window.roamAlphaAPI.ui.components.renderBlock({
34
- uid,
24
+ (0, createPage_1.default)({
25
+ uid: parentUid,
26
+ title: (0, nanoid_1.default)(),
27
+ tree: defaultEmbed,
28
+ }).then(() => {
29
+ window.roamAlphaAPI.ui.components.renderPage({
30
+ uid: parentUid,
35
31
  el,
32
+ hideMentions: true,
36
33
  });
37
34
  if (autoFocus) {
38
35
  const block = el.querySelector(`div[id*="block-input"],textarea[id*="block-input"]`);
@@ -47,7 +44,7 @@ const EmbedInput = ({ defaultValue = "", onChange, autoFocus, }) => {
47
44
  }
48
45
  });
49
46
  // In the future, we can return the whole tree of data from `parentUid`
50
- onChange(() => (0, getTextByBlockUid_1.default)(uid));
47
+ onChange(() => (0, getFullTreeByParentUid_1.default)(parentUid).children);
51
48
  return () => {
52
49
  window.roamAlphaAPI.deleteBlock({ block: { uid } });
53
50
  window.roamAlphaAPI.deletePage({ page: { uid: parentUid } });
@@ -57,16 +54,20 @@ const EmbedInput = ({ defaultValue = "", onChange, autoFocus, }) => {
57
54
  return () => { };
58
55
  }, [
59
56
  elRef,
60
- defaultValue,
57
+ defaultEmbed,
61
58
  autoFocus,
62
59
  // Triggering infinite rerender
63
60
  // onChange
64
61
  ]);
65
62
  return (react_1.default.createElement(react_1.default.Fragment, null,
66
63
  react_1.default.createElement("style", null, `div.rm-autocomplete__results {
67
- z-index: 1000;
64
+ z-index: 1000;
65
+ }
66
+ .roamjs-form-embed div div:has(> h1.rm-title-display),
67
+ .roamjs-form-embed .rm-api-render--page > div:has(.rm-reference-main) {
68
+ display: none;
68
69
  }`),
69
- react_1.default.createElement("div", { ref: elRef, className: "rounded-md bg-white font-normal mt-1 bp3-input h-32 overflow-scroll" })));
70
+ react_1.default.createElement("div", { ref: elRef, className: "rounded-md bg-white font-normal mt-1 bp3-input h-32 overflow-scroll roamjs-form-embed py-2 px-4" })));
70
71
  };
71
72
  const FormDialog = ({ title, content, isOpen, onClose, onSubmit = () => Promise.resolve(), fields = {}, }) => {
72
73
  const [loading, setLoading] = (0, react_1.useState)(false);
@@ -74,7 +75,12 @@ const FormDialog = ({ title, content, isOpen, onClose, onSubmit = () => Promise.
74
75
  const [data, setData] = (0, react_1.useState)(() => Object.fromEntries(Object.entries(fields)
75
76
  .filter(([, meta]) => typeof meta.defaultValue !== "undefined")
76
77
  .map(([key, meta]) => [key, meta.defaultValue])));
77
- const onClick = (0, react_1.useCallback)(() => Promise.resolve(onSubmit(Object.fromEntries(Object.entries(data).map(([key, value]) => [key, typeof value === "function" ? value() : value]))))
78
+ const onClick = (0, react_1.useCallback)(() => Promise.resolve(onSubmit(Object.fromEntries(Object.entries(data)
79
+ .filter(([key]) => {
80
+ const { conditional } = fields[key];
81
+ return !conditional || !!data[conditional];
82
+ })
83
+ .map(([key, value]) => [key, typeof value === "function" ? value() : value]))))
78
84
  .then(onClose)
79
85
  .catch((e) => {
80
86
  setError(e.message);
@@ -84,33 +90,36 @@ const FormDialog = ({ title, content, isOpen, onClose, onSubmit = () => Promise.
84
90
  react_1.default.createElement("div", { className: core_1.Classes.DIALOG_BODY },
85
91
  content,
86
92
  Object.entries(fields).map(([name, meta], index) => {
93
+ if (meta.conditional && !data[meta.conditional]) {
94
+ return react_1.default.createElement("div", { key: name });
95
+ }
87
96
  if (meta.type === "text") {
88
- return (react_1.default.createElement(core_1.Label, null,
97
+ return (react_1.default.createElement(core_1.Label, { key: name },
89
98
  meta.label,
90
99
  react_1.default.createElement(core_1.InputGroup, { value: data[name], onChange: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e.target.value })), autoFocus: index === 0 })));
91
100
  }
92
101
  else if (meta.type === "number") {
93
- return (react_1.default.createElement(core_1.Label, null,
102
+ return (react_1.default.createElement(core_1.Label, { key: name },
94
103
  meta.label,
95
104
  react_1.default.createElement(core_1.NumericInput, { value: data[name], onChange: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e.target.value })), autoFocus: index === 0 })));
96
105
  }
97
106
  else if (meta.type === "flag") {
98
- return (react_1.default.createElement(core_1.Checkbox, { label: meta.label, value: data[name], onChange: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e.target.checked })), autoFocus: index === 0 }));
107
+ return (react_1.default.createElement(core_1.Checkbox, { label: meta.label, value: data[name], onChange: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e.target.checked })), key: name, autoFocus: index === 0 }));
99
108
  }
100
109
  else if (meta.type === "select") {
101
- return (react_1.default.createElement(core_1.Label, null,
110
+ return (react_1.default.createElement(core_1.Label, { key: name },
102
111
  meta.label,
103
112
  react_1.default.createElement(MenuItemSelect_1.default, { activeItem: data[name], onItemSelect: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e })), items: meta.options || [], ButtonProps: {
104
113
  autoFocus: index === 0,
105
114
  } })));
106
115
  }
107
116
  else if (meta.type === "page") {
108
- return (react_1.default.createElement(core_1.Label, null,
117
+ return (react_1.default.createElement(core_1.Label, { key: name },
109
118
  meta.label,
110
- react_1.default.createElement(PageInput_1.default, { value: data[name], setValue: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e })), autoFocus: index === 0 })));
119
+ react_1.default.createElement(PageInput_1.default, { key: name, value: data[name], setValue: (e) => setData(Object.assign(Object.assign({}, data), { [name]: e })), autoFocus: index === 0 })));
111
120
  }
112
121
  else if (meta.type === "block") {
113
- return (react_1.default.createElement(core_1.Label, null,
122
+ return (react_1.default.createElement(core_1.Label, { key: name },
114
123
  meta.label,
115
124
  react_1.default.createElement(BlockInput_1.default, { value: (0, getTextByBlockUid_1.default)(data[name]) ||
116
125
  data[name], setValue: (text, uid) => setData(Object.assign(Object.assign({}, data), { [name]: window.roamAlphaAPI.pull("[:db/id]", [
@@ -121,21 +130,22 @@ const FormDialog = ({ title, content, isOpen, onClose, onSubmit = () => Promise.
121
130
  : text })), autoFocus: index === 0 })));
122
131
  }
123
132
  else if (meta.type === "embed") {
124
- return (react_1.default.createElement(core_1.Label, null,
133
+ return (react_1.default.createElement(core_1.Label, { key: name },
125
134
  meta.label,
126
135
  react_1.default.createElement(EmbedInput, { defaultValue: meta.defaultValue, onChange: (value) => {
127
136
  setData(Object.assign(Object.assign({}, data), { [name]: value }));
128
137
  }, autoFocus: index === 0 })));
129
138
  }
130
139
  else {
131
- return react_1.default.createElement(react_1.default.Fragment, null);
140
+ return react_1.default.createElement("div", { key: name });
132
141
  }
133
142
  })),
134
143
  react_1.default.createElement("div", { className: core_1.Classes.DIALOG_FOOTER },
135
- react_1.default.createElement("div", { className: core_1.Classes.DIALOG_FOOTER_ACTIONS },
144
+ react_1.default.createElement("div", { className: `${core_1.Classes.DIALOG_FOOTER_ACTIONS} items-center` },
145
+ loading && react_1.default.createElement(core_1.Spinner, { size: core_1.SpinnerSize.SMALL }),
136
146
  react_1.default.createElement("span", { className: "text-red-700" }, error),
137
- react_1.default.createElement(core_1.Button, { text: "Cancel", onClick: onClose, disabled: loading }),
138
- react_1.default.createElement(core_1.Button, { text: "Submit", intent: core_1.Intent.PRIMARY, onClick: onClick, disabled: loading })))));
147
+ react_1.default.createElement(core_1.Button, { text: "Cancel", onClick: onClose, disabled: loading, className: "flex-shrink-0" }),
148
+ react_1.default.createElement(core_1.Button, { text: "Submit", intent: core_1.Intent.PRIMARY, onClick: onClick, disabled: loading, className: "flex-shrink-0" })))));
139
149
  };
140
150
  exports.render = (0, createOverlayRender_1.default)("form-dialog", FormDialog);
141
151
  const prompt = ({ defaultAnswer, question, title, }) => new Promise((resolve) => (0, exports.render)({
@@ -1 +1 @@
1
- {"version":3,"file":"FormDialog.js","sourceRoot":"","sources":["../../src/components/FormDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n Checkbox,\n Classes,\n Dialog,\n InputGroup,\n Intent,\n Label,\n NumericInput,\n} from \"@blueprintjs/core\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport getTextByBlockUid from \"../queries/getTextByBlockUid\";\nimport createOverlayRender from \"../util/createOverlayRender\";\nimport type { RoamOverlayProps } from \"../util/renderOverlay\";\nimport BlockInput from \"./BlockInput\";\nimport MenuItemSelect from \"./MenuItemSelect\";\nimport PageInput from \"./PageInput\";\nimport nanoid from \"nanoid\";\nimport { getUids } from \"../dom\";\n\ntype Props<T> = {\n title?: React.ReactNode;\n content?: React.ReactNode;\n onSubmit?: (data: T) => Promise<unknown> | unknown;\n fields?: Record<\n string,\n (\n | {\n defaultValue?: string;\n type: \"text\";\n }\n | {\n defaultValue?: number;\n type: \"number\";\n }\n | {\n defaultValue?: string;\n type: \"select\";\n options?: string[];\n }\n | {\n defaultValue?: string;\n type: \"page\";\n }\n | {\n defaultValue?: string;\n type: \"block\";\n }\n | {\n defaultValue?: boolean;\n type: \"flag\";\n }\n | {\n defaultValue?: string;\n type: \"embed\";\n }\n ) & { label?: string }\n >;\n};\n\nconst EmbedInput = ({\n defaultValue = \"\",\n onChange,\n autoFocus,\n}: {\n defaultValue?: string;\n onChange: (s: () => string) => void;\n autoFocus: boolean;\n}) => {\n const elRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = elRef.current;\n if (el) {\n const uid = window.roamAlphaAPI.util.generateUID();\n const parentUid = window.roamAlphaAPI.util.generateUID();\n window.roamAlphaAPI.createPage({\n page: { uid: parentUid, title: nanoid() },\n });\n window.roamAlphaAPI\n .createBlock({\n location: {\n \"parent-uid\": parentUid,\n order: 0,\n },\n block: { uid, string: defaultValue },\n })\n .then(() => {\n window.roamAlphaAPI.ui.components.renderBlock({\n uid,\n el,\n });\n if (autoFocus) {\n const block = el.querySelector<\n HTMLDivElement | HTMLTextAreaElement\n >(`div[id*=\"block-input\"],textarea[id*=\"block-input\"]`);\n const { windowId, blockUid } = getUids(block);\n if (blockUid)\n window.roamAlphaAPI.ui.setBlockFocusAndSelection({\n location: {\n \"block-uid\": blockUid,\n \"window-id\": windowId,\n },\n });\n }\n });\n // In the future, we can return the whole tree of data from `parentUid`\n onChange(() => getTextByBlockUid(uid));\n return () => {\n window.roamAlphaAPI.deleteBlock({ block: { uid } });\n window.roamAlphaAPI.deletePage({ page: { uid: parentUid } });\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }, [\n elRef,\n defaultValue,\n autoFocus,\n // Triggering infinite rerender\n // onChange\n ]);\n return (\n <>\n <style>{`div.rm-autocomplete__results {\nz-index: 1000;\n}`}</style>\n <div\n ref={elRef}\n className=\"rounded-md bg-white font-normal mt-1 bp3-input h-32 overflow-scroll\"\n />\n </>\n );\n};\n\nconst FormDialog = <T extends Record<string, unknown>>({\n title,\n content,\n isOpen,\n onClose,\n onSubmit = () => Promise.resolve(),\n fields = {},\n}: RoamOverlayProps<Props<T>>) => {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(\"\");\n const [data, setData] = useState<T>(\n () =>\n Object.fromEntries(\n Object.entries(fields)\n .filter(([, meta]) => typeof meta.defaultValue !== \"undefined\")\n .map(([key, meta]) => [key, meta.defaultValue])\n ) as T\n );\n const onClick = useCallback(\n () =>\n Promise.resolve(\n onSubmit(\n Object.fromEntries(\n Object.entries(data).map(\n ([key, value]) =>\n [key, typeof value === \"function\" ? value() : value] as const\n )\n ) as T\n )\n )\n .then(onClose)\n .catch((e) => {\n setError(e.message);\n setLoading(false);\n }),\n [data, onClose, setError, setLoading]\n );\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n enforceFocus={!title}\n autoFocus={!title}\n >\n <div className={Classes.DIALOG_BODY}>\n {content}\n {Object.entries(fields).map(([name, meta], index) => {\n if (meta.type === \"text\") {\n return (\n <Label>\n {meta.label}\n <InputGroup\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: e.target.value,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"number\") {\n return (\n <Label>\n {meta.label}\n <NumericInput\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: e.target.value,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"flag\") {\n return (\n <Checkbox\n label={meta.label}\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: (e.target as HTMLInputElement).checked,\n })\n }\n autoFocus={index === 0}\n />\n );\n } else if (meta.type === \"select\") {\n return (\n <Label>\n {meta.label}\n <MenuItemSelect\n activeItem={data[name] as string}\n onItemSelect={(e) =>\n setData({\n ...data,\n [name]: e,\n })\n }\n items={meta.options || []}\n ButtonProps={{\n autoFocus: index === 0,\n }}\n />\n </Label>\n );\n } else if (meta.type === \"page\") {\n return (\n <Label>\n {meta.label}\n <PageInput\n value={data[name] as string}\n setValue={(e) =>\n setData({\n ...data,\n [name]: e,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"block\") {\n return (\n <Label>\n {meta.label}\n <BlockInput\n value={\n getTextByBlockUid(data[name] as string) ||\n (data[name] as string)\n }\n setValue={(text, uid) =>\n setData({\n ...data,\n [name]: window.roamAlphaAPI.pull(\"[:db/id]\", [\n \":block/uid\",\n uid || \"\",\n ])\n ? uid\n : text,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"embed\") {\n return (\n <Label>\n {meta.label}\n <EmbedInput\n defaultValue={meta.defaultValue}\n onChange={(value) => {\n setData({\n ...data,\n [name]: value,\n });\n }}\n autoFocus={index === 0}\n />\n </Label>\n );\n } else {\n return <></>;\n }\n })}\n </div>\n <div className={Classes.DIALOG_FOOTER}>\n <div className={Classes.DIALOG_FOOTER_ACTIONS}>\n <span className=\"text-red-700\">{error}</span>\n <Button text={\"Cancel\"} onClick={onClose} disabled={loading} />\n <Button\n text={\"Submit\"}\n intent={Intent.PRIMARY}\n onClick={onClick}\n disabled={loading}\n />\n </div>\n </div>\n </Dialog>\n );\n};\n\nexport const render = createOverlayRender<Props<Record<string, unknown>>>(\n \"form-dialog\",\n FormDialog\n);\n\nexport const prompt = ({\n defaultAnswer,\n question,\n title,\n}: {\n title: string;\n question: string;\n defaultAnswer: string;\n}) =>\n new Promise<string>((resolve) =>\n render({\n onSubmit: (data) => resolve(data.value as string),\n fields: { value: { type: \"text\", defaultValue: defaultAnswer } },\n title,\n content: (\n <div className=\"whitespace-pre-wrap font-semibold text-lg mb-4\">\n {question}\n </div>\n ),\n })\n );\n\nexport default FormDialog;\n"]}
1
+ {"version":3,"file":"FormDialog.js","sourceRoot":"","sources":["../../src/components/FormDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n Checkbox,\n Classes,\n Dialog,\n InputGroup,\n Intent,\n Label,\n NumericInput,\n Spinner,\n SpinnerSize,\n} from \"@blueprintjs/core\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport getTextByBlockUid from \"../queries/getTextByBlockUid\";\nimport createOverlayRender from \"../util/createOverlayRender\";\nimport type { RoamOverlayProps } from \"../util/renderOverlay\";\nimport BlockInput from \"./BlockInput\";\nimport MenuItemSelect from \"./MenuItemSelect\";\nimport PageInput from \"./PageInput\";\nimport nanoid from \"nanoid\";\nimport { getUids } from \"../dom\";\nimport { InputTextNode } from \"../types\";\nimport getFullTreeByParentUid from \"../queries/getFullTreeByParentUid\";\nimport createPage from \"../writes/createPage\";\n\ntype Props<T> = {\n title?: React.ReactNode;\n content?: React.ReactNode;\n onSubmit?: (data: T) => Promise<unknown> | unknown;\n fields?: Record<\n string,\n (\n | {\n defaultValue?: string;\n type: \"text\";\n }\n | {\n defaultValue?: number;\n type: \"number\";\n }\n | {\n defaultValue?: string;\n type: \"select\";\n options?: string[];\n }\n | {\n defaultValue?: string;\n type: \"page\";\n }\n | {\n defaultValue?: string;\n type: \"block\";\n }\n | {\n defaultValue?: boolean;\n type: \"flag\";\n }\n | {\n defaultValue?: InputTextNode[];\n type: \"embed\";\n }\n ) & { label?: string; conditional?: string }\n >;\n};\n\nconst EmbedInput = ({\n defaultValue,\n onChange,\n autoFocus,\n}: {\n defaultValue?: InputTextNode[];\n onChange: (s: () => InputTextNode[]) => void;\n autoFocus: boolean;\n}) => {\n const defaultEmbed = useMemo(() => defaultValue || [], [defaultValue]);\n const elRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = elRef.current;\n if (el) {\n const uid = window.roamAlphaAPI.util.generateUID();\n const parentUid = window.roamAlphaAPI.util.generateUID();\n createPage({\n uid: parentUid,\n title: nanoid(),\n tree: defaultEmbed,\n }).then(() => {\n window.roamAlphaAPI.ui.components.renderPage({\n uid: parentUid,\n el,\n hideMentions: true,\n });\n if (autoFocus) {\n const block = el.querySelector<HTMLDivElement | HTMLTextAreaElement>(\n `div[id*=\"block-input\"],textarea[id*=\"block-input\"]`\n );\n const { windowId, blockUid } = getUids(block);\n if (blockUid)\n window.roamAlphaAPI.ui.setBlockFocusAndSelection({\n location: {\n \"block-uid\": blockUid,\n \"window-id\": windowId,\n },\n });\n }\n });\n // In the future, we can return the whole tree of data from `parentUid`\n onChange(() => getFullTreeByParentUid(parentUid).children);\n return () => {\n window.roamAlphaAPI.deleteBlock({ block: { uid } });\n window.roamAlphaAPI.deletePage({ page: { uid: parentUid } });\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }, [\n elRef,\n defaultEmbed,\n autoFocus,\n // Triggering infinite rerender\n // onChange\n ]);\n return (\n <>\n <style>{`div.rm-autocomplete__results {\n z-index: 1000;\n}\n.roamjs-form-embed div div:has(> h1.rm-title-display),\n.roamjs-form-embed .rm-api-render--page > div:has(.rm-reference-main) {\n display: none;\n}`}</style>\n <div\n ref={elRef}\n className=\"rounded-md bg-white font-normal mt-1 bp3-input h-32 overflow-scroll roamjs-form-embed py-2 px-4\"\n />\n </>\n );\n};\n\nconst FormDialog = <T extends Record<string, unknown>>({\n title,\n content,\n isOpen,\n onClose,\n onSubmit = () => Promise.resolve(),\n fields = {},\n}: RoamOverlayProps<Props<T>>) => {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(\"\");\n const [data, setData] = useState<T>(\n () =>\n Object.fromEntries(\n Object.entries(fields)\n .filter(([, meta]) => typeof meta.defaultValue !== \"undefined\")\n .map(([key, meta]) => [key, meta.defaultValue])\n ) as T\n );\n const onClick = useCallback(\n () =>\n Promise.resolve(\n onSubmit(\n Object.fromEntries(\n Object.entries(data)\n .filter(([key]) => {\n const { conditional } = fields[key];\n return !conditional || !!data[conditional];\n })\n .map(\n ([key, value]) =>\n [key, typeof value === \"function\" ? value() : value] as const\n )\n ) as T\n )\n )\n .then(onClose)\n .catch((e) => {\n setError(e.message);\n setLoading(false);\n }),\n [data, onClose, setError, setLoading]\n );\n return (\n <Dialog\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n enforceFocus={!title}\n autoFocus={!title}\n >\n <div className={Classes.DIALOG_BODY}>\n {content}\n {Object.entries(fields).map(([name, meta], index) => {\n if (meta.conditional && !data[meta.conditional]) {\n return <div key={name} />;\n }\n if (meta.type === \"text\") {\n return (\n <Label key={name}>\n {meta.label}\n <InputGroup\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: e.target.value,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"number\") {\n return (\n <Label key={name}>\n {meta.label}\n <NumericInput\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: e.target.value,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"flag\") {\n return (\n <Checkbox\n label={meta.label}\n value={data[name] as string}\n onChange={(e) =>\n setData({\n ...data,\n [name]: (e.target as HTMLInputElement).checked,\n })\n }\n key={name}\n autoFocus={index === 0}\n />\n );\n } else if (meta.type === \"select\") {\n return (\n <Label key={name}>\n {meta.label}\n <MenuItemSelect\n activeItem={data[name] as string}\n onItemSelect={(e) =>\n setData({\n ...data,\n [name]: e,\n })\n }\n items={meta.options || []}\n ButtonProps={{\n autoFocus: index === 0,\n }}\n />\n </Label>\n );\n } else if (meta.type === \"page\") {\n return (\n <Label key={name}>\n {meta.label}\n <PageInput\n key={name}\n value={data[name] as string}\n setValue={(e) =>\n setData({\n ...data,\n [name]: e,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"block\") {\n return (\n <Label key={name}>\n {meta.label}\n <BlockInput\n value={\n getTextByBlockUid(data[name] as string) ||\n (data[name] as string)\n }\n setValue={(text, uid) =>\n setData({\n ...data,\n [name]: window.roamAlphaAPI.pull(\"[:db/id]\", [\n \":block/uid\",\n uid || \"\",\n ])\n ? uid\n : text,\n })\n }\n autoFocus={index === 0}\n />\n </Label>\n );\n } else if (meta.type === \"embed\") {\n return (\n <Label key={name}>\n {meta.label}\n <EmbedInput\n defaultValue={meta.defaultValue}\n onChange={(value) => {\n setData({\n ...data,\n [name]: value,\n });\n }}\n autoFocus={index === 0}\n />\n </Label>\n );\n } else {\n return <div key={name} />;\n }\n })}\n </div>\n <div className={Classes.DIALOG_FOOTER}>\n <div className={`${Classes.DIALOG_FOOTER_ACTIONS} items-center`}>\n {loading && <Spinner size={SpinnerSize.SMALL} />}\n <span className=\"text-red-700\">{error}</span>\n <Button\n text={\"Cancel\"}\n onClick={onClose}\n disabled={loading}\n className=\"flex-shrink-0\"\n />\n <Button\n text={\"Submit\"}\n intent={Intent.PRIMARY}\n onClick={onClick}\n disabled={loading}\n className=\"flex-shrink-0\"\n />\n </div>\n </div>\n </Dialog>\n );\n};\n\nexport const render = createOverlayRender<Props<Record<string, unknown>>>(\n \"form-dialog\",\n FormDialog\n);\n\nexport const prompt = ({\n defaultAnswer,\n question,\n title,\n}: {\n title: string;\n question: string;\n defaultAnswer: string;\n}) =>\n new Promise<string>((resolve) =>\n render({\n onSubmit: (data) => resolve(data.value as string),\n fields: { value: { type: \"text\", defaultValue: defaultAnswer } },\n title,\n content: (\n <div className=\"whitespace-pre-wrap font-semibold text-lg mb-4\">\n {question}\n </div>\n ),\n })\n );\n\nexport default FormDialog;\n"]}
package/components.js CHANGED
@@ -50,18 +50,24 @@ const components = [
50
50
  react_1.default.createElement(FormDialog_1.default, { isOpen: isOpen, onClose: () => setIsOpen(false), onSubmit: (data) => window.roamAlphaAPI.ui.mainWindow
51
51
  .getOpenPageOrBlockUid()
52
52
  .then((parentUid) => (0, writes_1.createBlock)({
53
- parentUid: parentUid || "",
53
+ parentUid: parentUid ||
54
+ window.roamAlphaAPI.util.dateToPageUid(new Date()),
54
55
  node: {
55
56
  text: "Response",
56
57
  children: Object.entries(data).map(([k, v]) => ({
57
58
  text: k,
58
- children: [{ text: `${v}` }],
59
+ children: Array.isArray(v) ? v : [{ text: `${v}` }],
59
60
  })),
60
61
  },
61
62
  })), fields: {
62
63
  text: { type: "text", label: "Text Field" },
63
64
  number: { type: "number", label: "Number Field" },
64
65
  flag: { type: "flag", label: "Flag Field" },
66
+ conditionalText: {
67
+ type: "text",
68
+ label: "Conditional Text Field",
69
+ conditional: "flag",
70
+ },
65
71
  page: { type: "page", label: "Page Field" },
66
72
  block: { type: "block", label: "Block Field" },
67
73
  select: {
package/components.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"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","sourcesContent":["import ReactDOM from \"react-dom\";\nimport React, { useState, useMemo } from \"react\";\nimport { Button } from \"@blueprintjs/core\";\n\nimport AutocompleteInput from \"./components/AutocompleteInput\";\nimport FormDialog from \"./components/FormDialog\";\nimport PageInput from \"./components/PageInput\";\nimport renderToast from \"./components/Toast\";\n\nimport renderOverlay from \"./util/renderOverlay\";\nimport runExtension from \"./util/runExtension\";\n\nimport { createBlock } from \"./writes\";\n\n// const blockRender = (Component: React.FC) => {\n// const block = window.roamAlphaAPI.ui.getFocusedBlock();\n// const parent = document.getElementById(\n// `block-input-${block?.[\"window-id\"]}-${block?.[\"block-uid\"]}`\n// );\n// ReactDOM.render(<Component />, parent);\n// };\n\nconst unloads = new Set<() => void>();\n\nconst rootRender = (Component: React.FC) => {\n const root = document.querySelector(\".roam-article\");\n const parent = document.createElement(\"div\");\n root?.insertBefore(parent, root.firstElementChild);\n ReactDOM.render(<Component />, parent);\n unloads.add(() => {\n ReactDOM.unmountComponentAtNode(parent);\n parent.remove();\n });\n};\n\nconst components = [\n {\n callback: () =>\n rootRender(() => {\n const [value, setValue] = useState(\"\");\n const options = useMemo(() => [\"apple\", \"banana\", \"orange\"], []);\n return (\n <>\n <AutocompleteInput\n value={value}\n setValue={setValue}\n options={options}\n />\n <div>Chosen value: {value}</div>\n </>\n );\n }),\n label: \"AutocompleteInput\",\n },\n {\n callback: () =>\n rootRender(() => {\n const [isOpen, setIsOpen] = useState(false);\n return (\n <>\n <Button onClick={() => setIsOpen(true)} text={\"Open Form\"} />\n <FormDialog\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n onSubmit={(data) =>\n window.roamAlphaAPI.ui.mainWindow\n .getOpenPageOrBlockUid()\n .then((parentUid) =>\n createBlock({\n parentUid: parentUid || \"\",\n node: {\n text: \"Response\",\n children: Object.entries(data).map(([k, v]) => ({\n text: k,\n children: [{ text: `${v}` }],\n })),\n },\n })\n )\n }\n fields={{\n text: { type: \"text\", label: \"Text Field\" },\n number: { type: \"number\", label: \"Number Field\" },\n flag: { type: \"flag\", label: \"Flag Field\" },\n page: { type: \"page\", label: \"Page Field\" },\n block: { type: \"block\", label: \"Block Field\" },\n select: {\n type: \"select\",\n label: \"Select Field\",\n options: [\"apple\", \"banana\", \"orange\"],\n },\n embed: {\n type: \"embed\",\n label: \"Embed Field\",\n },\n }}\n />\n </>\n );\n }),\n label: \"FormDialog\",\n },\n {\n callback: () =>\n rootRender(() => {\n const [value, setValue] = useState(\"\");\n const [multiline, setMultiline] = useState(false);\n return (\n <>\n <PageInput\n value={value}\n setValue={setValue}\n multiline={multiline}\n />\n <input\n className=\"ml-8 inline-block\"\n checked={multiline}\n onChange={(e) => setMultiline(e.target.checked)}\n type={\"checkbox\"}\n />\n </>\n );\n }),\n label: \"PageInput\",\n },\n];\n\nexport default runExtension({\n extensionId: \"components\",\n run: (args) => {\n components.forEach(({ callback, label }) => {\n args.extensionAPI.ui.commandPalette.addCommand({\n label: `Render RoamJS component ${label}`,\n callback,\n });\n });\n window.roamjs.extension.developer = {\n components: {\n AutocompleteInput,\n FormDialog,\n PageInput,\n renderToast,\n },\n util: {\n renderOverlay,\n runExtension,\n },\n args,\n };\n return () => {\n unloads.forEach((unload) => unload());\n };\n },\n});\n"]}
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"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","sourcesContent":["import ReactDOM from \"react-dom\";\nimport React, { useState, useMemo } from \"react\";\nimport { Button } from \"@blueprintjs/core\";\n\nimport AutocompleteInput from \"./components/AutocompleteInput\";\nimport FormDialog from \"./components/FormDialog\";\nimport PageInput from \"./components/PageInput\";\nimport renderToast from \"./components/Toast\";\n\nimport renderOverlay from \"./util/renderOverlay\";\nimport runExtension from \"./util/runExtension\";\n\nimport { createBlock } from \"./writes\";\n\n// const blockRender = (Component: React.FC) => {\n// const block = window.roamAlphaAPI.ui.getFocusedBlock();\n// const parent = document.getElementById(\n// `block-input-${block?.[\"window-id\"]}-${block?.[\"block-uid\"]}`\n// );\n// ReactDOM.render(<Component />, parent);\n// };\n\nconst unloads = new Set<() => void>();\n\nconst rootRender = (Component: React.FC) => {\n const root = document.querySelector(\".roam-article\");\n const parent = document.createElement(\"div\");\n root?.insertBefore(parent, root.firstElementChild);\n ReactDOM.render(<Component />, parent);\n unloads.add(() => {\n ReactDOM.unmountComponentAtNode(parent);\n parent.remove();\n });\n};\n\nconst components = [\n {\n callback: () =>\n rootRender(() => {\n const [value, setValue] = useState(\"\");\n const options = useMemo(() => [\"apple\", \"banana\", \"orange\"], []);\n return (\n <>\n <AutocompleteInput\n value={value}\n setValue={setValue}\n options={options}\n />\n <div>Chosen value: {value}</div>\n </>\n );\n }),\n label: \"AutocompleteInput\",\n },\n {\n callback: () =>\n rootRender(() => {\n const [isOpen, setIsOpen] = useState(false);\n return (\n <>\n <Button onClick={() => setIsOpen(true)} text={\"Open Form\"} />\n <FormDialog\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n onSubmit={(data) =>\n window.roamAlphaAPI.ui.mainWindow\n .getOpenPageOrBlockUid()\n .then((parentUid) =>\n createBlock({\n parentUid:\n parentUid ||\n window.roamAlphaAPI.util.dateToPageUid(new Date()),\n node: {\n text: \"Response\",\n children: Object.entries(data).map(([k, v]) => ({\n text: k,\n children: Array.isArray(v) ? v : [{ text: `${v}` }],\n })),\n },\n })\n )\n }\n fields={{\n text: { type: \"text\", label: \"Text Field\" },\n number: { type: \"number\", label: \"Number Field\" },\n flag: { type: \"flag\", label: \"Flag Field\" },\n conditionalText: {\n type: \"text\",\n label: \"Conditional Text Field\",\n conditional: \"flag\",\n },\n page: { type: \"page\", label: \"Page Field\" },\n block: { type: \"block\", label: \"Block Field\" },\n select: {\n type: \"select\",\n label: \"Select Field\",\n options: [\"apple\", \"banana\", \"orange\"],\n },\n embed: {\n type: \"embed\",\n label: \"Embed Field\",\n },\n }}\n />\n </>\n );\n }),\n label: \"FormDialog\",\n },\n {\n callback: () =>\n rootRender(() => {\n const [value, setValue] = useState(\"\");\n const [multiline, setMultiline] = useState(false);\n return (\n <>\n <PageInput\n value={value}\n setValue={setValue}\n multiline={multiline}\n />\n <input\n className=\"ml-8 inline-block\"\n checked={multiline}\n onChange={(e) => setMultiline(e.target.checked)}\n type={\"checkbox\"}\n />\n </>\n );\n }),\n label: \"PageInput\",\n },\n];\n\nexport default runExtension({\n extensionId: \"components\",\n run: (args) => {\n components.forEach(({ callback, label }) => {\n args.extensionAPI.ui.commandPalette.addCommand({\n label: `Render RoamJS component ${label}`,\n callback,\n });\n });\n window.roamjs.extension.developer = {\n components: {\n AutocompleteInput,\n FormDialog,\n PageInput,\n renderToast,\n },\n util: {\n renderOverlay,\n runExtension,\n },\n args,\n };\n return () => {\n unloads.forEach((unload) => unload());\n };\n },\n});\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "roamjs-components",
3
3
  "description": "Expansive toolset, utilities, & components for developing RoamJS extensions.",
4
- "version": "0.78.7",
4
+ "version": "0.78.9",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
7
  "scripts": {
@@ -7,6 +7,7 @@ const ExtensionApiContext_1 = tslib_1.__importDefault(require("../components/Ext
7
7
  const dispatchToRegistry_1 = tslib_1.__importDefault(require("./dispatchToRegistry"));
8
8
  const removeFromRegistry_1 = tslib_1.__importDefault(require("./removeFromRegistry"));
9
9
  const renderWithUnmount = (el, p, args) => {
10
+ const oldChildren = p.children;
10
11
  react_dom_1.default.render(react_1.default.createElement(ExtensionApiContext_1.default, args, el), p);
11
12
  const unmount = (observer) => {
12
13
  observer.disconnect();
@@ -15,6 +16,9 @@ const renderWithUnmount = (el, p, args) => {
15
16
  reactRoots: [p],
16
17
  observers: [observer],
17
18
  });
19
+ if (oldChildren.length && document.body.contains(p)) {
20
+ Array.from(oldChildren).forEach((c) => p.appendChild(c));
21
+ }
18
22
  };
19
23
  const unmountObserver = new MutationObserver((ms, observer) => {
20
24
  const parentRemoved = ms
@@ -1 +1 @@
1
- {"version":3,"file":"renderWithUnmount.js","sourceRoot":"","sources":["../../src/util/renderWithUnmount.ts"],"names":[],"mappings":";;;AAAA,0DAA0B;AAC1B,kEAAiC;AACjC,oGAA4E;AAE5E,sFAAsD;AACtD,sFAAsD;AAEtD,MAAM,iBAAiB,GAAG,CACxB,EAAsB,EACtB,CAAc,EACd,IAAiB,EACH,EAAE;IAChB,mBAAQ,CAAC,MAAM,CACb,eAAK,CAAC,aAAa,CAAC,6BAA2B,EAAE,IAAI,EAAE,EAAE,CAAC,EAC1D,CAAC,CACF,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,QAA0B,EAAE,EAAE;QAC7C,QAAQ,CAAC,UAAU,EAAE,CAAC;QACtB,mBAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACnC,IAAA,4BAAkB,EAAC;YACjB,UAAU,EAAE,CAAC,CAAC,CAAC;YACf,SAAS,EAAE,CAAC,QAAQ,CAAC;SACtB,CAAC,CAAC;IACL,CAAC,CAAC;IACF,MAAM,eAAe,GAAG,IAAI,gBAAgB,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;QAC5D,MAAM,aAAa,GAAG,EAAE;aACrB,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;aAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,aAAa,EAAE;YACjB,OAAO,CAAC,QAAQ,CAAC,CAAC;SACnB;IACH,CAAC,CAAC,CAAC;IACH,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,IAAA,4BAAkB,EAAC;QACjB,UAAU,EAAE,CAAC,CAAC,CAAC;QACf,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,kBAAe,iBAAiB,CAAC","sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport ExtensionApiContextProvider from \"../components/ExtensionApiContext\";\nimport { OnloadArgs } from \"../types\";\nimport dispatchToRegistry from \"./dispatchToRegistry\";\nimport removeFromRegistry from \"./removeFromRegistry\";\n\nconst renderWithUnmount = (\n el: React.ReactElement,\n p: HTMLElement,\n args?: OnloadArgs\n): (() => void) => {\n ReactDOM.render(\n React.createElement(ExtensionApiContextProvider, args, el),\n p\n );\n const unmount = (observer: MutationObserver) => {\n observer.disconnect();\n ReactDOM.unmountComponentAtNode(p);\n removeFromRegistry({\n reactRoots: [p],\n observers: [observer],\n });\n };\n const unmountObserver = new MutationObserver((ms, observer) => {\n const parentRemoved = ms\n .flatMap((m) => Array.from(m.removedNodes))\n .some((n) => n === p || n.contains(p));\n if (parentRemoved) {\n unmount(observer);\n }\n });\n unmountObserver.observe(document.body, { childList: true, subtree: true });\n dispatchToRegistry({\n reactRoots: [p],\n observers: [unmountObserver],\n });\n return () => unmount(unmountObserver);\n};\n\nexport default renderWithUnmount;\n"]}
1
+ {"version":3,"file":"renderWithUnmount.js","sourceRoot":"","sources":["../../src/util/renderWithUnmount.ts"],"names":[],"mappings":";;;AAAA,0DAA0B;AAC1B,kEAAiC;AACjC,oGAA4E;AAE5E,sFAAsD;AACtD,sFAAsD;AAEtD,MAAM,iBAAiB,GAAG,CACxB,EAAsB,EACtB,CAAc,EACd,IAAiB,EACH,EAAE;IAChB,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC/B,mBAAQ,CAAC,MAAM,CACb,eAAK,CAAC,aAAa,CAAC,6BAA2B,EAAE,IAAI,EAAE,EAAE,CAAC,EAC1D,CAAC,CACF,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,QAA0B,EAAE,EAAE;QAC7C,QAAQ,CAAC,UAAU,EAAE,CAAC;QACtB,mBAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACnC,IAAA,4BAAkB,EAAC;YACjB,UAAU,EAAE,CAAC,CAAC,CAAC;YACf,SAAS,EAAE,CAAC,QAAQ,CAAC;SACtB,CAAC,CAAC;QACH,IAAI,WAAW,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;YACnD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;SAC1D;IACH,CAAC,CAAC;IACF,MAAM,eAAe,GAAG,IAAI,gBAAgB,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;QAC5D,MAAM,aAAa,GAAG,EAAE;aACrB,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;aAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,aAAa,EAAE;YACjB,OAAO,CAAC,QAAQ,CAAC,CAAC;SACnB;IACH,CAAC,CAAC,CAAC;IACH,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,IAAA,4BAAkB,EAAC;QACjB,UAAU,EAAE,CAAC,CAAC,CAAC;QACf,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,kBAAe,iBAAiB,CAAC","sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport ExtensionApiContextProvider from \"../components/ExtensionApiContext\";\nimport { OnloadArgs } from \"../types\";\nimport dispatchToRegistry from \"./dispatchToRegistry\";\nimport removeFromRegistry from \"./removeFromRegistry\";\n\nconst renderWithUnmount = (\n el: React.ReactElement,\n p: HTMLElement,\n args?: OnloadArgs\n): (() => void) => {\n const oldChildren = p.children;\n ReactDOM.render(\n React.createElement(ExtensionApiContextProvider, args, el),\n p\n );\n const unmount = (observer: MutationObserver) => {\n observer.disconnect();\n ReactDOM.unmountComponentAtNode(p);\n removeFromRegistry({\n reactRoots: [p],\n observers: [observer],\n });\n if (oldChildren.length && document.body.contains(p)) {\n Array.from(oldChildren).forEach((c) => p.appendChild(c));\n }\n };\n const unmountObserver = new MutationObserver((ms, observer) => {\n const parentRemoved = ms\n .flatMap((m) => Array.from(m.removedNodes))\n .some((n) => n === p || n.contains(p));\n if (parentRemoved) {\n unmount(observer);\n }\n });\n unmountObserver.observe(document.body, { childList: true, subtree: true });\n dispatchToRegistry({\n reactRoots: [p],\n observers: [unmountObserver],\n });\n return () => unmount(unmountObserver);\n};\n\nexport default renderWithUnmount;\n"]}