@jobber/components 8.9.1 → 8.11.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/dist/Icon-cjs.js CHANGED
@@ -15,7 +15,8 @@ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_classNam
15
15
  icon = getTruck(pathStyle, customColor);
16
16
  }
17
17
  else {
18
- icon = paths.map((path) => (React.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
18
+ // getIcon returns undefined paths for an unknown icon name; render nothing rather than crash.
19
+ icon = (paths !== null && paths !== void 0 ? paths : []).map((path) => (React.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
19
20
  }
20
21
  return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
21
22
  }
package/dist/Icon-es.js CHANGED
@@ -13,7 +13,8 @@ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_classNam
13
13
  icon = getTruck(pathStyle, customColor);
14
14
  }
15
15
  else {
16
- icon = paths.map((path) => (React__default.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
16
+ // getIcon returns undefined paths for an unknown icon name; render nothing rather than crash.
17
+ icon = (paths !== null && paths !== void 0 ? paths : []).map((path) => (React__default.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
17
18
  }
18
19
  return (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
19
20
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  var React = require('react');
4
4
  var classnames = require('classnames');
5
+ var ActivityIndicator = require('./ActivityIndicator-cjs.js');
5
6
  var Button = require('./Button-cjs.js');
6
7
  var Icon = require('./Icon-cjs.js');
7
8
  var useValueChanged = require('./useValueChanged-cjs.js');
@@ -607,10 +608,11 @@ const FieldDescription = /*#__PURE__*/React__namespace.forwardRef(function Field
607
608
  });
608
609
  if (process.env.NODE_ENV !== "production") FieldDescription.displayName = "FieldDescription";
609
610
 
610
- var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};
611
+ var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","loadingIndicator":"NLptJ1t9Pj4-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};
611
612
 
612
613
  /**
613
- * Preserve user-typed decimals on blur. Without `maximumFractionDigits: 20`,
614
+ * Default formatting used only when the consumer does not pass `format`.
615
+ * Preserves user-typed decimals on blur: without `maximumFractionDigits: 20`,
614
616
  * `Intl.NumberFormat` rounds to 3 digits and silently truncates input.
615
617
  */
616
618
  const DEFAULT_FORMAT = {
@@ -627,7 +629,7 @@ function useInputNumberExperimentalContext(consumer) {
627
629
  }
628
630
  // eslint-disable-next-line max-statements
629
631
  function InputNumberExperimentalInternal(props, ref) {
630
- const { align, autocomplete, children, description, disabled, error, id: idProp, inline, invalid, keyboard, max, maxLength, min, name, onBlur, onChange, onEnter, onFocus, onKeyDown, onKeyUp, onValueChange, placeholder, prefix, readonly, showMiniLabel = true, size = "default", suffix, value, } = props;
632
+ const { align, autocomplete, children, description, disabled, error, format, id: idProp, inline, invalid, keyboard, loading, max, maxLength, min, name, onBlur, onChange, onEnter, onFocus, onKeyDown, onKeyUp, onValueChange, placeholder, prefix, readonly, showMiniLabel = true, size = "default", suffix, value, } = props;
631
633
  const generatedId = React.useId();
632
634
  const id = idProp !== null && idProp !== void 0 ? idProp : generatedId;
633
635
  const innerInputRef = React.useRef(null);
@@ -672,6 +674,7 @@ function InputNumberExperimentalInternal(props, ref) {
672
674
  id,
673
675
  innerInputRef,
674
676
  keyboard,
677
+ loading,
675
678
  maxLength,
676
679
  onBlur,
677
680
  onFocus,
@@ -688,6 +691,7 @@ function InputNumberExperimentalInternal(props, ref) {
688
691
  disabled,
689
692
  id,
690
693
  keyboard,
694
+ loading,
691
695
  maxLength,
692
696
  onBlur,
693
697
  onFocus,
@@ -702,7 +706,7 @@ function InputNumberExperimentalInternal(props, ref) {
702
706
  const fieldInvalid = invalid || Boolean(error);
703
707
  return (React.createElement(FieldRoot, { className: classnames(styles.container, inline && styles.inline), disabled: disabled, invalid: fieldInvalid, name: name },
704
708
  React.createElement(InputNumberExperimentalContext.Provider, { value: contextValue },
705
- React.createElement(NumberFieldInput.NumberFieldRoot, { allowOutOfRange: true, format: DEFAULT_FORMAT, id: id, max: max, min: min, onValueChange: handleValueChange, onValueCommitted: handleValueCommitted, readOnly: readonly, value: value !== null && value !== void 0 ? value : null },
709
+ React.createElement(NumberFieldInput.NumberFieldRoot, { allowOutOfRange: true, format: format !== null && format !== void 0 ? format : DEFAULT_FORMAT, id: id, max: max, min: min, onValueChange: handleValueChange, onValueCommitted: handleValueCommitted, readOnly: readonly, value: value !== null && value !== void 0 ? value : null },
706
710
  React.createElement(NumberFieldInput.NumberFieldGroup, { className: classnames(styles.wrapper, align && styles[align], disabled && styles.disabled, size !== "default" && styles[size]) }, isUsingCompoundPattern
707
711
  ? children
708
712
  : renderDefaultComposition({ prefix, suffix, size })))),
@@ -723,9 +727,10 @@ function InputNumberExperimentalInputCompound(props = {}) {
723
727
  const ctx = useInputNumberExperimentalContext("Input");
724
728
  const labelText = (_a = props.placeholder) !== null && _a !== void 0 ? _a : ctx.placeholder;
725
729
  return (React.createElement("div", { className: classnames(styles.inputWrapper, !ctx.showMiniLabel && styles.hideLabel, ctx.size !== "default" && styles[ctx.size], ctx.disabled && styles.disabled) },
726
- React.createElement(NumberFieldInput.NumberFieldInput, { autoComplete: resolveAutocomplete(ctx.autocomplete), className: styles.input, inputMode: ctx.keyboard, maxLength: ctx.maxLength, onBlur: ctx.onBlur, onFocus: ctx.onFocus, onKeyDown: ctx.onKeyDown, onKeyUp: ctx.onKeyUp, placeholder: " ", ref: ctx.innerInputRef }),
730
+ React.createElement(NumberFieldInput.NumberFieldInput, { "aria-busy": ctx.loading || undefined, autoComplete: resolveAutocomplete(ctx.autocomplete), className: styles.input, inputMode: ctx.keyboard, maxLength: ctx.maxLength, onBlur: ctx.onBlur, onFocus: ctx.onFocus, onKeyDown: ctx.onKeyDown, onKeyUp: ctx.onKeyUp, placeholder: " ", ref: ctx.innerInputRef }),
727
731
  labelText && (React.createElement("label", { className: styles.label, htmlFor: ctx.id }, labelText)),
728
- !ctx.compoundLayout && React.createElement(InputNumberExperimentalStepperCompound, null)));
732
+ ctx.loading ? (React.createElement("div", { className: styles.loadingIndicator },
733
+ React.createElement(ActivityIndicator.ActivityIndicator, { size: "small" }))) : (!ctx.compoundLayout && React.createElement(InputNumberExperimentalStepperCompound, null))));
729
734
  }
730
735
  function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick, ariaLabel, }) {
731
736
  const ctx = useInputNumberExperimentalContext("Affix");
@@ -739,7 +744,9 @@ function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick,
739
744
  function InputNumberExperimentalStepperCompound({ incrementLabel, decrementLabel, } = {}) {
740
745
  var _a;
741
746
  const ctx = useInputNumberExperimentalContext("Stepper");
742
- if (!ctx.showStepper) {
747
+ // Hidden while loading; the loading indicator renders in the input wrapper
748
+ // instead, independent of where this stepper is composed.
749
+ if (ctx.loading || !ctx.showStepper) {
743
750
  return null;
744
751
  }
745
752
  const labelTarget = (_a = ctx.placeholder) !== null && _a !== void 0 ? _a : "value";
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { createContext, forwardRef, useId, useRef, useImperativeHandle, useCallback, useMemo, useContext } from 'react';
3
3
  import classnames from 'classnames';
4
+ import { A as ActivityIndicator } from './ActivityIndicator-es.js';
4
5
  import { B as Button } from './Button-es.js';
5
6
  import { I as Icon } from './Icon-es.js';
6
7
  import { a as useStableCallback, c as useTimeout, t as transitionStatusMapping, d as useTransitionStatus, u as useIsoLayoutEffect, e as useOpenChangeComplete } from './useValueChanged-es.js';
@@ -587,10 +588,11 @@ const FieldDescription = /*#__PURE__*/React.forwardRef(function FieldDescription
587
588
  });
588
589
  if (process.env.NODE_ENV !== "production") FieldDescription.displayName = "FieldDescription";
589
590
 
590
- var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};
591
+ var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","loadingIndicator":"NLptJ1t9Pj4-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};
591
592
 
592
593
  /**
593
- * Preserve user-typed decimals on blur. Without `maximumFractionDigits: 20`,
594
+ * Default formatting used only when the consumer does not pass `format`.
595
+ * Preserves user-typed decimals on blur: without `maximumFractionDigits: 20`,
594
596
  * `Intl.NumberFormat` rounds to 3 digits and silently truncates input.
595
597
  */
596
598
  const DEFAULT_FORMAT = {
@@ -607,7 +609,7 @@ function useInputNumberExperimentalContext(consumer) {
607
609
  }
608
610
  // eslint-disable-next-line max-statements
609
611
  function InputNumberExperimentalInternal(props, ref) {
610
- const { align, autocomplete, children, description, disabled, error, id: idProp, inline, invalid, keyboard, max, maxLength, min, name, onBlur, onChange, onEnter, onFocus, onKeyDown, onKeyUp, onValueChange, placeholder, prefix, readonly, showMiniLabel = true, size = "default", suffix, value, } = props;
612
+ const { align, autocomplete, children, description, disabled, error, format, id: idProp, inline, invalid, keyboard, loading, max, maxLength, min, name, onBlur, onChange, onEnter, onFocus, onKeyDown, onKeyUp, onValueChange, placeholder, prefix, readonly, showMiniLabel = true, size = "default", suffix, value, } = props;
611
613
  const generatedId = useId();
612
614
  const id = idProp !== null && idProp !== void 0 ? idProp : generatedId;
613
615
  const innerInputRef = useRef(null);
@@ -652,6 +654,7 @@ function InputNumberExperimentalInternal(props, ref) {
652
654
  id,
653
655
  innerInputRef,
654
656
  keyboard,
657
+ loading,
655
658
  maxLength,
656
659
  onBlur,
657
660
  onFocus,
@@ -668,6 +671,7 @@ function InputNumberExperimentalInternal(props, ref) {
668
671
  disabled,
669
672
  id,
670
673
  keyboard,
674
+ loading,
671
675
  maxLength,
672
676
  onBlur,
673
677
  onFocus,
@@ -682,7 +686,7 @@ function InputNumberExperimentalInternal(props, ref) {
682
686
  const fieldInvalid = invalid || Boolean(error);
683
687
  return (React__default.createElement(FieldRoot, { className: classnames(styles.container, inline && styles.inline), disabled: disabled, invalid: fieldInvalid, name: name },
684
688
  React__default.createElement(InputNumberExperimentalContext.Provider, { value: contextValue },
685
- React__default.createElement(NumberFieldRoot, { allowOutOfRange: true, format: DEFAULT_FORMAT, id: id, max: max, min: min, onValueChange: handleValueChange, onValueCommitted: handleValueCommitted, readOnly: readonly, value: value !== null && value !== void 0 ? value : null },
689
+ React__default.createElement(NumberFieldRoot, { allowOutOfRange: true, format: format !== null && format !== void 0 ? format : DEFAULT_FORMAT, id: id, max: max, min: min, onValueChange: handleValueChange, onValueCommitted: handleValueCommitted, readOnly: readonly, value: value !== null && value !== void 0 ? value : null },
686
690
  React__default.createElement(NumberFieldGroup, { className: classnames(styles.wrapper, align && styles[align], disabled && styles.disabled, size !== "default" && styles[size]) }, isUsingCompoundPattern
687
691
  ? children
688
692
  : renderDefaultComposition({ prefix, suffix, size })))),
@@ -703,9 +707,10 @@ function InputNumberExperimentalInputCompound(props = {}) {
703
707
  const ctx = useInputNumberExperimentalContext("Input");
704
708
  const labelText = (_a = props.placeholder) !== null && _a !== void 0 ? _a : ctx.placeholder;
705
709
  return (React__default.createElement("div", { className: classnames(styles.inputWrapper, !ctx.showMiniLabel && styles.hideLabel, ctx.size !== "default" && styles[ctx.size], ctx.disabled && styles.disabled) },
706
- React__default.createElement(NumberFieldInput, { autoComplete: resolveAutocomplete(ctx.autocomplete), className: styles.input, inputMode: ctx.keyboard, maxLength: ctx.maxLength, onBlur: ctx.onBlur, onFocus: ctx.onFocus, onKeyDown: ctx.onKeyDown, onKeyUp: ctx.onKeyUp, placeholder: " ", ref: ctx.innerInputRef }),
710
+ React__default.createElement(NumberFieldInput, { "aria-busy": ctx.loading || undefined, autoComplete: resolveAutocomplete(ctx.autocomplete), className: styles.input, inputMode: ctx.keyboard, maxLength: ctx.maxLength, onBlur: ctx.onBlur, onFocus: ctx.onFocus, onKeyDown: ctx.onKeyDown, onKeyUp: ctx.onKeyUp, placeholder: " ", ref: ctx.innerInputRef }),
707
711
  labelText && (React__default.createElement("label", { className: styles.label, htmlFor: ctx.id }, labelText)),
708
- !ctx.compoundLayout && React__default.createElement(InputNumberExperimentalStepperCompound, null)));
712
+ ctx.loading ? (React__default.createElement("div", { className: styles.loadingIndicator },
713
+ React__default.createElement(ActivityIndicator, { size: "small" }))) : (!ctx.compoundLayout && React__default.createElement(InputNumberExperimentalStepperCompound, null))));
709
714
  }
710
715
  function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick, ariaLabel, }) {
711
716
  const ctx = useInputNumberExperimentalContext("Affix");
@@ -719,7 +724,9 @@ function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick,
719
724
  function InputNumberExperimentalStepperCompound({ incrementLabel, decrementLabel, } = {}) {
720
725
  var _a;
721
726
  const ctx = useInputNumberExperimentalContext("Stepper");
722
- if (!ctx.showStepper) {
727
+ // Hidden while loading; the loading indicator renders in the input wrapper
728
+ // instead, independent of where this stepper is composed.
729
+ if (ctx.loading || !ctx.showStepper) {
723
730
  return null;
724
731
  }
725
732
  const labelTarget = (_a = ctx.placeholder) !== null && _a !== void 0 ? _a : "value";
@@ -3,6 +3,7 @@
3
3
  var InputNumberExperimental = require('../../InputNumberExperimental-cjs.js');
4
4
  require('react');
5
5
  require('classnames');
6
+ require('../../ActivityIndicator-cjs.js');
6
7
  require('../../Button-cjs.js');
7
8
  require('../../tslib.es6-cjs.js');
8
9
  require('react-router-dom');
@@ -1,6 +1,7 @@
1
1
  export { I as InputNumberExperimental } from '../../InputNumberExperimental-es.js';
2
2
  import 'react';
3
3
  import 'classnames';
4
+ import '../../ActivityIndicator-es.js';
4
5
  import '../../Button-es.js';
5
6
  import '../../tslib.es6-es.js';
6
7
  import 'react-router-dom';
@@ -52,12 +52,25 @@ export interface InputNumberExperimentalProps {
52
52
  readonly disabled?: boolean;
53
53
  /** When set, renders a styled error message below the field. */
54
54
  readonly error?: string;
55
+ /**
56
+ * Number formatting for the displayed value, forwarded verbatim to Base UI
57
+ * `NumberField`'s native `format`. Accepts standard `Intl.NumberFormatOptions`
58
+ * (e.g. `{ style: "currency", currency: "USD" }` or `{ maximumFractionDigits: 2 }`).
59
+ * When omitted, typed decimals are preserved without premature rounding.
60
+ */
61
+ readonly format?: Intl.NumberFormatOptions;
55
62
  readonly id?: string;
56
63
  /** Shrink-wrap the field to its content (auto width). */
57
64
  readonly inline?: boolean;
58
65
  /** Style the error border without showing an error message. */
59
66
  readonly invalid?: boolean;
60
67
  readonly keyboard?: "numeric" | "decimal";
68
+ /**
69
+ * Shows a non-blocking loading indicator in the stepper's slot to signal
70
+ * background activity. The field stays editable while loading (use `readonly`
71
+ * or `disabled` to lock it); the stepper is hidden so the two never overlap.
72
+ */
73
+ readonly loading?: boolean;
61
74
  readonly max?: number;
62
75
  readonly maxLength?: number;
63
76
  readonly min?: number;
@@ -19,6 +19,7 @@ require('../Text-cjs.js');
19
19
  require('../Typography-cjs.js');
20
20
  require('../Icon-cjs.js');
21
21
  require('@jobber/design');
22
+ require('../ActivityIndicator-cjs.js');
22
23
  require('../Button-cjs.js');
23
24
  require('react-router-dom');
24
25
  require('../NumberFieldInput-cjs.js');
@@ -17,6 +17,7 @@ import '../Text-es.js';
17
17
  import '../Typography-es.js';
18
18
  import '../Icon-es.js';
19
19
  import '@jobber/design';
20
+ import '../ActivityIndicator-es.js';
20
21
  import '../Button-es.js';
21
22
  import 'react-router-dom';
22
23
  import '../NumberFieldInput-es.js';
package/dist/styles.css CHANGED
@@ -4269,7 +4269,8 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
4269
4269
  * enough room for multi-digit values to display.
4270
4270
  */
4271
4271
 
4272
- .k9dAO6d010o-:has(> .t42w4ZDiDyI-) .D-PmE-l-hZU- {
4272
+ .k9dAO6d010o-:has(> .t42w4ZDiDyI-) .D-PmE-l-hZU-,
4273
+ .k9dAO6d010o-:has(> .NLptJ1t9Pj4-) .D-PmE-l-hZU- {
4273
4274
  padding-right: 2px;
4274
4275
  padding-right: var(--space-smallest);
4275
4276
  }
@@ -4456,8 +4457,9 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
4456
4457
 
4457
4458
  /**
4458
4459
  * Compound `<.Affix>`: a single flex sibling of .inputWrapper that bundles
4459
- * icon and/or label inline. Visually slightly less integrated than the default
4460
- * (split) layout but lets users compose freely.
4460
+ * icon and/or label inline. Uses the field's vertical padding so it tracks the
4461
+ * floating mini-label and lines up with the typed value (and the loading
4462
+ * indicator), matching the default split composition.
4461
4463
  */
4462
4464
 
4463
4465
  .tZjZRRcAShY- {
@@ -4467,8 +4469,10 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
4467
4469
  align-items: center;
4468
4470
  gap: 4px;
4469
4471
  gap: var(--space-smaller);
4470
- padding: 0 16px;
4471
- padding: 0 var(--space-base);
4472
+ padding: var(--field--padding-top) 16px
4473
+ var(--field--padding-bottom);
4474
+ padding: var(--field--padding-top) var(--space-base)
4475
+ var(--field--padding-bottom);
4472
4476
  color: hsl(197, 21%, 36%);
4473
4477
  color: var(--color-text--secondary);
4474
4478
  font-size: 14px;
@@ -4494,6 +4498,36 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
4494
4498
  flex: 0 0 auto;
4495
4499
  }
4496
4500
 
4501
+ /*
4502
+ * Loading indicator: occupies the stepper's slot, always visible (no hover
4503
+ * reveal), vertically centered in the field to match InputText's spinner.
4504
+ * The default right padding is just a small gap from a following suffix.
4505
+ */
4506
+
4507
+ .NLptJ1t9Pj4- {
4508
+ display: -ms-flexbox;
4509
+ display: flex;
4510
+ z-index: calc(var(--field--base-elevation) + 1);
4511
+ -ms-flex-align: center;
4512
+ align-items: center;
4513
+ -ms-flex-pack: center;
4514
+ justify-content: center;
4515
+ -ms-flex: 0 0 auto;
4516
+ flex: 0 0 auto;
4517
+ padding-right: 4px;
4518
+ padding-right: var(--space-smaller);
4519
+ }
4520
+
4521
+ /*
4522
+ * When the indicator sits flush to the field's right edge (no suffix follows),
4523
+ * inset it by the field's right padding so it matches InputText's spinner
4524
+ * spacing instead of hugging the border.
4525
+ */
4526
+
4527
+ .c20czk-FSyY- > .k9dAO6d010o-:last-child > .NLptJ1t9Pj4- {
4528
+ padding-right: var(--field--padding-right);
4529
+ }
4530
+
4497
4531
  /* Default mode: stepper lives inside .inputWrapper. Reveal on local hover/focus. */
4498
4532
 
4499
4533
  .k9dAO6d010o-:hover .t42w4ZDiDyI-,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "8.9.1",
3
+ "version": "8.11.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -556,5 +556,5 @@
556
556
  "> 1%",
557
557
  "IE 10"
558
558
  ],
559
- "gitHead": "2dd2b2d127e9e7e00f8db56c9a5c8ab05344e128"
559
+ "gitHead": "b4fe4a75ec2c46f3b252f974a73631e4c7669433"
560
560
  }