@lexical/hashtag 0.35.1-nightly.20250924.0 → 0.36.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.
@@ -8,6 +8,7 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ var text = require('@lexical/text');
11
12
  var utils = require('@lexical/utils');
12
13
  var lexical = require('lexical');
13
14
 
@@ -62,6 +63,166 @@ function $isHashtagNode(node) {
62
63
  return node instanceof HashtagNode;
63
64
  }
64
65
 
66
+ /**
67
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
68
+ *
69
+ * This source code is licensed under the MIT license found in the
70
+ * LICENSE file in the root directory of this source tree.
71
+ *
72
+ */
73
+
74
+ function getHashtagRegexStringChars() {
75
+ // Latin accented characters
76
+ // Excludes 0xd7 from the range
77
+ // (the multiplication sign, confusable with "x").
78
+ // Also excludes 0xf7, the division sign
79
+ const latinAccents = '\xc0-\xd6' + '\xd8-\xf6' + '\xf8-\xff' + '\u0100-\u024f' + '\u0253-\u0254' + '\u0256-\u0257' + '\u0259' + '\u025b' + '\u0263' + '\u0268' + '\u026f' + '\u0272' + '\u0289' + '\u028b' + '\u02bb' + '\u0300-\u036f' + '\u1e00-\u1eff';
80
+
81
+ // Cyrillic (Russian, Ukrainian, etc.)
82
+ const nonLatinChars = '\u0400-\u04ff' +
83
+ // Cyrillic
84
+ '\u0500-\u0527' +
85
+ // Cyrillic Supplement
86
+ '\u2de0-\u2dff' +
87
+ // Cyrillic Extended A
88
+ '\ua640-\ua69f' +
89
+ // Cyrillic Extended B
90
+ '\u0591-\u05bf' +
91
+ // Hebrew
92
+ '\u05c1-\u05c2' + '\u05c4-\u05c5' + '\u05c7' + '\u05d0-\u05ea' + '\u05f0-\u05f4' + '\ufb12-\ufb28' +
93
+ // Hebrew Presentation Forms
94
+ '\ufb2a-\ufb36' + '\ufb38-\ufb3c' + '\ufb3e' + '\ufb40-\ufb41' + '\ufb43-\ufb44' + '\ufb46-\ufb4f' + '\u0610-\u061a' +
95
+ // Arabic
96
+ '\u0620-\u065f' + '\u066e-\u06d3' + '\u06d5-\u06dc' + '\u06de-\u06e8' + '\u06ea-\u06ef' + '\u06fa-\u06fc' + '\u06ff' + '\u0750-\u077f' +
97
+ // Arabic Supplement
98
+ '\u08a0' +
99
+ // Arabic Extended A
100
+ '\u08a2-\u08ac' + '\u08e4-\u08fe' + '\ufb50-\ufbb1' +
101
+ // Arabic Pres. Forms A
102
+ '\ufbd3-\ufd3d' + '\ufd50-\ufd8f' + '\ufd92-\ufdc7' + '\ufdf0-\ufdfb' + '\ufe70-\ufe74' +
103
+ // Arabic Pres. Forms B
104
+ '\ufe76-\ufefc' + '\u200c-\u200c' +
105
+ // Zero-Width Non-Joiner
106
+ '\u0e01-\u0e3a' +
107
+ // Thai
108
+ '\u0e40-\u0e4e' +
109
+ // Hangul (Korean)
110
+ '\u1100-\u11ff' +
111
+ // Hangul Jamo
112
+ '\u3130-\u3185' +
113
+ // Hangul Compatibility Jamo
114
+ '\uA960-\uA97F' +
115
+ // Hangul Jamo Extended-A
116
+ '\uAC00-\uD7AF' +
117
+ // Hangul Syllables
118
+ '\uD7B0-\uD7FF' +
119
+ // Hangul Jamo Extended-B
120
+ '\uFFA1-\uFFDC'; // Half-width Hangul
121
+
122
+ const charCode = String.fromCharCode;
123
+ const cjkChars = '\u30A1-\u30FA\u30FC-\u30FE' +
124
+ // Katakana (full-width)
125
+ '\uFF66-\uFF9F' +
126
+ // Katakana (half-width)
127
+ '\uFF10-\uFF19\uFF21-\uFF3A' + '\uFF41-\uFF5A' +
128
+ // Latin (full-width)
129
+ '\u3041-\u3096\u3099-\u309E' +
130
+ // Hiragana
131
+ '\u3400-\u4DBF' +
132
+ // Kanji (CJK Extension A)
133
+ '\u4E00-\u9FFF' +
134
+ // Kanji (Unified)
135
+ // Disabled as it breaks the Regex.
136
+ // charCode(0x20000) + '-' + charCode(0x2A6DF) + // Kanji (CJK Extension B)
137
+ charCode(0x2a700) + '-' + charCode(0x2b73f) +
138
+ // Kanji (CJK Extension C)
139
+ charCode(0x2b740) + '-' + charCode(0x2b81f) +
140
+ // Kanji (CJK Extension D)
141
+ charCode(0x2f800) + '-' + charCode(0x2fa1f) + '\u3003\u3005\u303B'; // Kanji (CJK supplement)
142
+
143
+ const otherChars = latinAccents + nonLatinChars + cjkChars;
144
+ // equivalent of \p{L}
145
+
146
+ const unicodeLetters = '\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u0241\u0250-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u037A\u0386' + '\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481' + '\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587' + '\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640-\u064A\u066E-\u066F' + '\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710' + '\u0712-\u072F\u074D-\u076D\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950' + '\u0958-\u0961\u097D\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0' + '\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1' + '\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33' + '\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D' + '\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD' + '\u0AD0\u0AE0-\u0AE1\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30' + '\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83' + '\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F' + '\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10' + '\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C' + '\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE' + '\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39' + '\u0D60-\u0D61\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6' + '\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E81-\u0E82\u0E84\u0E87-\u0E88' + '\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7' + '\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6' + '\u0EDC-\u0EDD\u0F00\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021' + '\u1023-\u1027\u1029-\u102A\u1050-\u1055\u10A0-\u10C5\u10D0-\u10FA\u10FC' + '\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1248\u124A-\u124D' + '\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0' + '\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310' + '\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C' + '\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711' + '\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7' + '\u17DC\u1820-\u1877\u1880-\u18A8\u1900-\u191C\u1950-\u196D\u1970-\u1974' + '\u1980-\u19A9\u19C1-\u19C7\u1A00-\u1A16\u1D00-\u1DBF\u1E00-\u1E9B' + '\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D' + '\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC' + '\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC' + '\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u2094\u2102\u2107' + '\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D' + '\u212F-\u2131\u2133-\u2139\u213C-\u213F\u2145-\u2149\u2C00-\u2C2E' + '\u2C30-\u2C5E\u2C80-\u2CE4\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96' + '\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6' + '\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3006\u3031-\u3035' + '\u303B-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF' + '\u3105-\u312C\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5' + '\u4E00-\u9FBB\uA000-\uA48C\uA800-\uA801\uA803-\uA805\uA807-\uA80A' + '\uA80C-\uA822\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9' + '\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C' + '\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F' + '\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A' + '\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7' + '\uFFDA-\uFFDC';
147
+
148
+ // equivalent of \p{Mn}\p{Mc}
149
+ const unicodeAccents = '\u0300-\u036F\u0483-\u0486\u0591-\u05B9\u05BB-\u05BD\u05BF' + '\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u0615\u064B-\u065E\u0670' + '\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A' + '\u07A6-\u07B0\u0901-\u0903\u093C\u093E-\u094D\u0951-\u0954\u0962-\u0963' + '\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7' + '\u09E2-\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D' + '\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD' + '\u0AE2-\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D' + '\u0B56-\u0B57\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7' + '\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56' + '\u0C82-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6' + '\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D82-\u0D83' + '\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2-\u0DF3\u0E31\u0E34-\u0E3A' + '\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19' + '\u0F35\u0F37\u0F39\u0F3E-\u0F3F\u0F71-\u0F84\u0F86-\u0F87\u0F90-\u0F97' + '\u0F99-\u0FBC\u0FC6\u102C-\u1032\u1036-\u1039\u1056-\u1059\u135F' + '\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B6-\u17D3\u17DD' + '\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8-\u19C9' + '\u1A17-\u1A1B\u1DC0-\u1DC3\u20D0-\u20DC\u20E1\u20E5-\u20EB\u302A-\u302F' + '\u3099-\u309A\uA802\uA806\uA80B\uA823-\uA827\uFB1E\uFE00-\uFE0F' + '\uFE20-\uFE23';
150
+
151
+ // equivalent of \p{Dn}
152
+ const unicodeDigits = '\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF' + '\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F' + '\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29' + '\u1040-\u1049\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9' + '\uFF10-\uFF19';
153
+
154
+ // An alpha char is a unicode chars excluding unicode combining marks
155
+ // but including other chars, a hashtag must start with one of these,
156
+ // it does not make sense to have a combining mark before a base character.
157
+ const alpha = unicodeLetters + otherChars;
158
+
159
+ // A numeric character is any with the number digit property, or
160
+ // underscore. These characters can be included in hashtags, but a hashtag
161
+ // cannot have only these characters.
162
+ const numeric = unicodeDigits + '_';
163
+
164
+ // Alphanumeric char is any alpha char or a unicode char with decimal
165
+ // number property \p{Nd}
166
+ const alphanumeric = alpha + unicodeAccents + numeric;
167
+ const hashChars = '#\\uFF03'; // normal '#' or full-width '#'
168
+
169
+ return {
170
+ alpha,
171
+ alphanumeric,
172
+ hashChars
173
+ };
174
+ }
175
+ function getHashtagRegexString() {
176
+ const {
177
+ alpha,
178
+ alphanumeric,
179
+ hashChars
180
+ } = getHashtagRegexStringChars();
181
+ const hashtagAlpha = '[' + alpha + ']';
182
+ const hashtagAlphanumeric = '[' + alphanumeric + ']';
183
+ const hashtagBoundary = '^|$|[^&/' + alphanumeric + ']';
184
+ const hashCharList = '[' + hashChars + ']';
185
+
186
+ // A hashtag contains characters, numbers and underscores,
187
+ // but not all numbers.
188
+ const hashtag = '(' + hashtagBoundary + ')(' + hashCharList + ')(' + hashtagAlphanumeric + '*' + hashtagAlpha + hashtagAlphanumeric + '*)';
189
+ return hashtag;
190
+ }
191
+ const REGEX = new RegExp(getHashtagRegexString(), 'i');
192
+ function getHashtagMatch(text) {
193
+ const matchArr = REGEX.exec(text);
194
+ if (matchArr === null) {
195
+ return null;
196
+ }
197
+ const hashtagLength = matchArr[3].length + 1;
198
+ const startOffset = matchArr.index + matchArr[1].length;
199
+ const endOffset = startOffset + hashtagLength;
200
+ return {
201
+ end: endOffset,
202
+ start: startOffset
203
+ };
204
+ }
205
+
206
+ /** @internal */
207
+ const defaultHashtagConfig = {
208
+ getHashtagMatch
209
+ };
210
+ /** @internal */
211
+ function registerLexicalHashtag(editor, config = defaultHashtagConfig) {
212
+ return utils.mergeRegister(...text.registerLexicalTextEntity(editor, config.getHashtagMatch, HashtagNode, textNode => $createHashtagNode(textNode.getTextContent())));
213
+ }
214
+ /**
215
+ * Add `#hashtag` support to the editor
216
+ */
217
+ const HashtagExtension = lexical.defineExtension({
218
+ config: defaultHashtagConfig,
219
+ name: '@lexical/hashtag/Hashtag',
220
+ nodes: [HashtagNode],
221
+ register: registerLexicalHashtag
222
+ });
223
+
65
224
  exports.$createHashtagNode = $createHashtagNode;
