@momentum-design/components 0.139.8 → 0.140.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.
Files changed (30) hide show
  1. package/dist/browser/index.js +483 -444
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/input/input.component.d.ts +30 -10
  4. package/dist/components/input/input.component.js +5 -0
  5. package/dist/components/input/input.constants.d.ts +12 -1
  6. package/dist/components/input/input.constants.js +12 -1
  7. package/dist/components/input/input.types.d.ts +3 -2
  8. package/dist/components/numberinput/index.d.ts +7 -0
  9. package/dist/components/numberinput/index.js +4 -0
  10. package/dist/components/numberinput/numberinput.component.d.ts +193 -0
  11. package/dist/components/numberinput/numberinput.component.js +330 -0
  12. package/dist/components/numberinput/numberinput.constants.d.ts +15 -0
  13. package/dist/components/numberinput/numberinput.constants.js +17 -0
  14. package/dist/components/numberinput/numberinput.styles.d.ts +2 -0
  15. package/dist/components/numberinput/numberinput.styles.js +27 -0
  16. package/dist/components/numberinput/numberinput.types.d.ts +17 -0
  17. package/dist/components/numberinput/numberinput.types.js +1 -0
  18. package/dist/components/popover/popover.component.js +11 -9
  19. package/dist/custom-elements.json +2189 -250
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +2 -1
  22. package/dist/react/index.d.ts +1 -0
  23. package/dist/react/index.js +1 -0
  24. package/dist/react/input/index.d.ts +24 -8
  25. package/dist/react/numberinput/index.d.ts +90 -0
  26. package/dist/react/numberinput/index.js +65 -0
  27. package/dist/utils/dom.js +3 -0
  28. package/dist/utils/number.d.ts +1 -0
  29. package/dist/utils/number.js +10 -0
  30. package/package.json +1 -1
