overtype 2.1.1 → 2.2.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OverType v2.1.0
2
+ * OverType v2.2.0
3
3
  * A lightweight markdown editor library with perfect WYSIWYG alignment
4
4
  * @license MIT
5
5
  * @author David Miranda
@@ -79,6 +79,7 @@ var MarkdownParser = class {
79
79
  static parseHeader(html) {
80
80
  return html.replace(/^(#{1,3})\s(.+)$/, (match, hashes, content) => {
81
81
  const level = hashes.length;
82
+ content = this.parseInlineElements(content);
82
83
  return `<h${level}><span class="syntax-marker">${hashes} </span>${content}</h${level}>`;
83
84
  });
84
85
  }
@@ -110,6 +111,7 @@ var MarkdownParser = class {
110
111
  */
111
112
  static parseBulletList(html) {
112
113
  return html.replace(/^((?:&nbsp;)*)([-*+])\s(.+)$/, (match, indent, marker, content) => {
114
+ content = this.parseInlineElements(content);
113
115
  return `${indent}<li class="bullet-list"><span class="syntax-marker">${marker} </span>${content}</li>`;
114
116
  });
115
117
  }
@@ -121,6 +123,7 @@ var MarkdownParser = class {
121
123
  */
122
124
  static parseTaskList(html, isPreviewMode = false) {
123
125
  return html.replace(/^((?:&nbsp;)*)-\s+\[([ xX])\]\s+(.+)$/, (match, indent, checked, content) => {
126
+ content = this.parseInlineElements(content);
124
127
  if (isPreviewMode) {
125
128
  const isChecked = checked.toLowerCase() === "x";
126
129
  return `${indent}<li class="task-list"><input type="checkbox" ${isChecked ? "checked" : ""}> ${content}</li>`;
@@ -136,6 +139,7 @@ var MarkdownParser = class {
136
139
  */
137
140
  static parseNumberedList(html) {
138
141
  return html.replace(/^((?:&nbsp;)*)(\d+\.)\s(.+)$/, (match, indent, marker, content) => {
142
+ content = this.parseInlineElements(content);
139
143
  return `${indent}<li class="ordered-list"><span class="syntax-marker">${marker} </span>${content}</li>`;
140
144
  });
141
145
  }
@@ -357,7 +361,9 @@ var MarkdownParser = class {
357
361
  html = this.parseTaskList(html, isPreviewMode);
358
362
  html = this.parseBulletList(html);
359
363
  html = this.parseNumberedList(html);
360
- html = this.parseInlineElements(html);
364
+ if (!html.includes("<li") && !html.includes("<h")) {
365
+ html = this.parseInlineElements(html);
366
+ }
361
367
  if (html.trim() === "") {
362
368
  return "<div>&nbsp;</div>";
363
369
  }
@@ -846,8 +852,10 @@ var solar = {
846
852
  // Yale Blue - icon color
847
853
  toolbarHover: "#f5f5f5",
848
854
  // Light gray - hover background
849
- toolbarActive: "#faf0ca"
855
+ toolbarActive: "#faf0ca",
850
856
  // Lemon Chiffon - active button background
857
+ placeholder: "#999999"
858
+ // Gray - placeholder text
851
859
  }
852
860
  };
853
861
  var cave = {
@@ -910,13 +918,16 @@ var cave = {
910
918
  // Light blue-gray - icon color
911
919
  toolbarHover: "#243546",
912
920
  // Slightly lighter charcoal - hover background
913
- toolbarActive: "#2a3f52"
921
+ toolbarActive: "#2a3f52",
914
922
  // Even lighter - active button background
923
+ placeholder: "#6a7a88"
924
+ // Muted blue-gray - placeholder text
915
925
  }
916
926
  };
917
927
  var themes = {
918
928
  solar,
919
929
  cave,
930
+ auto: solar,
920
931
  // Aliases for backward compatibility
921
932
  light: solar,
922
933
  dark: cave
@@ -928,6 +939,12 @@ function getTheme(theme) {
928
939
  }
929
940
  return theme;
930
941
  }
942
+ function resolveAutoTheme(themeName) {
943
+ if (themeName !== "auto")
944
+ return themeName;
945
+ const mq = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)");
946
+ return (mq == null ? void 0 : mq.matches) ? "cave" : "solar";
947
+ }
931
948
  function themeToCSSVars(colors) {
932
949
  const vars = [];
933
950
  for (const [key, value] of Object.entries(colors)) {
@@ -1141,17 +1158,36 @@ function generateStyles(options = {}) {
1141
1158
  /* Prevent mobile zoom on focus */
1142
1159
  touch-action: manipulation !important;
1143
1160
 
1144
- /* Disable autofill and spellcheck */
1161
+ /* Disable autofill */
1145
1162
  autocomplete: off !important;
1146
1163
  autocorrect: off !important;
1147
1164
  autocapitalize: off !important;
1148
- spellcheck: false !important;
1149
1165
  }
1150
1166
 
1151
1167
  .overtype-wrapper .overtype-input::selection {
1152
1168
  background-color: var(--selection, rgba(244, 211, 94, 0.4));
1153
1169
  }
1154
1170
 
1171
+ /* Placeholder shim - visible when textarea is empty */
1172
+ .overtype-wrapper .overtype-placeholder {
1173
+ position: absolute !important;
1174
+ top: 0 !important;
1175
+ left: 0 !important;
1176
+ width: 100% !important;
1177
+ z-index: 0 !important;
1178
+ pointer-events: none !important;
1179
+ user-select: none !important;
1180
+ font-family: ${fontFamily} !important;
1181
+ font-size: var(--instance-font-size, ${fontSize}) !important;
1182
+ line-height: var(--instance-line-height, ${lineHeight}) !important;
1183
+ padding: var(--instance-padding, ${padding}) !important;
1184
+ box-sizing: border-box !important;
1185
+ color: var(--placeholder, #999) !important;
1186
+ overflow: hidden !important;
1187
+ white-space: nowrap !important;
1188
+ text-overflow: ellipsis !important;
1189
+ }
1190
+
1155
1191
  /* Preview layer styles */
1156
1192
  .overtype-wrapper .overtype-preview {
1157
1193
  /* Layer positioning */
@@ -1419,6 +1455,10 @@ function generateStyles(options = {}) {
1419
1455
 
1420
1456
 
1421
1457
  /* Toolbar Styles */
1458
+ .overtype-toolbar.overtype-toolbar-hidden {
1459
+ display: none !important;
1460
+ }
1461
+
1422
1462
  .overtype-toolbar {
1423
1463
  display: flex !important;
1424
1464
  align-items: center !important;
@@ -1693,19 +1733,14 @@ function generateStyles(options = {}) {
1693
1733
 
1694
1734
  /* Code blocks - proper pre/code styling in preview mode */
1695
1735
  .overtype-container[data-mode="preview"] .overtype-wrapper .overtype-preview pre.code-block {
1696
- background: #2d2d2d !important;
1697
- color: #f8f8f2 !important;
1736
+ background: var(--code-bg, rgba(244, 211, 94, 0.4)) !important;
1737
+ color: var(--code, #0d3b66) !important;
1698
1738
  padding: 1.2em !important;
1699
1739
  border-radius: 3px !important;
1700
1740
  overflow-x: auto !important;
1701
1741
  margin: 0 !important;
1702
1742
  display: block !important;
1703
1743
  }
1704
-
1705
- /* Cave theme code block background in preview mode */
1706
- .overtype-container[data-theme="cave"][data-mode="preview"] .overtype-wrapper .overtype-preview pre.code-block {
1707
- background: #11171F !important;
1708
- }
1709
1744
 
1710
1745
  .overtype-container[data-mode="preview"] .overtype-wrapper .overtype-preview pre.code-block code {
1711
1746
  background: transparent !important;
@@ -1770,16 +1805,17 @@ function generateStyles(options = {}) {
1770
1805
  height: 2px !important;
1771
1806
  }
1772
1807
 
1773
- /* Link Tooltip - Base styles (all browsers) */
1808
+ /* Link Tooltip */
1774
1809
  .overtype-link-tooltip {
1775
- /* Visual styles that work for both positioning methods */
1776
1810
  background: #333 !important;
1777
1811
  color: white !important;
1778
1812
  padding: 6px 10px !important;
1779
1813
  border-radius: 16px !important;
1780
1814
  font-size: 12px !important;
1781
1815
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
1782
- display: none !important;
1816
+ display: flex !important;
1817
+ visibility: hidden !important;
1818
+ pointer-events: none !important;
1783
1819
  z-index: 10000 !important;
1784
1820
  cursor: pointer !important;
1785
1821
  box-shadow: 0 2px 8px rgba(0,0,0,0.3) !important;
@@ -1787,25 +1823,14 @@ function generateStyles(options = {}) {
1787
1823
  white-space: nowrap !important;
1788
1824
  overflow: hidden !important;
1789
1825
  text-overflow: ellipsis !important;
1790
-
1791
- /* Base positioning for Floating UI fallback */
1792
- position: absolute;
1826
+ position: fixed;
1827
+ top: 0;
1828
+ left: 0;
1793
1829
  }
1794
1830
 
1795
1831
  .overtype-link-tooltip.visible {
1796
- display: flex !important;
1797
- }
1798
-
1799
- /* CSS Anchor Positioning (modern browsers only) */
1800
- @supports (position-anchor: --x) and (position-area: center) {
1801
- .overtype-link-tooltip {
1802
- /* Only anchor positioning specific properties */
1803
- position-anchor: var(--target-anchor, --link-0);
1804
- position-area: block-end center;
1805
- margin-top: 8px !important;
1806
- position-try: most-width block-end inline-end, flip-inline, block-start center;
1807
- position-visibility: anchors-visible;
1808
- }
1832
+ visibility: visible !important;
1833
+ pointer-events: auto !important;
1809
1834
  }
1810
1835
 
1811
1836
  ${mobileStyles}
@@ -2887,6 +2912,16 @@ var Toolbar = class {
2887
2912
  } catch (error) {
2888
2913
  }
2889
2914
  }
2915
+ show() {
2916
+ if (this.container) {
2917
+ this.container.classList.remove("overtype-toolbar-hidden");
2918
+ }
2919
+ }
2920
+ hide() {
2921
+ if (this.container) {
2922
+ this.container.classList.add("overtype-toolbar-hidden");
2923
+ }
2924
+ }
2890
2925
  /**
2891
2926
  * Destroy toolbar and cleanup
2892
2927
  */
@@ -2908,6 +2943,1203 @@ var Toolbar = class {
2908
2943
  }
2909
2944
  };
2910
2945
 
2946
+ // node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
2947
+ var min = Math.min;
2948
+ var max = Math.max;
2949
+ var round = Math.round;
2950
+ var createCoords = (v) => ({
2951
+ x: v,
2952
+ y: v
2953
+ });
2954
+ var oppositeSideMap = {
2955
+ left: "right",
2956
+ right: "left",
2957
+ bottom: "top",
2958
+ top: "bottom"
2959
+ };
2960
+ var oppositeAlignmentMap = {
2961
+ start: "end",
2962
+ end: "start"
2963
+ };
2964
+ function clamp(start, value, end) {
2965
+ return max(start, min(value, end));
2966
+ }
2967
+ function evaluate(value, param) {
2968
+ return typeof value === "function" ? value(param) : value;
2969
+ }
2970
+ function getSide(placement) {
2971
+ return placement.split("-")[0];
2972
+ }
2973
+ function getAlignment(placement) {
2974
+ return placement.split("-")[1];
2975
+ }
2976
+ function getOppositeAxis(axis) {
2977
+ return axis === "x" ? "y" : "x";
2978
+ }
2979
+ function getAxisLength(axis) {
2980
+ return axis === "y" ? "height" : "width";
2981
+ }
2982
+ var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
2983
+ function getSideAxis(placement) {
2984
+ return yAxisSides.has(getSide(placement)) ? "y" : "x";
2985
+ }
2986
+ function getAlignmentAxis(placement) {
2987
+ return getOppositeAxis(getSideAxis(placement));
2988
+ }
2989
+ function getAlignmentSides(placement, rects, rtl) {
2990
+ if (rtl === void 0) {
2991
+ rtl = false;
2992
+ }
2993
+ const alignment = getAlignment(placement);
2994
+ const alignmentAxis = getAlignmentAxis(placement);
2995
+ const length = getAxisLength(alignmentAxis);
2996
+ let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
2997
+ if (rects.reference[length] > rects.floating[length]) {
2998
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
2999
+ }
3000
+ return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
3001
+ }
3002
+ function getExpandedPlacements(placement) {
3003
+ const oppositePlacement = getOppositePlacement(placement);
3004
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
3005
+ }
3006
+ function getOppositeAlignmentPlacement(placement) {
3007
+ return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
3008
+ }
3009
+ var lrPlacement = ["left", "right"];
3010
+ var rlPlacement = ["right", "left"];
3011
+ var tbPlacement = ["top", "bottom"];
3012
+ var btPlacement = ["bottom", "top"];
3013
+ function getSideList(side, isStart, rtl) {
3014
+ switch (side) {
3015
+ case "top":
3016
+ case "bottom":
3017
+ if (rtl)
3018
+ return isStart ? rlPlacement : lrPlacement;
3019
+ return isStart ? lrPlacement : rlPlacement;
3020
+ case "left":
3021
+ case "right":
3022
+ return isStart ? tbPlacement : btPlacement;
3023
+ default:
3024
+ return [];
3025
+ }
3026
+ }
3027
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
3028
+ const alignment = getAlignment(placement);
3029
+ let list = getSideList(getSide(placement), direction === "start", rtl);
3030
+ if (alignment) {
3031
+ list = list.map((side) => side + "-" + alignment);
3032
+ if (flipAlignment) {
3033
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
3034
+ }
3035
+ }
3036
+ return list;
3037
+ }
3038
+ function getOppositePlacement(placement) {
3039
+ return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
3040
+ }
3041
+ function expandPaddingObject(padding) {
3042
+ return {
3043
+ top: 0,
3044
+ right: 0,
3045
+ bottom: 0,
3046
+ left: 0,
3047
+ ...padding
3048
+ };
3049
+ }
3050
+ function getPaddingObject(padding) {
3051
+ return typeof padding !== "number" ? expandPaddingObject(padding) : {
3052
+ top: padding,
3053
+ right: padding,
3054
+ bottom: padding,
3055
+ left: padding
3056
+ };
3057
+ }
3058
+ function rectToClientRect(rect) {
3059
+ const {
3060
+ x,
3061
+ y,
3062
+ width,
3063
+ height
3064
+ } = rect;
3065
+ return {
3066
+ width,
3067
+ height,
3068
+ top: y,
3069
+ left: x,
3070
+ right: x + width,
3071
+ bottom: y + height,
3072
+ x,
3073
+ y
3074
+ };
3075
+ }
3076
+
3077
+ // node_modules/@floating-ui/core/dist/floating-ui.core.mjs
3078
+ function computeCoordsFromPlacement(_ref, placement, rtl) {
3079
+ let {
3080
+ reference,
3081
+ floating
3082
+ } = _ref;
3083
+ const sideAxis = getSideAxis(placement);
3084
+ const alignmentAxis = getAlignmentAxis(placement);
3085
+ const alignLength = getAxisLength(alignmentAxis);
3086
+ const side = getSide(placement);
3087
+ const isVertical = sideAxis === "y";
3088
+ const commonX = reference.x + reference.width / 2 - floating.width / 2;
3089
+ const commonY = reference.y + reference.height / 2 - floating.height / 2;
3090
+ const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
3091
+ let coords;
3092
+ switch (side) {
3093
+ case "top":
3094
+ coords = {
3095
+ x: commonX,
3096
+ y: reference.y - floating.height
3097
+ };
3098
+ break;
3099
+ case "bottom":
3100
+ coords = {
3101
+ x: commonX,
3102
+ y: reference.y + reference.height
3103
+ };
3104
+ break;
3105
+ case "right":
3106
+ coords = {
3107
+ x: reference.x + reference.width,
3108
+ y: commonY
3109
+ };
3110
+ break;
3111
+ case "left":
3112
+ coords = {
3113
+ x: reference.x - floating.width,
3114
+ y: commonY
3115
+ };
3116
+ break;
3117
+ default:
3118
+ coords = {
3119
+ x: reference.x,
3120
+ y: reference.y
3121
+ };
3122
+ }
3123
+ switch (getAlignment(placement)) {
3124
+ case "start":
3125
+ coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
3126
+ break;
3127
+ case "end":
3128
+ coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
3129
+ break;
3130
+ }
3131
+ return coords;
3132
+ }
3133
+ async function detectOverflow(state, options) {
3134
+ var _await$platform$isEle;
3135
+ if (options === void 0) {
3136
+ options = {};
3137
+ }
3138
+ const {
3139
+ x,
3140
+ y,
3141
+ platform: platform2,
3142
+ rects,
3143
+ elements,
3144
+ strategy
3145
+ } = state;
3146
+ const {
3147
+ boundary = "clippingAncestors",
3148
+ rootBoundary = "viewport",
3149
+ elementContext = "floating",
3150
+ altBoundary = false,
3151
+ padding = 0
3152
+ } = evaluate(options, state);
3153
+ const paddingObject = getPaddingObject(padding);
3154
+ const altContext = elementContext === "floating" ? "reference" : "floating";
3155
+ const element = elements[altBoundary ? altContext : elementContext];
3156
+ const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
3157
+ element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
3158
+ boundary,
3159
+ rootBoundary,
3160
+ strategy
3161
+ }));
3162
+ const rect = elementContext === "floating" ? {
3163
+ x,
3164
+ y,
3165
+ width: rects.floating.width,
3166
+ height: rects.floating.height
3167
+ } : rects.reference;
3168
+ const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
3169
+ const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
3170
+ x: 1,
3171
+ y: 1
3172
+ } : {
3173
+ x: 1,
3174
+ y: 1
3175
+ };
3176
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
3177
+ elements,
3178
+ rect,
3179
+ offsetParent,
3180
+ strategy
3181
+ }) : rect);
3182
+ return {
3183
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
3184
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
3185
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
3186
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
3187
+ };
3188
+ }
3189
+ var computePosition = async (reference, floating, config) => {
3190
+ const {
3191
+ placement = "bottom",
3192
+ strategy = "absolute",
3193
+ middleware = [],
3194
+ platform: platform2
3195
+ } = config;
3196
+ const validMiddleware = middleware.filter(Boolean);
3197
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
3198
+ let rects = await platform2.getElementRects({
3199
+ reference,
3200
+ floating,
3201
+ strategy
3202
+ });
3203
+ let {
3204
+ x,
3205
+ y
3206
+ } = computeCoordsFromPlacement(rects, placement, rtl);
3207
+ let statefulPlacement = placement;
3208
+ let middlewareData = {};
3209
+ let resetCount = 0;
3210
+ for (let i = 0; i < validMiddleware.length; i++) {
3211
+ var _platform$detectOverf;
3212
+ const {
3213
+ name,
3214
+ fn
3215
+ } = validMiddleware[i];
3216
+ const {
3217
+ x: nextX,
3218
+ y: nextY,
3219
+ data,
3220
+ reset
3221
+ } = await fn({
3222
+ x,
3223
+ y,
3224
+ initialPlacement: placement,
3225
+ placement: statefulPlacement,
3226
+ strategy,
3227
+ middlewareData,
3228
+ rects,
3229
+ platform: {
3230
+ ...platform2,
3231
+ detectOverflow: (_platform$detectOverf = platform2.detectOverflow) != null ? _platform$detectOverf : detectOverflow
3232
+ },
3233
+ elements: {
3234
+ reference,
3235
+ floating
3236
+ }
3237
+ });
3238
+ x = nextX != null ? nextX : x;
3239
+ y = nextY != null ? nextY : y;
3240
+ middlewareData = {
3241
+ ...middlewareData,
3242
+ [name]: {
3243
+ ...middlewareData[name],
3244
+ ...data
3245
+ }
3246
+ };
3247
+ if (reset && resetCount <= 50) {
3248
+ resetCount++;
3249
+ if (typeof reset === "object") {
3250
+ if (reset.placement) {
3251
+ statefulPlacement = reset.placement;
3252
+ }
3253
+ if (reset.rects) {
3254
+ rects = reset.rects === true ? await platform2.getElementRects({
3255
+ reference,
3256
+ floating,
3257
+ strategy
3258
+ }) : reset.rects;
3259
+ }
3260
+ ({
3261
+ x,
3262
+ y
3263
+ } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
3264
+ }
3265
+ i = -1;
3266
+ }
3267
+ }
3268
+ return {
3269
+ x,
3270
+ y,
3271
+ placement: statefulPlacement,
3272
+ strategy,
3273
+ middlewareData
3274
+ };
3275
+ };
3276
+ var flip = function(options) {
3277
+ if (options === void 0) {
3278
+ options = {};
3279
+ }
3280
+ return {
3281
+ name: "flip",
3282
+ options,
3283
+ async fn(state) {
3284
+ var _middlewareData$arrow, _middlewareData$flip;
3285
+ const {
3286
+ placement,
3287
+ middlewareData,
3288
+ rects,
3289
+ initialPlacement,
3290
+ platform: platform2,
3291
+ elements
3292
+ } = state;
3293
+ const {
3294
+ mainAxis: checkMainAxis = true,
3295
+ crossAxis: checkCrossAxis = true,
3296
+ fallbackPlacements: specifiedFallbackPlacements,
3297
+ fallbackStrategy = "bestFit",
3298
+ fallbackAxisSideDirection = "none",
3299
+ flipAlignment = true,
3300
+ ...detectOverflowOptions
3301
+ } = evaluate(options, state);
3302
+ if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
3303
+ return {};
3304
+ }
3305
+ const side = getSide(placement);
3306
+ const initialSideAxis = getSideAxis(initialPlacement);
3307
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
3308
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
3309
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
3310
+ const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
3311
+ if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
3312
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
3313
+ }
3314
+ const placements2 = [initialPlacement, ...fallbackPlacements];
3315
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
3316
+ const overflows = [];
3317
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
3318
+ if (checkMainAxis) {
3319
+ overflows.push(overflow[side]);
3320
+ }
3321
+ if (checkCrossAxis) {
3322
+ const sides2 = getAlignmentSides(placement, rects, rtl);
3323
+ overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
3324
+ }
3325
+ overflowsData = [...overflowsData, {
3326
+ placement,
3327
+ overflows
3328
+ }];
3329
+ if (!overflows.every((side2) => side2 <= 0)) {
3330
+ var _middlewareData$flip2, _overflowsData$filter;
3331
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
3332
+ const nextPlacement = placements2[nextIndex];
3333
+ if (nextPlacement) {
3334
+ const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
3335
+ if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
3336
+ // overflows the main axis.
3337
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
3338
+ return {
3339
+ data: {
3340
+ index: nextIndex,
3341
+ overflows: overflowsData
3342
+ },
3343
+ reset: {
3344
+ placement: nextPlacement
3345
+ }
3346
+ };
3347
+ }
3348
+ }
3349
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
3350
+ if (!resetPlacement) {
3351
+ switch (fallbackStrategy) {
3352
+ case "bestFit": {
3353
+ var _overflowsData$filter2;
3354
+ const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
3355
+ if (hasFallbackAxisSideDirection) {
3356
+ const currentSideAxis = getSideAxis(d.placement);
3357
+ return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
3358
+ // reading directions favoring greater width.
3359
+ currentSideAxis === "y";
3360
+ }
3361
+ return true;
3362
+ }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
3363
+ if (placement2) {
3364
+ resetPlacement = placement2;
3365
+ }
3366
+ break;
3367
+ }
3368
+ case "initialPlacement":
3369
+ resetPlacement = initialPlacement;
3370
+ break;
3371
+ }
3372
+ }
3373
+ if (placement !== resetPlacement) {
3374
+ return {
3375
+ reset: {
3376
+ placement: resetPlacement
3377
+ }
3378
+ };
3379
+ }
3380
+ }
3381
+ return {};
3382
+ }
3383
+ };
3384
+ };
3385
+ var originSides = /* @__PURE__ */ new Set(["left", "top"]);
3386
+ async function convertValueToCoords(state, options) {
3387
+ const {
3388
+ placement,
3389
+ platform: platform2,
3390
+ elements
3391
+ } = state;
3392
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
3393
+ const side = getSide(placement);
3394
+ const alignment = getAlignment(placement);
3395
+ const isVertical = getSideAxis(placement) === "y";
3396
+ const mainAxisMulti = originSides.has(side) ? -1 : 1;
3397
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
3398
+ const rawValue = evaluate(options, state);
3399
+ let {
3400
+ mainAxis,
3401
+ crossAxis,
3402
+ alignmentAxis
3403
+ } = typeof rawValue === "number" ? {
3404
+ mainAxis: rawValue,
3405
+ crossAxis: 0,
3406
+ alignmentAxis: null
3407
+ } : {
3408
+ mainAxis: rawValue.mainAxis || 0,
3409
+ crossAxis: rawValue.crossAxis || 0,
3410
+ alignmentAxis: rawValue.alignmentAxis
3411
+ };
3412
+ if (alignment && typeof alignmentAxis === "number") {
3413
+ crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
3414
+ }
3415
+ return isVertical ? {
3416
+ x: crossAxis * crossAxisMulti,
3417
+ y: mainAxis * mainAxisMulti
3418
+ } : {
3419
+ x: mainAxis * mainAxisMulti,
3420
+ y: crossAxis * crossAxisMulti
3421
+ };
3422
+ }
3423
+ var offset = function(options) {
3424
+ if (options === void 0) {
3425
+ options = 0;
3426
+ }
3427
+ return {
3428
+ name: "offset",
3429
+ options,
3430
+ async fn(state) {
3431
+ var _middlewareData$offse, _middlewareData$arrow;
3432
+ const {
3433
+ x,
3434
+ y,
3435
+ placement,
3436
+ middlewareData
3437
+ } = state;
3438
+ const diffCoords = await convertValueToCoords(state, options);
3439
+ if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
3440
+ return {};
3441
+ }
3442
+ return {
3443
+ x: x + diffCoords.x,
3444
+ y: y + diffCoords.y,
3445
+ data: {
3446
+ ...diffCoords,
3447
+ placement
3448
+ }
3449
+ };
3450
+ }
3451
+ };
3452
+ };
3453
+ var shift = function(options) {
3454
+ if (options === void 0) {
3455
+ options = {};
3456
+ }
3457
+ return {
3458
+ name: "shift",
3459
+ options,
3460
+ async fn(state) {
3461
+ const {
3462
+ x,
3463
+ y,
3464
+ placement,
3465
+ platform: platform2
3466
+ } = state;
3467
+ const {
3468
+ mainAxis: checkMainAxis = true,
3469
+ crossAxis: checkCrossAxis = false,
3470
+ limiter = {
3471
+ fn: (_ref) => {
3472
+ let {
3473
+ x: x2,
3474
+ y: y2
3475
+ } = _ref;
3476
+ return {
3477
+ x: x2,
3478
+ y: y2
3479
+ };
3480
+ }
3481
+ },
3482
+ ...detectOverflowOptions
3483
+ } = evaluate(options, state);
3484
+ const coords = {
3485
+ x,
3486
+ y
3487
+ };
3488
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
3489
+ const crossAxis = getSideAxis(getSide(placement));
3490
+ const mainAxis = getOppositeAxis(crossAxis);
3491
+ let mainAxisCoord = coords[mainAxis];
3492
+ let crossAxisCoord = coords[crossAxis];
3493
+ if (checkMainAxis) {
3494
+ const minSide = mainAxis === "y" ? "top" : "left";
3495
+ const maxSide = mainAxis === "y" ? "bottom" : "right";
3496
+ const min2 = mainAxisCoord + overflow[minSide];
3497
+ const max2 = mainAxisCoord - overflow[maxSide];
3498
+ mainAxisCoord = clamp(min2, mainAxisCoord, max2);
3499
+ }
3500
+ if (checkCrossAxis) {
3501
+ const minSide = crossAxis === "y" ? "top" : "left";
3502
+ const maxSide = crossAxis === "y" ? "bottom" : "right";
3503
+ const min2 = crossAxisCoord + overflow[minSide];
3504
+ const max2 = crossAxisCoord - overflow[maxSide];
3505
+ crossAxisCoord = clamp(min2, crossAxisCoord, max2);
3506
+ }
3507
+ const limitedCoords = limiter.fn({
3508
+ ...state,
3509
+ [mainAxis]: mainAxisCoord,
3510
+ [crossAxis]: crossAxisCoord
3511
+ });
3512
+ return {
3513
+ ...limitedCoords,
3514
+ data: {
3515
+ x: limitedCoords.x - x,
3516
+ y: limitedCoords.y - y,
3517
+ enabled: {
3518
+ [mainAxis]: checkMainAxis,
3519
+ [crossAxis]: checkCrossAxis
3520
+ }
3521
+ }
3522
+ };
3523
+ }
3524
+ };
3525
+ };
3526
+
3527
+ // node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
3528
+ function hasWindow() {
3529
+ return typeof window !== "undefined";
3530
+ }
3531
+ function getNodeName(node) {
3532
+ if (isNode(node)) {
3533
+ return (node.nodeName || "").toLowerCase();
3534
+ }
3535
+ return "#document";
3536
+ }
3537
+ function getWindow(node) {
3538
+ var _node$ownerDocument;
3539
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
3540
+ }
3541
+ function getDocumentElement(node) {
3542
+ var _ref;
3543
+ return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
3544
+ }
3545
+ function isNode(value) {
3546
+ if (!hasWindow()) {
3547
+ return false;
3548
+ }
3549
+ return value instanceof Node || value instanceof getWindow(value).Node;
3550
+ }
3551
+ function isElement(value) {
3552
+ if (!hasWindow()) {
3553
+ return false;
3554
+ }
3555
+ return value instanceof Element || value instanceof getWindow(value).Element;
3556
+ }
3557
+ function isHTMLElement(value) {
3558
+ if (!hasWindow()) {
3559
+ return false;
3560
+ }
3561
+ return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
3562
+ }
3563
+ function isShadowRoot(value) {
3564
+ if (!hasWindow() || typeof ShadowRoot === "undefined") {
3565
+ return false;
3566
+ }
3567
+ return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
3568
+ }
3569
+ var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
3570
+ function isOverflowElement(element) {
3571
+ const {
3572
+ overflow,
3573
+ overflowX,
3574
+ overflowY,
3575
+ display
3576
+ } = getComputedStyle2(element);
3577
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
3578
+ }
3579
+ var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
3580
+ function isTableElement(element) {
3581
+ return tableElements.has(getNodeName(element));
3582
+ }
3583
+ var topLayerSelectors = [":popover-open", ":modal"];
3584
+ function isTopLayer(element) {
3585
+ return topLayerSelectors.some((selector) => {
3586
+ try {
3587
+ return element.matches(selector);
3588
+ } catch (_e) {
3589
+ return false;
3590
+ }
3591
+ });
3592
+ }
3593
+ var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
3594
+ var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
3595
+ var containValues = ["paint", "layout", "strict", "content"];
3596
+ function isContainingBlock(elementOrCss) {
3597
+ const webkit = isWebKit();
3598
+ const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
3599
+ return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
3600
+ }
3601
+ function getContainingBlock(element) {
3602
+ let currentNode = getParentNode(element);
3603
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
3604
+ if (isContainingBlock(currentNode)) {
3605
+ return currentNode;
3606
+ } else if (isTopLayer(currentNode)) {
3607
+ return null;
3608
+ }
3609
+ currentNode = getParentNode(currentNode);
3610
+ }
3611
+ return null;
3612
+ }
3613
+ function isWebKit() {
3614
+ if (typeof CSS === "undefined" || !CSS.supports)
3615
+ return false;
3616
+ return CSS.supports("-webkit-backdrop-filter", "none");
3617
+ }
3618
+ var lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
3619
+ function isLastTraversableNode(node) {
3620
+ return lastTraversableNodeNames.has(getNodeName(node));
3621
+ }
3622
+ function getComputedStyle2(element) {
3623
+ return getWindow(element).getComputedStyle(element);
3624
+ }
3625
+ function getNodeScroll(element) {
3626
+ if (isElement(element)) {
3627
+ return {
3628
+ scrollLeft: element.scrollLeft,
3629
+ scrollTop: element.scrollTop
3630
+ };
3631
+ }
3632
+ return {
3633
+ scrollLeft: element.scrollX,
3634
+ scrollTop: element.scrollY
3635
+ };
3636
+ }
3637
+ function getParentNode(node) {
3638
+ if (getNodeName(node) === "html") {
3639
+ return node;
3640
+ }
3641
+ const result = (
3642
+ // Step into the shadow DOM of the parent of a slotted node.
3643
+ node.assignedSlot || // DOM Element detected.
3644
+ node.parentNode || // ShadowRoot detected.
3645
+ isShadowRoot(node) && node.host || // Fallback.
3646
+ getDocumentElement(node)
3647
+ );
3648
+ return isShadowRoot(result) ? result.host : result;
3649
+ }
3650
+ function getNearestOverflowAncestor(node) {
3651
+ const parentNode = getParentNode(node);
3652
+ if (isLastTraversableNode(parentNode)) {
3653
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
3654
+ }
3655
+ if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
3656
+ return parentNode;
3657
+ }
3658
+ return getNearestOverflowAncestor(parentNode);
3659
+ }
3660
+ function getOverflowAncestors(node, list, traverseIframes) {
3661
+ var _node$ownerDocument2;
3662
+ if (list === void 0) {
3663
+ list = [];
3664
+ }
3665
+ if (traverseIframes === void 0) {
3666
+ traverseIframes = true;
3667
+ }
3668
+ const scrollableAncestor = getNearestOverflowAncestor(node);
3669
+ const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
3670
+ const win = getWindow(scrollableAncestor);
3671
+ if (isBody) {
3672
+ const frameElement = getFrameElement(win);
3673
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
3674
+ }
3675
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
3676
+ }
3677
+ function getFrameElement(win) {
3678
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
3679
+ }
3680
+
3681
+ // node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
3682
+ function getCssDimensions(element) {
3683
+ const css = getComputedStyle2(element);
3684
+ let width = parseFloat(css.width) || 0;
3685
+ let height = parseFloat(css.height) || 0;
3686
+ const hasOffset = isHTMLElement(element);
3687
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
3688
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
3689
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
3690
+ if (shouldFallback) {
3691
+ width = offsetWidth;
3692
+ height = offsetHeight;
3693
+ }
3694
+ return {
3695
+ width,
3696
+ height,
3697
+ $: shouldFallback
3698
+ };
3699
+ }
3700
+ function unwrapElement(element) {
3701
+ return !isElement(element) ? element.contextElement : element;
3702
+ }
3703
+ function getScale(element) {
3704
+ const domElement = unwrapElement(element);
3705
+ if (!isHTMLElement(domElement)) {
3706
+ return createCoords(1);
3707
+ }
3708
+ const rect = domElement.getBoundingClientRect();
3709
+ const {
3710
+ width,
3711
+ height,
3712
+ $
3713
+ } = getCssDimensions(domElement);
3714
+ let x = ($ ? round(rect.width) : rect.width) / width;
3715
+ let y = ($ ? round(rect.height) : rect.height) / height;
3716
+ if (!x || !Number.isFinite(x)) {
3717
+ x = 1;
3718
+ }
3719
+ if (!y || !Number.isFinite(y)) {
3720
+ y = 1;
3721
+ }
3722
+ return {
3723
+ x,
3724
+ y
3725
+ };
3726
+ }
3727
+ var noOffsets = /* @__PURE__ */ createCoords(0);
3728
+ function getVisualOffsets(element) {
3729
+ const win = getWindow(element);
3730
+ if (!isWebKit() || !win.visualViewport) {
3731
+ return noOffsets;
3732
+ }
3733
+ return {
3734
+ x: win.visualViewport.offsetLeft,
3735
+ y: win.visualViewport.offsetTop
3736
+ };
3737
+ }
3738
+ function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
3739
+ if (isFixed === void 0) {
3740
+ isFixed = false;
3741
+ }
3742
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
3743
+ return false;
3744
+ }
3745
+ return isFixed;
3746
+ }
3747
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
3748
+ if (includeScale === void 0) {
3749
+ includeScale = false;
3750
+ }
3751
+ if (isFixedStrategy === void 0) {
3752
+ isFixedStrategy = false;
3753
+ }
3754
+ const clientRect = element.getBoundingClientRect();
3755
+ const domElement = unwrapElement(element);
3756
+ let scale = createCoords(1);
3757
+ if (includeScale) {
3758
+ if (offsetParent) {
3759
+ if (isElement(offsetParent)) {
3760
+ scale = getScale(offsetParent);
3761
+ }
3762
+ } else {
3763
+ scale = getScale(element);
3764
+ }
3765
+ }
3766
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
3767
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
3768
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
3769
+ let width = clientRect.width / scale.x;
3770
+ let height = clientRect.height / scale.y;
3771
+ if (domElement) {
3772
+ const win = getWindow(domElement);
3773
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
3774
+ let currentWin = win;
3775
+ let currentIFrame = getFrameElement(currentWin);
3776
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
3777
+ const iframeScale = getScale(currentIFrame);
3778
+ const iframeRect = currentIFrame.getBoundingClientRect();
3779
+ const css = getComputedStyle2(currentIFrame);
3780
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
3781
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
3782
+ x *= iframeScale.x;
3783
+ y *= iframeScale.y;
3784
+ width *= iframeScale.x;
3785
+ height *= iframeScale.y;
3786
+ x += left;
3787
+ y += top;
3788
+ currentWin = getWindow(currentIFrame);
3789
+ currentIFrame = getFrameElement(currentWin);
3790
+ }
3791
+ }
3792
+ return rectToClientRect({
3793
+ width,
3794
+ height,
3795
+ x,
3796
+ y
3797
+ });
3798
+ }
3799
+ function getWindowScrollBarX(element, rect) {
3800
+ const leftScroll = getNodeScroll(element).scrollLeft;
3801
+ if (!rect) {
3802
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
3803
+ }
3804
+ return rect.left + leftScroll;
3805
+ }
3806
+ function getHTMLOffset(documentElement, scroll) {
3807
+ const htmlRect = documentElement.getBoundingClientRect();
3808
+ const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
3809
+ const y = htmlRect.top + scroll.scrollTop;
3810
+ return {
3811
+ x,
3812
+ y
3813
+ };
3814
+ }
3815
+ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
3816
+ let {
3817
+ elements,
3818
+ rect,
3819
+ offsetParent,
3820
+ strategy
3821
+ } = _ref;
3822
+ const isFixed = strategy === "fixed";
3823
+ const documentElement = getDocumentElement(offsetParent);
3824
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
3825
+ if (offsetParent === documentElement || topLayer && isFixed) {
3826
+ return rect;
3827
+ }
3828
+ let scroll = {
3829
+ scrollLeft: 0,
3830
+ scrollTop: 0
3831
+ };
3832
+ let scale = createCoords(1);
3833
+ const offsets = createCoords(0);
3834
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
3835
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
3836
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
3837
+ scroll = getNodeScroll(offsetParent);
3838
+ }
3839
+ if (isHTMLElement(offsetParent)) {
3840
+ const offsetRect = getBoundingClientRect(offsetParent);
3841
+ scale = getScale(offsetParent);
3842
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
3843
+ offsets.y = offsetRect.y + offsetParent.clientTop;
3844
+ }
3845
+ }
3846
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
3847
+ return {
3848
+ width: rect.width * scale.x,
3849
+ height: rect.height * scale.y,
3850
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
3851
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
3852
+ };
3853
+ }
3854
+ function getClientRects(element) {
3855
+ return Array.from(element.getClientRects());
3856
+ }
3857
+ function getDocumentRect(element) {
3858
+ const html = getDocumentElement(element);
3859
+ const scroll = getNodeScroll(element);
3860
+ const body = element.ownerDocument.body;
3861
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
3862
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
3863
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
3864
+ const y = -scroll.scrollTop;
3865
+ if (getComputedStyle2(body).direction === "rtl") {
3866
+ x += max(html.clientWidth, body.clientWidth) - width;
3867
+ }
3868
+ return {
3869
+ width,
3870
+ height,
3871
+ x,
3872
+ y
3873
+ };
3874
+ }
3875
+ var SCROLLBAR_MAX = 25;
3876
+ function getViewportRect(element, strategy) {
3877
+ const win = getWindow(element);
3878
+ const html = getDocumentElement(element);
3879
+ const visualViewport = win.visualViewport;
3880
+ let width = html.clientWidth;
3881
+ let height = html.clientHeight;
3882
+ let x = 0;
3883
+ let y = 0;
3884
+ if (visualViewport) {
3885
+ width = visualViewport.width;
3886
+ height = visualViewport.height;
3887
+ const visualViewportBased = isWebKit();
3888
+ if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
3889
+ x = visualViewport.offsetLeft;
3890
+ y = visualViewport.offsetTop;
3891
+ }
3892
+ }
3893
+ const windowScrollbarX = getWindowScrollBarX(html);
3894
+ if (windowScrollbarX <= 0) {
3895
+ const doc = html.ownerDocument;
3896
+ const body = doc.body;
3897
+ const bodyStyles = getComputedStyle(body);
3898
+ const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
3899
+ const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
3900
+ if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
3901
+ width -= clippingStableScrollbarWidth;
3902
+ }
3903
+ } else if (windowScrollbarX <= SCROLLBAR_MAX) {
3904
+ width += windowScrollbarX;
3905
+ }
3906
+ return {
3907
+ width,
3908
+ height,
3909
+ x,
3910
+ y
3911
+ };
3912
+ }
3913
+ var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
3914
+ function getInnerBoundingClientRect(element, strategy) {
3915
+ const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
3916
+ const top = clientRect.top + element.clientTop;
3917
+ const left = clientRect.left + element.clientLeft;
3918
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
3919
+ const width = element.clientWidth * scale.x;
3920
+ const height = element.clientHeight * scale.y;
3921
+ const x = left * scale.x;
3922
+ const y = top * scale.y;
3923
+ return {
3924
+ width,
3925
+ height,
3926
+ x,
3927
+ y
3928
+ };
3929
+ }
3930
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
3931
+ let rect;
3932
+ if (clippingAncestor === "viewport") {
3933
+ rect = getViewportRect(element, strategy);
3934
+ } else if (clippingAncestor === "document") {
3935
+ rect = getDocumentRect(getDocumentElement(element));
3936
+ } else if (isElement(clippingAncestor)) {
3937
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
3938
+ } else {
3939
+ const visualOffsets = getVisualOffsets(element);
3940
+ rect = {
3941
+ x: clippingAncestor.x - visualOffsets.x,
3942
+ y: clippingAncestor.y - visualOffsets.y,
3943
+ width: clippingAncestor.width,
3944
+ height: clippingAncestor.height
3945
+ };
3946
+ }
3947
+ return rectToClientRect(rect);
3948
+ }
3949
+ function hasFixedPositionAncestor(element, stopNode) {
3950
+ const parentNode = getParentNode(element);
3951
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
3952
+ return false;
3953
+ }
3954
+ return getComputedStyle2(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
3955
+ }
3956
+ function getClippingElementAncestors(element, cache) {
3957
+ const cachedResult = cache.get(element);
3958
+ if (cachedResult) {
3959
+ return cachedResult;
3960
+ }
3961
+ let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
3962
+ let currentContainingBlockComputedStyle = null;
3963
+ const elementIsFixed = getComputedStyle2(element).position === "fixed";
3964
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
3965
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
3966
+ const computedStyle = getComputedStyle2(currentNode);
3967
+ const currentNodeIsContaining = isContainingBlock(currentNode);
3968
+ if (!currentNodeIsContaining && computedStyle.position === "fixed") {
3969
+ currentContainingBlockComputedStyle = null;
3970
+ }
3971
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
3972
+ if (shouldDropCurrentNode) {
3973
+ result = result.filter((ancestor) => ancestor !== currentNode);
3974
+ } else {
3975
+ currentContainingBlockComputedStyle = computedStyle;
3976
+ }
3977
+ currentNode = getParentNode(currentNode);
3978
+ }
3979
+ cache.set(element, result);
3980
+ return result;
3981
+ }
3982
+ function getClippingRect(_ref) {
3983
+ let {
3984
+ element,
3985
+ boundary,
3986
+ rootBoundary,
3987
+ strategy
3988
+ } = _ref;
3989
+ const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
3990
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
3991
+ const firstClippingAncestor = clippingAncestors[0];
3992
+ const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
3993
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
3994
+ accRect.top = max(rect.top, accRect.top);
3995
+ accRect.right = min(rect.right, accRect.right);
3996
+ accRect.bottom = min(rect.bottom, accRect.bottom);
3997
+ accRect.left = max(rect.left, accRect.left);
3998
+ return accRect;
3999
+ }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
4000
+ return {
4001
+ width: clippingRect.right - clippingRect.left,
4002
+ height: clippingRect.bottom - clippingRect.top,
4003
+ x: clippingRect.left,
4004
+ y: clippingRect.top
4005
+ };
4006
+ }
4007
+ function getDimensions(element) {
4008
+ const {
4009
+ width,
4010
+ height
4011
+ } = getCssDimensions(element);
4012
+ return {
4013
+ width,
4014
+ height
4015
+ };
4016
+ }
4017
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
4018
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
4019
+ const documentElement = getDocumentElement(offsetParent);
4020
+ const isFixed = strategy === "fixed";
4021
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
4022
+ let scroll = {
4023
+ scrollLeft: 0,
4024
+ scrollTop: 0
4025
+ };
4026
+ const offsets = createCoords(0);
4027
+ function setLeftRTLScrollbarOffset() {
4028
+ offsets.x = getWindowScrollBarX(documentElement);
4029
+ }
4030
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
4031
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
4032
+ scroll = getNodeScroll(offsetParent);
4033
+ }
4034
+ if (isOffsetParentAnElement) {
4035
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
4036
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
4037
+ offsets.y = offsetRect.y + offsetParent.clientTop;
4038
+ } else if (documentElement) {
4039
+ setLeftRTLScrollbarOffset();
4040
+ }
4041
+ }
4042
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
4043
+ setLeftRTLScrollbarOffset();
4044
+ }
4045
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
4046
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
4047
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
4048
+ return {
4049
+ x,
4050
+ y,
4051
+ width: rect.width,
4052
+ height: rect.height
4053
+ };
4054
+ }
4055
+ function isStaticPositioned(element) {
4056
+ return getComputedStyle2(element).position === "static";
4057
+ }
4058
+ function getTrueOffsetParent(element, polyfill) {
4059
+ if (!isHTMLElement(element) || getComputedStyle2(element).position === "fixed") {
4060
+ return null;
4061
+ }
4062
+ if (polyfill) {
4063
+ return polyfill(element);
4064
+ }
4065
+ let rawOffsetParent = element.offsetParent;
4066
+ if (getDocumentElement(element) === rawOffsetParent) {
4067
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
4068
+ }
4069
+ return rawOffsetParent;
4070
+ }
4071
+ function getOffsetParent(element, polyfill) {
4072
+ const win = getWindow(element);
4073
+ if (isTopLayer(element)) {
4074
+ return win;
4075
+ }
4076
+ if (!isHTMLElement(element)) {
4077
+ let svgOffsetParent = getParentNode(element);
4078
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
4079
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
4080
+ return svgOffsetParent;
4081
+ }
4082
+ svgOffsetParent = getParentNode(svgOffsetParent);
4083
+ }
4084
+ return win;
4085
+ }
4086
+ let offsetParent = getTrueOffsetParent(element, polyfill);
4087
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
4088
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
4089
+ }
4090
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
4091
+ return win;
4092
+ }
4093
+ return offsetParent || getContainingBlock(element) || win;
4094
+ }
4095
+ var getElementRects = async function(data) {
4096
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
4097
+ const getDimensionsFn = this.getDimensions;
4098
+ const floatingDimensions = await getDimensionsFn(data.floating);
4099
+ return {
4100
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
4101
+ floating: {
4102
+ x: 0,
4103
+ y: 0,
4104
+ width: floatingDimensions.width,
4105
+ height: floatingDimensions.height
4106
+ }
4107
+ };
4108
+ };
4109
+ function isRTL(element) {
4110
+ return getComputedStyle2(element).direction === "rtl";
4111
+ }
4112
+ var platform = {
4113
+ convertOffsetParentRelativeRectToViewportRelativeRect,
4114
+ getDocumentElement,
4115
+ getClippingRect,
4116
+ getOffsetParent,
4117
+ getElementRects,
4118
+ getClientRects,
4119
+ getDimensions,
4120
+ getScale,
4121
+ isElement,
4122
+ isRTL
4123
+ };
4124
+ var offset2 = offset;
4125
+ var shift2 = shift;
4126
+ var flip2 = flip;
4127
+ var computePosition2 = (reference, floating, options) => {
4128
+ const cache = /* @__PURE__ */ new Map();
4129
+ const mergedOptions = {
4130
+ platform,
4131
+ ...options
4132
+ };
4133
+ const platformWithCache = {
4134
+ ...mergedOptions.platform,
4135
+ _c: cache
4136
+ };
4137
+ return computePosition(reference, floating, {
4138
+ ...mergedOptions,
4139
+ platform: platformWithCache
4140
+ });
4141
+ };
4142
+
2911
4143
  // src/link-tooltip.js