66
225
  exports.$isHashtagNode = $isHashtagNode;
226
+ exports.HashtagExtension = HashtagExtension;
67
227
  exports.HashtagNode = HashtagNode;
228
+ exports.registerLexicalHashtag = registerLexicalHashtag;
@@ -6,8 +6,9 @@
6
6
  *
7
7
  */
8
8
 
9
- import { addClassNamesToElement } from '@lexical/utils';
10
- import { TextNode, $applyNodeReplacement } from 'lexical';
9
+ import { registerLexicalTextEntity } from '@lexical/text';
10
+ import { addClassNamesToElement, mergeRegister } from '@lexical/utils';
11
+ import { TextNode, $applyNodeReplacement, defineExtension } from 'lexical';
11
12
 
12
13
  /**
13
14
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -60,4 +61,162 @@ function $isHashtagNode(node) {
60
61
  return node instanceof HashtagNode;
61
62
  }
62
63
 
63
- export { $createHashtagNode, $isHashtagNode, HashtagNode };
64
+ /**
65
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
66
+ *
67
+ * This source code is licensed under the MIT license found in the
68
+ * LICENSE file in the root directory of this source tree.
69
+ *
70
+ */
71
+
72
+ function getHashtagRegexStringChars() {
73
+ // Latin accented characters
74
+ // Excludes 0xd7 from the range
75
+ // (the multiplication sign, confusable with "x").
76
+ // Also excludes 0xf7, the division sign
77
+ const latinAccents = '\xc0-\xd6' + '\xd8-\xf6' + '\xf8-\xff' + '\u0100-\u024f' + '\u0253-\u0254' + '\u0256-\u0257' + '\u0259' + '\u025b' + '\u0263' + '\u0268' + '\u026f' + '\u0272' + '\u0289' + '\u028b' + '\u02bb' + '\u0300-\u036f' + '\u1e00-\u1eff';
78
+
79
+ // Cyrillic (Russian, Ukrainian, etc.)
80
+ const nonLatinChars = '\u0400-\u04ff' +
81
+ // Cyrillic
82
+ '\u0500-\u0527' +
83
+ // Cyrillic Supplement
84
+ '\u2de0-\u2dff' +
85
+ // Cyrillic Extended A
86
+ '\ua640-\ua69f' +
87
+ // Cyrillic Extended B
88
+ '\u0591-\u05bf' +
89
+ // Hebrew
90
+ '\u05c1-\u05c2' + '\u05c4-\u05c5' + '\u05c7' + '\u05d0-\u05ea' + '\u05f0-\u05f4' + '\ufb12-\ufb28' +
91
+ // Hebrew Presentation Forms
92
+ '\ufb2a-\ufb36' + '\ufb38-\ufb3c' + '\ufb3e' + '\ufb40-\ufb41' + '\ufb43-\ufb44' + '\ufb46-\ufb4f' + '\u0610-\u061a' +
93
+ // Arabic
94
+ '\u0620-\u065f' + '\u066e-\u06d3' + '\u06d5-\u06dc' + '\u06de-\u06e8' + '\u06ea-\u06ef' + '\u06fa-\u06fc' + '\u06ff' + '\u0750-\u077f' +
95
+ // Arabic Supplement
96
+ '\u08a0' +
97
+ // Arabic Extended A
98
+ '\u08a2-\u08ac' + '\u08e4-\u08fe' + '\ufb50-\ufbb1' +
99
+ // Arabic Pres. Forms A
100
+ '\ufbd3-\ufd3d' + '\ufd50-\ufd8f' + '\ufd92-\ufdc7' + '\ufdf0-\ufdfb' + '\ufe70-\ufe74' +
101
+ // Arabic Pres. Forms B
102
+ '\ufe76-\ufefc' + '\u200c-\u200c' +
103
+ // Zero-Width Non-Joiner
104
+ '\u0e01-\u0e3a' +
105
+ // Thai
106
+ '\u0e40-\u0e4e' +
107
+ // Hangul (Korean)
108
+ '\u1100-\u11ff' +
109
+ // Hangul Jamo
110
+ '\u3130-\u3185' +
111
+ // Hangul Compatibility Jamo
112
+ '\uA960-\uA97F' +
113
+ // Hangul Jamo Extended-A
114
+ '\uAC00-\uD7AF' +
115
+ // Hangul Syllables
116
+ '\uD7B0-\uD7FF' +
117
+ // Hangul Jamo Extended-B
118
+ '\uFFA1-\uFFDC'; // Half-width Hangul
119
+
120
+ const charCode = String.fromCharCode;
121
+ const cjkChars = '\u30A1-\u30FA\u30FC-\u30FE' +
122
+ // Katakana (full-width)
123
+ '\uFF66-\uFF9F' +
124
+ // Katakana (half-width)
125
+ '\uFF10-\uFF19\uFF21-\uFF3A' + '\uFF41-\uFF5A' +
126
+ // Latin (full-width)
127
+ '\u3041-\u3096\u3099-\u309E' +
128
+ // Hiragana
129
+ '\u3400-\u4DBF' +
130
+ // Kanji (CJK Extension A)
131
+ '\u4E00-\u9FFF' +
132
+ // Kanji (Unified)
133
+ // Disabled as it breaks the Regex.
134
+ // charCode(0x20000) + '-' + charCode(0x2A6DF) + // Kanji (CJK Extension B)
135
+ charCode(0x2a700) + '-' + charCode(0x2b73f) +
136
+ // Kanji (CJK Extension C)
137
+ charCode(0x2b740) + '-' + charCode(0x2b81f) +
138
+ // Kanji (CJK Extension D)
139
+ charCode(0x2f800) + '-' + charCode(0x2fa1f) + '\u3003\u3005\u303B'; // Kanji (CJK supplement)
140
+
141
+ const otherChars = latinAccents + nonLatinChars + cjkChars;
142
+ // equivalent of \p{L}
143
+
144
+ const unicodeLetters = '\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u0241\u0250-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u037A\u0386' + '\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481' + '\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587' + '\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640-\u064A\u066E-\u066F' + '\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710' + '\u0712-\u072F\u074D-\u076D\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950' + '\u0958-\u0961\u097D\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0' + '\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1' + '\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33' + '\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D' + '\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD' + '\u0AD0\u0AE0-\u0AE1\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30' + '\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83' + '\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F' + '\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10' + '\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C' + '\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE' + '\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39' + '\u0D60-\u0D61\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6' + '\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E81-\u0E82\u0E84\u0E87-\u0E88' + '\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7' + '\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6' + '\u0EDC-\u0EDD\u0F00\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021' + '\u1023-\u1027\u1029-\u102A\u1050-\u1055\u10A0-\u10C5\u10D0-\u10FA\u10FC' + '\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1248\u124A-\u124D' + '\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0' + '\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310' + '\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C' + '\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711' + '\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7' + '\u17DC\u1820-\u1877\u1880-\u18A8\u1900-\u191C\u1950-\u196D\u1970-\u1974' + '\u1980-\u19A9\u19C1-\u19C7\u1A00-\u1A16\u1D00-\u1DBF\u1E00-\u1E9B' + '\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D' + '\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC' + '\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC' + '\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u2094\u2102\u2107' + '\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D' + '\u212F-\u2131\u2133-\u2139\u213C-\u213F\u2145-\u2149\u2C00-\u2C2E' + '\u2C30-\u2C5E\u2C80-\u2CE4\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96' + '\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6' + '\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3006\u3031-\u3035' + '\u303B-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF' + '\u3105-\u312C\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5' + '\u4E00-\u9FBB\uA000-\uA48C\uA800-\uA801\uA803-\uA805\uA807-\uA80A' + '\uA80C-\uA822\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9' + '\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C' + '\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F' + '\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A' + '\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7' + '\uFFDA-\uFFDC';
145
+
146
+ // equivalent of \p{Mn}\p{Mc}
147
+ const unicodeAccents = '\u0300-\u036F\u0483-\u0486\u0591-\u05B9\u05BB-\u05BD\u05BF' + '\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u0615\u064B-\u065E\u0670' + '\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A' + '\u07A6-\u07B0\u0901-\u0903\u093C\u093E-\u094D\u0951-\u0954\u0962-\u0963' + '\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7' + '\u09E2-\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D' + '\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD' + '\u0AE2-\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D' + '\u0B56-\u0B57\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7' + '\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56' + '\u0C82-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6' + '\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D82-\u0D83' + '\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2-\u0DF3\u0E31\u0E34-\u0E3A' + '\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19' + '\u0F35\u0F37\u0F39\u0F3E-\u0F3F\u0F71-\u0F84\u0F86-\u0F87\u0F90-\u0F97' + '\u0F99-\u0FBC\u0FC6\u102C-\u1032\u1036-\u1039\u1056-\u1059\u135F' + '\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B6-\u17D3\u17DD' + '\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8-\u19C9' + '\u1A17-\u1A1B\u1DC0-\u1DC3\u20D0-\u20DC\u20E1\u20E5-\u20EB\u302A-\u302F' + '\u3099-\u309A\uA802\uA806\uA80B\uA823-\uA827\uFB1E\uFE00-\uFE0F' + '\uFE20-\uFE23';
148
+
149
+ // equivalent of \p{Dn}
150
+ const unicodeDigits = '\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF' + '\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F' + '\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29' + '\u1040-\u1049\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9' + '\uFF10-\uFF19';
151
+
152
+ // An alpha char is a unicode chars excluding unicode combining marks
153
+ // but including other chars, a hashtag must start with one of these,
154
+ // it does not make sense to have a combining mark before a base character.
155
+ const alpha = unicodeLetters + otherChars;
156
+
157
+ // A numeric character is any with the number digit property, or
158
+ // underscore. These characters can be included in hashtags, but a hashtag
159
+ // cannot have only these characters.
160
+ const numeric = unicodeDigits + '_';
161
+
162
+ // Alphanumeric char is any alpha char or a unicode char with decimal
163
+ // number property \p{Nd}
164
+ const alphanumeric = alpha + unicodeAccents + numeric;
165
+ const hashChars = '#\\uFF03'; // normal '#' or full-width '#'
166
+
167
+ return {
168
+ alpha,
169
+ alphanumeric,
170
+ hashChars
171
+ };
172
+ }
173
+ function getHashtagRegexString() {
174
+ const {
175
+ alpha,
176
+ alphanumeric,
177
+ hashChars
178
+ } = getHashtagRegexStringChars();
179
+ const hashtagAlpha = '[' + alpha + ']';
180
+ const hashtagAlphanumeric = '[' + alphanumeric + ']';
181
+ const hashtagBoundary = '^|$|[^&/' + alphanumeric + ']';
182
+ const hashCharList = '[' + hashChars + ']';
183
+
184
+ // A hashtag contains characters, numbers and underscores,
185
+ // but not all numbers.
186
+ const hashtag = '(' + hashtagBoundary + ')(' + hashCharList + ')(' + hashtagAlphanumeric + '*' + hashtagAlpha + hashtagAlphanumeric + '*)';
187
+ return hashtag;
188
+ }
189
+ const REGEX = new RegExp(getHashtagRegexString(), 'i');
190
+ function getHashtagMatch(text) {
191
+ const matchArr = REGEX.exec(text);
192
+ if (matchArr === null) {
193
+ return null;
194
+ }
195
+ const hashtagLength = matchArr[3].length + 1;
196
+ const startOffset = matchArr.index + matchArr[1].length;
197
+ const endOffset = startOffset + hashtagLength;
198
+ return {
199
+ end: endOffset,
200
+ start: startOffset
201
+ };
202
+ }
203
+
204
+ /** @internal */
205
+ const defaultHashtagConfig = {
206
+ getHashtagMatch
207
+ };
208
+ /** @internal */
209
+ function registerLexicalHashtag(editor, config = defaultHashtagConfig) {
210
+ return mergeRegister(...registerLexicalTextEntity(editor, config.getHashtagMatch, HashtagNode, textNode => $createHashtagNode(textNode.getTextContent())));
211
+ }
212
+ /**
213
+ * Add `#hashtag` support to the editor
214
+ */
215
+ const HashtagExtension = defineExtension({
216
+ config: defaultHashtagConfig,
217
+ name: '@lexical/hashtag/Hashtag',
218
+ nodes: [HashtagNode],
219
+ register: registerLexicalHashtag
220
+ });
221
+
222
+ export { $createHashtagNode, $isHashtagNode, HashtagExtension, HashtagNode, registerLexicalHashtag };
@@ -12,6 +12,7 @@ import type {
12
12
  LexicalNode,
13
13
  NodeKey,
14
14
  SerializedTextNode,
15
+ LexicalExtension,
15
16
  } from 'lexical';
