testomatio-editor-blocks 0.4.56 → 0.4.58

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.
@@ -1101,58 +1101,15 @@ function parseQuote(lines, index) {
1101
1101
  };
1102
1102
  }
1103
1103
  function parseParagraph(lines, index) {
1104
- const buffer = [];
1105
- let next = index;
1106
- const isTermination = (line) => {
1107
- const trimmed = line.trim();
1108
- if (!trimmed) {
1109
- return true;
1110
- }
1111
- if (trimmed.startsWith(":::test-case")) {
1112
- return true;
1113
- }
1114
- if (trimmed.startsWith("* ")) {
1115
- return true;
1116
- }
1117
- if (trimmed.startsWith("#")) {
1118
- return true;
1119
- }
1120
- if (trimmed.startsWith(">")) {
1121
- return true;
1122
- }
1123
- if (trimmed.startsWith("```")) {
1124
- return true;
1125
- }
1126
- if (detectListType(trimmed)) {
1127
- return true;
1128
- }
1129
- return false;
1130
- };
1131
- while (next < lines.length) {
1132
- const line = lines[next];
1133
- if (isTableRowLine(line) &&
1134
- next + 1 < lines.length &&
1135
- isSeparatorRow(lines[next + 1])) {
1136
- break;
1137
- }
1138
- if (isTermination(line) && buffer.length > 0) {
1139
- break;
1140
- }
1141
- if (!line.trim()) {
1142
- next += 1;
1143
- break;
1144
- }
1145
- buffer.push(line.trim());
1146
- next += 1;
1147
- }
1104
+ const line = lines[index];
1148
1105
  return {
1149
1106
  block: {
1150
1107
  type: "paragraph",
1151
1108
  props: cloneBaseProps(),
1152
- content: createTextContent(unescapeMarkdown(buffer.join(" "))),
1109
+ content: createTextContent(unescapeMarkdown(line.trim())),
1153
1110
  children: [],
1154
1111
  },
1155
- nextIndex: next,
1112
+ nextIndex: index + 1,
1156
1113
  };
1157
1114
  }
