@mantine-vue/core 3.3.0 → 3.5.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.
package/cjs/index.cjs CHANGED
@@ -1738,7 +1738,7 @@ function hashStyleProps(styles, media) {
1738
1738
  return `mantine-vue-${Math.abs(hash).toString(36)}`;
1739
1739
  }
1740
1740
  function useRandomClassName() {
1741
- return `mantine-vue-${Math.random().toString(36).slice(2, 9)}`;
1741
+ return `mantine-vue-${((0, vue.getCurrentInstance)() ? (0, vue.useId)() : Math.random().toString(36).slice(2, 9)).replace(/[^A-Za-z0-9_-]/g, "-")}`;
1742
1742
  }
1743
1743
  //#endregion
1744
1744
  //#region src/core/Box/style-props/style-props-data.ts
@@ -8725,21 +8725,21 @@ var AccordionChevron = /* @__PURE__ */ (0, vue.defineComponent)({
8725
8725
  //#region src/components/Accordion/Accordion.context.ts
8726
8726
  var [provideAccordionContext, useAccordionContext] = createSafeContext("Accordion component was not found in the tree");
8727
8727
  var Accordion_module_default = {
8728
- root: "_root_ltqd9_1",
8729
- panel: "_panel_ltqd9_5",
8730
- content: "_content_ltqd9_9",
8731
- itemTitle: "_itemTitle_ltqd9_14",
8732
- control: "_control_ltqd9_20",
8733
- "control--default": "_control--default_ltqd9_42",
8734
- "control--contained": "_control--contained_ltqd9_43",
8735
- label: "_label_ltqd9_57",
8736
- chevron: "_chevron_ltqd9_67",
8737
- icon: "_icon_ltqd9_86",
8738
- item: "_item_ltqd9_14",
8739
- "item--default": "_item--default_ltqd9_110",
8740
- "item--contained": "_item--contained_ltqd9_114",
8741
- "item--filled": "_item--filled_ltqd9_147",
8742
- "item--separated": "_item--separated_ltqd9_155"
8728
+ root: "_root_1ysxv_1",
8729
+ panel: "_panel_1ysxv_5",
8730
+ content: "_content_1ysxv_9",
8731
+ itemTitle: "_itemTitle_1ysxv_14",
8732
+ control: "_control_1ysxv_20",
8733
+ "control--default": "_control--default_1ysxv_42",
8734
+ "control--contained": "_control--contained_1ysxv_43",
8735
+ label: "_label_1ysxv_57",
8736
+ chevron: "_chevron_1ysxv_67",
8737
+ icon: "_icon_1ysxv_86",
8738
+ item: "_item_1ysxv_14",
8739
+ "item--default": "_item--default_1ysxv_110",
8740
+ "item--contained": "_item--contained_1ysxv_114",
8741
+ "item--filled": "_item--filled_1ysxv_149",
8742
+ "item--separated": "_item--separated_1ysxv_157"
8743
8743
  };
8744
8744
  //#endregion
8745
8745
  //#region src/components/Accordion/Accordion.vue?vue&type=script&setup=true&lang.ts
@@ -13852,13 +13852,21 @@ var leadingZerosPattern = /^-?0\d+(\.\d+)?\.?$/;
13852
13852
  var trailingZerosPattern = /\.\d*0$/;
13853
13853
  var trailingDecimalSeparatorPattern = /^-?\d+\.$/;
13854
13854
  function clamp$3(value, min, max) {
13855
- return Math.min(max ?? value, Math.max(min ?? value, value));
13855
+ return Math.min(max ?? Number.POSITIVE_INFINITY, Math.max(min ?? Number.NEGATIVE_INFINITY, value));
13856
13856
  }
13857
13857
  function clampBigInt(value, min, max) {
13858
13858
  if (min !== void 0 && value < min) return min;
13859
13859
  if (max !== void 0 && value > max) return max;
13860
13860
  return value;
13861
13861
  }
13862
+ function canStep(value) {
13863
+ if (typeof value === "number") return value < Number.MAX_SAFE_INTEGER;
13864
+ return value === "" || value !== "-" && !Number.isNaN(Number(value)) && Number(value) < Number.MAX_SAFE_INTEGER;
13865
+ }
13866
+ function canStepBigInt(value, allowNegative) {
13867
+ if (typeof value === "bigint") return true;
13868
+ return value === "" || value !== "-" && (allowNegative || !value.startsWith("-")) && /^-?\d+$/.test(value);
13869
+ }
13862
13870
  function stripFormatting(value, options) {
13863
13871
  let next = value;
13864
13872
  if (options.prefix && next.startsWith(options.prefix)) next = next.slice(options.prefix.length);
@@ -13888,25 +13896,77 @@ function parseNumberInputValue(rawValue, allowDecimal, allowNegative, allowLeadi
13888
13896
  return parsed;
13889
13897
  }
13890
13898
  function sanitizeNumberInputString(rawValue, allowDecimal, allowNegative, decimalScale) {
13891
- let normalized = rawValue;
13892
- if (!allowNegative) normalized = normalized.replace(/-/g, "");
13893
- if (!allowDecimal) return normalized.split(".")[0];
13899
+ let normalized = "";
13900
+ let hasDecimalSeparator = false;
13901
+ for (const character of rawValue) {
13902
+ if (character === "." && !allowDecimal) break;
13903
+ if (/\d/.test(character)) normalized += character;
13904
+ else if (character === "-" && allowNegative && normalized.length === 0) normalized = "-";
13905
+ else if (character === "." && allowDecimal && !hasDecimalSeparator) {
13906
+ normalized += character;
13907
+ hasDecimalSeparator = true;
13908
+ }
13909
+ }
13910
+ if (normalized.startsWith(".")) normalized = `0${normalized}`;
13911
+ else if (normalized.startsWith("-.")) normalized = `-0${normalized.slice(1)}`;
13894
13912
  if (typeof decimalScale === "number" && normalized.includes(".")) {
13895
13913
  const [integerPart, decimalPart = ""] = normalized.split(".");
13896
13914
  return `${integerPart}.${decimalPart.slice(0, decimalScale)}`;
13897
13915
  }
13898
13916
  return normalized;
13899
13917
  }
13900
- function clampAndSanitizeInput(sanitizedValue, max, min) {
13901
- const stringValue = sanitizedValue.toString();
13902
- const hasTrailingDecimalSeparator = trailingDecimalSeparatorPattern.test(stringValue);
13903
- const replaced = stringValue.replace(/^0+(?=\d)/, "");
13904
- const parsedValue = parseFloat(replaced);
13905
- if (Number.isNaN(parsedValue)) return replaced;
13906
- if (parsedValue > Number.MAX_SAFE_INTEGER) return max !== void 0 ? max : replaced;
13907
- const clamped = clamp$3(parsedValue, min, max);
13908
- if (hasTrailingDecimalSeparator) return `${clamped.toString().replace(/^0+(?=\d)/, "")}.`;
13909
- return clamped;
13918
+ function withTrailingSeparator(value, hasTrailingDecimalSeparator) {
13919
+ return hasTrailingDecimalSeparator ? `${value}.` : value;
13920
+ }
13921
+ function sanitizeInputOnBlur(value, options) {
13922
+ const hasTrailingDecimalSeparator = trailingDecimalSeparatorPattern.test(value);
13923
+ const trimmed = options.trim ? value.replace(/^0+(?=\d)/, "") : value;
13924
+ const parsedValue = parseFloat(trimmed);
13925
+ if (Number.isNaN(parsedValue)) return trimmed;
13926
+ if (!options.clamp) return options.trim ? withTrailingSeparator(parsedValue, hasTrailingDecimalSeparator) : value;
13927
+ const clamped = parsedValue > Number.MAX_SAFE_INTEGER && options.max !== void 0 ? options.max : clamp$3(parsedValue, options.min, options.max);
13928
+ if (!options.trim && clamped === parsedValue) return value;
13929
+ return withTrailingSeparator(clamped, hasTrailingDecimalSeparator);
13930
+ }
13931
+ function countTrailingDigits(value, from) {
13932
+ let count = 0;
13933
+ while (from + count < value.length && /\d/.test(value[from + count])) count += 1;
13934
+ return count;
13935
+ }
13936
+ function normalizePastedValue(value, options) {
13937
+ const candidates = new Set([...options.allowedDecimalSeparators, options.decimalSeparator].filter((separator) => separator.length === 1));
13938
+ const chars = value.split("");
13939
+ const occurrences = chars.reduce((result, char, index) => {
13940
+ if (candidates.has(char)) result.push(index);
13941
+ return result;
13942
+ }, []);
13943
+ if (occurrences.length === 0) return value;
13944
+ const lastIndex = occurrences[occurrences.length - 1];
13945
+ const lastChar = chars[lastIndex];
13946
+ const lastCharCount = occurrences.filter((index) => chars[index] === lastChar).length;
13947
+ const lastGroupSize = options.thousandsGroupStyle === "wan" ? 4 : 3;
13948
+ let decimalIndex = -1;
13949
+ if (lastCharCount === 1) if (lastChar === options.decimalSeparator) decimalIndex = lastIndex;
13950
+ else if (lastChar === options.thousandSeparator) decimalIndex = countTrailingDigits(value, lastIndex + 1) === lastGroupSize ? -1 : lastIndex;
13951
+ else decimalIndex = lastIndex;
13952
+ return chars.map((char, index) => {
13953
+ if (index === decimalIndex) return options.decimalSeparator;
13954
+ if (candidates.has(char) && char !== options.thousandSeparator) return "";
13955
+ return char;
13956
+ }).join("");
13957
+ }
13958
+ function isSignificant(char, decimalSeparator) {
13959
+ return /\d/.test(char) || char === decimalSeparator;
13960
+ }
13961
+ function getCaretPositionAfterPaste(rawValue, rawCaret, formattedValue, decimalSeparator) {
13962
+ let remaining = 0;
13963
+ for (let index = 0; index < rawCaret && index < rawValue.length; index += 1) if (isSignificant(rawValue[index], decimalSeparator)) remaining += 1;
13964
+ if (remaining === 0) return Math.min(rawCaret, formattedValue.length);
13965
+ for (let index = 0; index < formattedValue.length; index += 1) if (isSignificant(formattedValue[index], decimalSeparator)) {
13966
+ remaining -= 1;
13967
+ if (remaining === 0) return index + 1;
13968
+ }
13969
+ return formattedValue.length;
13910
13970
  }
13911
13971
  function isInRange(value, min, max) {
13912
13972
  if (value === void 0) return true;
@@ -14110,7 +14170,6 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14110
14170
  const slots = (0, vue.useSlots)();
14111
14171
  const attrs = (0, vue.useAttrs)();
14112
14172
  const inputRef = (0, vue.ref)(null);
14113
- const isEditing = (0, vue.ref)(false);
14114
14173
  const isBigIntMode = (0, vue.computed)(() => typeof props.modelValue === "bigint" || typeof props.defaultValue === "bigint");
14115
14174
  const [value, setValue] = (0, _mantine_vue_hooks.useUncontrolled)({
14116
14175
  value: () => props.modelValue,
@@ -14143,11 +14202,7 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14143
14202
  thousandsGroupStyle: props.thousandsGroupStyle,
14144
14203
  thousandSeparator: props.thousandSeparator
14145
14204
  }));
14146
- const getFormatterOptions = (nextValue = value.value) => ({
14147
- ...formatterOptions.value,
14148
- fixedDecimalScale: isEditing.value || typeof nextValue === "string" ? false : formatterOptions.value.fixedDecimalScale
14149
- });
14150
- const displayValue = (0, vue.computed)(() => value.value === "" || value.value === "-" ? String(value.value) : formatNumber(value.value, getFormatterOptions()));
14205
+ const displayValue = (0, vue.computed)(() => value.value === "" || value.value === "-" ? String(value.value) : formatNumber(value.value, formatterOptions.value));
14151
14206
  const clampCaretToFormatting = (input) => {
14152
14207
  const { min, max } = getCaretBoundaries(input.value, formatterOptions.value);
14153
14208
  const start = input.selectionStart;
@@ -14160,6 +14215,14 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14160
14215
  const scheduleCaretClamp = (input) => {
14161
14216
  setTimeout(() => clampCaretToFormatting(input), 0);
14162
14217
  };
14218
+ const getFormattedCaretPosition = (value, formattedValue, position) => {
14219
+ let formattedPosition = 0;
14220
+ for (const character of value.slice(0, position)) {
14221
+ const nextPosition = formattedValue.indexOf(character, formattedPosition);
14222
+ if (nextPosition !== -1) formattedPosition = nextPosition + 1;
14223
+ }
14224
+ return formattedPosition;
14225
+ };
14163
14226
  const commitValue = (nextValue, source = "event") => {
14164
14227
  if (props.clampBehavior === "strict") {
14165
14228
  const numeric = toNumeric(nextValue);
@@ -14171,18 +14234,19 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14171
14234
  const raw = typeof nextValue === "bigint" ? nextValue.toString() : String(nextValue);
14172
14235
  emit("value-change", {
14173
14236
  floatValue: typeof nextValue === "number" ? nextValue : Number.isNaN(Number(raw)) ? void 0 : Number(raw),
14174
- formattedValue: nextValue === "" ? "" : formatNumber(nextValue, getFormatterOptions(nextValue)),
14237
+ formattedValue: nextValue === "" ? "" : formatNumber(nextValue, formatterOptions.value),
14175
14238
  value: raw
14176
14239
  }, { source });
14177
14240
  };
14241
+ const canStepValue = (0, vue.computed)(() => isBigIntMode.value ? canStepBigInt(value.value, props.allowNegative) : canStep(value.value));
14178
14242
  const stepValue = (direction) => {
14179
- if (props.disabled || props.readOnly) return;
14243
+ if (props.disabled || props.readOnly || !canStepValue.value) return;
14180
14244
  if (isBigIntMode.value) {
14181
14245
  const current = typeof value.value === "bigint" ? value.value : BigInt(0);
14182
14246
  const step = typeof props.step === "bigint" ? props.step : BigInt(props.step);
14183
14247
  const start = typeof props.startValue === "bigint" ? props.startValue : BigInt(props.startValue);
14184
14248
  const next = (value.value === "" || value.value === "-" ? start : current) + step * BigInt(direction);
14185
- const min = typeof props.min === "bigint" ? props.min : props.min === void 0 ? void 0 : BigInt(props.min);
14249
+ const min = typeof props.min === "bigint" ? props.min : props.min === void 0 ? props.allowNegative ? void 0 : BigInt(0) : BigInt(props.min);
14186
14250
  const max = typeof props.max === "bigint" ? props.max : props.max === void 0 ? void 0 : BigInt(props.max);
14187
14251
  const clamped = clampBigInt(next, min, max);
14188
14252
  if (max !== void 0 && next > max) emit("max-reached");
@@ -14272,7 +14336,7 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14272
14336
  onPointercancel: clearHold
14273
14337
  }, () => (0, vue.h)(NumberInputChevron, { direction: "down" }))]);
14274
14338
  /** The step controls double as the right section unless one was supplied. */
14275
- const rightSection = (0, vue.computed)(() => props.hideControls || props.readOnly ? props.rightSection : props.rightSection !== void 0 || slots.rightSection ? props.rightSection : controls);
14339
+ const rightSection = (0, vue.computed)(() => props.hideControls || props.readOnly || !canStepValue.value ? props.rightSection : props.rightSection !== void 0 || slots.rightSection ? props.rightSection : controls);
14276
14340
  const rightSectionPointerEvents = (0, vue.computed)(() => props.rightSectionPointerEvents ?? (props.disabled ? "none" : void 0));
14277
14341
  const rightSectionWidth = (0, vue.computed)(() => props.rightSectionWidth ?? `var(--ni-right-section-width-${props.size || "sm"})`);
14278
14342
  /** `bigint` values are integers only, so the numeric keypad is the right hint. */
@@ -14289,22 +14353,52 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14289
14353
  };
14290
14354
  __expose({ rootElement });
14291
14355
  function onInput(event) {
14292
- isEditing.value = true;
14293
14356
  const input = event.currentTarget;
14294
- const rawValue = stripFormatting(input.value, formatterOptions.value);
14357
+ const inputValue = input.value;
14358
+ const selectionStart = input.selectionStart;
14359
+ const selectionEnd = input.selectionEnd;
14360
+ const rawValue = stripFormatting(inputValue, formatterOptions.value);
14295
14361
  const decimalSeparator = props.decimalSeparator || ".";
14296
- const sanitized = sanitizeNumberInputString(props.allowedDecimalSeparators.filter((separator) => separator !== decimalSeparator).reduce((acc, separator) => acc.split(separator).join("."), rawValue.replace(decimalSeparator, ".")), props.allowDecimal, props.allowNegative, props.decimalScale);
14362
+ const sanitized = sanitizeNumberInputString(props.allowedDecimalSeparators.filter((separator) => separator !== decimalSeparator).reduce((acc, separator) => acc.split(separator).join("."), rawValue.replace(decimalSeparator, ".")), isBigIntMode.value ? false : props.allowDecimal, props.allowNegative, props.decimalScale);
14297
14363
  const nextValue = isBigIntMode.value ? parseBigIntInputValue(sanitized, props.allowNegative, props.allowLeadingZeros) : parseNumberInputValue(sanitized, props.allowDecimal, props.allowNegative, props.allowLeadingZeros, props.decimalScale, props.fixedDecimalScale);
14298
14364
  if (props.clampBehavior === "strict" && !isBigIntMode.value && !isStrictAllowed(nextValue, typeof props.min === "number" ? props.min : void 0, typeof props.max === "number" ? props.max : void 0)) {
14299
14365
  restoreInputValue(input, displayValue.value);
14300
14366
  return;
14301
14367
  }
14302
- const formattedNextValue = nextValue === "" || nextValue === "-" ? String(nextValue) : formatNumber(nextValue, getFormatterOptions(nextValue));
14303
- if (input.value !== formattedNextValue) restoreInputValue(input, formattedNextValue);
14368
+ const formattedNextValue = nextValue === "" || nextValue === "-" ? String(nextValue) : formatNumber(nextValue, formatterOptions.value);
14369
+ if (input.value !== formattedNextValue) {
14370
+ restoreInputValue(input, formattedNextValue);
14371
+ if (props.fixedDecimalScale && selectionStart !== null && selectionEnd !== null) input.setSelectionRange(getFormattedCaretPosition(inputValue, formattedNextValue, selectionStart), getFormattedCaretPosition(inputValue, formattedNextValue, selectionEnd));
14372
+ }
14304
14373
  scheduleCaretClamp(input);
14305
- commitValue(nextValue);
14374
+ if (!Object.is(nextValue, value.value)) commitValue(nextValue);
14306
14375
  }
14307
14376
  function onKeydown(event) {
14377
+ const input = event.currentTarget;
14378
+ if (event.key === "Backspace" && !props.readOnly && !props.disabled && input.selectionStart !== null && input.selectionStart === input.selectionEnd) {
14379
+ if (input.selectionStart === 0) event.preventDefault();
14380
+ else if (props.fixedDecimalScale && typeof props.decimalScale === "number") {
14381
+ const decimalPosition = input.value.indexOf(props.decimalSeparator);
14382
+ const isAfterDecimalSeparator = input.value[input.selectionStart - 1] === props.decimalSeparator;
14383
+ const deletePosition = input.selectionStart - (isAfterDecimalSeparator ? 2 : 1);
14384
+ if (deletePosition >= 0 && deletePosition < decimalPosition) {
14385
+ const nextInputValue = input.value.slice(0, deletePosition) + input.value.slice(deletePosition + 1);
14386
+ const unformattedValue = stripFormatting(nextInputValue, formatterOptions.value);
14387
+ const [integerPart, decimalPart = ""] = (unformattedValue.startsWith("-") ? unformattedValue.slice(1) : unformattedValue).split(".");
14388
+ if (!/\d/.test(integerPart) && /^0*$/.test(decimalPart)) {
14389
+ event.preventDefault();
14390
+ input.value = "";
14391
+ input.setSelectionRange(0, 0);
14392
+ input.dispatchEvent(new Event("input", { bubbles: true }));
14393
+ } else if (isAfterDecimalSeparator) {
14394
+ event.preventDefault();
14395
+ input.value = nextInputValue;
14396
+ input.setSelectionRange(deletePosition, deletePosition);
14397
+ input.dispatchEvent(new Event("input", { bubbles: true }));
14398
+ }
14399
+ }
14400
+ }
14401
+ }
14308
14402
  if (!props.readOnly && props.withKeyboardEvents && event.key === "ArrowUp") {
14309
14403
  event.preventDefault();
14310
14404
  stepValue(1);
@@ -14313,7 +14407,7 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14313
14407
  event.preventDefault();
14314
14408
  stepValue(-1);
14315
14409
  }
14316
- scheduleCaretClamp(event.currentTarget);
14410
+ scheduleCaretClamp(input);
14317
14411
  }
14318
14412
  function onKeyup(event) {
14319
14413
  scheduleCaretClamp(event.currentTarget);
@@ -14322,17 +14416,44 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14322
14416
  scheduleCaretClamp(event.currentTarget);
14323
14417
  }
14324
14418
  function onFocus(event) {
14325
- isEditing.value = true;
14326
14419
  if (props.selectAllOnFocus) window.setTimeout(() => inputRef.value?.select(), 0);
14327
14420
  else scheduleCaretClamp(event.currentTarget);
14328
14421
  }
14422
+ function onPaste(event) {
14423
+ const pastedText = event.clipboardData?.getData("text") ?? "";
14424
+ const decimalSeparator = props.decimalSeparator || ".";
14425
+ const modifiedText = normalizePastedValue(pastedText, {
14426
+ decimalSeparator,
14427
+ thousandSeparator: props.thousandSeparator === true ? "," : props.thousandSeparator === false ? void 0 : props.thousandSeparator,
14428
+ allowedDecimalSeparators: props.allowedDecimalSeparators,
14429
+ thousandsGroupStyle: props.thousandsGroupStyle
14430
+ });
14431
+ if (modifiedText !== pastedText && inputRef.value) {
14432
+ event.preventDefault();
14433
+ const input = inputRef.value;
14434
+ const start = input.selectionStart ?? 0;
14435
+ const end = input.selectionEnd ?? 0;
14436
+ const newValue = input.value.slice(0, start) + modifiedText + input.value.slice(end);
14437
+ input.value = newValue;
14438
+ input.dispatchEvent(new Event("input", { bubbles: true }));
14439
+ const rawCaret = start + modifiedText.length;
14440
+ setTimeout(() => {
14441
+ const caret = getCaretPositionAfterPaste(newValue, rawCaret, input.value, decimalSeparator);
14442
+ input.setSelectionRange(caret, caret);
14443
+ }, 0);
14444
+ }
14445
+ }
14329
14446
  function onBlur() {
14330
- isEditing.value = false;
14331
14447
  let sanitizedValue = value.value;
14332
14448
  const min = typeof props.min === "number" ? props.min : void 0;
14333
14449
  const max = typeof props.max === "number" ? props.max : void 0;
14334
14450
  if (props.clampBehavior === "blur" && typeof sanitizedValue === "number") sanitizedValue = clamp$3(sanitizedValue, min, max);
14335
- if (props.trimLeadingZeroesOnBlur && typeof sanitizedValue === "string" && getDecimalPlaces(sanitizedValue) < 15) sanitizedValue = clampAndSanitizeInput(sanitizedValue, max, min);
14451
+ if (!isBigIntMode.value && typeof sanitizedValue === "string") sanitizedValue = sanitizeInputOnBlur(sanitizedValue, {
14452
+ min,
14453
+ max,
14454
+ trim: props.trimLeadingZeroesOnBlur && getDecimalPlaces(sanitizedValue) < 15,
14455
+ clamp: props.clampBehavior === "blur"
14456
+ });
14336
14457
  if (sanitizedValue !== value.value) commitValue(sanitizedValue, "blur");
14337
14458
  }
14338
14459
  return (_ctx, _cache) => {
@@ -14366,6 +14487,7 @@ var NumberInput = factory(/* @__PURE__ */ (0, vue.defineComponent)({
14366
14487
  onKeyup,
14367
14488
  onClick,
14368
14489
  onFocus,
14490
+ onPaste,
14369
14491
  onBlur
14370
14492
  }), (0, vue.createSlots)({ _: 2 }, [
14371
14493
  (0, vue.unref)(slots).label ? {
@@ -16482,8 +16604,16 @@ var SegmentedControl = Object.assign(/* @__PURE__ */ (0, vue.defineComponent)({
16482
16604
  parent.value = node?.$el ?? node ?? null;
16483
16605
  };
16484
16606
  const setItemRef = (key, node) => {
16485
- itemRefs[key] = node?.$el ?? node ?? null;
16607
+ const element = node?.$el ?? node ?? null;
16608
+ if (element === null) delete itemRefs[key];
16609
+ else itemRefs[key] = element;
16486
16610
  };
16611
+ (0, vue.watch)(normalizedData, (items) => {
16612
+ const values = new Set(items.map((item) => String(item.value)));
16613
+ Object.keys(itemRefs).forEach((key) => {
16614
+ if (!values.has(key)) delete itemRefs[key];
16615
+ });
16616
+ });
16487
16617
  const ItemLabel = (item) => (0, vue.h)("span", getStyles("innerLabel"), resolveNode(item.label));
16488
16618
  const handleClick = (event) => {
16489
16619
  if (props.readOnly) event.preventDefault();
@@ -18224,6 +18354,7 @@ var Autosize_default = /* @__PURE__ */ (0, vue.defineComponent)({
18224
18354
  }
18225
18355
  }
18226
18356
  const cleanupFns = [];
18357
+ let resizeFrame = 0;
18227
18358
  (0, vue.onMounted)(() => {
18228
18359
  resizeTextarea();
18229
18360
  const onResize = () => resizeTextarea();
@@ -18235,11 +18366,15 @@ var Autosize_default = /* @__PURE__ */ (0, vue.defineComponent)({
18235
18366
  const observer = new ResizeObserver(() => {
18236
18367
  if (textareaRef.value && textareaRef.value.offsetWidth !== widthRef.value) {
18237
18368
  widthRef.value = textareaRef.value.offsetWidth;
18238
- resizeTextarea();
18369
+ cancelAnimationFrame(resizeFrame);
18370
+ resizeFrame = requestAnimationFrame(resizeTextarea);
18239
18371
  }
18240
18372
  });
18241
18373
  observer.observe(node);
18242
- cleanupFns.push(() => observer.disconnect());
18374
+ cleanupFns.push(() => {
18375
+ cancelAnimationFrame(resizeFrame);
18376
+ observer.disconnect();
18377
+ });
18243
18378
  }
18244
18379
  const onFontsLoaded = () => resizeTextarea();
18245
18380
  document.fonts.addEventListener("loadingdone", onFontsLoaded);
@@ -18256,6 +18391,7 @@ var Autosize_default = /* @__PURE__ */ (0, vue.defineComponent)({
18256
18391
  cleanupFns.push(() => document.body.removeEventListener("reset", onReset));
18257
18392
  });
18258
18393
  (0, vue.onUnmounted)(() => {
18394
+ cancelAnimationFrame(resizeFrame);
18259
18395
  cleanupFns.forEach((fn) => fn());
18260
18396
  cleanupFns.length = 0;
18261
18397
  });
@@ -22769,20 +22905,30 @@ function getEl$1(value) {
22769
22905
  function useDimensions(element) {
22770
22906
  const dimensions = (0, vue.ref)(null);
22771
22907
  let observer = null;
22908
+ let frame = 0;
22772
22909
  (0, vue.onMounted)(() => {
22773
22910
  const el = getEl$1(element.value);
22774
22911
  if (!el || typeof ResizeObserver === "undefined") return;
22775
22912
  observer = new ResizeObserver(([entry]) => {
22776
- if (entry) dimensions.value = {
22777
- width: entry.borderBoxSize?.[0]?.inlineSize ?? entry.target.clientWidth,
22778
- height: entry.borderBoxSize?.[0]?.blockSize ?? entry.target.clientHeight,
22779
- contentWidth: entry.contentRect.width,
22780
- contentHeight: entry.contentRect.height
22781
- };
22913
+ if (entry) {
22914
+ const nextDimensions = {
22915
+ width: entry.borderBoxSize?.[0]?.inlineSize ?? entry.target.clientWidth,
22916
+ height: entry.borderBoxSize?.[0]?.blockSize ?? entry.target.clientHeight,
22917
+ contentWidth: entry.contentRect.width,
22918
+ contentHeight: entry.contentRect.height
22919
+ };
22920
+ cancelAnimationFrame(frame);
22921
+ frame = requestAnimationFrame(() => {
22922
+ dimensions.value = nextDimensions;
22923
+ });
22924
+ }
22782
22925
  });
22783
22926
  observer.observe(el);
22784
22927
  });
22785
- (0, vue.onBeforeUnmount)(() => observer?.disconnect());
22928
+ (0, vue.onBeforeUnmount)(() => {
22929
+ cancelAnimationFrame(frame);
22930
+ observer?.disconnect();
22931
+ });
22786
22932
  return dimensions;
22787
22933
  }
22788
22934
  var OverflowList_module_default = { root: "_root_uggjd_1" };
@@ -28211,7 +28357,10 @@ function useModal(input) {
28211
28357
  const bodyMounted = (0, vue.ref)(false);
28212
28358
  (0, _mantine_vue_hooks.useWindowEvent)("keydown", (event) => {
28213
28359
  const stopped = event.target?.getAttribute?.("data-mantine-stop-propagation") === "true";
28214
- if (event.key === "Escape" && !event.isComposing && input.opened() && input.closeOnEscape() && !stopped) input.onClose();
28360
+ if (event.key === "Escape" && !event.isComposing && input.opened() && input.closeOnEscape() && !input.handledEscapeEvents?.has(event) && !stopped) {
28361
+ input.handledEscapeEvents?.add(event);
28362
+ input.onClose();
28363
+ }
28215
28364
  }, { capture: true });
28216
28365
  (0, _mantine_vue_hooks.useFocusReturn)({
28217
28366
  opened: input.opened,
@@ -28230,6 +28379,7 @@ var ModalBase = factory(/* @__PURE__ */ (0, vue.defineComponent)({
28230
28379
  inheritAttrs: false,
28231
28380
  __name: "ModalBase",
28232
28381
  props: {
28382
+ __handledEscapeEvents: {},
28233
28383
  rootRef: {},
28234
28384
  opened: { type: Boolean },
28235
28385
  id: { default: void 0 },
@@ -28291,7 +28441,8 @@ var ModalBase = factory(/* @__PURE__ */ (0, vue.defineComponent)({
28291
28441
  onClose: () => emit("close"),
28292
28442
  trapFocus: () => props.trapFocus,
28293
28443
  closeOnEscape: () => props.closeOnEscape,
28294
- returnFocus: () => props.returnFocus
28444
+ returnFocus: () => props.returnFocus,
28445
+ handledEscapeEvents: props.__handledEscapeEvents
28295
28446
  });
28296
28447
  useLockScroll((0, vue.computed)(() => props.opened && props.lockScroll));
28297
28448
  provideModalBaseContext({
@@ -28722,6 +28873,7 @@ var ModalRoot_default = /* @__PURE__ */ (0, vue.defineComponent)({
28722
28873
  classNames: {},
28723
28874
  styles: {},
28724
28875
  vars: {},
28876
+ __handledEscapeEvents: {},
28725
28877
  rootRef: {},
28726
28878
  opened: { type: Boolean },
28727
28879
  id: {},
@@ -28885,6 +29037,7 @@ var Modal_default = /* @__PURE__ */ (0, vue.defineComponent)({
28885
29037
  classNames: {},
28886
29038
  styles: {},
28887
29039
  vars: {},
29040
+ __handledEscapeEvents: {},
28888
29041
  rootRef: {},
28889
29042
  opened: { type: Boolean },
28890
29043
  id: {},
@@ -29107,6 +29260,7 @@ var DrawerRoot_default = /* @__PURE__ */ (0, vue.defineComponent)({
29107
29260
  offset: { default: 0 },
29108
29261
  size: { default: "md" },
29109
29262
  scrollAreaComponent: {},
29263
+ __handledEscapeEvents: {},
29110
29264
  rootRef: {},
29111
29265
  opened: { type: Boolean },
29112
29266
  id: {},
@@ -29270,6 +29424,7 @@ var Drawer_default = /* @__PURE__ */ (0, vue.defineComponent)({
29270
29424
  offset: {},
29271
29425
  size: {},
29272
29426
  scrollAreaComponent: {},
29427
+ __handledEscapeEvents: {},
29273
29428
  rootRef: {},
29274
29429
  opened: { type: Boolean },
29275
29430
  id: {},
@@ -29341,7 +29496,8 @@ var Drawer_default = /* @__PURE__ */ (0, vue.defineComponent)({
29341
29496
  const isCurrent = stackCtx.currentId === props.stackId;
29342
29497
  return {
29343
29498
  closeOnEscape: isCurrent,
29344
- trapFocus: isCurrent
29499
+ trapFocus: isCurrent,
29500
+ __handledEscapeEvents: stackCtx.handledEscapeEvents
29345
29501
  };
29346
29502
  });
29347
29503
  /** One overlay for the whole stack: only the topmost drawer renders it. */
@@ -29446,7 +29602,8 @@ var DrawerStack_default = /* @__PURE__ */ (0, vue.defineComponent)({
29446
29602
  },
29447
29603
  get maxZIndex() {
29448
29604
  return maxZIndex.value;
29449
- }
29605
+ },
29606
+ handledEscapeEvents: /* @__PURE__ */ new WeakSet()
29450
29607
  }));
29451
29608
  return (_ctx, _cache) => {
29452
29609
  return (0, vue.renderSlot)(_ctx.$slots, "default");
@@ -32192,6 +32349,8 @@ var MenuSub_default = /* @__PURE__ */ (0, vue.defineComponent)({
32192
32349
  inheritAttrs: false,
32193
32350
  __name: "MenuSub",
32194
32351
  props: {
32352
+ withinPortal: {},
32353
+ portalProps: {},
32195
32354
  opened: {
32196
32355
  type: Boolean,
32197
32356
  default: void 0
@@ -32225,7 +32384,7 @@ var MenuSub_default = /* @__PURE__ */ (0, vue.defineComponent)({
32225
32384
  transitionProps: props.transitionProps,
32226
32385
  middlewares: props.middlewares,
32227
32386
  closeOnItemClick: false,
32228
- withinPortal: attrs.withinPortal ?? false
32387
+ withinPortal: false
32229
32388
  }));
32230
32389
  return (_ctx, _cache) => {
32231
32390
  return (0, vue.openBlock)(), (0, vue.createBlock)(Menu_default, (0, vue.normalizeProps)((0, vue.guardReactiveProps)(menuBindings.value)), {
@@ -33211,7 +33370,6 @@ function useCombobox(options = {}) {
33211
33370
  const items = () => Array.from(list()?.querySelectorAll("[data-combobox-option]") ?? []);
33212
33371
  const clearSelected = () => items().forEach((item) => {
33213
33372
  item.removeAttribute("data-combobox-selected");
33214
- item.removeAttribute("aria-selected");
33215
33373
  });
33216
33374
  const selectOption = (index) => {
33217
33375
  const optionsList = items();
@@ -33226,7 +33384,6 @@ function useCombobox(options = {}) {
33226
33384
  selectedIndex.value = next;
33227
33385
  clearSelected();
33228
33386
  optionsList[next].setAttribute("data-combobox-selected", "true");
33229
- optionsList[next].setAttribute("aria-selected", "true");
33230
33387
  optionsList[next].scrollIntoView?.({
33231
33388
  block: "nearest",
33232
33389
  behavior: options.scrollBehavior ?? "instant"
@@ -34678,7 +34835,6 @@ var ComboboxPopover_default = /* @__PURE__ */ (0, vue.defineComponent)({
34678
34835
  onDropdownClose: () => {
34679
34836
  emit("dropdown-close");
34680
34837
  combobox.resetSelectedOption();
34681
- if (props.searchable) combobox.focusTarget();
34682
34838
  }
34683
34839
  });
34684
34840
  function handleSearchChange(val) {
@@ -34714,6 +34870,7 @@ var ComboboxPopover_default = /* @__PURE__ */ (0, vue.defineComponent)({
34714
34870
  styles: props.styles,
34715
34871
  unstyled: props.unstyled,
34716
34872
  onOptionSubmit: handleOptionSubmit,
34873
+ returnFocus: true,
34717
34874
  ...props.comboboxProps,
34718
34875
  ...attrs
34719
34876
  }));