16
17
 
17
18
  import {TextNode} from 'lexical';
@@ -30,3 +31,9 @@ declare export function $createHashtagNode(text?: string): HashtagNode;
30
31
  declare export function $isHashtagNode(
31
32
  node: ?LexicalNode,
32
33
  ): node is HashtagNode;
34
+
35
+
36
+ export type HashtagConfig = {
37
+ getHashtagMatch: (text: string) => null | {start: number; end: number};
38
+ }
39
+ declare export var HashtagExtension: LexicalExtension<HashtagConfig, "@lexical/hashtag/Hashtag", void, void>;
@@ -11,4 +11,6 @@ import * as modProd from './LexicalHashtag.prod.mjs';
11
11
  const mod = process.env.NODE_ENV !== 'production' ? modDev : modProd;
12
12
  export const $createHashtagNode = mod.$createHashtagNode;
13
13
  export const $isHashtagNode = mod.$isHashtagNode;
14
- export const HashtagNode = mod.HashtagNode;
14
+ export const HashtagExtension = mod.HashtagExtension;
15
+ export const HashtagNode = mod.HashtagNode;
16
+ export const registerLexicalHashtag = mod.registerLexicalHashtag;
@@ -9,4 +9,6 @@
9
9
  const mod = await (process.env.NODE_ENV !== 'production' ? import('./LexicalHashtag.dev.mjs') : import('./LexicalHashtag.prod.mjs'));