1158
1115
  function parseSnippetWrapper(lines, index) {
@@ -951,6 +951,11 @@ html.dark .bn-step-image-preview__content {
951
951
  overflow-x: clip;
952
952
  }
953
953
 
954
+ .bn-container .bn-suggestion-menu {
955
+ max-height: none !important;
956
+ overflow: visible !important;
957
+ }
958
+
954
959
  [data-tooltip] {
955
960
  position: relative;
956
961
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testomatio-editor-blocks",
3
- "version": "0.4.56",
3
+ "version": "0.4.58",
4
4
  "description": "Custom BlockNote schema, markdown conversion helpers, and UI for Testomatio-style test cases and steps.",
5
5
  "type": "module",
6
6
  "main": "./package/index.js",
package/src/App.tsx CHANGED
@@ -364,20 +364,36 @@ function CustomSlashMenu() {
364
364
  offset(10),
365
365
  size({
366
366
  apply({ elements }) {
367
- Object.assign(elements.floating.style, { maxHeight: "" });
367
+ Object.assign(elements.floating.style, { maxHeight: "", overflowY: "" });
368
368
  },
369
369
  }),
370
370
  flip({
371
+ padding: 10,
371
372
  fallbackPlacements: ["top-start"],
372
373
  }),
373
- shift(),
374
- size({
375
- apply({ availableHeight, elements }) {
374
+ shift({ padding: 10 }),
375
+ {
376
+ name: "fitToViewport",
377
+ fn({ y, rects, elements }) {
378
+ const padding = 10;
379
+ if (y < padding) {
380
+ const bottomEdge = rects.reference.y - 10;
381
+ const maxHeight = Math.max(bottomEdge - padding, 100);
382
+ Object.assign(elements.floating.style, {
383
+ maxHeight: `${maxHeight}px`,
384
+ overflowY: "auto",
385
+ });
386
+ return { y: padding };
387
+ }
388
+ const viewportHeight = window.innerHeight;
389
+ const available = viewportHeight - y - padding;
376
390
  Object.assign(elements.floating.style, {
377
- maxHeight: `${Math.max(availableHeight - 10, 0)}px`,
391
+ maxHeight: `${Math.max(available, 100)}px`,
392
+ overflowY: "auto",
378
393
  });
394
+ return {};
379
395
  },
380
- }),
396
+ },
381
397
  ],
382
398
  }}
383
399
  />
@@ -1309,63 +1309,15 @@ function parseQuote(lines: string[], index: number): { block: CustomPartialBlock
1309
1309
  }
1310
1310
 
1311
1311
  function parseParagraph(lines: string[], index: number): { block: CustomPartialBlock; nextIndex: number } {
1312
- const buffer: string[] = [];
1313
- let next = index;
1314
-
1315
- const isTermination = (line: string) => {
1316
- const trimmed = line.trim();
1317
- if (!trimmed) {
1318
- return true;
1319
- }
1320
- if (trimmed.startsWith(":::test-case")) {
1321
- return true;
1322
- }
1323
- if (trimmed.startsWith("* ")) {
1324
- return true;
1325
- }
1326
- if (trimmed.startsWith("#")) {
1327
- return true;
1328
- }
1329
- if (trimmed.startsWith(">")) {
1330
- return true;
1331
- }
1332
- if (trimmed.startsWith("```") ) {
1333
- return true;
1334
- }
1335
- if (detectListType(trimmed)) {
1336
- return true;
1337
- }
1338
- return false;
1339
- };
1340
-
1341
- while (next < lines.length) {
1342
- const line = lines[next];
1343
- if (
1344
- isTableRowLine(line) &&
1345
- next + 1 < lines.length &&
1346
- isSeparatorRow(lines[next + 1])
1347
- ) {
1348
- break;
1349
- }
1350
- if (isTermination(line) && buffer.length > 0) {
1351
- break;
1352
- }
1353
- if (!line.trim()) {
1354
- next += 1;
1355
- break;
1356
- }
1357
- buffer.push(line.trim());
1358
- next += 1;
1359
- }
1360
-
1312
+ const line = lines[index];
1361
1313
  return {
1362
1314
  block: {
1363
1315
  type: "paragraph",
1364
1316
  props: cloneBaseProps(),
1365
- content: createTextContent(unescapeMarkdown(buffer.join(" "))),
1317
+ content: createTextContent(unescapeMarkdown(line.trim())),
1366
1318
  children: [],
1367
1319
  },
1368
- nextIndex: next,
1320
+ nextIndex: index + 1,
1369
1321
  };
1370
1322
  }
1371
1323
 
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { markdownToBlocks } from "./customMarkdownConverter";
2
+ import { markdownToBlocks, blocksToMarkdown } from "./customMarkdownConverter";
3
3
 
4
4
  const baseProps = {
5
5
  textAlignment: "left" as const,
@@ -131,6 +131,37 @@ describe("markdownToBlocks", () => {
131
131
  });
132
132
  });
133
133
 
134
+ it("treats each consecutive text line as a separate paragraph block", () => {
135
+ const markdown = "One line\nAnother line\nThird line";
136
+ const blocks = markdownToBlocks(markdown);
137
+
138
+ expect(blocks).toHaveLength(3);
139
+ expect(blocks[0]).toEqual({
140
+ type: "paragraph",
141
+ props: baseProps,
142
+ content: [{ type: "text", text: "One line", styles: {} }],
143
+ children: [],
144
+ });
145
+ expect(blocks[1]).toEqual({
146
+ type: "paragraph",
147
+ props: baseProps,
148
+ content: [{ type: "text", text: "Another line", styles: {} }],
149
+ children: [],
150
+ });
151
+ expect(blocks[2]).toEqual({
152
+ type: "paragraph",
153
+ props: baseProps,
154
+ content: [{ type: "text", text: "Third line", styles: {} }],
155
+ children: [],
156
+ });
157
+ });
158
+
159
+ it("round-trips consecutive text lines through blocksToMarkdown", () => {
160
+ const markdown = "One line\nAnother line\nThird line";
161
+ const blocks = markdownToBlocks(markdown);
162
+ expect(blocksToMarkdown(blocks as any)).toBe("One line\nAnother line\nThird line");
163
+ });
164
+
134
165
  it("parses combined bold+italic using nested delimiters", () => {
135
166
  const blocks = markdownToBlocks(
136
167
  "The _**Username**_ and **_Password_** fields and ***both*** and ___both___.",
@@ -951,6 +951,11 @@ html.dark .bn-step-image-preview__content {
951
951
  overflow-x: clip;
952
952
  }
953
953
 
954
+ .bn-container .bn-suggestion-menu {
955
+ max-height: none !important;
956
+ overflow: visible !important;
957
+ }
958
+
954
959
  [data-tooltip] {
955
960
  position: relative;
956
961
  }