@prosekit/core 0.2.2 → 0.2.3

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.
@@ -120,6 +120,17 @@ declare interface BaseNodeViewOptions {
120
120
  export { BaseNodeViewOptions }
121
121
  export { BaseNodeViewOptions as BaseNodeViewOptions_alias_1 }
122
122
 
123
+ /**
124
+ * A utility for constructing `className` strings conditionally.
125
+ *
126
+ * It is a re-export of [clsx/lite](https://www.npmjs.com/package/clsx) with stricter types.
127
+ *
128
+ * @public
129
+ */
130
+ declare const clsx: (...args: Array<string | boolean | null | undefined>) => string;
131
+ export { clsx }
132
+ export { clsx as clsx_alias_1 }
133
+
123
134
  export declare function collectNodes(content: NodeContent): ProseMirrorNode[];
124
135
 
125
136
  export declare interface CommandApplier<Args extends any[] = any[]> {
@@ -321,6 +332,13 @@ declare function defineKeymap(keymap: Keymap): Extension;
321
332
  export { defineKeymap }
322
333
  export { defineKeymap as defineKeymap_alias_1 }
323
334
 
335
+ /**
336
+ * @public
337
+ */
338
+ declare function defineMarkAttr(options: MarkAttrOptions): Extension;
339
+ export { defineMarkAttr }
340
+ export { defineMarkAttr as defineMarkAttr_alias_1 }
341
+
324
342
  /**
325
343
  * @public
326
344
  */
@@ -340,6 +358,17 @@ export { defineMountHandler }
340
358
  export { defineMountHandler as defineMountHandler_alias_1 }
341
359
 
342
360
  /**
361
+ * Defines an attribute for a node type.
362
+ *
363
+ * @public
364
+ */
365
+ declare function defineNodeAttr(options: NodeAttrOptions): Extension;
366
+ export { defineNodeAttr }
367
+ export { defineNodeAttr as defineNodeAttr_alias_1 }
368
+
369
+ /**
370
+ * Defines a node type.
371
+ *
343
372
  * @public
344
373
  */
345
374
  declare function defineNodeSpec<NodeName extends string>(options: NodeSpecOptions<NodeName>): Extension<{
@@ -701,6 +730,8 @@ declare function isAllSelection(sel: Selection_2): sel is AllSelection;
701
730
  export { isAllSelection }
702
731
  export { isAllSelection as isAllSelection_alias_1 }
703
732
 
733
+ export declare function isElement(value: unknown): value is Element;
734
+
704
735
  export declare const isMac: boolean;
705
736
 
706
737
  /**
@@ -796,6 +827,36 @@ declare type KeymapPayload = Keymap;
796
827
  export { KeymapPayload }
797
828
  export { KeymapPayload as KeymapPayload_alias_1 }
798
829
 
830
+ /**
831
+ * @public
832
+ */
833
+ declare interface MarkAttrOptions {
834
+ /**
835
+ * The name of the mark type.
836
+ */
837
+ type: string;
838
+ /**
839
+ * The name of the attribute.
840
+ */
841
+ attr: string;
842
+ /**
843
+ * The default value for this attribute, to use when no explicit value is
844
+ * provided. Attributes that have no default must be provided whenever a mark
845
+ * of a type that has them is created.
846
+ */
847
+ default?: any;
848
+ /**
849
+ * Returns the attribute key and value to be set on the DOM node.
850
+ */
851
+ toDOM?: (value: any) => [key: string, value: string] | null | void;
852
+ /**
853
+ * Parses the attribute value from the DOM.
854
+ */
855
+ parseDOM?: (node: HTMLElement) => any;
856
+ }
857
+ export { MarkAttrOptions }
858
+ export { MarkAttrOptions as MarkAttrOptions_alias_1 }
859
+
799
860
  export declare interface MarkBuilder {
800
861
  (attrs: Attrs | null, ...children: NodeChild[]): ProseMirrorNode[];
801
862
  (...children: NodeChild[]): ProseMirrorNode[];
@@ -822,6 +883,36 @@ declare type MountHandler = (view: EditorView) => void;
822
883
  export { MountHandler }
823
884
  export { MountHandler as MountHandler_alias_1 }
824
885
 
886
+ /**
887
+ * @public
888
+ */
889
+ declare interface NodeAttrOptions {
890
+ /**
891
+ * The name of the node type.
892
+ */
893
+ type: string;
894
+ /**
895
+ * The name of the attribute.
896
+ */
897
+ attr: string;
898
+ /**
899
+ * The default value for this attribute, to use when no explicit value is
900
+ * provided. Attributes that have no default must be provided whenever a node
901
+ * of a type that has them is created.
902
+ */
903
+ default?: any;
904
+ /**
905
+ * Returns the attribute key and value to be set on the DOM node.
906
+ */
907
+ toDOM?: (value: any) => [key: string, value: string] | null | void;
908
+ /**
909
+ * Parses the attribute value from the DOM.
910
+ */
911
+ parseDOM?: (node: HTMLElement) => any;
912
+ }
913
+ export { NodeAttrOptions }
914
+ export { NodeAttrOptions as NodeAttrOptions_alias_1 }
915
+
825
916
  export declare interface NodeBuilder {
826
917
  (attrs: Attrs | null, ...children: NodeChild[]): ProseMirrorNode;
827
918
  (...children: NodeChild[]): ProseMirrorNode;
@@ -931,6 +1022,8 @@ export { PluginPayload }
931
1022
  export { PluginPayload as PluginPayload_alias_1 }
932
1023
 
933
1024
  /**
1025
+ * ProseKit extension priority.
1026
+ *
934
1027
  * @public
935
1028
  */
936
1029
  declare const enum Priority {
@@ -15,14 +15,14 @@ export { defineCommands } from './_tsup-dts-rollup';
15
15
  export { defineDefaultState } from './_tsup-dts-rollup';
16
16
  export { DefaultStateOptions } from './_tsup-dts-rollup';
17
17
  export { defineDoc } from './_tsup-dts-rollup';
18
+ export { defineDocChangeHandler } from './_tsup-dts-rollup';
19
+ export { DocChangeHandler } from './_tsup-dts-rollup';
18
20
  export { defineMountHandler } from './_tsup-dts-rollup';
19
21
  export { defineUnmountHandler } from './_tsup-dts-rollup';
20
22
  export { defineUpdateHandler } from './_tsup-dts-rollup';
21
23
  export { MountHandler } from './_tsup-dts-rollup';
22
24
  export { UnmountHandler } from './_tsup-dts-rollup';
23
25
  export { UpdateHandler } from './_tsup-dts-rollup';
24
- export { defineDocChangeHandler } from './_tsup-dts-rollup';
25
- export { DocChangeHandler } from './_tsup-dts-rollup';
26
26
  export { defineHistory } from './_tsup-dts-rollup';
27
27
  export { defineInputRule } from './_tsup-dts-rollup';
28
28
  export { defineBaseKeymap } from './_tsup-dts-rollup';
@@ -30,9 +30,13 @@ export { defineKeymap } from './_tsup-dts-rollup';
30
30
  export { keymapFacet } from './_tsup-dts-rollup';
31
31
  export { Keymap } from './_tsup-dts-rollup';
32
32
  export { KeymapPayload } from './_tsup-dts-rollup';
33
+ export { defineMarkAttr } from './_tsup-dts-rollup';
33
34
  export { defineMarkSpec } from './_tsup-dts-rollup';
35
+ export { MarkAttrOptions } from './_tsup-dts-rollup';
34
36
  export { MarkSpecOptions } from './_tsup-dts-rollup';
37
+ export { defineNodeAttr } from './_tsup-dts-rollup';
35
38
  export { defineNodeSpec } from './_tsup-dts-rollup';
39
+ export { NodeAttrOptions } from './_tsup-dts-rollup';
36
40
  export { NodeSpecOptions } from './_tsup-dts-rollup';
37
41
  export { defineNodeView } from './_tsup-dts-rollup';
38
42
  export { NodeViewOptions } from './_tsup-dts-rollup';
@@ -59,6 +63,7 @@ export { SelectionJSON } from './_tsup-dts-rollup';
59
63
  export { StateJSON } from './_tsup-dts-rollup';
60
64
  export { Priority } from './_tsup-dts-rollup';
61
65
  export { SimplifyUnion } from './_tsup-dts-rollup';
66
+ export { clsx } from './_tsup-dts-rollup';
62
67
  export { _getId } from './_tsup-dts-rollup';
63
68
  export { getMarkType } from './_tsup-dts-rollup';
64
69
  export { getNodeType } from './_tsup-dts-rollup';
@@ -1099,26 +1099,110 @@ function defineBaseCommands() {
1099
1099
  });
1100
1100
  }
1101
1101
 
1102
+ // src/utils/is-element.ts
1103
+ var hasElement = typeof Element !== "undefined";
1104
+ function isElement(value) {
1105
+ return hasElement && value instanceof Element;
1106
+ }
1107
+
1108
+ // src/utils/is-not-null.ts
1109
+ function isNotNull(value) {
1110
+ return value != null;
1111
+ }
1112
+
1102
1113
  // src/extensions/node-spec.ts
1103
1114
  function defineNodeSpec(options) {
1104
- return nodeSpecFacet.extension([options]);
1115
+ const payload = [options, void 0];
1116
+ return nodeSpecFacet.extension([payload]);
1117
+ }
1118
+ function defineNodeAttr(options) {
1119
+ const payload = [void 0, options];
1120
+ return nodeSpecFacet.extension([payload]);
1105
1121
  }
1106
1122
  var nodeSpecFacet = Facet.define({
1107
- convert: (options) => {
1123
+ convert: (payloads) => {
1108
1124
  const nodes = {};
1109
1125
  let topNodeName = void 0;
1110
- for (const { name, topNode, ...spec } of options) {
1126
+ const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1127
+ const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
1128
+ for (const { name, topNode, ...spec } of specPayloads) {
1111
1129
  if (nodes[name]) {
1112
1130
  throw new ProseKitError(`Node type ${name} has already been defined`);
1113
1131
  }
1114
- if (topNodeName && !topNode) {
1132
+ if (topNode) {
1115
1133
  topNodeName = name;
1116
1134
  }
1117
1135
  nodes[name] = spec;
1118
1136
  }
1137
+ for (const {
1138
+ type,
1139
+ attr,
1140
+ default: defaultValue,
1141
+ toDOM,
1142
+ parseDOM
1143
+ } of attrPayloads) {
1144
+ const spec = nodes[type];
1145
+ if (!spec) {
1146
+ throw new ProseKitError(
1147
+ `Node type ${type} must be defined before defining attributes`
1148
+ );
1149
+ }
1150
+ if (!spec.attrs) {
1151
+ spec.attrs = {};
1152
+ }
1153
+ spec.attrs[attr] = { default: defaultValue };
1154
+ if (toDOM && spec.toDOM) {
1155
+ const existingToDom = spec.toDOM;
1156
+ spec.toDOM = (node) => {
1157
+ const dom = existingToDom(node);
1158
+ if (!dom) {
1159
+ return dom;
1160
+ }
1161
+ const attrDOM = toDOM(node.attrs[attr]);
1162
+ if (!attrDOM) {
1163
+ return dom;
1164
+ }
1165
+ const [key, value] = attrDOM;
1166
+ if (!key) {
1167
+ return dom;
1168
+ }
1169
+ if (Array.isArray(dom)) {
1170
+ if (typeof dom[1] === "object") {
1171
+ return [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)];
1172
+ } else {
1173
+ return [dom[0], { [key]: value }, ...dom.slice(1)];
1174
+ }
1175
+ } else if (isElement(dom)) {
1176
+ dom.setAttribute(key, value);
1177
+ } else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) {
1178
+ dom.dom.setAttribute(key, value);
1179
+ }
1180
+ return dom;
1181
+ };
1182
+ }
1183
+ if (parseDOM && spec.parseDOM) {
1184
+ for (const rule of spec.parseDOM) {
1185
+ const existingGetAttrs = rule.getAttrs;
1186
+ const existingAttrs = rule.attrs;
1187
+ rule.getAttrs = (dom) => {
1188
+ var _a;
1189
+ const attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs;
1190
+ if (attrs === false || !dom || !isElement(dom)) {
1191
+ return attrs != null ? attrs : null;
1192
+ }
1193
+ const value = parseDOM(dom);
1194
+ return {
1195
+ ...attrs,
1196
+ [attr]: value
1197
+ };
1198
+ };
1199
+ }
1200
+ }
1201
+ }
1119
1202
  return { nodes, topNode: topNodeName };
1120
1203
  },
1121
- next: schemaFacet
1204
+ next: schemaFacet,
1205
+ singleton: true
1122
1206
  });
1123
1207
 
1124
1208
  // src/extensions/doc.ts
@@ -1351,20 +1435,93 @@ var inputRuleFacet = Facet.define({
1351
1435
 
1352
1436
  // src/extensions/mark-spec.ts
1353
1437
  function defineMarkSpec(options) {
1354
- return markSpecFacet.extension([options]);
1438
+ const payload = [options, void 0];
1439
+ return markSpecFacet.extension([payload]);
1440
+ }
1441
+ function defineMarkAttr(options) {
1442
+ const payload = [void 0, options];
1443
+ return markSpecFacet.extension([payload]);
1355
1444
  }
1356
1445
  var markSpecFacet = Facet.define({
1357
- convert: (options) => {
1446
+ convert: (payloads) => {
1358
1447
  const marks = {};
1359
- for (const { name, ...spec } of options) {
1448
+ const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1449
+ const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
1450
+ for (const { name, ...spec } of specPayloads) {
1360
1451
  if (marks[name]) {
1361
1452
  throw new ProseKitError(`Mark type ${name} has already been defined`);
1362
1453
  }
1363
1454
  marks[name] = spec;
1364
1455
  }
1456
+ for (const {
1457
+ type,
1458
+ attr,
1459
+ default: defaultValue,
1460
+ toDOM,
1461
+ parseDOM
1462
+ } of attrPayloads) {
1463
+ const spec = marks[type];
1464
+ if (!spec) {
1465
+ throw new ProseKitError(
1466
+ `Mark type ${type} must be defined before defining attributes`
1467
+ );
1468
+ }
1469
+ if (!spec.attrs) {
1470
+ spec.attrs = {};
1471
+ }
1472
+ spec.attrs[attr] = { default: defaultValue };
1473
+ if (toDOM && spec.toDOM) {
1474
+ const existingToDom = spec.toDOM;
1475
+ spec.toDOM = (mark, inline) => {
1476
+ const dom = existingToDom(mark, inline);
1477
+ if (!dom) {
1478
+ return dom;
1479
+ }
1480
+ const attrDOM = toDOM(mark.attrs[attr]);
1481
+ if (!attrDOM) {
1482
+ return dom;
1483
+ }
1484
+ const [key, value] = attrDOM;
1485
+ if (!key) {
1486
+ return dom;
1487
+ }
1488
+ if (Array.isArray(dom)) {
1489
+ if (typeof dom[1] === "object") {
1490
+ return [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)];
1491
+ } else {
1492
+ return [dom[0], { [key]: value }, ...dom.slice(1)];
1493
+ }
1494
+ } else if (isElement(dom)) {
1495
+ dom.setAttribute(key, value);
1496
+ } else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) {
1497
+ dom.dom.setAttribute(key, value);
1498
+ }
1499
+ return dom;
1500
+ };
1501
+ }
1502
+ if (parseDOM && spec.parseDOM) {
1503
+ for (const rule of spec.parseDOM) {
1504
+ const existingGetAttrs = rule.getAttrs;
1505
+ const existingAttrs = rule.attrs;
1506
+ rule.getAttrs = (dom) => {
1507
+ var _a;
1508
+ const attrs = (_a = existingGetAttrs == null ? void 0 : existingGetAttrs(dom)) != null ? _a : existingAttrs;
1509
+ if (attrs === false || !dom || !isElement(dom)) {
1510
+ return attrs != null ? attrs : null;
1511
+ }
1512
+ const value = parseDOM(dom);
1513
+ return {
1514
+ ...attrs,
1515
+ [attr]: value
1516
+ };
1517
+ };
1518
+ }
1519
+ }
1520
+ }
1365
1521
  return { marks, nodes: {} };
1366
1522
  },
1367
- next: schemaFacet
1523
+ next: schemaFacet,
1524
+ singleton: true
1368
1525
  });
1369
1526
 
1370
1527
  // src/extensions/node-view.ts
@@ -1444,6 +1601,10 @@ function defineText() {
1444
1601
  });
1445
1602
  }
1446
1603
 
1604
+ // src/utils/clsx.ts
1605
+ import clsxLite from "clsx/lite";
1606
+ var clsx = clsxLite;
1607
+
1447
1608
  // src/utils/get-id.ts
1448
1609
  var id = 0;
1449
1610
  function getId() {
@@ -1457,6 +1618,7 @@ export {
1457
1618
  ProseKitError,
1458
1619
  getId as _getId,
1459
1620
  addMark,
1621
+ clsx,
1460
1622
  createEditor,
1461
1623
  defineBaseCommands,
1462
1624
  defineBaseKeymap,
@@ -1467,8 +1629,10 @@ export {
1467
1629
  defineHistory,
1468
1630
  defineInputRule,
1469
1631
  defineKeymap,
1632
+ defineMarkAttr,
1470
1633
  defineMarkSpec,
1471
1634
  defineMountHandler,
1635
+ defineNodeAttr,
1472
1636
  defineNodeSpec,
1473
1637
  defineNodeView,
1474
1638
  defineNodeViewFactory,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -36,6 +36,7 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@prosekit/pm": "^0.1.1",
39
+ "clsx": "^2.1.0",
39
40
  "orderedmap": "^2.1.1",
40
41
  "type-fest": "^4.9.0"
41
42
  },
@@ -43,7 +44,7 @@
43
44
  "@prosekit/dev": "*",
44
45
  "tsup": "^8.0.1",
45
46
  "typescript": "^5.3.3",
46
- "vitest": "^1.1.1"
47
+ "vitest": "^1.1.3"
47
48
  },
48
49
  "scripts": {
49
50
  "build:tsup": "tsup",
package/src/index.ts CHANGED
@@ -14,6 +14,10 @@ export {
14
14
  type DefaultStateOptions,
15
15
  } from './extensions/default-state'
16
16
  export { defineDoc } from './extensions/doc'
17
+ export {
18
+ defineDocChangeHandler,
19
+ type DocChangeHandler,
20
+ } from './extensions/events/doc-change'
17
21
  export {
18
22
  defineMountHandler,
19
23
  defineUnmountHandler,
@@ -22,10 +26,6 @@ export {
22
26
  type UnmountHandler,
23
27
  type UpdateHandler,
24
28
  } from './extensions/events/plugin-view'
25
- export {
26
- defineDocChangeHandler,
27
- type DocChangeHandler,
28
- } from './extensions/events/doc-change'
29
29
  export { defineHistory } from './extensions/history'
30
30
  export { defineInputRule } from './extensions/input-rules'
31
31
  export {
@@ -35,8 +35,18 @@ export {
35
35
  type Keymap,
36
36
  type KeymapPayload,
37
37
  } from './extensions/keymap'
38
- export { defineMarkSpec, type MarkSpecOptions } from './extensions/mark-spec'
39
- export { defineNodeSpec, type NodeSpecOptions } from './extensions/node-spec'
38
+ export {
39
+ defineMarkAttr,
40
+ defineMarkSpec,
41
+ type MarkAttrOptions,
42
+ type MarkSpecOptions,
43
+ } from './extensions/mark-spec'
44
+ export {
45
+ defineNodeAttr,
46
+ defineNodeSpec,
47
+ type NodeAttrOptions,
48
+ type NodeSpecOptions,
49
+ } from './extensions/node-spec'
40
50
  export { defineNodeView, type NodeViewOptions } from './extensions/node-view'
41
51
  export {
42
52
  defineNodeViewFactory,
@@ -64,6 +74,7 @@ export { type ExtensionTyping } from './types/extension-typing'
64
74
  export type { NodeJSON, SelectionJSON, StateJSON } from './types/model'
65
75
  export { Priority } from './types/priority'
66
76
  export { type SimplifyUnion } from './types/simplify-union'
77
+ export { clsx } from './utils/clsx'
67
78
  export { getId as _getId } from './utils/get-id'
68
79
  export { getMarkType } from './utils/get-mark-type'
69
80
  export { getNodeType } from './utils/get-node-type'