10
10
  export const $createHashtagNode = mod.$createHashtagNode;
11
11
  export const $isHashtagNode = mod.$isHashtagNode;
12
- export const HashtagNode = mod.HashtagNode;
12
+ export const HashtagExtension = mod.HashtagExtension;
13
+ export const HashtagNode = mod.HashtagNode;
14
+ export const registerLexicalHashtag = mod.registerLexicalHashtag;
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/utils"),t=require("lexical");class r extends t.TextNode{static getType(){return"hashtag"}static clone(e){return new r(e.__text,e.__key)}createDOM(t){const r=super.createDOM(t);return e.addClassNamesToElement(r,t.theme.hashtag),r}static importJSON(e){return a().updateFromJSON(e)}canInsertTextBefore(){return!1}isTextEntity(){return!0}}function a(e=""){return t.$applyNodeReplacement(new r(e))}exports.$createHashtagNode=a,exports.$isHashtagNode=function(e){return e instanceof r},exports.HashtagNode=r;
9
+ "use strict";var e=require("@lexical/text"),t=require("@lexical/utils"),n=require("lexical");class r extends n.TextNode{static getType(){return"hashtag"}static clone(e){return new r(e.__text,e.__key)}createDOM(e){const n=super.createDOM(e);return t.addClassNamesToElement(n,e.theme.hashtag),n}static importJSON(e){return a().updateFromJSON(e)}canInsertTextBefore(){return!1}isTextEntity(){return!0}}function a(e=""){return n.$applyNodeReplacement(new r(e))}const s=new RegExp(function(){const{alpha:e,alphanumeric:t,hashChars:n}=function(){const e=String.fromCharCode,t="A-Za-zªµºÀ-ÖØ-öø-Ɂɐ-ˁˆ-ˑˠ-ˤˮͺΆΈ-ΊΌΎ-ΡΣ-ώϐ-ϵϷ-ҁҊ-ӎӐ-ӹԀ-ԏԱ-Ֆՙա-ևא-תװ-ײء-غـ-يٮ-ٯٱ-ۓەۥ-ۦۮ-ۯۺ-ۼۿܐܒ-ܯݍ-ݭހ-ޥޱऄ-हऽॐक़-ॡॽঅ-ঌএ-ঐও-নপ-রলশ-হঽৎড়-ঢ়য়-ৡৰ-ৱਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼ਵ-ਸ਼ਸ-ਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલ-ળવ-હઽૐૠ-ૡଅ-ଌଏ-ଐଓ-ନପ-ରଲ-ଳଵ-ହଽଡ଼-ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கங-சஜஞ-டண-தந-பம-ஹఅ-ఌఎ-ఐఒ-నప-ళవ-హౠ-ౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠ-ೡഅ-ഌഎ-ഐഒ-നപ-ഹൠ-ൡඅ-ඖක-නඳ-රලව-ෆก-ะา-ำเ-ๆກ-ຂຄງ-ຈຊຍດ-ທນ-ຟມ-ຣລວສ-ຫອ-ະາ-ຳຽເ-ໄໆໜ-ໝༀཀ-ཇཉ-ཪྈ-ྋက-အဣ-ဧဩ-ဪၐ-ၕႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᴀ-ᶿḀ-ẛẠ-ỹἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℱℳ-ℹℼ-ℿⅅ-ⅉⰀ-Ⱞⰰ-ⱞⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〆〱-〵〻-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄬㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀-䶵一-龻ꀀ-ꒌꠀ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢ가-힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵÀ-ÖØ-öø-ÿĀ-ɏɓ-ɔɖ-ɗəɛɣɨɯɲʉʋʻ̀-ͯḀ-ỿЀ-ӿԀ-ԧⷠ-ⷿꙀ-֑ꚟ-ֿׁ-ׂׄ-ׇׅא-תװ-״﬒-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﭏؐ-ؚؠ-ٟٮ-ۓە-ۜ۞-۪ۨ-ۯۺ-ۼۿݐ-ݿࢠࢢ-ࢬࣤ-ࣾﭐ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼ‌-‌ก-ฺเ-๎ᄀ-ᇿ㄰-ㆅꥠ-꥿가-힯ힰ-퟿ᄀ-ᅵァ-ヺー-ヾヲ-゚0-9A-Za-zぁ-ゖ゙-ゞ㐀-䶿一-鿿"+e(173824)+"-"+e(177983)+e(177984)+"-"+e(178207)+e(194560)+"-"+e(195103)+"〃々〻";return{alpha:t,alphanumeric:t+"̀-ͯ҃-֑҆-ֹֻ-ֽֿׁ-ׂׄ-ׇׅؐ-ًؕ-ٰٞۖ-ۜ۟-ۤۧ-۪ۨ-ܑۭܰ-݊ަ-ްँ-ः़ा-्॑-॔ॢ-ॣঁ-ঃ়া-ৄে-ৈো-্ৗৢ-ৣਁ-ਃ਼ਾ-ੂੇ-ੈੋ-੍ੰ-ੱઁ-ઃ઼ા-ૅે-ૉો-્ૢ-ૣଁ-ଃ଼ା-ୃେ-ୈୋ-୍ୖ-ୗஂா-ூெ-ைொ-்ௗఁ-ఃా-ౄె-ైొ-్ౕ-ౖಂ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕ-ೖം-ഃാ-ൃെ-ൈൊ-്ൗං-ඃ්ා-ුූෘ-ෟෲ-ෳัิ-ฺ็-๎ັິ-ູົ-ຼ່-ໍ༘-༹༙༵༷༾-༿ཱ-྄྆-྇ྐ-ྗྙ-ྼ࿆ာ-ဲံ-္ၖ-ၙ፟ᜒ-᜔ᜲ-᜴ᝒ-ᝓᝲ-ᝳា-៓៝᠋-᠍ᢩᤠ-ᤫᤰ-᤻ᦰ-ᧀᧈ-ᧉᨗ-ᨛ᷀-᷃⃐-⃥⃜⃡-⃫〪-゙〯-゚ꠂ꠆ꠋꠣ-ꠧﬞ︀-️︠-︣0-9٠-٩۰-۹०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉០-៩᠐-᠙᥆-᥏᧐-᧙0-9_",hashChars:"#\\uFF03"}}(),r="["+t+"]";return"("+("^|$|[^&/"+t+"]")+")("+("["+n+"]")+")("+r+"*"+("["+e+"]")+r+"*)"}(),"i");const i={getHashtagMatch:function(e){const t=s.exec(e);if(null===t)return null;const n=t[3].length+1,r=t.index+t[1].length;return{end:r+n,start:r}}};function c(n,s=i){return t.mergeRegister(...e.registerLexicalTextEntity(n,s.getHashtagMatch,r,(e=>a(e.getTextContent()))))}const o=n.defineExtension({config:i,name:"@lexical/hashtag/Hashtag",nodes:[r],register:c});exports.$createHashtagNode=a,exports.$isHashtagNode=function(e){return e instanceof r},exports.HashtagExtension=o,exports.HashtagNode=r,exports.registerLexicalHashtag=c;
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{addClassNamesToElement as t}from"@lexical/utils";import{TextNode as e,$applyNodeReplacement as r}from"lexical";class n extends e{static getType(){return"hashtag"}static clone(t){return new n(t.__text,t.__key)}createDOM(e){const r=super.createDOM(e);return t(r,e.theme.hashtag),r}static importJSON(t){return a().updateFromJSON(t)}canInsertTextBefore(){return!1}isTextEntity(){return!0}}function a(t=""){return r(new n(t))}function c(t){return t instanceof n}export{a as $createHashtagNode,c as $isHashtagNode,n as HashtagNode};
9
+ import{registerLexicalTextEntity as t}from"@lexical/text";import{addClassNamesToElement as e,mergeRegister as n}from"@lexical/utils";import{TextNode as r,$applyNodeReplacement as a,defineExtension as c}from"lexical";class s extends r{static getType(){return"hashtag"}static clone(t){return new s(t.__text,t.__key)}createDOM(t){const n=super.createDOM(t);return e(n,t.theme.hashtag),n}static importJSON(t){return o().updateFromJSON(t)}canInsertTextBefore(){return!1}isTextEntity(){return!0}}function o(t=""){return a(new s(t))}function i(t){return t instanceof s}const u=new RegExp(function(){const{alpha:t,alphanumeric:e,hashChars:n}=function(){const t=String.fromCharCode,e="A-Za-zªµºÀ-ÖØ-öø-Ɂɐ-ˁˆ-ˑˠ-ˤˮͺΆΈ-ΊΌΎ-ΡΣ-ώϐ-ϵϷ-ҁҊ-ӎӐ-ӹԀ-ԏԱ-Ֆՙա-ևא-תװ-ײء-غـ-يٮ-ٯٱ-ۓەۥ-ۦۮ-ۯۺ-ۼۿܐܒ-ܯݍ-ݭހ-ޥޱऄ-हऽॐक़-ॡॽঅ-ঌএ-ঐও-নপ-রলশ-হঽৎড়-ঢ়য়-ৡৰ-ৱਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼ਵ-ਸ਼ਸ-ਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલ-ળવ-હઽૐૠ-ૡଅ-ଌଏ-ଐଓ-ନପ-ରଲ-ଳଵ-ହଽଡ଼-ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கங-சஜஞ-டண-தந-பம-ஹఅ-ఌఎ-ఐఒ-నప-ళవ-హౠ-ౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠ-ೡഅ-ഌഎ-ഐഒ-നപ-ഹൠ-ൡඅ-ඖක-නඳ-රලව-ෆก-ะา-ำเ-ๆກ-ຂຄງ-ຈຊຍດ-ທນ-ຟມ-ຣລວສ-ຫອ-ະາ-ຳຽເ-ໄໆໜ-ໝༀཀ-ཇཉ-ཪྈ-ྋက-အဣ-ဧဩ-ဪၐ-ၕႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᴀ-ᶿḀ-ẛẠ-ỹἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℱℳ-ℹℼ-ℿⅅ-ⅉⰀ-Ⱞⰰ-ⱞⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〆〱-〵〻-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄬㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀-䶵一-龻ꀀ-ꒌꠀ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢ가-힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵÀ-ÖØ-öø-ÿĀ-ɏɓ-ɔɖ-ɗəɛɣɨɯɲʉʋʻ̀-ͯḀ-ỿЀ-ӿԀ-ԧⷠ-ⷿꙀ-֑ꚟ-ֿׁ-ׂׄ-ׇׅא-תװ-״﬒-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﭏؐ-ؚؠ-ٟٮ-ۓە-ۜ۞-۪ۨ-ۯۺ-ۼۿݐ-ݿࢠࢢ-ࢬࣤ-ࣾﭐ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼ‌-‌ก-ฺเ-๎ᄀ-ᇿ㄰-ㆅꥠ-꥿가-힯ힰ-퟿ᄀ-ᅵァ-ヺー-ヾヲ-゚0-9A-Za-zぁ-ゖ゙-ゞ㐀-䶿一-鿿"+t(173824)+"-"+t(177983)+t(177984)+"-"+t(178207)+t(194560)+"-"+t(195103)+"〃々〻";return{alpha:e,alphanumeric:e+"̀-ͯ҃-֑҆-ֹֻ-ֽֿׁ-ׂׄ-ׇׅؐ-ًؕ-ٰٞۖ-ۜ۟-ۤۧ-۪ۨ-ܑۭܰ-݊ަ-ްँ-ः़ा-्॑-॔ॢ-ॣঁ-ঃ়া-ৄে-ৈো-্ৗৢ-ৣਁ-ਃ਼ਾ-ੂੇ-ੈੋ-੍ੰ-ੱઁ-ઃ઼ા-ૅે-ૉો-્ૢ-ૣଁ-ଃ଼ା-ୃେ-ୈୋ-୍ୖ-ୗஂா-ூெ-ைொ-்ௗఁ-ఃా-ౄె-ైొ-్ౕ-ౖಂ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕ-ೖം-ഃാ-ൃെ-ൈൊ-്ൗං-ඃ්ා-ුූෘ-ෟෲ-ෳัิ-ฺ็-๎ັິ-ູົ-ຼ່-ໍ༘-༹༙༵༷༾-༿ཱ-྄྆-྇ྐ-ྗྙ-ྼ࿆ာ-ဲံ-္ၖ-ၙ፟ᜒ-᜔ᜲ-᜴ᝒ-ᝓᝲ-ᝳា-៓៝᠋-᠍ᢩᤠ-ᤫᤰ-᤻ᦰ-ᧀᧈ-ᧉᨗ-ᨛ᷀-᷃⃐-⃥⃜⃡-⃫〪-゙〯-゚ꠂ꠆ꠋꠣ-ꠧﬞ︀-️︠-︣0-9٠-٩۰-۹०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉០-៩᠐-᠙᥆-᥏᧐-᧙0-9_",hashChars:"#\\uFF03"}}(),r="["+e+"]";return"("+("^|$|[^&/"+e+"]")+")("+("["+n+"]")+")("+r+"*"+("["+t+"]")+r+"*)"}(),"i");const h={getHashtagMatch:function(t){const e=u.exec(t);if(null===e)return null;const n=e[3].length+1,r=e.index+e[1].length;return{end:r+n,start:r}}};function l(e,r=h){return n(...t(e,r.getHashtagMatch,s,(t=>o(t.getTextContent()))))}const g=c({config:h,name:"@lexical/hashtag/Hashtag",nodes:[s],register:l});export{o as $createHashtagNode,i as $isHashtagNode,g as HashtagExtension,s as HashtagNode,l as registerLexicalHashtag};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { LexicalEditor } from 'lexical';
9
+ /** @internal */
10
+ declare const defaultHashtagConfig: HashtagConfig;
11
+ /** @internal */
12
+ export declare function registerLexicalHashtag(editor: LexicalEditor, config?: typeof defaultHashtagConfig): () => void;
13
+ export interface HashtagConfig {
14
+ /**
15
+ * The matching function used by the extension. Has a default
16
+ * implementation that should be suitable for most use cases.
17
+ *
18
+ * @param text The string of text to match
19
+ * @returns `null` if no match, otherwise an object with the start and end index of the first `#hashtag` match
20
+ */
21
+ getHashtagMatch: (text: string) => null | {
22
+ start: number;
23
+ end: number;
24
+ };
25
+ }
26
+ /**
27
+ * Add `#hashtag` support to the editor
28
+ */
29
+ export declare const HashtagExtension: import("lexical").LexicalExtension<HashtagConfig, "@lexical/hashtag/Hashtag", unknown, unknown>;
30
+ export {};
package/index.d.ts CHANGED
@@ -5,5 +5,5 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import { $createHashtagNode, $isHashtagNode, HashtagNode } from './LexicalHashtagNode';
9
- export { $createHashtagNode, $isHashtagNode, HashtagNode };
8
+ export { type HashtagConfig, HashtagExtension, registerLexicalHashtag, } from './LexicalHashtagExtension';
9
+ export { $createHashtagNode, $isHashtagNode, HashtagNode, } from './LexicalHashtagNode';
package/package.json CHANGED
@@ -8,12 +8,13 @@
8
8
  "hashtag"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.35.1-nightly.20250924.0",
11
+ "version": "0.36.0",
12
12
  "main": "LexicalHashtag.js",
13
13
  "types": "index.d.ts",
14
14
  "dependencies": {
15
- "@lexical/utils": "0.35.1-nightly.20250924.0",
16
- "lexical": "0.35.1-nightly.20250924.0"
15
+ "@lexical/text": "0.36.0",
16
+ "@lexical/utils": "0.36.0",
17
+ "lexical": "0.36.0"
17
18
  },
18
19
  "repository": {
19
20
  "type": "git",