@jobber/components 8.10.0 → 8.11.1

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.
@@ -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,7 +608,7 @@ 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
614
  * Default formatting used only when the consumer does not pass `format`.
@@ -628,7 +629,7 @@ function useInputNumberExperimentalContext(consumer) {
628
629
  }
629
630
  // eslint-disable-next-line max-statements
630
631
  function InputNumberExperimentalInternal(props, ref) {
631
- const { align, autocomplete, children, description, disabled, error, format, 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;
632
633
  const generatedId = React.useId();
633
634
  const id = idProp !== null && idProp !== void 0 ? idProp : generatedId;
634
635
  const innerInputRef = React.useRef(null);
@@ -673,6 +674,7 @@ function InputNumberExperimentalInternal(props, ref) {
673
674
  id,
674
675
  innerInputRef,
675
676
  keyboard,
677
+ loading,
676
678
  maxLength,
677
679
  onBlur,
678
680
  onFocus,
@@ -689,6 +691,7 @@ function InputNumberExperimentalInternal(props, ref) {
689
691
  disabled,
690
692
  id,
691
693
  keyboard,
694
+ loading,
692
695
  maxLength,
693
696
  onBlur,
694
697
  onFocus,
@@ -724,9 +727,10 @@ function InputNumberExperimentalInputCompound(props = {}) {
724
727
  const ctx = useInputNumberExperimentalContext("Input");
725
728
  const labelText = (_a = props.placeholder) !== null && _a !== void 0 ? _a : ctx.placeholder;
726
729
  return (React.createElement("div", { className: classnames(styles.inputWrapper, !ctx.showMiniLabel && styles.hideLabel, ctx.size !== "default" && styles[ctx.size], ctx.disabled && styles.disabled) },
727
- 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 }),
728
731
  labelText && (React.createElement("label", { className: styles.label, htmlFor: ctx.id }, labelText)),
729
- !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))));
730
734
  }
731
735
  function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick, ariaLabel, }) {
732
736
  const ctx = useInputNumberExperimentalContext("Affix");
@@ -740,7 +744,9 @@ function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick,
740
744
  function InputNumberExperimentalStepperCompound({ incrementLabel, decrementLabel, } = {}) {
741
745
  var _a;
742
746
  const ctx = useInputNumberExperimentalContext("Stepper");
743
- 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) {
744
750
  return null;
745
751
  }
746
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,7 +588,7 @@ 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
594
  * Default formatting used only when the consumer does not pass `format`.
@@ -608,7 +609,7 @@ function useInputNumberExperimentalContext(consumer) {
608
609
  }
609
610
  // eslint-disable-next-line max-statements
610
611
  function InputNumberExperimentalInternal(props, ref) {
611
- const { align, autocomplete, children, description, disabled, error, format, 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;
612
613
  const generatedId = useId();
613
614
  const id = idProp !== null && idProp !== void 0 ? idProp : generatedId;
614
615
  const innerInputRef = useRef(null);
@@ -653,6 +654,7 @@ function InputNumberExperimentalInternal(props, ref) {
653
654
  id,
654
655
  innerInputRef,
655
656
  keyboard,
657
+ loading,
656
658
  maxLength,
657
659
  onBlur,
658
660
  onFocus,
@@ -669,6 +671,7 @@ function InputNumberExperimentalInternal(props, ref) {
669
671
  disabled,
670
672
  id,
671
673
  keyboard,
674
+ loading,
672
675
  maxLength,
673
676
  onBlur,
674
677
  onFocus,
@@ -704,9 +707,10 @@ function InputNumberExperimentalInputCompound(props = {}) {
704
707
  const ctx = useInputNumberExperimentalContext("Input");
705
708
  const labelText = (_a = props.placeholder) !== null && _a !== void 0 ? _a : ctx.placeholder;
706
709
  return (React__default.createElement("div", { className: classnames(styles.inputWrapper, !ctx.showMiniLabel && styles.hideLabel, ctx.size !== "default" && styles[ctx.size], ctx.disabled && styles.disabled) },
707
- 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 }),
708
711
  labelText && (React__default.createElement("label", { className: styles.label, htmlFor: ctx.id }, labelText)),
709
- !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))));
710
714
  }
711
715
  function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick, ariaLabel, }) {
712
716
  const ctx = useInputNumberExperimentalContext("Affix");
@@ -720,7 +724,9 @@ function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick,
720
724
  function InputNumberExperimentalStepperCompound({ incrementLabel, decrementLabel, } = {}) {
721
725
  var _a;
722
726
  const ctx = useInputNumberExperimentalContext("Stepper");
723
- 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) {
724
730
  return null;
725
731
  }
726
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';
@@ -65,6 +65,12 @@ export interface InputNumberExperimentalProps {
65
65
  /** Style the error border without showing an error message. */
66
66
  readonly invalid?: boolean;
67
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;
68
74
  readonly max?: number;
69
75
  readonly maxLength?: number;
70
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.10.0",
3
+ "version": "8.11.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -502,7 +502,7 @@
502
502
  "devDependencies": {
503
503
  "@apollo/client": "^3.7.10",
504
504
  "@csstools/postcss-global-data": "^1.0.3",
505
- "@jobber/design": "0.102.0",
505
+ "@jobber/design": "0.103.0",
506
506
  "@jobber/hooks": "2.21.0",
507
507
  "@rollup/plugin-alias": "^5.1.0",
508
508
  "@rollup/plugin-commonjs": "^25.0.7",
@@ -556,5 +556,5 @@
556
556
  "> 1%",
557
557
  "IE 10"
558
558
  ],
559
- "gitHead": "fff8aa8019d89e4a0d517f1eb963c8442935a16d"
559
+ "gitHead": "85613843d134dfa6dee673b87293f5e0ceb3bfa5"
560
560
  }