overtype 1.1.1 → 1.1.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.
- package/README.md +28 -0
- package/dist/overtype.esm.js +131 -30
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +131 -30
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +63 -54
- package/package.json +1 -1
- package/src/overtype.js +147 -13
- package/src/parser.js +3 -1
- package/src/styles.js +29 -20
package/README.md
CHANGED
|
@@ -140,6 +140,26 @@ editors.forEach((editor, index) => {
|
|
|
140
140
|
});
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
+
### Form Integration
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// Use with form validation
|
|
147
|
+
const [editor] = new OverType('#message', {
|
|
148
|
+
placeholder: 'Your message...',
|
|
149
|
+
textareaProps: {
|
|
150
|
+
required: true,
|
|
151
|
+
maxLength: 500,
|
|
152
|
+
name: 'message'
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// The textarea will work with native form validation
|
|
157
|
+
document.querySelector('form').addEventListener('submit', (e) => {
|
|
158
|
+
const content = editor.getValue();
|
|
159
|
+
// Form will automatically validate required field
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
143
163
|
### Custom Theme
|
|
144
164
|
|
|
145
165
|
```javascript
|
|
@@ -270,6 +290,14 @@ new OverType(target, options)
|
|
|
270
290
|
placeholder: 'Start typing...',
|
|
271
291
|
value: '',
|
|
272
292
|
|
|
293
|
+
// Native textarea properties
|
|
294
|
+
textareaProps: {
|
|
295
|
+
required: true,
|
|
296
|
+
maxLength: 500,
|
|
297
|
+
name: 'content',
|
|
298
|
+
// Any HTML textarea attribute
|
|
299
|
+
},
|
|
300
|
+
|
|
273
301
|
// Stats bar
|
|
274
302
|
showStats: false, // Enable/disable stats bar
|
|
275
303
|
statsFormatter: (stats) => { // Custom stats format
|
package/dist/overtype.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.1.
|
|
2
|
+
* OverType v1.1.3
|
|
3
3
|
* A lightweight markdown editor library with perfect WYSIWYG alignment
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @author Demo User
|
|
@@ -105,7 +105,7 @@ var MarkdownParser = class {
|
|
|
105
105
|
* @returns {string|null} Parsed code fence or null
|
|
106
106
|
*/
|
|
107
107
|
static parseCodeBlock(html) {
|
|
108
|
-
if (html.
|
|
108
|
+
if (html.match(/^```(\s*|\w*)$/)) {
|
|
109
109
|
return `<div><span class="code-fence">${html}</span></div>`;
|
|
110
110
|
}
|
|
111
111
|
return null;
|
|
@@ -1294,7 +1294,7 @@ function generateStyles(options = {}) {
|
|
|
1294
1294
|
const {
|
|
1295
1295
|
fontSize = "14px",
|
|
1296
1296
|
lineHeight = 1.6,
|
|
1297
|
-
fontFamily = "
|
|
1297
|
+
fontFamily = '"SF Mono", SFMono-Regular, Menlo, Monaco, "Cascadia Code", Consolas, "Roboto Mono", "Noto Sans Mono", "Droid Sans Mono", "Ubuntu Mono", "DejaVu Sans Mono", "Liberation Mono", "Courier New", Courier, monospace',
|
|
1298
1298
|
padding = "20px",
|
|
1299
1299
|
theme = null,
|
|
1300
1300
|
mobile = {}
|
|
@@ -1314,7 +1314,8 @@ function generateStyles(options = {}) {
|
|
|
1314
1314
|
return `
|
|
1315
1315
|
/* OverType Editor Styles */
|
|
1316
1316
|
.overtype-container {
|
|
1317
|
-
|
|
1317
|
+
display: grid !important;
|
|
1318
|
+
grid-template-rows: auto 1fr auto !important;
|
|
1318
1319
|
width: 100% !important;
|
|
1319
1320
|
height: 100% !important;
|
|
1320
1321
|
${themeVars ? `
|
|
@@ -1322,12 +1323,26 @@ function generateStyles(options = {}) {
|
|
|
1322
1323
|
${themeVars}` : ""}
|
|
1323
1324
|
}
|
|
1324
1325
|
|
|
1326
|
+
/* Auto-resize mode styles */
|
|
1327
|
+
.overtype-container.overtype-auto-resize {
|
|
1328
|
+
height: auto !important;
|
|
1329
|
+
grid-template-rows: auto auto auto !important;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
.overtype-container.overtype-auto-resize .overtype-wrapper {
|
|
1333
|
+
height: auto !important;
|
|
1334
|
+
min-height: 60px !important;
|
|
1335
|
+
overflow: visible !important;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1325
1338
|
.overtype-wrapper {
|
|
1326
1339
|
position: relative !important;
|
|
1327
1340
|
width: 100% !important;
|
|
1328
|
-
height: 100% !important;
|
|
1341
|
+
height: 100% !important; /* Take full height of grid cell */
|
|
1342
|
+
min-height: 60px !important; /* Minimum usable height */
|
|
1329
1343
|
overflow: hidden !important;
|
|
1330
1344
|
background: var(--bg-secondary, #ffffff) !important;
|
|
1345
|
+
grid-row: 2 !important; /* Always second row in grid */
|
|
1331
1346
|
}
|
|
1332
1347
|
|
|
1333
1348
|
/* Critical alignment styles - must be identical for both layers */
|
|
@@ -1342,6 +1357,8 @@ function generateStyles(options = {}) {
|
|
|
1342
1357
|
|
|
1343
1358
|
/* Font properties - any difference breaks alignment */
|
|
1344
1359
|
font-family: ${fontFamily} !important;
|
|
1360
|
+
font-synthesis: none !important; /* no faux bold/italic width drift */
|
|
1361
|
+
font-variant-ligatures: none !important; /* keep metrics stable for code */
|
|
1345
1362
|
font-size: var(--instance-font-size, ${fontSize}) !important;
|
|
1346
1363
|
line-height: var(--instance-line-height, ${lineHeight}) !important;
|
|
1347
1364
|
font-weight: normal !important;
|
|
@@ -1608,15 +1625,9 @@ function generateStyles(options = {}) {
|
|
|
1608
1625
|
}
|
|
1609
1626
|
|
|
1610
1627
|
/* Stats bar */
|
|
1611
|
-
.overtype-wrapper.with-stats {
|
|
1612
|
-
padding-bottom: 40px !important;
|
|
1613
|
-
}
|
|
1614
1628
|
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
bottom: 0 !important;
|
|
1618
|
-
left: 0 !important;
|
|
1619
|
-
right: 0 !important;
|
|
1629
|
+
/* Stats bar - positioned by grid, not absolute */
|
|
1630
|
+
.overtype-stats {
|
|
1620
1631
|
height: 40px !important;
|
|
1621
1632
|
padding: 0 20px !important;
|
|
1622
1633
|
background: #f8f9fa !important;
|
|
@@ -1627,24 +1638,24 @@ function generateStyles(options = {}) {
|
|
|
1627
1638
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
|
1628
1639
|
font-size: 0.85rem !important;
|
|
1629
1640
|
color: #666 !important;
|
|
1630
|
-
|
|
1641
|
+
grid-row: 3 !important; /* Always third row in grid */
|
|
1631
1642
|
}
|
|
1632
1643
|
|
|
1633
1644
|
/* Dark theme stats bar */
|
|
1634
|
-
.overtype-
|
|
1645
|
+
.overtype-container[data-theme="cave"] .overtype-stats {
|
|
1635
1646
|
background: var(--bg-secondary, #1D2D3E) !important;
|
|
1636
1647
|
border-top: 1px solid rgba(197, 221, 232, 0.1) !important;
|
|
1637
1648
|
color: var(--text, #c5dde8) !important;
|
|
1638
1649
|
}
|
|
1639
1650
|
|
|
1640
|
-
.overtype-
|
|
1651
|
+
.overtype-stats .overtype-stat {
|
|
1641
1652
|
display: flex !important;
|
|
1642
1653
|
align-items: center !important;
|
|
1643
1654
|
gap: 5px !important;
|
|
1644
1655
|
white-space: nowrap !important;
|
|
1645
1656
|
}
|
|
1646
1657
|
|
|
1647
|
-
.overtype-
|
|
1658
|
+
.overtype-stats .live-dot {
|
|
1648
1659
|
width: 8px !important;
|
|
1649
1660
|
height: 8px !important;
|
|
1650
1661
|
background: #4caf50 !important;
|
|
@@ -1657,11 +1668,6 @@ function generateStyles(options = {}) {
|
|
|
1657
1668
|
50% { opacity: 0.6; transform: scale(1.2); }
|
|
1658
1669
|
}
|
|
1659
1670
|
|
|
1660
|
-
/* Adjust textarea and preview for stats bar */
|
|
1661
|
-
.overtype-wrapper.with-stats .overtype-input,
|
|
1662
|
-
.overtype-wrapper.with-stats .overtype-preview {
|
|
1663
|
-
height: calc(100% - 40px) !important;
|
|
1664
|
-
}
|
|
1665
1671
|
|
|
1666
1672
|
/* Toolbar Styles */
|
|
1667
1673
|
.overtype-toolbar {
|
|
@@ -1672,6 +1678,9 @@ function generateStyles(options = {}) {
|
|
|
1672
1678
|
background: var(--toolbar-bg, var(--bg-primary, #f8f9fa));
|
|
1673
1679
|
overflow-x: auto;
|
|
1674
1680
|
-webkit-overflow-scrolling: touch;
|
|
1681
|
+
flex-shrink: 0;
|
|
1682
|
+
height: auto !important;
|
|
1683
|
+
grid-row: 1 !important; /* Always first row in grid */
|
|
1675
1684
|
}
|
|
1676
1685
|
|
|
1677
1686
|
.overtype-toolbar-button {
|
|
@@ -2223,8 +2232,16 @@ var _OverType = class _OverType {
|
|
|
2223
2232
|
padding: "12px",
|
|
2224
2233
|
lineHeight: 1.5
|
|
2225
2234
|
},
|
|
2235
|
+
// Native textarea properties
|
|
2236
|
+
textareaProps: {},
|
|
2226
2237
|
// Behavior
|
|
2227
2238
|
autofocus: false,
|
|
2239
|
+
autoResize: false,
|
|
2240
|
+
// Auto-expand height with content
|
|
2241
|
+
minHeight: "100px",
|
|
2242
|
+
// Minimum height for autoResize mode
|
|
2243
|
+
maxHeight: null,
|
|
2244
|
+
// Maximum height for autoResize mode (null = unlimited)
|
|
2228
2245
|
placeholder: "Start typing...",
|
|
2229
2246
|
value: "",
|
|
2230
2247
|
// Callbacks
|
|
@@ -2341,9 +2358,6 @@ var _OverType = class _OverType {
|
|
|
2341
2358
|
}
|
|
2342
2359
|
this.wrapper = document.createElement("div");
|
|
2343
2360
|
this.wrapper.className = "overtype-wrapper";
|
|
2344
|
-
if (this.options.showStats) {
|
|
2345
|
-
this.wrapper.classList.add("with-stats");
|
|
2346
|
-
}
|
|
2347
2361
|
if (this.options.fontSize) {
|
|
2348
2362
|
this.wrapper.style.setProperty("--instance-font-size", this.options.fontSize);
|
|
2349
2363
|
}
|
|
@@ -2358,19 +2372,47 @@ var _OverType = class _OverType {
|
|
|
2358
2372
|
this.textarea.className = "overtype-input";
|
|
2359
2373
|
this.textarea.placeholder = this.options.placeholder;
|
|
2360
2374
|
this._configureTextarea();
|
|
2375
|
+
if (this.options.textareaProps) {
|
|
2376
|
+
Object.entries(this.options.textareaProps).forEach(([key, value]) => {
|
|
2377
|
+
if (key === "className" || key === "class") {
|
|
2378
|
+
this.textarea.className += " " + value;
|
|
2379
|
+
} else if (key === "style" && typeof value === "object") {
|
|
2380
|
+
Object.assign(this.textarea.style, value);
|
|
2381
|
+
} else {
|
|
2382
|
+
this.textarea.setAttribute(key, value);
|
|
2383
|
+
}
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2361
2386
|
this.preview = document.createElement("div");
|
|
2362
2387
|
this.preview.className = "overtype-preview";
|
|
2363
2388
|
this.preview.setAttribute("aria-hidden", "true");
|
|
2364
2389
|
this.wrapper.appendChild(this.textarea);
|
|
2365
2390
|
this.wrapper.appendChild(this.preview);
|
|
2391
|
+
this.container.appendChild(this.wrapper);
|
|
2366
2392
|
if (this.options.showStats) {
|
|
2367
2393
|
this.statsBar = document.createElement("div");
|
|
2368
2394
|
this.statsBar.className = "overtype-stats";
|
|
2369
|
-
this.
|
|
2395
|
+
this.container.appendChild(this.statsBar);
|
|
2370
2396
|
this._updateStats();
|
|
2371
2397
|
}
|
|
2372
|
-
this.container.appendChild(this.wrapper);
|
|
2373
2398
|
this.element.appendChild(this.container);
|
|
2399
|
+
if (window.location.pathname.includes("demo.html")) {
|
|
2400
|
+
console.log("_createDOM completed:", {
|
|
2401
|
+
elementId: this.element.id,
|
|
2402
|
+
autoResize: this.options.autoResize,
|
|
2403
|
+
containerClasses: this.container.className,
|
|
2404
|
+
hasStats: !!this.statsBar,
|
|
2405
|
+
hasToolbar: this.options.toolbar
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
if (this.options.autoResize) {
|
|
2409
|
+
this._setupAutoResize();
|
|
2410
|
+
} else {
|
|
2411
|
+
this.container.classList.remove("overtype-auto-resize");
|
|
2412
|
+
if (window.location.pathname.includes("demo.html")) {
|
|
2413
|
+
console.log("Removed auto-resize class from:", this.element.id);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2374
2416
|
}
|
|
2375
2417
|
/**
|
|
2376
2418
|
* Configure textarea attributes
|
|
@@ -2393,6 +2435,13 @@ var _OverType = class _OverType {
|
|
|
2393
2435
|
if (this.options.autofocus) {
|
|
2394
2436
|
this.textarea.focus();
|
|
2395
2437
|
}
|
|
2438
|
+
if (this.options.autoResize) {
|
|
2439
|
+
if (!this.container.classList.contains("overtype-auto-resize")) {
|
|
2440
|
+
this._setupAutoResize();
|
|
2441
|
+
}
|
|
2442
|
+
} else {
|
|
2443
|
+
this.container.classList.remove("overtype-auto-resize");
|
|
2444
|
+
}
|
|
2396
2445
|
this.updatePreview();
|
|
2397
2446
|
}
|
|
2398
2447
|
/**
|
|
@@ -2517,6 +2566,9 @@ var _OverType = class _OverType {
|
|
|
2517
2566
|
setValue(value) {
|
|
2518
2567
|
this.textarea.value = value;
|
|
2519
2568
|
this.updatePreview();
|
|
2569
|
+
if (this.options.autoResize) {
|
|
2570
|
+
this._updateAutoHeight();
|
|
2571
|
+
}
|
|
2520
2572
|
}
|
|
2521
2573
|
/**
|
|
2522
2574
|
* Focus the editor
|
|
@@ -2580,6 +2632,57 @@ var _OverType = class _OverType {
|
|
|
2580
2632
|
`;
|
|
2581
2633
|
}
|
|
2582
2634
|
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Setup auto-resize functionality
|
|
2637
|
+
* @private
|
|
2638
|
+
*/
|
|
2639
|
+
_setupAutoResize() {
|
|
2640
|
+
this.container.classList.add("overtype-auto-resize");
|
|
2641
|
+
this.previousHeight = null;
|
|
2642
|
+
this._updateAutoHeight();
|
|
2643
|
+
this.textarea.addEventListener("input", () => this._updateAutoHeight());
|
|
2644
|
+
window.addEventListener("resize", () => this._updateAutoHeight());
|
|
2645
|
+
}
|
|
2646
|
+
/**
|
|
2647
|
+
* Update height based on scrollHeight
|
|
2648
|
+
* @private
|
|
2649
|
+
*/
|
|
2650
|
+
_updateAutoHeight() {
|
|
2651
|
+
if (!this.options.autoResize)
|
|
2652
|
+
return;
|
|
2653
|
+
const textarea = this.textarea;
|
|
2654
|
+
const preview = this.preview;
|
|
2655
|
+
const wrapper = this.wrapper;
|
|
2656
|
+
const computed = window.getComputedStyle(textarea);
|
|
2657
|
+
const paddingTop = parseFloat(computed.paddingTop);
|
|
2658
|
+
const paddingBottom = parseFloat(computed.paddingBottom);
|
|
2659
|
+
const scrollTop = textarea.scrollTop;
|
|
2660
|
+
textarea.style.setProperty("height", "auto", "important");
|
|
2661
|
+
let newHeight = textarea.scrollHeight;
|
|
2662
|
+
if (this.options.minHeight) {
|
|
2663
|
+
const minHeight = parseInt(this.options.minHeight);
|
|
2664
|
+
newHeight = Math.max(newHeight, minHeight);
|
|
2665
|
+
}
|
|
2666
|
+
let overflow = "hidden";
|
|
2667
|
+
if (this.options.maxHeight) {
|
|
2668
|
+
const maxHeight = parseInt(this.options.maxHeight);
|
|
2669
|
+
if (newHeight > maxHeight) {
|
|
2670
|
+
newHeight = maxHeight;
|
|
2671
|
+
overflow = "auto";
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
const heightPx = newHeight + "px";
|
|
2675
|
+
textarea.style.setProperty("height", heightPx, "important");
|
|
2676
|
+
textarea.style.setProperty("overflow-y", overflow, "important");
|
|
2677
|
+
preview.style.setProperty("height", heightPx, "important");
|
|
2678
|
+
preview.style.setProperty("overflow-y", overflow, "important");
|
|
2679
|
+
wrapper.style.setProperty("height", heightPx, "important");
|
|
2680
|
+
textarea.scrollTop = scrollTop;
|
|
2681
|
+
preview.scrollTop = scrollTop;
|
|
2682
|
+
if (this.previousHeight !== newHeight) {
|
|
2683
|
+
this.previousHeight = newHeight;
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2583
2686
|
/**
|
|
2584
2687
|
* Show or hide stats bar
|
|
2585
2688
|
* @param {boolean} show - Whether to show stats
|
|
@@ -2589,13 +2692,11 @@ var _OverType = class _OverType {
|
|
|
2589
2692
|
if (show && !this.statsBar) {
|
|
2590
2693
|
this.statsBar = document.createElement("div");
|
|
2591
2694
|
this.statsBar.className = "overtype-stats";
|
|
2592
|
-
this.
|
|
2593
|
-
this.wrapper.classList.add("with-stats");
|
|
2695
|
+
this.container.appendChild(this.statsBar);
|
|
2594
2696
|
this._updateStats();
|
|
2595
2697
|
} else if (!show && this.statsBar) {
|
|
2596
2698
|
this.statsBar.remove();
|
|
2597
2699
|
this.statsBar = null;
|
|
2598
|
-
this.wrapper.classList.remove("with-stats");
|
|
2599
2700
|
}
|
|
2600
2701
|
}
|
|
2601
2702
|
/**
|