@gravity-ui/markdown-editor 15.29.0 → 15.31.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/build/cjs/core/types/serializer.d.ts +5 -0
- package/build/cjs/core/types/serializer.js.map +1 -1
- package/build/cjs/extensions/behavior/Search/SearchViewPlugin.js +24 -0
- package/build/cjs/extensions/behavior/Search/SearchViewPlugin.js.map +1 -1
- package/build/cjs/extensions/markdown/Breaks/index.d.ts +2 -0
- package/build/cjs/extensions/markdown/Breaks/index.js +7 -4
- package/build/cjs/extensions/markdown/Breaks/index.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.d.ts +9 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/const.d.ts +2 -1
- package/build/cjs/extensions/markdown/CodeBlock/const.js +6 -1
- package/build/cjs/extensions/markdown/CodeBlock/const.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/index.d.ts +1 -2
- package/build/cjs/extensions/markdown/CodeBlock/index.js +5 -7
- package/build/cjs/extensions/markdown/CodeBlock/index.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +3 -0
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.js +5 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +2 -6
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/parser.js +27 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/parser.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +8 -2
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +3 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +14 -2
- package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/index.css +5 -9
- package/build/cjs/extensions/yfm/Checkbox/index.d.ts +8 -1
- package/build/cjs/extensions/yfm/Checkbox/index.js +1 -1
- package/build/cjs/extensions/yfm/Checkbox/index.js.map +1 -1
- package/build/cjs/extensions/yfm/Checkbox/plugin.d.ts +5 -1
- package/build/cjs/extensions/yfm/Checkbox/plugin.js +8 -3
- package/build/cjs/extensions/yfm/Checkbox/plugin.js.map +1 -1
- package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +5 -1
- package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
- package/build/cjs/markup/codemirror/search-plugin/plugin.js +10 -0
- package/build/cjs/markup/codemirror/search-plugin/plugin.js.map +1 -1
- package/build/cjs/modules/search/components/SearchPopup.d.ts +2 -0
- package/build/cjs/modules/search/components/SearchPopup.js +11 -2
- package/build/cjs/modules/search/components/SearchPopup.js.map +1 -1
- package/build/cjs/modules/search/components/hooks/useObserveIntersection.d.ts +10 -0
- package/build/cjs/modules/search/components/hooks/useObserveIntersection.js +44 -0
- package/build/cjs/modules/search/components/hooks/useObserveIntersection.js.map +1 -0
- package/build/cjs/react-utils/hooks/useRAF.d.ts +1 -0
- package/build/cjs/react-utils/hooks/useRAF.js +24 -0
- package/build/cjs/react-utils/hooks/useRAF.js.map +1 -0
- package/build/cjs/react-utils/useSticky.js +3 -12
- package/build/cjs/react-utils/useSticky.js.map +1 -1
- package/build/cjs/utils/dom.d.ts +3 -0
- package/build/cjs/utils/dom.js +32 -0
- package/build/cjs/utils/dom.js.map +1 -0
- package/build/cjs/version.js +1 -1
- package/build/cjs/version.js.map +1 -1
- package/build/esm/core/types/serializer.d.ts +5 -0
- package/build/esm/core/types/serializer.js.map +1 -1
- package/build/esm/extensions/behavior/Search/SearchViewPlugin.js +25 -1
- package/build/esm/extensions/behavior/Search/SearchViewPlugin.js.map +1 -1
- package/build/esm/extensions/markdown/Breaks/index.d.ts +2 -0
- package/build/esm/extensions/markdown/Breaks/index.js +7 -5
- package/build/esm/extensions/markdown/Breaks/index.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.d.ts +9 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/const.d.ts +2 -1
- package/build/esm/extensions/markdown/CodeBlock/const.js +5 -0
- package/build/esm/extensions/markdown/CodeBlock/const.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/index.d.ts +1 -2
- package/build/esm/extensions/markdown/CodeBlock/index.js +3 -5
- package/build/esm/extensions/markdown/CodeBlock/index.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +3 -0
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.js +4 -0
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +2 -6
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/parser.js +28 -2
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/parser.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +8 -2
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +3 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +14 -2
- package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/index.css +5 -9
- package/build/esm/extensions/yfm/Checkbox/index.d.ts +8 -1
- package/build/esm/extensions/yfm/Checkbox/index.js +1 -1
- package/build/esm/extensions/yfm/Checkbox/index.js.map +1 -1
- package/build/esm/extensions/yfm/Checkbox/plugin.d.ts +5 -1
- package/build/esm/extensions/yfm/Checkbox/plugin.js +8 -3
- package/build/esm/extensions/yfm/Checkbox/plugin.js.map +1 -1
- package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +5 -1
- package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
- package/build/esm/markup/codemirror/search-plugin/plugin.js +10 -0
- package/build/esm/markup/codemirror/search-plugin/plugin.js.map +1 -1
- package/build/esm/modules/search/components/SearchPopup.d.ts +2 -0
- package/build/esm/modules/search/components/SearchPopup.js +11 -2
- package/build/esm/modules/search/components/SearchPopup.js.map +1 -1
- package/build/esm/modules/search/components/hooks/useObserveIntersection.d.ts +10 -0
- package/build/esm/modules/search/components/hooks/useObserveIntersection.js +41 -0
- package/build/esm/modules/search/components/hooks/useObserveIntersection.js.map +1 -0
- package/build/esm/react-utils/hooks/useRAF.d.ts +1 -0
- package/build/esm/react-utils/hooks/useRAF.js +21 -0
- package/build/esm/react-utils/hooks/useRAF.js.map +1 -0
- package/build/esm/react-utils/useSticky.js +3 -12
- package/build/esm/react-utils/useSticky.js.map +1 -1
- package/build/esm/utils/dom.d.ts +3 -0
- package/build/esm/utils/dom.js +27 -0
- package/build/esm/utils/dom.js.map +1 -0
- package/build/esm/version.js +1 -1
- package/build/esm/version.js.map +1 -1
- package/build/styles.css +5 -9
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/schema.ts"],"names":[],"mappings":";;;AAAA,yDAAuE;AAIvE,sCAA4F;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/schema.ts"],"names":[],"mappings":"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","sourcesContent":["import {Fragment, type NodeSpec, type Schema} from 'prosemirror-model';\n\nimport type {PlaceholderOptions} from 'src/utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode, b, checkboxInputType, checkboxLabelType} from './const';\n\nconst DEFAULT_LABEL_PLACEHOLDER = 'Checkbox';\n\nexport type GetSchemaSpecsOptions = {\n multiline?: boolean;\n /**\n * @deprecated use placeholder option in BehaviorPreset instead.\n */\n checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];\n};\n\nexport const getSchemaSpecs = (\n opts?: GetSchemaSpecsOptions,\n placeholder?: PlaceholderOptions,\n): Record<CheckboxNode, NodeSpec> => ({\n [CheckboxNode.Checkbox]: {\n group: 'block checkbox',\n content: `${CheckboxNode.Input} ${CheckboxNode.Label}`,\n selectable: true,\n allowSelection: false,\n attrs: {\n [CheckboxAttr.Class]: {default: b(null, 'checkbox')},\n [CheckboxAttr.Line]: {default: null},\n ...(opts?.multiline ? {[CheckboxAttr.Tight]: {default: null}} : undefined),\n },\n parseDOM: [\n {\n tag: 'div.checkbox',\n priority: 100,\n getContent(node, schema) {\n if (node instanceof HTMLElement) {\n const input = node.querySelector<HTMLInputElement>('input[type=checkbox]');\n\n if (input && input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(\n schema,\n input.checked,\n label?.textContent,\n );\n }\n }\n return Fragment.empty;\n },\n },\n {\n tag: 'input[type=checkbox]',\n priority: 50,\n getContent(input, schema) {\n if (input instanceof HTMLInputElement) {\n const label = findLabelForInput(input);\n return createCheckboxFragment(schema, input.checked, label?.textContent);\n }\n return Fragment.empty;\n },\n },\n ],\n toDOM(node) {\n return ['div', node.attrs, 0];\n },\n complex: 'root',\n },\n\n [CheckboxNode.Input]: {\n group: 'block checkbox',\n parseDOM: [],\n attrs: {\n [CheckboxAttr.Type]: {default: 'checkbox'},\n [CheckboxAttr.Id]: {default: null},\n [CheckboxAttr.Checked]: {default: null},\n },\n toDOM(node) {\n return ['div', node.attrs];\n },\n selectable: false,\n allowSelection: false,\n complex: 'leaf',\n },\n\n [CheckboxNode.Label]: {\n content: 'inline*',\n group: 'block checkbox',\n parseDOM: [\n {\n tag: `span[class=\"${b('label')}\"]`,\n getAttrs: (node) => ({\n [CheckboxAttr.For]: (node as Element).getAttribute(CheckboxAttr.For) || '',\n }),\n },\n {\n // input handled by checkbox node parse rule\n // ignore label\n tag: 'input[type=checkbox] ~ label',\n ignore: true,\n consuming: true,\n },\n ],\n attrs: {\n [CheckboxAttr.For]: {default: null},\n },\n escapeText: false,\n placeholder: {\n content:\n placeholder?.[CheckboxNode.Label] ??\n opts?.checkboxLabelPlaceholder ??\n DEFAULT_LABEL_PLACEHOLDER,\n alwaysVisible: true,\n },\n toDOM(node) {\n return ['span', {...node.attrs, class: b('label')}, 0];\n },\n selectable: false,\n allowSelection: false,\n disableGapCursor: true,\n canContainBreaks: Boolean(opts?.multiline),\n complex: 'leaf',\n },\n});\n\n// fallback for invalid HTML (input without id + label without for)\nfunction findNextSiblingLabel(element: HTMLInputElement): HTMLLabelElement | null {\n const nextSibling = element.nextElementSibling;\n return nextSibling instanceof HTMLLabelElement ? nextSibling : null;\n}\n\nfunction findLabelForInput(element: HTMLInputElement): HTMLLabelElement | null {\n return element.labels?.[0] || findNextSiblingLabel(element);\n}\n\nfunction createCheckboxFragment(\n schema: Schema<any, any>,\n checked: boolean | null,\n labelText: string | null | undefined,\n): Fragment {\n return Fragment.from([\n checkboxInputType(schema).create({[CheckboxAttr.Checked]: checked ? 'true' : null}),\n checkboxLabelType(schema).create(null, labelText ? schema.text(labelText) : null),\n ]);\n}\n"]}
|
|
@@ -4,9 +4,21 @@ exports.serializerTokens = void 0;
|
|
|
4
4
|
const placeholder_1 = require("../../../../utils/placeholder.js");
|
|
5
5
|
const const_1 = require("./const.js");
|
|
6
6
|
exports.serializerTokens = {
|
|
7
|
-
[const_1.CheckboxNode.Checkbox]: (state, node) => {
|
|
7
|
+
[const_1.CheckboxNode.Checkbox]: (state, node, parent, index) => {
|
|
8
8
|
state.renderInline(node);
|
|
9
|
-
|
|
9
|
+
// TODO [MAJOR]: remove this check after removing `multiline` option
|
|
10
|
+
if (!node.type.spec.attrs?.[const_1.CheckboxAttr.Tight]) {
|
|
11
|
+
state.closeBlock(node);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const tight = node.attrs[const_1.CheckboxAttr.Tight];
|
|
15
|
+
const nextIsCheckbox = parent.maybeChild(index + 1)?.type.name === const_1.CheckboxNode.Checkbox;
|
|
16
|
+
if (tight === false || !nextIsCheckbox) {
|
|
17
|
+
state.closeBlock(node);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
state.ensureNewLine();
|
|
21
|
+
}
|
|
10
22
|
},
|
|
11
23
|
[const_1.CheckboxNode.Input]: (state, node) => {
|
|
12
24
|
const checked = node.attrs[const_1.CheckboxAttr.Checked] === 'true';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/serializer.ts"],"names":[],"mappings":";;;AACA,kEAAoE;AAEpE,sCAAmD;AAEtC,QAAA,gBAAgB,GAA8C;IACvE,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Checkbox/CheckboxSpecs/serializer.ts"],"names":[],"mappings":";;;AACA,kEAAoE;AAEpE,sCAAmD;AAEtC,QAAA,gBAAgB,GAA8C;IACvE,CAAC,oBAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QACpD,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAEzB,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,oBAAY,CAAC,QAAQ,CAAC;QAEzF,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YACrC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAY,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC;QAC5D,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YAC5E,KAAK,CAAC,KAAK,CAAC,IAAA,mCAAqB,EAAC,IAAI,CAAC,CAAC,CAAC;YACzC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ,CAAC","sourcesContent":["import type {SerializerNodeToken} from '../../../../core';\nimport {getPlaceholderContent} from '../../../../utils/placeholder';\n\nimport {CheckboxAttr, CheckboxNode} from './const';\n\nexport const serializerTokens: Record<CheckboxNode, SerializerNodeToken> = {\n [CheckboxNode.Checkbox]: (state, node, parent, index) => {\n state.renderInline(node);\n\n // TODO [MAJOR]: remove this check after removing `multiline` option\n if (!node.type.spec.attrs?.[CheckboxAttr.Tight]) {\n state.closeBlock(node);\n return;\n }\n\n const tight = node.attrs[CheckboxAttr.Tight];\n const nextIsCheckbox = parent.maybeChild(index + 1)?.type.name === CheckboxNode.Checkbox;\n\n if (tight === false || !nextIsCheckbox) {\n state.closeBlock(node);\n } else {\n state.ensureNewLine();\n }\n },\n\n [CheckboxNode.Input]: (state, node) => {\n const checked = node.attrs[CheckboxAttr.Checked] === 'true';\n state.write(`[${checked ? 'X' : ' '}] `);\n },\n\n [CheckboxNode.Label]: (state, node, _, idx) => {\n if ((!node.content.size || node.textContent.trim().length === 0) && idx !== 0) {\n state.write(getPlaceholderContent(node));\n return;\n }\n\n if (!idx) {\n state.write('[ ] ');\n }\n\n state.renderInline(node);\n },\n};\n"]}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
.g-md-checkbox {
|
|
1
|
+
.yfm-editor .g-md-checkbox {
|
|
2
2
|
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
/* Increasing selector specificity to override yfm styles with zero padding */
|
|
5
3
|
}
|
|
6
|
-
.g-md-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/* stylelint-disable declaration-no-important */
|
|
11
|
-
margin-right: 5px !important;
|
|
4
|
+
.yfm-editor .g-md-checkbox__input[type=checkbox] {
|
|
5
|
+
top: 3px;
|
|
6
|
+
align-self: flex-start;
|
|
7
|
+
margin-right: 5px;
|
|
12
8
|
}
|
|
@@ -3,7 +3,14 @@ import { type CheckboxSpecsOptions } from "./CheckboxSpecs/index.js";
|
|
|
3
3
|
import "./index.css";
|
|
4
4
|
declare const checkboxAction = "addCheckbox";
|
|
5
5
|
export { CheckboxAttr, CheckboxNode, checkboxType, checkboxLabelType, checkboxInputType, } from "./CheckboxSpecs/index.js";
|
|
6
|
-
export type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {
|
|
6
|
+
export type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {
|
|
7
|
+
/**
|
|
8
|
+
* Allow multiline label in checkboxes.
|
|
9
|
+
* Available with @diplodoc/transform v4.68.0 or higher.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
multiline?: boolean;
|
|
13
|
+
};
|
|
7
14
|
export declare const Checkbox: ExtensionAuto<CheckboxOptions>;
|
|
8
15
|
declare global {
|
|
9
16
|
namespace WysiwygEditor {
|
|
@@ -22,7 +22,7 @@ const Checkbox = (builder, opts) => {
|
|
|
22
22
|
inputView: () => nodeviews_1.CheckboxInputView.create,
|
|
23
23
|
});
|
|
24
24
|
builder
|
|
25
|
-
.addPlugin(plugin_1.keymapPlugin, builder.Priority.High)
|
|
25
|
+
.addPlugin(() => (0, plugin_1.keymapPlugin)(opts), builder.Priority.High)
|
|
26
26
|
.addPlugin(fix_paste_1.fixPastePlugin)
|
|
27
27
|
.addAction(checkboxAction, () => (0, actions_1.addCheckbox)())
|
|
28
28
|
.addInputRules(({ schema }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/index.ts"],"names":[],"mappings":";;;AACA,6DAAwD;AAExD,4DAAyE;AACzE,0CAAsC;AACtC,8CAA8C;AAC9C,wCAAsC;AACtC,sDAAmD;AACnD,sCAAwD;AAExD,uBAAsB;AAEtB,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,0DAMyB;AALrB,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,kHAAA,iBAAiB,OAAA;AACjB,kHAAA,iBAAiB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/index.ts"],"names":[],"mappings":";;;AACA,6DAAwD;AAExD,4DAAyE;AACzE,0CAAsC;AACtC,8CAA8C;AAC9C,wCAAsC;AACtC,sDAAmD;AACnD,sCAAwD;AAExD,uBAAsB;AAEtB,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,0DAMyB;AALrB,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,kHAAA,iBAAiB,OAAA;AACjB,kHAAA,iBAAiB,OAAA;AAad,MAAM,QAAQ,GAAmC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtE,OAAO,CAAC,GAAG,CAAC,6BAAa,EAAE;QACvB,GAAG,IAAI;QACP,SAAS,EAAE,GAAG,EAAE,CAAC,6BAAiB,CAAC,MAAM;KAC5C,CAAC,CAAC;IAEH,OAAO;SACF,SAAS,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAY,EAAC,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC1D,SAAS,CAAC,0BAAc,CAAC;SACzB,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC;SAC9C,aAAa,CAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE;YACH,IAAA,0BAAa,EACT,eAAe,EACf,IAAA,oBAAY,EAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAC1E,CAAC,CACJ;SACJ;KACJ,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AAnBW,QAAA,QAAQ,YAmBnB","sourcesContent":["import type {Action, ExtensionAuto} from '../../../core';\nimport {nodeInputRule} from '../../../utils/inputrules';\n\nimport {CheckboxSpecs, type CheckboxSpecsOptions} from './CheckboxSpecs';\nimport {addCheckbox} from './actions';\nimport {CheckboxInputView} from './nodeviews';\nimport {keymapPlugin} from './plugin';\nimport {fixPastePlugin} from './plugins/fix-paste';\nimport {checkboxInputType, checkboxType} from './utils';\n\nimport './index.scss';\n\nconst checkboxAction = 'addCheckbox';\n\nexport {\n CheckboxAttr,\n CheckboxNode,\n checkboxType,\n checkboxLabelType,\n checkboxInputType,\n} from './CheckboxSpecs';\n\nexport type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {\n /**\n * Allow multiline label in checkboxes.\n * Available with @diplodoc/transform v4.68.0 or higher.\n * @default false\n */\n // TODO [MAJOR]: enable by default and remove option\n multiline?: boolean;\n};\n\nexport const Checkbox: ExtensionAuto<CheckboxOptions> = (builder, opts) => {\n builder.use(CheckboxSpecs, {\n ...opts,\n inputView: () => CheckboxInputView.create,\n });\n\n builder\n .addPlugin(() => keymapPlugin(opts), builder.Priority.High)\n .addPlugin(fixPastePlugin)\n .addAction(checkboxAction, () => addCheckbox())\n .addInputRules(({schema}) => ({\n rules: [\n nodeInputRule(\n /^\\[(\\s?)\\]\\s$/,\n checkboxType(schema).createAndFill({}, checkboxInputType(schema).create()),\n 2,\n ),\n ],\n }));\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Actions {\n [checkboxAction]: Action;\n }\n }\n}\n"]}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { type Command } from 'prosemirror-state';
|
|
2
2
|
export declare const splitCheckbox: (replaceWithParagraph?: boolean) => Command;
|
|
3
|
-
|
|
3
|
+
type KeymapPluginOptions = {
|
|
4
|
+
multiline?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare const keymapPlugin: (props: KeymapPluginOptions) => import("prosemirror-state").Plugin<any>;
|
|
7
|
+
export {};
|
|
@@ -6,8 +6,9 @@ const prosemirror_model_1 = require("prosemirror-model");
|
|
|
6
6
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
7
7
|
// @ts-ignore // TODO: fix cjs build
|
|
8
8
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
9
|
-
const selection_1 = require("../../../utils/selection.js");
|
|
10
9
|
const BaseSchema_1 = require("../../base/BaseSchema/index.js");
|
|
10
|
+
const Breaks_1 = require("../../markdown/Breaks/index.js");
|
|
11
|
+
const selection_1 = require("../../../utils/selection.js");
|
|
11
12
|
const utils_1 = require("./utils.js");
|
|
12
13
|
const splitCheckbox = (replaceWithParagraph) => (state, dispatch) => {
|
|
13
14
|
const { $from, $to } = state.selection;
|
|
@@ -34,6 +35,10 @@ const splitCheckbox = (replaceWithParagraph) => (state, dispatch) => {
|
|
|
34
35
|
tr.insert($from.after(), [node]);
|
|
35
36
|
tr.replace(label.start + $from.parentOffset, label.pos + label.node.nodeSize);
|
|
36
37
|
tr.setSelection(new prosemirror_state_1.TextSelection(tr.doc.resolve(tr.selection.$from.after() + (replaceWithParagraph ? 2 : 4))));
|
|
38
|
+
// remove break before cursor
|
|
39
|
+
if ((0, Breaks_1.isBreakNode)($from.nodeBefore)) {
|
|
40
|
+
tr.replaceWith($from.pos - 1, $from.pos, prosemirror_model_1.Fragment.empty);
|
|
41
|
+
}
|
|
37
42
|
dispatch?.(tr);
|
|
38
43
|
return true;
|
|
39
44
|
}
|
|
@@ -58,10 +63,10 @@ const removeCheckbox = (state, dispatch) => {
|
|
|
58
63
|
}
|
|
59
64
|
return false;
|
|
60
65
|
};
|
|
61
|
-
const keymapPlugin = () => (0, prosemirror_keymap_1.keymap)({
|
|
66
|
+
const keymapPlugin = (props) => (0, prosemirror_keymap_1.keymap)({
|
|
62
67
|
Enter: (0, exports.splitCheckbox)(),
|
|
63
68
|
Backspace: removeCheckbox,
|
|
64
|
-
'Shift-Enter': (0, exports.splitCheckbox)(true),
|
|
69
|
+
...(props.multiline ? undefined : { 'Shift-Enter': (0, exports.splitCheckbox)(true) }),
|
|
65
70
|
});
|
|
66
71
|
exports.keymapPlugin = keymapPlugin;
|
|
67
72
|
//# sourceMappingURL=plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/plugin.ts"],"names":[],"mappings":";;;AAAA,2DAA0C;AAC1C,yDAA2C;AAC3C,yDAA8D;AAC9D,oCAAoC;AACpC,yDAAuD;AAEvD,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"../../../../../src","sources":["extensions/yfm/Checkbox/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {keymap} from 'prosemirror-keymap';\nimport {Fragment} from 'prosemirror-model';\nimport {type Command, TextSelection} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {findParentNodeOfType} from 'prosemirror-utils';\n\nimport {pType} from 'src/extensions/base/BaseSchema';\nimport {isBreakNode} from 'src/extensions/markdown/Breaks';\nimport {isWholeSelection} from 'src/utils/selection';\n\nimport {checkboxInputType, checkboxLabelType, checkboxType} from './utils';\n\nexport const splitCheckbox: (replaceWithParagraph?: boolean) => Command =\n (replaceWithParagraph) => (state, dispatch) => {\n const {$from, $to} = state.selection;\n const {schema} = state;\n const label = findParentNodeOfType(checkboxLabelType(schema))(state.selection);\n\n if (!label) return false;\n\n const checkbox = findParentNodeOfType(checkboxType(schema))(state.selection);\n\n if (label.node.content.size === 0 && checkbox) {\n dispatch?.(\n state.tr\n .replaceWith(\n checkbox.pos,\n checkbox.pos + checkbox.node.nodeSize,\n pType(schema).create(),\n )\n .scrollIntoView(),\n );\n\n return true;\n }\n\n if ($from.pos === $to.pos) {\n const {tr} = state;\n\n const content = Fragment.from($from.parent.cut($from.parentOffset).content);\n\n const node = replaceWithParagraph\n ? pType(state.schema).create({}, content)\n : checkboxType(schema).create({}, [\n checkboxInputType(schema).create(),\n checkboxLabelType(schema).create({}, content),\n ]);\n\n tr.insert($from.after(), [node]);\n\n tr.replace(label.start + $from.parentOffset, label.pos + label.node.nodeSize);\n tr.setSelection(\n new TextSelection(\n tr.doc.resolve(tr.selection.$from.after() + (replaceWithParagraph ? 2 : 4)),\n ),\n );\n\n // remove break before cursor\n if (isBreakNode($from.nodeBefore)) {\n tr.replaceWith($from.pos - 1, $from.pos, Fragment.empty);\n }\n\n dispatch?.(tr);\n\n return true;\n }\n\n return false;\n };\n\nconst removeCheckbox: Command = (state, dispatch) => {\n const label = findParentNodeOfType(checkboxLabelType(state.schema))(state.selection);\n const checkbox = findParentNodeOfType(checkboxType(state.schema))(state.selection);\n\n const {selection} = state;\n const {from, to} = selection;\n\n if (!label || !checkbox) {\n return false;\n }\n\n const idx = from - label.pos - 2;\n\n if (idx < 0 && from === to && !isWholeSelection(selection)) {\n const {tr} = state;\n dispatch?.(\n tr\n .replaceWith(\n checkbox.pos,\n checkbox.pos + checkbox.node.nodeSize,\n pType(state.schema).create(null, label.node.content),\n )\n .setSelection(new TextSelection(tr.doc.resolve(state.selection.from - 2))),\n );\n return true;\n }\n\n return false;\n};\n\ntype KeymapPluginOptions = {\n multiline?: boolean;\n};\n\nexport const keymapPlugin = (props: KeymapPluginOptions) =>\n keymap({\n Enter: splitCheckbox(),\n Backspace: removeCheckbox,\n ...(props.multiline ? undefined : {'Shift-Enter': splitCheckbox(true)}),\n });\n"]}
|
|
@@ -74,6 +74,10 @@ class EmojiHandler {
|
|
|
74
74
|
}
|
|
75
75
|
onEnter(action) {
|
|
76
76
|
this.updateState(action);
|
|
77
|
+
const emojiDef = this._emojiCarousel?.currentItem;
|
|
78
|
+
if (!emojiDef) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
77
81
|
this.select();
|
|
78
82
|
return true;
|
|
79
83
|
}
|
|
@@ -182,7 +186,7 @@ function filterEmojis(defs, text) {
|
|
|
182
186
|
}
|
|
183
187
|
return byShortcuts.concat(byName);
|
|
184
188
|
}
|
|
185
|
-
const CHARS_TO_HIDE =
|
|
189
|
+
const CHARS_TO_HIDE = 1;
|
|
186
190
|
function needToHide(defs, text) {
|
|
187
191
|
let iter = 1;
|
|
188
192
|
do {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n closeAutocomplete,\n getAutocompleteState,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view} = this;\n if (!view) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const autocompleteState = getAutocompleteState(view.state);\n if (!autocompleteState || !autocompleteState.active) return;\n\n const {range} = autocompleteState;\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view}: AutocompleteAction) {\n this._view = view;\n }\n\n private clear() {\n this._view = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n closeAutocomplete,\n getAutocompleteState,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) {\n return false;\n }\n\n this.select();\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view} = this;\n if (!view) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const autocompleteState = getAutocompleteState(view.state);\n if (!autocompleteState || !autocompleteState.active) return;\n\n const {range} = autocompleteState;\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view}: AutocompleteAction) {\n this._view = view;\n }\n\n private clear() {\n this._view = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 1;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
|
|
@@ -59,6 +59,16 @@ const SearchPanelPlugin = (params) => view_1.ViewPlugin.fromClass(class {
|
|
|
59
59
|
onSearchPrev: this.handleSearchPrev,
|
|
60
60
|
onReplaceNext: this.handleReplaceNext,
|
|
61
61
|
onReplaceAll: this.handleReplaceAll,
|
|
62
|
+
intersectionTracking: {
|
|
63
|
+
container: this.view.contentDOM,
|
|
64
|
+
selector: '.cm-searchMatch-selected',
|
|
65
|
+
observerOptions: {
|
|
66
|
+
childList: true,
|
|
67
|
+
subtree: true,
|
|
68
|
+
attributes: true,
|
|
69
|
+
attributeFilter: ['class'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
62
72
|
});
|
|
63
73
|
});
|
|
64
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"../../../../../src","sources":["markup/codemirror/search-plugin/plugin.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"../../../../../src","sources":["markup/codemirror/search-plugin/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SearchQuery,\n closeSearchPanel,\n findNext,\n findPrevious,\n getSearchQuery,\n replaceAll,\n replaceNext,\n search,\n searchKeymap,\n searchPanelOpen,\n setSearchQuery,\n} from '@codemirror/search';\nimport {\n type EditorView,\n type PluginValue,\n ViewPlugin,\n type ViewUpdate,\n keymap,\n} from '@codemirror/view';\n\nimport type {MarkdownEditorMode} from 'src/bundle';\nimport type {EventMap} from 'src/bundle/Editor';\nimport type {RendererItem} from 'src/extensions';\nimport {renderSearchPopup} from 'src/modules/search';\nimport type {Receiver} from 'src/utils';\n\nimport {ReactRendererFacet} from '../react-facet';\n\nimport {searchTheme} from './theme';\n\ntype SearchQueryConfig = ConstructorParameters<typeof SearchQuery>[0];\n\nexport interface SearchPanelPluginParams {\n anchorSelector: string;\n inputDelay?: number;\n receiver?: Receiver<EventMap>;\n}\n\nexport const SearchPanelPlugin = (params: SearchPanelPluginParams) =>\n ViewPlugin.fromClass(\n class implements PluginValue {\n readonly view: EditorView;\n readonly params: SearchPanelPluginParams;\n\n renderer: RendererItem;\n receiver: Receiver<EventMap> | undefined;\n\n panelOpened: boolean;\n searchState: SearchQuery | null;\n\n constructor(view: EditorView) {\n this.view = view;\n this.params = params;\n this.receiver = params.receiver;\n\n this.panelOpened = searchPanelOpen(view.state);\n this.searchState = getSearchQuery(view.state);\n this.renderer = this.createRenderer();\n\n this.handleClose = this.handleClose.bind(this);\n this.handleChange = this.handleChange.bind(this);\n this.handleSearchNext = this.handleSearchNext.bind(this);\n this.handleSearchPrev = this.handleSearchPrev.bind(this);\n this.handleReplaceNext = this.handleReplaceNext.bind(this);\n this.handleReplaceAll = this.handleReplaceAll.bind(this);\n this.handleEditorModeChange = this.handleEditorModeChange.bind(this);\n\n this.receiver?.on('change-editor-mode', this.handleEditorModeChange);\n }\n\n update(update: ViewUpdate): void {\n const isPanelOpen = searchPanelOpen(update.state);\n const searchQuery = getSearchQuery(update.state);\n\n if (isPanelOpen !== this.panelOpened || searchQuery !== this.searchState) {\n this.panelOpened = isPanelOpen;\n this.searchState = searchQuery;\n this.renderer.rerender();\n }\n }\n\n destroy() {\n this.renderer.remove();\n this.receiver?.off('change-editor-mode', this.handleEditorModeChange);\n }\n\n createRenderer() {\n return this.view.state.facet(ReactRendererFacet).createItem('cm-search', () => {\n if (!this.panelOpened || !this.searchState) return null;\n\n const anchor = this.view.dom.ownerDocument.querySelector(\n this.params.anchorSelector,\n );\n\n if (!anchor) return null;\n\n return renderSearchPopup({\n open: true,\n anchor: anchor,\n state: this.searchState,\n onClose: this.handleClose,\n onChange: this.handleChange,\n onSearchNext: this.handleSearchNext,\n onSearchPrev: this.handleSearchPrev,\n onReplaceNext: this.handleReplaceNext,\n onReplaceAll: this.handleReplaceAll,\n intersectionTracking: {\n container: this.view.contentDOM,\n selector: '.cm-searchMatch-selected',\n observerOptions: {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n },\n },\n });\n });\n }\n\n handleEditorModeChange({mode}: {mode: MarkdownEditorMode}) {\n if (mode === 'wysiwyg') {\n closeSearchPanel(this.view);\n }\n }\n\n handleChange(config: SearchQueryConfig) {\n this.view.dispatch({\n effects: setSearchQuery.of(\n new SearchQuery({\n search: config.search,\n replace: config.replace,\n caseSensitive: config.caseSensitive,\n wholeWord: config.wholeWord,\n }),\n ),\n });\n }\n\n handleClose() {\n this.handleChange({search: ''});\n closeSearchPanel(this.view);\n this.view.focus();\n }\n\n handleSearchNext() {\n findNext(this.view);\n }\n\n handleSearchPrev() {\n findPrevious(this.view);\n }\n\n handleReplaceNext() {\n replaceNext(this.view);\n }\n\n handleReplaceAll() {\n replaceAll(this.view);\n }\n },\n {\n provide: () => [\n keymap.of(searchKeymap),\n searchTheme,\n search({\n createPanel: () => ({\n // Create an empty search panel\n dom: document.createElement('div'),\n }),\n }),\n ],\n },\n );\n"]}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type UseSearchProps } from "../hooks/use-search.js";
|
|
2
2
|
import type { SearchCounter } from "../types.js";
|
|
3
|
+
import { type UseObserveIntersectionProps } from "./hooks/useObserveIntersection.js";
|
|
3
4
|
import "./SearchPopup.css";
|
|
4
5
|
export type SearchPopupProps = UseSearchProps & {
|
|
5
6
|
open: boolean;
|
|
6
7
|
anchor: Element;
|
|
7
8
|
counter?: SearchCounter;
|
|
8
9
|
onClose: () => void;
|
|
10
|
+
intersectionTracking: Pick<UseObserveIntersectionProps, 'container' | 'selector' | 'observerOptions'>;
|
|
9
11
|
};
|
|
10
12
|
export declare const SearchPopup: React.FC<SearchPopupProps>;
|
|
11
13
|
interface SearchPopupWithRefProps extends Omit<SearchPopupProps, 'anchor'> {
|
|
@@ -3,17 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SearchPopup = void 0;
|
|
4
4
|
exports.renderSearchPopup = renderSearchPopup;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
6
7
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
8
|
const classname_1 = require("../../../classname.js");
|
|
8
9
|
const use_search_1 = require("../hooks/use-search.js");
|
|
9
10
|
const qa_1 = require("../qa.js");
|
|
10
11
|
const SearchCardView_1 = require("./SearchCardView.js");
|
|
11
12
|
const SearchCompactView_1 = require("./SearchCompactView.js");
|
|
13
|
+
const useObserveIntersection_1 = require("./hooks/useObserveIntersection.js");
|
|
12
14
|
require("./SearchPopup.css");
|
|
13
15
|
const b = (0, classname_1.cn)('search-popup');
|
|
14
|
-
const SearchPopup = ({ open, anchor, counter, onClose, ...props }) => {
|
|
16
|
+
const SearchPopup = ({ open, anchor, counter, onClose, intersectionTracking, ...props }) => {
|
|
15
17
|
const { isCompact, searchState, handlers } = (0, use_search_1.useSearch)(props);
|
|
16
|
-
|
|
18
|
+
const floatingRef = (0, react_1.useRef)(null);
|
|
19
|
+
const { intersection } = (0, useObserveIntersection_1.useObserveIntersection)({
|
|
20
|
+
floatingRef,
|
|
21
|
+
container: intersectionTracking.container,
|
|
22
|
+
selector: intersectionTracking.selector,
|
|
23
|
+
observerOptions: intersectionTracking.observerOptions,
|
|
24
|
+
});
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { open: open, qa: qa_1.SearchQA.Panel, anchorElement: anchor, placement: "bottom-end", floatingRef: floatingRef, floatingStyles: { opacity: intersection ? 0.8 : 1 }, className: b({ compact: isCompact }), onOpenChange: (_open, _event, reason) => {
|
|
17
26
|
if (reason === 'escape-key') {
|
|
18
27
|
onClose();
|
|
19
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchPopup.js","sourceRoot":"../../../../../src","sources":["modules/search/components/SearchPopup.tsx"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"SearchPopup.js","sourceRoot":"../../../../../src","sources":["modules/search/components/SearchPopup.tsx"],"names":[],"mappings":";;;AAmGA,8CAIC;;AAvGD,iCAA6B;AAE7B,6CAAwC;AAExC,qDAAiC;AAEjC,uDAAmE;AACnE,iCAA+B;AAG/B,wDAAgD;AAChD,8DAAqD;AACrD,8EAGwC;AAExC,6BAA4B;AAE5B,MAAM,CAAC,GAAG,IAAA,cAAE,EAAC,cAAc,CAAC,CAAC;AAatB,MAAM,WAAW,GAA+B,CAAC,EACpD,IAAI,EACJ,MAAM,EACN,OAAO,EACP,OAAO,EACP,oBAAoB,EACpB,GAAG,KAAK,EACX,EAAE,EAAE;IACD,MAAM,EAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAC,GAAG,IAAA,sBAAS,EAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IACjD,MAAM,EAAC,YAAY,EAAC,GAAG,IAAA,+CAAsB,EAAC;QAC1C,WAAW;QACX,SAAS,EAAE,oBAAoB,CAAC,SAAS;QACzC,QAAQ,EAAE,oBAAoB,CAAC,QAAQ;QACvC,eAAe,EAAE,oBAAoB,CAAC,eAAe;KACxD,CAAC,CAAC;IAEH,OAAO,CACH,uBAAC,aAAK,IACF,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,aAAQ,CAAC,KAAK,EAClB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAC,YAAY,EACtB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,EACjD,SAAS,EAAE,CAAC,CAAC,EAAC,OAAO,EAAE,SAAS,EAAC,CAAC,EAClC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACpC,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC1B,OAAO,EAAE,CAAC;YACd,CAAC;QACL,CAAC,YAEA,SAAS,CAAC,CAAC,CAAC,CACT,uBAAC,oCAAgB,IACb,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,WAAW,CAAC,MAAM,EACzB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAC3B,QAAQ,EAAE,QAAQ,CAAC,cAAc,EACjC,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,cAAc,EAAE,QAAQ,CAAC,cAAc,GACzC,CACL,CAAC,CAAC,CAAC,CACA,uBAAC,+BAAc,IACX,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,QAAQ,CAAC,cAAc,EACvC,mBAAmB,EAAE,QAAQ,CAAC,eAAe,EAC7C,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,cAAc,EAAE,QAAQ,CAAC,cAAc,EACvC,SAAS,EAAE,QAAQ,CAAC,SAAS,EAC7B,YAAY,EAAE,QAAQ,CAAC,YAAY,EACnC,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,EAC7C,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB,GACvD,CACL,GACG,CACX,CAAC;AACN,CAAC,CAAC;AA3DW,QAAA,WAAW,eA2DtB;AAEF,mBAAW,CAAC,WAAW,GAAG,aAAa,CAAC;AAMxC,SAAgB,iBAAiB,CAAC,EAAC,MAAM,EAAE,GAAG,KAAK,EAA0B;IACzE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO,uBAAC,mBAAW,IAAC,MAAM,EAAE,MAAM,KAAM,KAAK,GAAI,CAAC;AACtD,CAAC","sourcesContent":["import {useRef} from 'react';\n\nimport {Popup} from '@gravity-ui/uikit';\n\nimport {cn} from 'src/classname';\n\nimport {type UseSearchProps, useSearch} from '../hooks/use-search';\nimport {SearchQA} from '../qa';\nimport type {SearchCounter} from '../types';\n\nimport {SearchCardView} from './SearchCardView';\nimport {SeachCompactView} from './SearchCompactView';\nimport {\n type UseObserveIntersectionProps,\n useObserveIntersection,\n} from './hooks/useObserveIntersection';\n\nimport './SearchPopup.scss';\n\nconst b = cn('search-popup');\n\nexport type SearchPopupProps = UseSearchProps & {\n open: boolean;\n anchor: Element;\n counter?: SearchCounter;\n onClose: () => void;\n intersectionTracking: Pick<\n UseObserveIntersectionProps,\n 'container' | 'selector' | 'observerOptions'\n >;\n};\n\nexport const SearchPopup: React.FC<SearchPopupProps> = ({\n open,\n anchor,\n counter,\n onClose,\n intersectionTracking,\n ...props\n}) => {\n const {isCompact, searchState, handlers} = useSearch(props);\n const floatingRef = useRef<HTMLDivElement>(null);\n const {intersection} = useObserveIntersection({\n floatingRef,\n container: intersectionTracking.container,\n selector: intersectionTracking.selector,\n observerOptions: intersectionTracking.observerOptions,\n });\n\n return (\n <Popup\n open={open}\n qa={SearchQA.Panel}\n anchorElement={anchor}\n placement=\"bottom-end\"\n floatingRef={floatingRef}\n floatingStyles={{opacity: intersection ? 0.8 : 1}}\n className={b({compact: isCompact})}\n onOpenChange={(_open, _event, reason) => {\n if (reason === 'escape-key') {\n onClose();\n }\n }}\n >\n {isCompact ? (\n <SeachCompactView\n counter={counter}\n onClose={onClose}\n value={searchState.search}\n onExpand={handlers.onExpand}\n onChange={handlers.onSearchChange}\n onFindNext={handlers.onFindNext}\n onFindPrevious={handlers.onFindPrevious}\n />\n ) : (\n <SearchCardView\n counter={counter}\n onClose={onClose}\n searchState={searchState}\n onSearchChange={handlers.onSearchChange}\n onReplacementChange={handlers.onReplaceChange}\n onFindNext={handlers.onFindNext}\n onFindPrevious={handlers.onFindPrevious}\n onReplace={handlers.onReplace}\n onReplaceAll={handlers.onReplaceAll}\n onWholeWordChange={handlers.onWholeWordChange}\n onCaseSensitiveChange={handlers.onCaseSensitiveChange}\n />\n )}\n </Popup>\n );\n};\n\nSearchPopup.displayName = 'SearchPopup';\n\ninterface SearchPopupWithRefProps extends Omit<SearchPopupProps, 'anchor'> {\n anchor: Element | null;\n}\n\nexport function renderSearchPopup({anchor, ...props}: SearchPopupWithRefProps) {\n if (!anchor) return null;\n\n return <SearchPopup anchor={anchor} {...props} />;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type UseObserveIntersectionProps = {
|
|
2
|
+
floatingRef: React.RefObject<HTMLElement>;
|
|
3
|
+
container: Element;
|
|
4
|
+
selector: string;
|
|
5
|
+
observerOptions?: MutationObserverInit;
|
|
6
|
+
};
|
|
7
|
+
export type UseObserveIntersectionReturn = {
|
|
8
|
+
intersection: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function useObserveIntersection({ floatingRef, container, selector, observerOptions, }: UseObserveIntersectionProps): UseObserveIntersectionReturn;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useObserveIntersection = useObserveIntersection;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const react_use_1 = require("react-use");
|
|
6
|
+
const useRAF_1 = require("../../../../react-utils/hooks/useRAF.js");
|
|
7
|
+
const dom_1 = require("../../../../utils/dom.js");
|
|
8
|
+
function useObserveIntersection({ floatingRef, container, selector, observerOptions, }) {
|
|
9
|
+
const [intersection, setIntersection] = (0, react_1.useState)(false);
|
|
10
|
+
const intersectionRef = (0, react_use_1.useLatest)(intersection);
|
|
11
|
+
const updateFunction = (0, react_1.useCallback)(() => {
|
|
12
|
+
const floating = floatingRef.current;
|
|
13
|
+
const element = container.querySelector(selector);
|
|
14
|
+
if (!element || !floating) {
|
|
15
|
+
if (intersectionRef.current)
|
|
16
|
+
setIntersection(false);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const isIntersecting = (0, dom_1.areElementsIntersecting)(element, floating);
|
|
20
|
+
if (isIntersecting !== intersectionRef.current)
|
|
21
|
+
setIntersection(isIntersecting);
|
|
22
|
+
}, [container, floatingRef, intersectionRef, selector]);
|
|
23
|
+
const observer = (0, useRAF_1.useRAF)(updateFunction);
|
|
24
|
+
(0, react_1.useEffect)(() => {
|
|
25
|
+
observer();
|
|
26
|
+
const containerObserver = new MutationObserver(observer);
|
|
27
|
+
containerObserver.observe(container, observerOptions ?? {
|
|
28
|
+
childList: true,
|
|
29
|
+
subtree: true,
|
|
30
|
+
attributes: true,
|
|
31
|
+
});
|
|
32
|
+
for (const event of dom_1.REFLOW_EVENTS) {
|
|
33
|
+
window.addEventListener(event, observer);
|
|
34
|
+
}
|
|
35
|
+
return () => {
|
|
36
|
+
containerObserver.disconnect();
|
|
37
|
+
for (const event of dom_1.REFLOW_EVENTS) {
|
|
38
|
+
window.removeEventListener(event, observer);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, [container, observer, observerOptions]);
|
|
42
|
+
return { intersection };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=useObserveIntersection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useObserveIntersection.js","sourceRoot":"../../../../../../src","sources":["modules/search/components/hooks/useObserveIntersection.ts"],"names":[],"mappings":";;AAkBA,wDAoDC;AAtED,iCAAuD;AAEvD,yCAAoC;AAEpC,oEAAoD;AACpD,kDAAqE;AAarE,SAAgB,sBAAsB,CAAC,EACnC,WAAW,EACX,SAAS,EACT,QAAQ,EACR,eAAe,GACW;IAC1B,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAU,KAAK,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,IAAA,qBAAS,EAAU,YAAY,CAAC,CAAC;IAEzD,MAAM,cAAc,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC;QACrC,MAAM,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,eAAe,CAAC,OAAO;gBAAE,eAAe,CAAC,KAAK,CAAC,CAAC;YACpD,OAAO;QACX,CAAC;QAED,MAAM,cAAc,GAAG,IAAA,6BAAuB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAClE,IAAI,cAAc,KAAK,eAAe,CAAC,OAAO;YAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IACpF,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,IAAA,eAAM,EAAC,cAAc,CAAC,CAAC;IAExC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACX,QAAQ,EAAE,CAAC;QAEX,MAAM,iBAAiB,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAEzD,iBAAiB,CAAC,OAAO,CACrB,SAAS,EACT,eAAe,IAAI;YACf,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;SACnB,CACJ,CAAC;QAEF,KAAK,MAAM,KAAK,IAAI,mBAAa,EAAE,CAAC;YAChC,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,GAAG,EAAE;YACR,iBAAiB,CAAC,UAAU,EAAE,CAAC;YAE/B,KAAK,MAAM,KAAK,IAAI,mBAAa,EAAE,CAAC;gBAChC,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChD,CAAC;QACL,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;IAE3C,OAAO,EAAC,YAAY,EAAC,CAAC;AAC1B,CAAC","sourcesContent":["import {useCallback, useEffect, useState} from 'react';\n\nimport {useLatest} from 'react-use';\n\nimport {useRAF} from 'src/react-utils/hooks/useRAF';\nimport {REFLOW_EVENTS, areElementsIntersecting} from 'src/utils/dom';\n\nexport type UseObserveIntersectionProps = {\n floatingRef: React.RefObject<HTMLElement>;\n container: Element;\n selector: string;\n observerOptions?: MutationObserverInit;\n};\n\nexport type UseObserveIntersectionReturn = {\n intersection: boolean;\n};\n\nexport function useObserveIntersection({\n floatingRef,\n container,\n selector,\n observerOptions,\n}: UseObserveIntersectionProps): UseObserveIntersectionReturn {\n const [intersection, setIntersection] = useState<boolean>(false);\n const intersectionRef = useLatest<boolean>(intersection);\n\n const updateFunction = useCallback(() => {\n const floating = floatingRef.current;\n const element = container.querySelector(selector);\n\n if (!element || !floating) {\n if (intersectionRef.current) setIntersection(false);\n return;\n }\n\n const isIntersecting = areElementsIntersecting(element, floating);\n if (isIntersecting !== intersectionRef.current) setIntersection(isIntersecting);\n }, [container, floatingRef, intersectionRef, selector]);\n\n const observer = useRAF(updateFunction);\n\n useEffect(() => {\n observer();\n\n const containerObserver = new MutationObserver(observer);\n\n containerObserver.observe(\n container,\n observerOptions ?? {\n childList: true,\n subtree: true,\n attributes: true,\n },\n );\n\n for (const event of REFLOW_EVENTS) {\n window.addEventListener(event, observer);\n }\n\n return () => {\n containerObserver.disconnect();\n\n for (const event of REFLOW_EVENTS) {\n window.removeEventListener(event, observer);\n }\n };\n }, [container, observer, observerOptions]);\n\n return {intersection};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useRAF(fn: () => void): () => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useRAF = useRAF;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
function useRAF(fn) {
|
|
6
|
+
const rafRef = (0, react_1.useRef)(null);
|
|
7
|
+
(0, react_1.useEffect)(() => {
|
|
8
|
+
return () => {
|
|
9
|
+
if (rafRef.current !== null) {
|
|
10
|
+
cancelAnimationFrame(rafRef.current);
|
|
11
|
+
rafRef.current = null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}, [fn]);
|
|
15
|
+
return (0, react_1.useCallback)(() => {
|
|
16
|
+
if (rafRef.current === null) {
|
|
17
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
18
|
+
rafRef.current = null;
|
|
19
|
+
fn();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}, [fn]);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=useRAF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRAF.js","sourceRoot":"../../../../src","sources":["react-utils/hooks/useRAF.ts"],"names":[],"mappings":";;AAEA,wBAoBC;AAtBD,iCAAqD;AAErD,SAAgB,MAAM,CAAC,EAAc;IACjC,MAAM,MAAM,GAAG,IAAA,cAAM,EAAgB,IAAI,CAAC,CAAC;IAE3C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACX,OAAO,GAAG,EAAE;YACR,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC1B,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACrC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,CAAC;QACL,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAET,OAAO,IAAA,mBAAW,EAAC,GAAG,EAAE;QACpB,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,OAAO,GAAG,qBAAqB,CAAC,GAAG,EAAE;gBACxC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;gBACtB,EAAE,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACb,CAAC","sourcesContent":["import {useCallback, useEffect, useRef} from 'react';\n\nexport function useRAF(fn: () => void): () => void {\n const rafRef = useRef<number | null>(null);\n\n useEffect(() => {\n return () => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [fn]);\n\n return useCallback(() => {\n if (rafRef.current === null) {\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n fn();\n });\n }\n }, [fn]);\n}\n"]}
|
|
@@ -3,30 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useSticky = useSticky;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const react_use_1 = require("react-use");
|
|
6
|
-
const
|
|
7
|
-
'resize',
|
|
8
|
-
'scroll',
|
|
9
|
-
'touchstart',
|
|
10
|
-
'touchmove',
|
|
11
|
-
'touchend',
|
|
12
|
-
'pageshow',
|
|
13
|
-
'load',
|
|
14
|
-
'orientationchange',
|
|
15
|
-
]);
|
|
6
|
+
const dom_1 = require("../utils/dom.js");
|
|
16
7
|
function useSticky(elemRef) {
|
|
17
8
|
const [sticky, setSticky] = (0, react_1.useState)(false);
|
|
18
9
|
const stickyRef = (0, react_use_1.useLatest)(sticky);
|
|
19
10
|
(0, react_use_1.useEffectOnce)(() => {
|
|
20
11
|
let rafId = null;
|
|
21
12
|
observe();
|
|
22
|
-
for (const eventName of
|
|
13
|
+
for (const eventName of dom_1.REFLOW_EVENTS) {
|
|
23
14
|
window.addEventListener(eventName, scheduleObserve, true);
|
|
24
15
|
}
|
|
25
16
|
return () => {
|
|
26
17
|
if (rafId !== null) {
|
|
27
18
|
cancelAnimationFrame(rafId);
|
|
28
19
|
}
|
|
29
|
-
for (const eventName of
|
|
20
|
+
for (const eventName of dom_1.REFLOW_EVENTS) {
|
|
30
21
|
window.removeEventListener(eventName, scheduleObserve, true);
|
|
31
22
|
}
|
|
32
23
|
};
|