@@ -0,0 +1,330 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { html } from 'lit';
11
+ import { property } from 'lit/decorators.js';
12
+ import Input from '../input/input.component';
13
+ import { INPUT_MODE, INPUT_TYPE } from '../input/input.constants';
14
+ import { clamp } from '../../utils/number';
15
+ import { KEYS } from '../../utils/keys';
16
+ import { CLAMP, DEFAULTS } from './numberinput.constants';
17
+ import styles from './numberinput.styles';
18
+ /**
19
+ * @tagname mdc-numberinput
20
+ *
21
+ * @event input - (React: onInput) This event is dispatched when the value of the number field changes (every press).
22
+ * @event change - (React: onChange) This event is dispatched when the value of the number field changes (on blur).
23
+ * @event focus - (React: onFocus) This event is dispatched when the number field receives focus.
24
+ * @event blur - (React: onBlur) This event is dispatched when the number field loses focus.
25
+ * @event clear - (React: onClear) This event is dispatched when the number field is cleared.
26
+ *
27
+ * @dependency mdc-icon
28
+ * @dependency mdc-text
29
+ * @dependency mdc-button
30
+ * @dependency mdc-toggletip
31
+ *
32
+ * @slot label - Slot for the label element. If not provided, the `label` property will be used to render the label.
33
+ * @slot toggletip - Slot for the toggletip info icon button. If not provided, the `toggletip-text` property will be used to render the info icon button and toggletip.
34
+ * @slot help-icon - Slot for the helper/validation icon. If not provided, the icon will be rendered based on the `helpTextType` property.
35
+ * @slot help-text - Slot for the helper/validation text. If not provided, the `helpText` property will be used to render the helper/validation text.
36
+ * @slot input-leading-icon - Slot for the leading icon before the input field. If not provided, the `leadingIcon` property will be used to render the leading icon.
37
+ * @slot input-prefix-text - Slot for the prefix text before the input field. If not provided, the `prefixText` property will be used to render the prefix text.
38
+ * @slot trailing-button - Slot for the trailing content. If not provided, the increment/decrement spinner buttons are rendered by default; set `hideSpinnerButtons` to true to render the clear button instead (when `trailingButton` is set to true).
39
+ *
40
+ * @csspart input-container - The container that wraps the input field, leading icon, prefix text, and trailing content.
41
+ * @csspart input-section - The container that wraps the input field and prefix text.
42
+ * @csspart input-text - The input field element.
43
+ * @csspart spinner-buttons - The container that wraps the increment and decrement spinner buttons.
44
+ * @csspart spinner-button - Each of the increment/decrement spinner button elements.
45
+ * @csspart label - The label element.
46
+ * @csspart helper-text - The helper/validation text element.
47
+ * @csspart helper-icon - The helper/validation icon element.
48
+ *
49
+ * @cssproperty --mdc-label-font-size - Font size for the label text.
50
+ * @cssproperty --mdc-label-font-weight - Font weight for the label text.
51
+ * @cssproperty --mdc-label-line-height - Line height for the label text.
52
+ * @cssproperty --mdc-label-color - Color for the label text.
53
+ * @cssproperty --mdc-help-text-font-size - Font size for the help text.
54
+ * @cssproperty --mdc-help-text-font-weight - Font weight for the help text.
55
+ * @cssproperty --mdc-help-text-line-height - Line height for the help text.
56
+ * @cssproperty --mdc-help-text-color - Color for the help text.
57
+ * @cssproperty --mdc-required-indicator-color - Color for the required indicator text.
58
+ * @cssproperty --mdc-input-text-color - Text color for the input field
59
+ * @cssproperty --mdc-input-border-color - Border color for the input container
60
+ * @cssproperty --mdc-input-background-color - Background color for the input field
61
+ * @cssproperty --mdc-input-selection-text-color - Text color for the selected text
62
+ * @cssproperty --mdc-input-selection-background-color - Background color for the selected text
63
+ */
64
+ class NumberInput extends Input {
65
+ constructor() {
66
+ super(...arguments);
67
+ /**
68
+ * Hints that a numeric virtual keyboard should be displayed.
69
+ * @default 'numeric'
70
+ */
71
+ this.inputmode = INPUT_MODE.NUMERIC;
72
+ /**
73
+ * The amount that the value changes for each increment/decrement, whether from the
74
+ * spinner buttons or the up/down arrow keys. Set to `'any'` to allow any decimal value with no
75
+ * step-mismatch validation.
76
+ * @default 1
77
+ */
78
+ this.step = DEFAULTS.STEP;
79
+ /**
80
+ * Increment and decrement spinner buttons are shown alongside the input field by default.
81
+ * Set this to true to hide them.
82
+ * @default false
83
+ */
84
+ this.hideSpinnerButtons = false;
85
+ /**
86
+ * Aria label for the increment spinner button.
87
+ * @default ''
88
+ */
89
+ this.incrementAriaLabel = '';
90
+ /**
91
+ * Aria label for the decrement spinner button.
92
+ * @default ''
93
+ */
94
+ this.decrementAriaLabel = '';
95
+ /**
96
+ * Controls whether a value typed into the field is clamped to the min/max range. The spinner
97
+ * buttons and arrow keys always clamp; this only affects manual keyboard entry.
98
+ * - `none`: a typed value is left as entered and reported through range validity.
99
+ * - `auto`: a typed value is clamped to the min/max range when the field is committed (on change).
100
+ * @default 'none'
101
+ */
102
+ this.clamp = DEFAULTS.CLAMP;
103
+ /**
104
+ * Blocks insertion of non-numeric characters, including the `e`/`E`/`+` that native
105
+ * `type="number"` still accepts (and the arbitrary letters Firefox allows). Typed text arrives
106
+ * in `data`; pasted/dropped text arrives in `dataTransfer`. Deletions, caret navigation and IME
107
+ * composition carry neither, so they pass through. The sign (`-`) and decimal point (`.`) are
108
+ * numeric structural characters, so they are allowed and left to native range/step validation.
109
+ */
110
+ this.handleBeforeInput = (event) => {
111
+ var _a, _b, _c;
112
+ const inserted = (_c = (_a = event.data) !== null && _a !== void 0 ? _a : (_b = event.dataTransfer) === null || _b === void 0 ? void 0 : _b.getData('text')) !== null && _c !== void 0 ? _c : '';
113
+ if (inserted === '') {
114
+ return;
115
+ }
116
+ if (!/^[\d.-]*$/.test(inserted)) {
117
+ event.preventDefault();
118
+ }
119
+ };
120
+ this.handleIncrement = () => this.stepBy('increment');
121
+ this.handleDecrement = () => this.stepBy('decrement');
122
+ }
123
+ firstUpdated(changedProperties) {
124
+ var _a;
125
+ super.firstUpdated(changedProperties);
126
+ this.syncNumberConstraints();
127
+ (_a = this.inputElement) === null || _a === void 0 ? void 0 : _a.addEventListener('beforeinput', this.handleBeforeInput);
128
+ }
129
+ updated(changedProperties) {
130
+ super.updated(changedProperties);
131
+ if (changedProperties.has('min') || changedProperties.has('max') || changedProperties.has('step')) {
132
+ this.syncNumberConstraints();
133
+ }
134
+ }
135
+ /**
136
+ * Applies the min/max/step constraints to the native input element.
137
+ * These are not part of the Input template, so they are synced imperatively.
138
+ */
139
+ syncNumberConstraints() {
140
+ if (!this.inputElement) {
141
+ return;
142
+ }
143
+ const inputElement = this.inputElement;
144
+ if (this.min === undefined) {
145
+ inputElement.removeAttribute('min');
146
+ }
147
+ else {
148
+ inputElement.min = String(this.min);
149
+ }
150
+ if (this.max === undefined) {
151
+ inputElement.removeAttribute('max');
152
+ }
153
+ else {
154
+ inputElement.max = String(this.max);
155
+ }
156
+ inputElement.step = this.step === DEFAULTS.STEP_ANY ? DEFAULTS.STEP_ANY : String(this.step);
157
+ this.setInputValidity();
158
+ }
159
+ /**
160
+ * Native arrow-key stepping with step="any" is browser-inconsistent: Firefox rounds to a whole
161
+ * number (dropping the decimal part) while Chrome/Safari add or subtract 1. Route the arrow keys
162
+ * through the same stepBy() path as the spinner buttons so the decimal part is preserved in every
163
+ * browser. Numeric steps keep native handling, which is already consistent across browsers.
164
+ */
165
+ handleKeyDown(event) {
166
+ const isStepKey = event.key === KEYS.ARROW_UP || event.key === KEYS.ARROW_DOWN;
167
+ if (this.step === DEFAULTS.STEP_ANY && isStepKey && !this.disabled && !this.readonly) {
168
+ event.preventDefault();
169
+ this.stepBy(event.key === KEYS.ARROW_UP ? 'increment' : 'decrement');
170
+ return;
171
+ }
172
+ super.handleKeyDown(event);
173
+ }
174
+ /**
175
+ * With clamp="auto", a committed value typed outside the range is pulled back in before the base
176
+ * change handler syncs and re-dispatches it, so consumers and validity observe the clamped value.
177
+ * When the value is actually clamped an input event is emitted first, mirroring the native
178
+ * input-before-change order, so consumers that collect the value on input see the corrected value.
179
+ * Stepping already clamps, so this only covers manual keyboard entry.
180
+ */
181
+ onChange(event) {
182
+ if (this.clamp === CLAMP.AUTO && this.clampInputToRange()) {
183
+ this.inputElement.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
184
+ }
185
+ super.onChange(event);
186
+ }
187
+ /**
188
+ * Clamps the native input's committed value into the min/max range in place, returning whether the
189
+ * value changed. An empty or non-numeric field is left untouched so a cleared input is not forced
190
+ * to min/max.
191
+ */
192
+ clampInputToRange() {
193
+ const inputElement = this.inputElement;
194
+ const { valueAsNumber } = inputElement;
195
+ if (inputElement.value === '' || Number.isNaN(valueAsNumber)) {
196
+ return false;
197
+ }
198
+ const clamped = clamp(valueAsNumber, this.min, this.max);
199
+ if (clamped !== valueAsNumber) {
200
+ inputElement.valueAsNumber = clamped;
201
+ return true;
202
+ }
203
+ return false;
204
+ }
205
+ /**
206
+ * stepUp()/stepDown() throw for step="any", so in that case the spinner buttons add/subtract 1 and
207
+ * clamp (matching native spin buttons); any value is already step-valid, so no alignment is
208
+ * needed. Otherwise the native step algorithm handles stepping and step-base alignment.
209
+ */
210
+ stepBy(direction) {
211
+ var _a;
212
+ const inputElement = this.inputElement;
213
+ const previousValue = inputElement.value;
214
+ if (this.step === DEFAULTS.STEP_ANY) {
215
+ const delta = direction === 'increment' ? 1 : -1;
216
+ const current = Number.isNaN(inputElement.valueAsNumber) ? 0 : inputElement.valueAsNumber;
217
+ // delta is an integer, so the result keeps current's decimal precision; round back to it to
218
+ // strip IEEE-754 error (e.g. 1.1 - 1 = 0.10000000000000009).
219
+ const decimals = ((_a = String(current).split('.')[1]) !== null && _a !== void 0 ? _a : '').length;
220
+ const stepped = Number((current + delta).toFixed(decimals));
221
+ inputElement.valueAsNumber = clamp(stepped, this.min, this.max);
222
+ }
223
+ else if (direction === 'increment') {
224
+ inputElement.stepUp();
225
+ }
226
+ else {
227
+ inputElement.stepDown();
228
+ }
229
+ // Spinner buttons that clamp at min/max leave the value unchanged; matching native spin buttons,
230
+ // no input/change events are emitted in that case.
231
+ if (inputElement.value !== previousValue) {
232
+ this.syncValueFromInputElement();
233
+ }
234
+ }
235
+ /**
236
+ * stepUp()/stepDown() and valueAsNumber update the input element's value without dispatching
237
+ * input/change events. Replaying them on the input replays the native flow so the base Input
238
+ * handlers sync the value, form value and validity, then re-dispatch to consumers.
239
+ */
240
+ syncValueFromInputElement() {
241
+ this.inputElement.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
242
+ this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
243
+ }
244
+ /**
245
+ * Renders a single increment or decrement spinner button.
246
+ *
247
+ * The buttons are given `tabindex="-1"` so they are not in the tab order, matching native
248
+ * spin buttons: they are redundant pointer affordances for the `ArrowUp`/`ArrowDown` stepping
249
+ * already available from the focused input, so keyboard users reach the same behaviour without
250
+ * two extra tab stops per field.
251
+ */
252
+ renderSpinnerButton(direction) {
253
+ const isIncrement = direction === 'increment';
254
+ return html `
255
+ <mdc-button
256
+ part="spinner-button"
257
+ class="own-focus-ring"
258
+ variant=${DEFAULTS.SPINNER_BUTTON_VARIANT}
259
+ size="${DEFAULTS.SPINNER_BUTTON_SIZE}"
260
+ prefix-icon="${isIncrement ? DEFAULTS.INCREMENT_ICON : DEFAULTS.DECREMENT_ICON}"
261
+ aria-label="${isIncrement ? this.incrementAriaLabel : this.decrementAriaLabel}"
262
+ ?disabled=${this.disabled || this.readonly}
263
+ @click=${isIncrement ? this.handleIncrement : this.handleDecrement}
264
+ tabindex="-1"
265
+ ></mdc-button>
266
+ `;
267
+ }
268
+ /**
269
+ * Renders the decrement/increment spinner buttons in place of the default trailing (clear) button
270
+ */
271
+ renderTrailingButton(show = false) {
272
+ if (this.hideSpinnerButtons) {
273
+ return super.renderTrailingButton(show);
274
+ }
275
+ return html `
276
+ <div part="spinner-buttons">
277
+ ${this.renderSpinnerButton('decrement')} ${this.renderSpinnerButton('increment')}
278
+ </div>
279
+ `;
280
+ }
281
+ renderInputElement(_, hidePlaceholder) {
282
+ return super.renderInputElement(INPUT_TYPE.NUMBER, hidePlaceholder);
283
+ }
284
+ }
285
+ NumberInput.styles = [...Input.styles, ...styles];
286
+ __decorate([
287
+ property({ type: String, reflect: true }),
288
+ __metadata("design:type", String)
289
+ ], NumberInput.prototype, "inputmode", void 0);
290
+ __decorate([
291
+ property({ type: Number, attribute: 'min' }),
292
+ __metadata("design:type", Number)
293
+ ], NumberInput.prototype, "min", void 0);
294
+ __decorate([
295
+ property({ type: Number, attribute: 'max' }),
296
+ __metadata("design:type", Number)
297
+ ], NumberInput.prototype, "max", void 0);
298
+ __decorate([
299
+ property({
300
+ attribute: 'step',
301
+ converter: {
302
+ fromAttribute: (value) => {
303
+ if (value === DEFAULTS.STEP_ANY) {
304
+ return DEFAULTS.STEP_ANY;
305
+ }
306
+ const parsed = value === null ? NaN : parseFloat(value);
307
+ return Number.isNaN(parsed) ? DEFAULTS.STEP : parsed;
308
+ },
309
+ toAttribute: (value) => String(value),
310
+ },
311
+ }),
312
+ __metadata("design:type", Object)
313
+ ], NumberInput.prototype, "step", void 0);
314
+ __decorate([
315
+ property({ type: Boolean, attribute: 'hide-spinner-buttons' }),
316
+ __metadata("design:type", Object)
317
+ ], NumberInput.prototype, "hideSpinnerButtons", void 0);
318
+ __decorate([
319
+ property({ type: String, attribute: 'increment-aria-label' }),
320
+ __metadata("design:type", Object)
321
+ ], NumberInput.prototype, "incrementAriaLabel", void 0);
322
+ __decorate([
323
+ property({ type: String, attribute: 'decrement-aria-label' }),
324
+ __metadata("design:type", Object)
325
+ ], NumberInput.prototype, "decrementAriaLabel", void 0);
326
+ __decorate([
327
+ property({ type: String, reflect: true }),
328
+ __metadata("design:type", String)
329
+ ], NumberInput.prototype, "clamp", void 0);
330
+ export default NumberInput;
@@ -0,0 +1,15 @@
1
+ declare const TAG_NAME: "mdc-numberinput";
2
+ declare const CLAMP: {
3
+ readonly NONE: "none";
4
+ readonly AUTO: "auto";
5
+ };
6
+ declare const DEFAULTS: {
7
+ readonly STEP: 1;
8
+ readonly STEP_ANY: "any";
9
+ readonly CLAMP: "none";
10
+ readonly INCREMENT_ICON: "plus-bold";
11
+ readonly DECREMENT_ICON: "minus-bold";
12
+ readonly SPINNER_BUTTON_VARIANT: "tertiary";
13
+ readonly SPINNER_BUTTON_SIZE: 20;
14
+ };
15
+ export { TAG_NAME, DEFAULTS, CLAMP };
@@ -0,0 +1,17 @@
1
+ import utils from '../../utils/tag-name';
2
+ import { BUTTON_VARIANTS, ICON_BUTTON_SIZES } from '../button/button.constants';
3
+ const TAG_NAME = utils.constructTagName('numberinput');
4
+ const CLAMP = {
5
+ NONE: 'none',
6
+ AUTO: 'auto',
7
+ };
8
+ const DEFAULTS = {
9
+ STEP: 1,
10
+ STEP_ANY: 'any',
11
+ CLAMP: CLAMP.NONE,
12
+ INCREMENT_ICON: 'plus-bold',
13
+ DECREMENT_ICON: 'minus-bold',
14
+ SPINNER_BUTTON_VARIANT: BUTTON_VARIANTS.TERTIARY,
15
+ SPINNER_BUTTON_SIZE: ICON_BUTTON_SIZES[20],
16
+ };
17
+ export { TAG_NAME, DEFAULTS, CLAMP };
@@ -0,0 +1,2 @@
1
+ declare const styles: import("lit").CSSResult[];
2
+ export default styles;
@@ -0,0 +1,27 @@
1
+ import { css } from 'lit';
2
+ const styles = [
3
+ css `
4
+ /* Hide native number spin buttons; the custom spinner buttons replace them. The input is
5
+ fallback content inside this shadow root, so it is targeted directly rather than
6
+ via ::part()/::slotted(), which only cross a shadow boundary from the outside. */
7
+ input[part='input-text']::-webkit-outer-spin-button,
8
+ input[part='input-text']::-webkit-inner-spin-button {
9
+ appearance: none;
10
+ -webkit-appearance: none;
11
+ margin: 0;
12
+ }
13
+
14
+ /* Firefox hides the spinners via textfield appearance. */
15
+ input[part='input-text'] {
16
+ appearance: textfield;
17
+ -moz-appearance: textfield;
18
+ }
19
+
20
+ :host::part(spinner-buttons) {
21
+ display: flex;
22
+ align-items: center;
23
+ gap: 0.375rem;
24
+ }
25
+ `,
26
+ ];
27
+ export default styles;
@@ -0,0 +1,17 @@
1
+ import type { OverrideEventTarget, TypedCustomEvent } from '../../utils/types';
2
+ import type { CLAMP } from './numberinput.constants';
3
+ import type NumberInput from './numberinput.component';
4
+ type ClampType = (typeof CLAMP)[keyof typeof CLAMP];
5
+ type NumberInputInputEvent = OverrideEventTarget<InputEvent, NumberInput>;
6
+ type NumberInputChangeEvent = TypedCustomEvent<NumberInput>;
7
+ type NumberInputFocusEvent = OverrideEventTarget<FocusEvent, NumberInput>;
8
+ type NumberInputBlurEvent = OverrideEventTarget<FocusEvent, NumberInput>;
9
+ type NumberInputClearEvent = TypedCustomEvent<NumberInput>;
10
+ interface Events {
11
+ onInputEvent: NumberInputInputEvent;
12
+ onChangeEvent: NumberInputChangeEvent;
13
+ onFocusEvent: NumberInputFocusEvent;
14
+ onBlurEvent: NumberInputBlurEvent;
15
+ onClearEvent: NumberInputClearEvent;
16
+ }
17
+ export type { NumberInputInputEvent, NumberInputChangeEvent, NumberInputFocusEvent, NumberInputBlurEvent, NumberInputClearEvent, ClampType, Events, };
@@ -0,0 +1 @@
1
+ export {};
@@ -667,10 +667,19 @@ class Popover extends KeyDownHandledMixin(KeyToActionMixin(BackdropMixin(Prevent
667
667
  ? 'clippingAncestors'
668
668
  : Array.from(document.querySelectorAll(this.boundary));
669
669
  const rootBoundary = this.boundaryRoot;
670
+ let arrowOffset = 0;
671
+ if (this.showArrow) {
672
+ this.arrowElement = this.renderRoot.querySelector('div[part="popover-arrow"]');
673
+ if (this.arrowElement) {
674
+ const arrowLen = this.arrowElement.offsetHeight;
675
+ arrowOffset = Math.sqrt(2 * arrowLen ** 2) / 2;
676
+ }
677
+ }
670
678
  const middleware = [];
671
679
  if (this.inline) {
672
680
  middleware.push(inlineMiddleware());
673
681
  }
682
+ middleware.push(offset(typeof this.offset === 'number' ? this.offset + arrowOffset : this.offset));
674
683
  middleware.push(shift({
675
684
  boundary,
676
685
  rootBoundary,
@@ -704,16 +713,9 @@ class Popover extends KeyDownHandledMixin(KeyToActionMixin(BackdropMixin(Prevent
704
713
  padding: 50,
705
714
  }));
706
715
  }
707
- let arrowOffset = 0;
708
- if (this.showArrow) {
709
- this.arrowElement = this.renderRoot.querySelector('div[part="popover-arrow"]');
710
- if (this.arrowElement) {
711
- const arrowLen = this.arrowElement.offsetHeight;
712
- arrowOffset = Math.sqrt(2 * arrowLen ** 2) / 2;
713
- middleware.push(arrow({ element: this.arrowElement, padding: 12 }));
714
- }
716
+ if (this.showArrow && this.arrowElement) {
717
+ middleware.push(arrow({ element: this.arrowElement, padding: 12 }));
715
718
  }
716
- middleware.push(offset(typeof this.offset === 'number' ? this.offset + arrowOffset : this.offset));
717
719
  this.floatingUICleanupFunction = autoUpdate(triggerElement, this, async () => {
718
720
  const { triggerElement } = this;
719
721
  if (!triggerElement)