2912
4144
  var LinkTooltip = class {
2913
4145
  constructor(editor) {
@@ -2916,27 +4148,10 @@ var LinkTooltip = class {
2916
4148
  this.currentLink = null;
2917
4149
  this.hideTimeout = null;
2918
4150
  this.visibilityChangeHandler = null;
2919
- this.useFloatingUI = false;
2920
- this.floatingUI = null;
2921
4151
  this.isTooltipHovered = false;
2922
4152
  this.init();
2923
4153
  }
2924
- async init() {
2925
- const supportsAnchorPositioning = CSS.supports("position-anchor: --x") && CSS.supports("position-area: center");
2926
- if (!supportsAnchorPositioning) {
2927
- try {
2928
- const importFn = new Function("url", "return import(url)");
2929
- const { computePosition, offset, shift, flip } = await importFn(
2930
- "https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.4/+esm"
2931
- );
2932
- this.floatingUI = { computePosition, offset, shift, flip };
2933
- this.useFloatingUI = true;
2934
- } catch (error) {
2935
- console.warn("Failed to load Floating UI fallback:", error);
2936
- this.floatingUI = null;
2937
- this.useFloatingUI = false;
2938
- }
2939
- }
4154
+ init() {
2940
4155
  this.createTooltip();
2941
4156
  this.editor.textarea.addEventListener("selectionchange", () => this.checkCursorPosition());
2942
4157
  this.editor.textarea.addEventListener("keyup", (e) => {
@@ -2946,10 +4161,8 @@ var LinkTooltip = class {
2946
4161
  });
2947
4162
  this.editor.textarea.addEventListener("input", () => this.hide());
2948
4163
  this.editor.textarea.addEventListener("scroll", () => {
2949
- if (this.useFloatingUI && this.currentLink) {
2950
- this.showWithFloatingUI(this.currentLink);
2951
- } else {
2952
- this.hide();
4164
+ if (this.currentLink) {
4165
+ this.positionTooltip(this.currentLink);
2953
4166
  }
2954
4167
  });
2955
4168
  this.editor.textarea.addEventListener("blur", () => {
@@ -3026,22 +4239,17 @@ var LinkTooltip = class {
3026
4239
  }
3027
4240
  return null;
3028
4241
  }
3029
- show(linkInfo) {
4242
+ async show(linkInfo) {
3030
4243
  this.currentLink = linkInfo;
3031
4244
  this.cancelHide();
3032
4245
  const urlSpan = this.tooltip.querySelector(".overtype-link-tooltip-url");
3033
4246
  urlSpan.textContent = linkInfo.url;
3034
- if (this.useFloatingUI) {
3035
- this.showWithFloatingUI(linkInfo);
3036
- } else {
3037
- this.showWithAnchorPositioning(linkInfo);
4247
+ await this.positionTooltip(linkInfo);
4248
+ if (this.currentLink === linkInfo) {
4249
+ this.tooltip.classList.add("visible");
3038
4250
  }
3039
- this.tooltip.classList.add("visible");
3040
- }
3041
- showWithAnchorPositioning(linkInfo) {
3042
- this.tooltip.style.setProperty("--target-anchor", `--link-${linkInfo.index}`);
3043
4251
  }
3044
- async showWithFloatingUI(linkInfo) {
4252
+ async positionTooltip(linkInfo) {
3045
4253
  const anchorElement = this.findAnchorElement(linkInfo.index);
3046
4254
  if (!anchorElement) {
3047
4255
  return;
@@ -3051,26 +4259,26 @@ var LinkTooltip = class {
3051
4259
  return;
3052
4260
  }
3053
4261
  try {
3054
- const { x, y } = await this.floatingUI.computePosition(
4262
+ const { x, y } = await computePosition2(
3055
4263
  anchorElement,
3056
4264
  this.tooltip,
3057
4265
  {
4266
+ strategy: "fixed",
3058
4267
  placement: "bottom",
3059
4268
  middleware: [
3060
- this.floatingUI.offset(8),
3061
- this.floatingUI.shift({ padding: 8 }),
3062
- this.floatingUI.flip()
4269
+ offset2(8),
4270
+ shift2({ padding: 8 }),
4271
+ flip2()
3063
4272
  ]
3064
4273
  }
3065
4274
  );
3066
4275
  Object.assign(this.tooltip.style, {
3067
4276
  left: `${x}px`,
3068
4277
  top: `${y}px`,
3069
- position: "absolute"
4278
+ position: "fixed"
3070
4279
  });
3071
4280
  } catch (error) {
3072
4281
  console.warn("Floating UI positioning failed:", error);
3073
- return;
3074
4282
  }
3075
4283
  }
3076
4284
  findAnchorElement(linkIndex) {
@@ -3103,8 +4311,6 @@ var LinkTooltip = class {
3103
4311
  }
3104
4312
  this.tooltip = null;
3105
4313
  this.currentLink = null;
3106
- this.floatingUI = null;
3107
- this.useFloatingUI = false;
3108
4314
  this.isTooltipHovered = false;
3109
4315
  }
3110
4316
  };
@@ -3167,6 +4373,11 @@ var taskListIcon = `<svg viewBox="0 0 18 18">
3167
4373
  <rect stroke="currentColor" fill="none" stroke-width="1.5" x="2" y="13" width="3" height="3" rx="0.5"></rect>
3168
4374
  <polyline stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" points="2.65 9.5 3.5 10.5 5 8.5"></polyline>
3169
4375
  </svg>`;
4376
+ var uploadIcon = `<svg viewBox="0 0 18 18">
4377
+ <path stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.25 12.375v1.688A1.688 1.688 0 0 0 3.938 15.75h10.124a1.688 1.688 0 0 0 1.688-1.688V12.375"></path>
4378
+ <path stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5.063 6.188L9 2.25l3.938 3.938"></path>
4379
+ <path stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 2.25v10.125"></path>
4380
+ </svg>`;
3170
4381
  var eyeIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3171
4382
  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" fill="none"></path>
3172
4383
  <circle cx="12" cy="12" r="3" fill="none"></circle>
@@ -3290,6 +4501,33 @@ var toolbarButtons = {
3290
4501
  editor.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3291
4502
  }
3292
4503
  },
4504
+ upload: {
4505
+ name: "upload",
4506
+ actionId: "uploadFile",
4507
+ icon: uploadIcon,
4508
+ title: "Upload File",
4509
+ action: ({ editor }) => {
4510
+ var _a, _b;
4511
+ if (!((_a = editor.options.fileUpload) == null ? void 0 : _a.enabled))
4512
+ return;
4513
+ const input = document.createElement("input");
4514
+ input.type = "file";
4515
+ input.multiple = true;
4516
+ if (((_b = editor.options.fileUpload.mimeTypes) == null ? void 0 : _b.length) > 0) {
4517
+ input.accept = editor.options.fileUpload.mimeTypes.join(",");
4518
+ }
4519
+ input.onchange = () => {
4520
+ var _a2;
4521
+ if (!((_a2 = input.files) == null ? void 0 : _a2.length))
4522
+ return;
4523
+ const dt = new DataTransfer();
4524
+ for (const f of input.files)
4525
+ dt.items.add(f);
4526
+ editor._handleDataTransfer(dt);
4527
+ };
4528
+ input.click();
4529
+ }
4530
+ },
3293
4531
  viewMode: {
3294
4532
  name: "viewMode",
3295
4533
  icon: eyeIcon,
@@ -3414,6 +4652,9 @@ var _OverType = class _OverType {
3414
4652
  } else {
3415
4653
  this._buildFromScratch();
3416
4654
  }
4655
+ if (this.instanceTheme === "auto") {
4656
+ this.setTheme("auto");
4657
+ }
3417
4658
  this.shortcuts = new ShortcutsManager(this);
3418
4659
  this._rebuildActionsMap();
3419
4660
  this.linkTooltip = new LinkTooltip(this);
@@ -3471,8 +4712,10 @@ var _OverType = class _OverType {
3471
4712
  statsFormatter: null,
3472
4713
  smartLists: true,
3473
4714
  // Enable smart list continuation
3474
- codeHighlighter: null
4715
+ codeHighlighter: null,
3475
4716
  // Per-instance code highlighter
4717
+ spellcheck: false
4718
+ // Browser spellcheck (disabled by default)
3476
4719
  };
3477
4720
  const { theme, colors, ...cleanOptions } = options;
3478
4721
  return {
@@ -3607,8 +4850,13 @@ var _OverType = class _OverType {
3607
4850
  this.preview = document.createElement("div");
3608
4851
  this.preview.className = "overtype-preview";
3609
4852
  this.preview.setAttribute("aria-hidden", "true");
4853
+ this.placeholderEl = document.createElement("div");
4854
+ this.placeholderEl.className = "overtype-placeholder";
4855
+ this.placeholderEl.setAttribute("aria-hidden", "true");
4856
+ this.placeholderEl.textContent = this.options.placeholder;
3610
4857
  this.wrapper.appendChild(this.textarea);
3611
4858
  this.wrapper.appendChild(this.preview);
4859
+ this.wrapper.appendChild(this.placeholderEl);
3612
4860
  this.container.appendChild(this.wrapper);
3613
4861
  if (this.options.showStats) {
3614
4862
  this.statsBar = document.createElement("div");
@@ -3631,7 +4879,7 @@ var _OverType = class _OverType {
3631
4879
  this.textarea.setAttribute("autocomplete", "off");
3632
4880
  this.textarea.setAttribute("autocorrect", "off");
3633
4881
  this.textarea.setAttribute("autocapitalize", "off");
3634
- this.textarea.setAttribute("spellcheck", "false");
4882
+ this.textarea.setAttribute("spellcheck", String(this.options.spellcheck));
3635
4883
  this.textarea.setAttribute("data-gramm", "false");
3636
4884
  this.textarea.setAttribute("data-gramm_editor", "false");
3637
4885
  this.textarea.setAttribute("data-enable-grammarly", "false");
@@ -3641,7 +4889,17 @@ var _OverType = class _OverType {
3641
4889
  * @private
3642
4890
  */
3643
4891
  _createToolbar() {
3644
- const toolbarButtons2 = this.options.toolbarButtons || defaultToolbarButtons;
4892
+ var _a;
4893
+ let toolbarButtons2 = this.options.toolbarButtons || defaultToolbarButtons;
4894
+ if (((_a = this.options.fileUpload) == null ? void 0 : _a.enabled) && !toolbarButtons2.some((b) => (b == null ? void 0 : b.name) === "upload")) {
4895
+ const viewModeIdx = toolbarButtons2.findIndex((b) => (b == null ? void 0 : b.name) === "viewMode");
4896
+ if (viewModeIdx !== -1) {
4897
+ toolbarButtons2 = [...toolbarButtons2];
4898
+ toolbarButtons2.splice(viewModeIdx, 0, toolbarButtons.separator, toolbarButtons.upload);
4899
+ } else {
4900
+ toolbarButtons2 = [...toolbarButtons2, toolbarButtons.separator, toolbarButtons.upload];
4901
+ }
4902
+ }
3645
4903
  this.toolbar = new Toolbar(this, { toolbarButtons: toolbarButtons2 });
3646
4904
  this.toolbar.create();
3647
4905
  this._toolbarSelectionListener = () => {
@@ -3677,10 +4935,14 @@ var _OverType = class _OverType {
3677
4935
  * @private
3678
4936
  */
3679
4937
  _rebuildActionsMap() {
4938
+ var _a;
3680
4939
  this.actionsById = buildActionsMap(defaultToolbarButtons);
3681
4940
  if (this.options.toolbarButtons) {
3682
4941
  Object.assign(this.actionsById, buildActionsMap(this.options.toolbarButtons));
3683
4942
  }
4943
+ if ((_a = this.options.fileUpload) == null ? void 0 : _a.enabled) {
4944
+ Object.assign(this.actionsById, buildActionsMap([toolbarButtons.upload]));
4945
+ }
3684
4946
  }
3685
4947
  /**
3686
4948
  * Apply options to the editor
@@ -3693,6 +4955,8 @@ var _OverType = class _OverType {
3693
4955
  if (this.options.autoResize) {
3694
4956
  if (!this.container.classList.contains("overtype-auto-resize")) {
3695
4957
  this._setupAutoResize();
4958
+ } else {
4959
+ this._updateAutoHeight();
3696
4960
  }
3697
4961
  } else {
3698
4962
  this.container.classList.remove("overtype-auto-resize");
@@ -3704,8 +4968,119 @@ var _OverType = class _OverType {
3704
4968
  this.toolbar.destroy();
3705
4969
  this.toolbar = null;
3706
4970
  }
4971
+ if (this.placeholderEl) {
4972
+ this.placeholderEl.textContent = this.options.placeholder;
4973
+ }
4974
+ if (this.options.fileUpload && !this.fileUploadInitialized) {
4975
+ this._initFileUpload();
4976
+ } else if (!this.options.fileUpload && this.fileUploadInitialized) {
4977
+ this._destroyFileUpload();
4978
+ }
3707
4979
  this.updatePreview();
3708
4980
  }
4981
+ _initFileUpload() {
4982
+ const options = this.options.fileUpload;
4983
+ if (!options || !options.enabled)
4984
+ return;
4985
+ options.maxSize = options.maxSize || 10 * 1024 * 1024;
4986
+ options.mimeTypes = options.mimeTypes || [];
4987
+ options.batch = options.batch || false;
4988
+ if (!options.onInsertFile || typeof options.onInsertFile !== "function") {
4989
+ console.warn("OverType: fileUpload.onInsertFile callback is required for file uploads.");
4990
+ return;
4991
+ }
4992
+ this._fileUploadCounter = 0;
4993
+ this._boundHandleFilePaste = this._handleFilePaste.bind(this);
4994
+ this._boundHandleFileDrop = this._handleFileDrop.bind(this);
4995
+ this._boundHandleDragOver = this._handleDragOver.bind(this);
4996
+ this.textarea.addEventListener("paste", this._boundHandleFilePaste);
4997
+ this.textarea.addEventListener("drop", this._boundHandleFileDrop);
4998
+ this.textarea.addEventListener("dragover", this._boundHandleDragOver);
4999
+ this.fileUploadInitialized = true;
5000
+ }
5001
+ _handleFilePaste(e) {
5002
+ var _a, _b;
5003
+ if (!((_b = (_a = e == null ? void 0 : e.clipboardData) == null ? void 0 : _a.files) == null ? void 0 : _b.length))
5004
+ return;
5005
+ e.preventDefault();
5006
+ this._handleDataTransfer(e.clipboardData);
5007
+ }
5008
+ _handleFileDrop(e) {
5009
+ var _a, _b;
5010
+ if (!((_b = (_a = e == null ? void 0 : e.dataTransfer) == null ? void 0 : _a.files) == null ? void 0 : _b.length))
5011
+ return;
5012
+ e.preventDefault();
5013
+ this._handleDataTransfer(e.dataTransfer);
5014
+ }
5015
+ _handleDataTransfer(dataTransfer) {
5016
+ const files = [];
5017
+ for (const file of dataTransfer.files) {
5018
+ if (file.size > this.options.fileUpload.maxSize)
5019
+ continue;
5020
+ if (this.options.fileUpload.mimeTypes.length > 0 && !this.options.fileUpload.mimeTypes.includes(file.type))
5021
+ continue;
5022
+ const id = ++this._fileUploadCounter;
5023
+ const prefix = file.type.startsWith("image/") ? "!" : "";
5024
+ const placeholder = `${prefix}[Uploading ${file.name} (#${id})...]()`;
5025
+ this.insertAtCursor(`${placeholder}
5026
+ `);
5027
+ if (this.options.fileUpload.batch) {
5028
+ files.push({ file, placeholder });
5029
+ continue;
5030
+ }
5031
+ this.options.fileUpload.onInsertFile(file).then((text) => {
5032
+ this.textarea.value = this.textarea.value.replace(placeholder, text);
5033
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
5034
+ }, (error) => {
5035
+ console.error("OverType: File upload failed", error);
5036
+ this.textarea.value = this.textarea.value.replace(placeholder, "[Upload failed]()");
5037
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
5038
+ });
5039
+ }
5040
+ if (this.options.fileUpload.batch && files.length > 0) {
5041
+ this.options.fileUpload.onInsertFile(files.map((f) => f.file)).then((result) => {
5042
+ const texts = Array.isArray(result) ? result : [result];
5043
+ texts.forEach((text, index) => {
5044
+ this.textarea.value = this.textarea.value.replace(files[index].placeholder, text);
5045
+ });
5046
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
5047
+ }, (error) => {
5048
+ console.error("OverType: File upload failed", error);
5049
+ files.forEach(({ placeholder }) => {
5050
+ this.textarea.value = this.textarea.value.replace(placeholder, "[Upload failed]()");
5051
+ });
5052
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
5053
+ });
5054
+ }
5055
+ }
5056
+ _handleDragOver(e) {
5057
+ e.preventDefault();
5058
+ }
5059
+ _destroyFileUpload() {
5060
+ this.textarea.removeEventListener("paste", this._boundHandleFilePaste);
5061
+ this.textarea.removeEventListener("drop", this._boundHandleFileDrop);
5062
+ this.textarea.removeEventListener("dragover", this._boundHandleDragOver);
5063
+ this._boundHandleFilePaste = null;
5064
+ this._boundHandleFileDrop = null;
5065
+ this._boundHandleDragOver = null;
5066
+ this.fileUploadInitialized = false;
5067
+ }
5068
+ insertAtCursor(text) {
5069
+ const start = this.textarea.selectionStart;
5070
+ const end = this.textarea.selectionEnd;
5071
+ let inserted = false;
5072
+ try {
5073
+ inserted = document.execCommand("insertText", false, text);
5074
+ } catch (_) {
5075
+ }
5076
+ if (!inserted) {
5077
+ const before = this.textarea.value.slice(0, start);
5078
+ const after = this.textarea.value.slice(end);
5079
+ this.textarea.value = before + text + after;
5080
+ this.textarea.setSelectionRange(start + text.length, start + text.length);
5081
+ }
5082
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
5083
+ }
3709
5084
  /**
3710
5085
  * Update preview with parsed markdown
3711
5086
  */
@@ -3715,7 +5090,10 @@ var _OverType = class _OverType {
3715
5090
  const activeLine = this._getCurrentLine(text, cursorPos);
3716
5091
  const isPreviewMode = this.container.dataset.mode === "preview";
3717
5092
  const html = MarkdownParser.parse(text, activeLine, this.options.showActiveLineRaw, this.options.codeHighlighter, isPreviewMode);
3718
- this.preview.innerHTML = html || '<span style="color: #808080;">Start typing...</span>';
5093
+ this.preview.innerHTML = html;
5094
+ if (this.placeholderEl) {
5095
+ this.placeholderEl.style.display = text ? "none" : "";
5096
+ }
3719
5097
  this._applyCodeBlockBackgrounds();
3720
5098
  if (this.options.showStats && this.statsBar) {
3721
5099
  this._updateStats();
@@ -3898,7 +5276,7 @@ var _OverType = class _OverType {
3898
5276
  const cursorPos = this.textarea.selectionStart;
3899
5277
  const newValue = MarkdownParser.renumberLists(value);
3900
5278
  if (newValue !== value) {
3901
- let offset = 0;
5279
+ let offset3 = 0;
3902
5280
  const oldLines = value.split("\n");
3903
5281
  const newLines = newValue.split("\n");
3904
5282
  let charCount = 0;
@@ -3906,13 +5284,13 @@ var _OverType = class _OverType {
3906
5284
  if (oldLines[i] !== newLines[i]) {
3907
5285
  const diff = newLines[i].length - oldLines[i].length;
3908
5286
  if (charCount + oldLines[i].length < cursorPos) {
3909
- offset += diff;
5287
+ offset3 += diff;
3910
5288
  }
3911
5289
  }
3912
5290
  charCount += oldLines[i].length + 1;
3913
5291
  }
3914
5292
  this.textarea.value = newValue;
3915
- const newCursorPos = cursorPos + offset;
5293
+ const newCursorPos = cursorPos + offset3;
3916
5294
  this.textarea.setSelectionRange(newCursorPos, newCursorPos);
3917
5295
  this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3918
5296
  }
@@ -4044,27 +5422,61 @@ var _OverType = class _OverType {
4044
5422
  this.toolbar = null;
4045
5423
  this._createToolbar();
4046
5424
  }
5425
+ if (this.fileUploadInitialized) {
5426
+ this._destroyFileUpload();
5427
+ }
5428
+ if (this.options.fileUpload) {
5429
+ this._initFileUpload();
5430
+ }
4047
5431
  this._applyOptions();
4048
5432
  this.updatePreview();
4049
5433
  }
5434
+ showToolbar() {
5435
+ if (this.toolbar) {
5436
+ this.toolbar.show();
5437
+ } else {
5438
+ this._createToolbar();
5439
+ }
5440
+ }
5441
+ hideToolbar() {
5442
+ if (this.toolbar) {
5443
+ this.toolbar.hide();
5444
+ }
5445
+ }
4050
5446
  /**
4051
5447
  * Set theme for this instance
4052
5448
  * @param {string|Object} theme - Theme name or custom theme object
4053
5449
  * @returns {this} Returns this for chaining
4054
5450
  */
4055
5451
  setTheme(theme) {
5452
+ _OverType._autoInstances.delete(this);
4056
5453
  this.instanceTheme = theme;
4057
- const themeObj = typeof theme === "string" ? getTheme(theme) : theme;
4058
- const themeName = typeof themeObj === "string" ? themeObj : themeObj.name;
4059
- if (themeName) {
4060
- this.container.setAttribute("data-theme", themeName);
5454
+ if (theme === "auto") {
5455
+ _OverType._autoInstances.add(this);
5456
+ _OverType._startAutoListener();
5457
+ this._applyResolvedTheme(resolveAutoTheme("auto"));
5458
+ } else {
5459
+ const themeObj = typeof theme === "string" ? getTheme(theme) : theme;
5460
+ const themeName = typeof themeObj === "string" ? themeObj : themeObj.name;
5461
+ if (themeName) {
5462
+ this.container.setAttribute("data-theme", themeName);
5463
+ }
5464
+ if (themeObj && themeObj.colors) {
5465
+ const cssVars = themeToCSSVars(themeObj.colors);
5466
+ this.container.style.cssText += cssVars;
5467
+ }
5468
+ this.updatePreview();
4061
5469
  }
5470
+ _OverType._stopAutoListener();
5471
+ return this;
5472
+ }
5473
+ _applyResolvedTheme(themeName) {
5474
+ const themeObj = getTheme(themeName);
5475
+ this.container.setAttribute("data-theme", themeName);
4062
5476
  if (themeObj && themeObj.colors) {
4063
- const cssVars = themeToCSSVars(themeObj.colors);
4064
- this.container.style.cssText += cssVars;
5477
+ this.container.style.cssText = themeToCSSVars(themeObj.colors);
4065
5478
  }
4066
5479
  this.updatePreview();
4067
- return this;
4068
5480
  }
4069
5481
  /**
4070
5482
  * Set instance-specific code highlighter
@@ -4218,6 +5630,11 @@ var _OverType = class _OverType {
4218
5630
  * Destroy the editor instance
4219
5631
  */
4220
5632
  destroy() {
5633
+ _OverType._autoInstances.delete(this);
5634
+ _OverType._stopAutoListener();
5635
+ if (this.fileUploadInitialized) {
5636
+ this._destroyFileUpload();
5637
+ }
4221
5638
  this.element.overTypeInstance = null;
4222
5639
  _OverType.instances.delete(this.element);
4223
5640
  if (this.shortcuts) {
@@ -4260,7 +5677,7 @@ var _OverType = class _OverType {
4260
5677
  options[key] = _OverType._parseDataValue(attr.value);
4261
5678
  }
4262
5679
  }
4263
- return new _OverType(el, options);
5680
+ return new _OverType(el, options)[0];
4264
5681
  });
4265
5682
  }
4266
5683
  /**
@@ -4323,23 +5740,35 @@ var _OverType = class _OverType {
4323
5740
  * @param {Object} customColors - Optional color overrides
4324
5741
  */
4325
5742
  static setTheme(theme, customColors = null) {
5743
+ _OverType._globalAutoTheme = false;
5744
+ _OverType._globalAutoCustomColors = null;
5745
+ if (theme === "auto") {
5746
+ _OverType._globalAutoTheme = true;
5747
+ _OverType._globalAutoCustomColors = customColors;
5748
+ _OverType._startAutoListener();
5749
+ _OverType._applyGlobalTheme(resolveAutoTheme("auto"), customColors);
5750
+ return;
5751
+ }
5752
+ _OverType._stopAutoListener();
5753
+ _OverType._applyGlobalTheme(theme, customColors);
5754
+ }
5755
+ static _applyGlobalTheme(theme, customColors = null) {
4326
5756
  let themeObj = typeof theme === "string" ? getTheme(theme) : theme;
4327
5757
  if (customColors) {
4328
5758
  themeObj = mergeTheme(themeObj, customColors);
4329
5759
  }
4330
5760
  _OverType.currentTheme = themeObj;
4331
5761
  _OverType.injectStyles(true);
5762
+ const themeName = typeof themeObj === "string" ? themeObj : themeObj.name;
4332
5763
  document.querySelectorAll(".overtype-container").forEach((container) => {
4333
- const themeName2 = typeof themeObj === "string" ? themeObj : themeObj.name;
4334
- if (themeName2) {
4335
- container.setAttribute("data-theme", themeName2);
5764
+ if (themeName) {
5765
+ container.setAttribute("data-theme", themeName);
4336
5766
  }
4337
5767
  });
4338
5768
  document.querySelectorAll(".overtype-wrapper").forEach((wrapper) => {
4339
5769
  if (!wrapper.closest(".overtype-container")) {
4340
- const themeName2 = typeof themeObj === "string" ? themeObj : themeObj.name;
4341
- if (themeName2) {
4342
- wrapper.setAttribute("data-theme", themeName2);
5770
+ if (themeName) {
5771
+ wrapper.setAttribute("data-theme", themeName);
4343
5772
  }
4344
5773
  }
4345
5774
  const instance = wrapper._instance;
@@ -4347,7 +5776,6 @@ var _OverType = class _OverType {
4347
5776
  instance.updatePreview();
4348
5777
  }
4349
5778
  });
4350
- const themeName = typeof themeObj === "string" ? themeObj : themeObj.name;
4351
5779
  document.querySelectorAll("overtype-editor").forEach((webComponent) => {
4352
5780
  if (themeName && typeof webComponent.setAttribute === "function") {
4353
5781
  webComponent.setAttribute("theme", themeName);
@@ -4357,6 +5785,30 @@ var _OverType = class _OverType {
4357
5785
  }
4358
5786
  });
4359
5787
  }
5788
+ static _startAutoListener() {
5789
+ if (_OverType._autoMediaQuery)
5790
+ return;
5791
+ if (!window.matchMedia)
5792
+ return;
5793
+ _OverType._autoMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
5794
+ _OverType._autoMediaListener = (e) => {
5795
+ const resolved = e.matches ? "cave" : "solar";
5796
+ if (_OverType._globalAutoTheme) {
5797
+ _OverType._applyGlobalTheme(resolved, _OverType._globalAutoCustomColors);
5798
+ }
5799
+ _OverType._autoInstances.forEach((inst) => inst._applyResolvedTheme(resolved));
5800
+ };
5801
+ _OverType._autoMediaQuery.addEventListener("change", _OverType._autoMediaListener);
5802
+ }
5803
+ static _stopAutoListener() {
5804
+ if (_OverType._autoInstances.size > 0 || _OverType._globalAutoTheme)
5805
+ return;
5806
+ if (!_OverType._autoMediaQuery)
5807
+ return;
5808
+ _OverType._autoMediaQuery.removeEventListener("change", _OverType._autoMediaListener);
5809
+ _OverType._autoMediaQuery = null;
5810
+ _OverType._autoMediaListener = null;
5811
+ }
4360
5812
  /**
4361
5813
  * Set global code highlighter for all OverType instances
4362
5814
  * @param {Function|null} highlighter - Function that takes (code, language) and returns highlighted HTML
@@ -4458,6 +5910,11 @@ __publicField(_OverType, "instances", /* @__PURE__ */ new WeakMap());
4458
5910
  __publicField(_OverType, "stylesInjected", false);
4459
5911
  __publicField(_OverType, "globalListenersInitialized", false);
4460
5912
  __publicField(_OverType, "instanceCount", 0);
5913
+ __publicField(_OverType, "_autoMediaQuery", null);
5914
+ __publicField(_OverType, "_autoMediaListener", null);
5915
+ __publicField(_OverType, "_autoInstances", /* @__PURE__ */ new Set());
5916
+ __publicField(_OverType, "_globalAutoTheme", false);
5917
+ __publicField(_OverType, "_globalAutoCustomColors", null);
4461
5918
  var OverType = _OverType;
4462
5919
  OverType.MarkdownParser = MarkdownParser;
4463
5920
  OverType.ShortcutsManager = ShortcutsManager;
@@ -4484,7 +5941,8 @@ var OBSERVED_ATTRIBUTES = [
4484
5941
  "autofocus",
4485
5942
  "show-stats",
4486
5943
  "smart-lists",
4487
- "readonly"
5944
+ "readonly",
5945
+ "spellcheck"
4488
5946
  ];
4489
5947
  var OverTypeEditor = class extends HTMLElement {
4490
5948
  constructor() {
@@ -4667,6 +6125,7 @@ var OverTypeEditor = class extends HTMLElement {
4667
6125
  autoResize: this.hasAttribute("auto-resize"),
4668
6126
  showStats: this.hasAttribute("show-stats"),
4669
6127
  smartLists: !this.hasAttribute("smart-lists") || this.getAttribute("smart-lists") !== "false",
6128
+ spellcheck: this.hasAttribute("spellcheck") && this.getAttribute("spellcheck") !== "false",
4670
6129
  onChange: this._handleChange,
4671
6130
  onKeydown: this._handleKeydown
4672
6131
  };
@@ -4722,8 +6181,14 @@ var OverTypeEditor = class extends HTMLElement {
4722
6181
  }
4723
6182
  break;
4724
6183
  case "placeholder":
4725
- if (this._editor.textarea) {
4726
- this._editor.textarea.placeholder = value || "";
6184
+ if (this._editor) {
6185
+ this._editor.options.placeholder = value || "";
6186
+ if (this._editor.textarea) {
6187
+ this._editor.textarea.placeholder = value || "";
6188
+ }
6189
+ if (this._editor.placeholderEl) {
6190
+ this._editor.placeholderEl.textContent = value || "";
6191
+ }
4727
6192
  }
4728
6193
  break;
4729
6194
  case "readonly":
@@ -4773,6 +6238,15 @@ var OverTypeEditor = class extends HTMLElement {
4773
6238
  this._reinitializeEditor();
4774
6239
  break;
4775
6240
  }
6241
+ case "spellcheck":
6242
+ if (this._editor) {
6243
+ const enabled = this.hasAttribute("spellcheck") && this.getAttribute("spellcheck") !== "false";
6244
+ this._editor.options.spellcheck = enabled;
6245
+ if (this._editor.textarea) {
6246
+ this._editor.textarea.setAttribute("spellcheck", String(enabled));
6247
+ }
6248
+ }
6249
+ break;
4776
6250
  }
4777
6251
  }
4778
6252
  /**
@@ -5016,6 +6490,16 @@ var OverTypeEditor = class extends HTMLElement {
5016
6490
  getEditor() {
5017
6491
  return this._editor;
5018
6492
  }
6493
+ showToolbar() {
6494
+ if (this._editor) {
6495
+ this._editor.showToolbar();
6496
+ }
6497
+ }
6498
+ hideToolbar() {
6499
+ if (this._editor) {
6500
+ this._editor.hideToolbar();
6501
+ }
6502
+ }
5019
6503
  };
5020
6504
  if (!customElements.get("overtype-editor")) {
5021
6505
  customElements.define("overtype-editor", OverTypeEditor);