@simplybusiness/mobius 7.0.0 → 7.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7ac6357: Add Toast component for non-blocking notification messages, built on Sonner library with Alert color token integration
8
+
9
+ ### Patch Changes
10
+
11
+ - 45ddf19: set is changing to false when blurring away from combobox
12
+
3
13
  ## 7.0.0
4
14
 
5
15
  ### Major Changes
package/dist/cjs/index.js CHANGED
@@ -93,10 +93,12 @@ __export(index_exports, {
93
93
  TextField: () => TextField,
94
94
  TextOrHTML: () => TextOrHTML,
95
95
  Title: () => Title,
96
+ Toaster: () => Toaster,
96
97
  Trust: () => Trust,
97
98
  VisuallyHidden: () => VisuallyHidden,
98
99
  convertToDateFormat: () => convertToDateFormat,
99
100
  isValidDate: () => isValidDate,
101
+ toast: () => toast,
100
102
  useBodyScrollLock: () => useBodyScrollLock,
101
103
  useBreakpoint: () => useBreakpoint,
102
104
  useButton: () => useButton,
@@ -1736,6 +1738,7 @@ var ComboboxInner = ({
1736
1738
  blurTimeoutRef.current = setTimeout(() => {
1737
1739
  onBlur?.(e);
1738
1740
  setIsOpen(false);
1741
+ setIsChanging(false);
1739
1742
  }, 150);
1740
1743
  };
1741
1744
  const handleKeyDown = (e) => {
@@ -4427,9 +4430,149 @@ var Title = ({ ref, ...props }) => {
4427
4430
  };
4428
4431
  Title.displayName = "Title";
4429
4432
 
4430
- // src/components/Trust/Trust.tsx
4433
+ // src/components/Toast/Toast.tsx
4434
+ var import_icons14 = require("@simplybusiness/icons");
4431
4435
  var import_dedupe58 = __toESM(require("classnames/dedupe"));
4436
+ var import_sonner = require("sonner");
4437
+
4438
+ // src/components/Toast/state.ts
4439
+ var toastState = {
4440
+ showCloseButton: true
4441
+ };
4442
+
4443
+ // src/components/Toast/Toast.tsx
4444
+ var import_jsx_runtime71 = require("react/jsx-runtime");
4445
+ var variantIcons = {
4446
+ info: import_icons14.circleInfo,
4447
+ success: import_icons14.circleCheck,
4448
+ warning: import_icons14.triangleExclamation,
4449
+ error: import_icons14.circleExclamation
4450
+ };
4451
+ var variantColors = {
4452
+ info: "var(--color-info)",
4453
+ success: "var(--color-valid)",
4454
+ warning: "var(--color-warning)",
4455
+ error: "var(--color-error)"
4456
+ };
4457
+ var ToastIcon = ({ variant }) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "mobius-toast__icon", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Icon, { icon: variantIcons[variant], color: variantColors[variant] }) });
4458
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "mobius-toast__close-icon", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Icon, { icon: import_icons14.cross }) });
4459
+ var ToastContent = ({
4460
+ toastId,
4461
+ variant,
4462
+ title,
4463
+ description,
4464
+ action,
4465
+ cancel,
4466
+ showCloseButton = toastState.showCloseButton
4467
+ }) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: (0, import_dedupe58.default)("mobius", "mobius-toast", `--${variant}`), children: [
4468
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ToastIcon, { variant }),
4469
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "mobius-toast__body", children: [
4470
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "mobius-toast__content", children: [
4471
+ title && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "mobius-toast__title", children: title }),
4472
+ description && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "mobius-toast__description", children: description })
4473
+ ] }),
4474
+ (action || cancel) && /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "mobius-toast__actions", children: [
4475
+ cancel && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4476
+ "button",
4477
+ {
4478
+ type: "button",
4479
+ className: "mobius-toast__cancel",
4480
+ onClick: () => {
4481
+ cancel.onClick?.();
4482
+ import_sonner.toast.dismiss(toastId);
4483
+ },
4484
+ children: cancel.label
4485
+ }
4486
+ ),
4487
+ action && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4488
+ "button",
4489
+ {
4490
+ type: "button",
4491
+ className: "mobius-toast__action",
4492
+ onClick: () => {
4493
+ action.onClick();
4494
+ import_sonner.toast.dismiss(toastId);
4495
+ },
4496
+ children: action.label
4497
+ }
4498
+ )
4499
+ ] })
4500
+ ] }),
4501
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4502
+ "button",
4503
+ {
4504
+ type: "button",
4505
+ className: "mobius-toast__close",
4506
+ onClick: () => import_sonner.toast.dismiss(toastId),
4507
+ "aria-label": "Close",
4508
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(CloseIcon, {})
4509
+ }
4510
+ )
4511
+ ] });
4512
+ var createCustomToast = (message, variant, options) => import_sonner.toast.custom(
4513
+ (id) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4514
+ ToastContent,
4515
+ {
4516
+ toastId: id,
4517
+ variant,
4518
+ title: options?.title,
4519
+ description: options?.description ?? message,
4520
+ action: options?.action,
4521
+ cancel: options?.cancel,
4522
+ showCloseButton: options?.showCloseButton
4523
+ }
4524
+ ),
4525
+ {
4526
+ duration: options?.duration,
4527
+ onDismiss: options?.onDismiss,
4528
+ onAutoClose: options?.onAutoClose
4529
+ }
4530
+ );
4531
+ var toast = {
4532
+ /** Show an info toast */
4533
+ info: (message, options) => createCustomToast(message, "info", options),
4534
+ /** Show a success toast */
4535
+ success: (message, options) => createCustomToast(message, "success", options),
4536
+ /** Show a warning toast */
4537
+ warning: (message, options) => createCustomToast(message, "warning", options),
4538
+ /** Show an error toast */
4539
+ error: (message, options) => createCustomToast(message, "error", options),
4540
+ /** Dismiss a specific toast by ID or all toasts */
4541
+ dismiss: (toastId) => import_sonner.toast.dismiss(toastId)
4542
+ };
4543
+
4544
+ // src/components/Toast/Toaster.tsx
4432
4545
  var import_react51 = require("react");
4546
+ var import_sonner2 = require("sonner");
4547
+ var import_jsx_runtime72 = require("react/jsx-runtime");
4548
+ var Toaster = ({
4549
+ position = "top-right",
4550
+ closeButton = true,
4551
+ expand = false,
4552
+ duration = 4e3,
4553
+ visibleToasts = 3,
4554
+ gap = 8
4555
+ }) => {
4556
+ (0, import_react51.useEffect)(() => {
4557
+ toastState.showCloseButton = closeButton;
4558
+ }, [closeButton]);
4559
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
4560
+ import_sonner2.Toaster,
4561
+ {
4562
+ position,
4563
+ closeButton: false,
4564
+ expand,
4565
+ duration,
4566
+ visibleToasts,
4567
+ gap
4568
+ }
4569
+ );
4570
+ };
4571
+ Toaster.displayName = "Toaster";
4572
+
4573
+ // src/components/Trust/Trust.tsx
4574
+ var import_dedupe59 = __toESM(require("classnames/dedupe"));
4575
+ var import_react52 = require("react");
4433
4576
 
4434
4577
  // src/components/Trust/constants.ts
4435
4578
  var REQUIRED_TRUSTPILOT_CLASS_NAME = "trustpilot-widget";
@@ -4493,7 +4636,7 @@ var TRUSTPILOT_WIDGET = {
4493
4636
  };
4494
4637
 
4495
4638
  // src/components/Trust/Trust.tsx
4496
- var import_jsx_runtime71 = require("react/jsx-runtime");
4639
+ var import_jsx_runtime73 = require("react/jsx-runtime");
4497
4640
  var Trust = ({ ref, ...props }) => {
4498
4641
  const {
4499
4642
  elementType: Element = "div",
@@ -4505,8 +4648,8 @@ var Trust = ({ ref, ...props }) => {
4505
4648
  stars,
4506
4649
  className
4507
4650
  } = props;
4508
- const [isMounted, setIsMounted] = (0, import_react51.useState)(false);
4509
- const trustRef = (0, import_react51.useRef)(null);
4651
+ const [isMounted, setIsMounted] = (0, import_react52.useState)(false);
4652
+ const trustRef = (0, import_react52.useRef)(null);
4510
4653
  const {
4511
4654
  templateId,
4512
4655
  className: variantClassName,
@@ -4523,7 +4666,7 @@ var Trust = ({ ref, ...props }) => {
4523
4666
  "data-style-height": height,
4524
4667
  "data-stars": stars
4525
4668
  };
4526
- const classes = (0, import_dedupe58.default)(
4669
+ const classes = (0, import_dedupe59.default)(
4527
4670
  "mobius",
4528
4671
  "mobius-trust",
4529
4672
  REQUIRED_TRUSTPILOT_CLASS_NAME,
@@ -4533,24 +4676,24 @@ var Trust = ({ ref, ...props }) => {
4533
4676
  },
4534
4677
  className
4535
4678
  );
4536
- (0, import_react51.useEffect)(() => {
4679
+ (0, import_react52.useEffect)(() => {
4537
4680
  const hasTrustpilotLoaded = trustRef.current && window?.Trustpilot && window?.Trustpilot.loadFromElement;
4538
4681
  if (isMounted && hasTrustpilotLoaded) {
4539
4682
  window.Trustpilot.loadFromElement(trustRef.current, true);
4540
4683
  }
4541
4684
  }, [isMounted]);
4542
- (0, import_react51.useEffect)(() => {
4685
+ (0, import_react52.useEffect)(() => {
4543
4686
  setIsMounted(true);
4544
4687
  }, []);
4545
- if (!isMounted) return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: styles });
4546
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4688
+ if (!isMounted) return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: styles });
4689
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4547
4690
  Element,
4548
4691
  {
4549
4692
  ref: mergeRefs([trustRef, ref]),
4550
4693
  className: classes,
4551
4694
  style: styles,
4552
4695
  ...dataProps,
4553
- children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
4696
+ children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4554
4697
  "a",
4555
4698
  {
4556
4699
  href: link,
@@ -4565,9 +4708,9 @@ var Trust = ({ ref, ...props }) => {
4565
4708
  };
4566
4709
 
4567
4710
  // src/components/ExpandableText/ExpandableText.tsx
4568
- var import_dedupe59 = __toESM(require("classnames/dedupe"));
4569
- var import_react52 = require("react");
4570
- var import_jsx_runtime72 = require("react/jsx-runtime");
4711
+ var import_dedupe60 = __toESM(require("classnames/dedupe"));
4712
+ var import_react53 = require("react");
4713
+ var import_jsx_runtime74 = require("react/jsx-runtime");
4571
4714
  var ExpandableText = ({ ref, ...props }) => {
4572
4715
  const {
4573
4716
  text,
@@ -4581,14 +4724,14 @@ var ExpandableText = ({ ref, ...props }) => {
4581
4724
  onToggle,
4582
4725
  ...otherProps
4583
4726
  } = props;
4584
- const [isExpanded, setIsExpanded] = (0, import_react52.useState)(false);
4585
- const [isCollapsed, setIsCollapsed] = (0, import_react52.useState)(false);
4586
- const textRef = (0, import_react52.useRef)(null);
4727
+ const [isExpanded, setIsExpanded] = (0, import_react53.useState)(false);
4728
+ const [isCollapsed, setIsCollapsed] = (0, import_react53.useState)(false);
4729
+ const textRef = (0, import_react53.useRef)(null);
4587
4730
  const { down } = useBreakpoint();
4588
- const baseId = (0, import_react52.useId)();
4731
+ const baseId = (0, import_react53.useId)();
4589
4732
  const expandButtonId = `expandable-text-expand-${baseId}`;
4590
4733
  const shouldCollapse = breakpoint ? down(breakpoint) : true;
4591
- (0, import_react52.useEffect)(() => {
4734
+ (0, import_react53.useEffect)(() => {
4592
4735
  if (!shouldCollapse || !textRef.current) {
4593
4736
  setIsCollapsed(false);
4594
4737
  return;
@@ -4598,20 +4741,20 @@ var ExpandableText = ({ ref, ...props }) => {
4598
4741
  setIsCollapsed(isOverflowing);
4599
4742
  }, [text, shouldCollapse, maxLines]);
4600
4743
  if (breakpoint && !shouldCollapse) {
4601
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { ref, className, ...otherProps, children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(TextOrHTML, { text, textWrapper: true, ...textProps }) });
4744
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { ref, className, ...otherProps, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(TextOrHTML, { text, textWrapper: true, ...textProps }) });
4602
4745
  }
4603
4746
  const handleAccordionChange = (expanded) => {
4604
4747
  setIsExpanded(expanded);
4605
4748
  onToggle?.(expanded);
4606
4749
  };
4607
- const classes = (0, import_dedupe59.default)("mobius-expandable-text", className);
4608
- const textContainerClasses = (0, import_dedupe59.default)("mobius-expandable-text__content", {
4750
+ const classes = (0, import_dedupe60.default)("mobius-expandable-text", className);
4751
+ const textContainerClasses = (0, import_dedupe60.default)("mobius-expandable-text__content", {
4609
4752
  "mobius-expandable-text__content--collapsed": !isExpanded
4610
4753
  });
4611
4754
  const textContainerStyle = {
4612
4755
  "--line-clamp": maxLines
4613
4756
  };
4614
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
4757
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
4615
4758
  "div",
4616
4759
  {
4617
4760
  ref,
@@ -4619,7 +4762,7 @@ var ExpandableText = ({ ref, ...props }) => {
4619
4762
  "data-testid": "expandable-text",
4620
4763
  ...otherProps,
4621
4764
  children: [
4622
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
4765
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
4623
4766
  "div",
4624
4767
  {
4625
4768
  ref: textRef,
@@ -4627,10 +4770,10 @@ var ExpandableText = ({ ref, ...props }) => {
4627
4770
  style: textContainerStyle,
4628
4771
  "data-testid": "expandable-text-content",
4629
4772
  "aria-describedby": isCollapsed ? expandButtonId : void 0,
4630
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(TextOrHTML, { elementType: "span", textWrapper: true, text, ...textProps })
4773
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(TextOrHTML, { elementType: "span", textWrapper: true, text, ...textProps })
4631
4774
  }
4632
4775
  ),
4633
- isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
4776
+ isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
4634
4777
  Accordion,
4635
4778
  {
4636
4779
  showText,
@@ -4651,11 +4794,11 @@ var ExpandableText = ({ ref, ...props }) => {
4651
4794
  ExpandableText.displayName = "ExpandableText";
4652
4795
 
4653
4796
  // src/components/MaskedField/MaskedField.tsx
4654
- var import_react53 = require("react");
4797
+ var import_react54 = require("react");
4655
4798
  var import_react_imask = require("react-imask");
4656
- var import_jsx_runtime73 = require("react/jsx-runtime");
4799
+ var import_jsx_runtime75 = require("react/jsx-runtime");
4657
4800
  var useAcceptHandler = (onChange, useMaskedValue, name) => {
4658
- return (0, import_react53.useCallback)(
4801
+ return (0, import_react54.useCallback)(
4659
4802
  (maskedValue, maskInstance) => {
4660
4803
  if (!onChange) {
4661
4804
  return;
@@ -4671,7 +4814,7 @@ var useAcceptHandler = (onChange, useMaskedValue, name) => {
4671
4814
  );
4672
4815
  };
4673
4816
  var useCombinedRef = (imaskRef, forwardedRef) => {
4674
- return (0, import_react53.useCallback)(
4817
+ return (0, import_react54.useCallback)(
4675
4818
  (element) => {
4676
4819
  imaskRef.current = element;
4677
4820
  if (typeof forwardedRef === "function") {
@@ -4684,7 +4827,7 @@ var useCombinedRef = (imaskRef, forwardedRef) => {
4684
4827
  );
4685
4828
  };
4686
4829
  var useBlurHandler = (onBlur, maskRef, useMaskedValue, name) => {
4687
- return (0, import_react53.useCallback)(
4830
+ return (0, import_react54.useCallback)(
4688
4831
  (event) => {
4689
4832
  if (!onBlur || !maskRef.current) {
4690
4833
  return;
@@ -4714,7 +4857,7 @@ var ControlledMaskedField = ({
4714
4857
  const { ref: imaskRef, maskRef, setValue } = (0, import_react_imask.useIMask)(mask, { onAccept });
4715
4858
  const combinedRef = useCombinedRef(imaskRef, forwardedRef);
4716
4859
  const handleBlur = useBlurHandler(onBlur, maskRef, useMaskedValue, name);
4717
- (0, import_react53.useEffect)(() => {
4860
+ (0, import_react54.useEffect)(() => {
4718
4861
  if (!maskRef.current) {
4719
4862
  return;
4720
4863
  }
@@ -4725,7 +4868,7 @@ var ControlledMaskedField = ({
4725
4868
  setValue(stringValue);
4726
4869
  }
4727
4870
  }, [value, maskRef, setValue, imaskRef]);
4728
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4871
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
4729
4872
  TextField,
4730
4873
  {
4731
4874
  ...textFieldProps,
@@ -4749,7 +4892,7 @@ var UncontrolledMaskedField = ({
4749
4892
  const { ref: imaskRef, maskRef } = (0, import_react_imask.useIMask)(mask, { onAccept });
4750
4893
  const combinedRef = useCombinedRef(imaskRef, forwardedRef);
4751
4894
  const handleBlur = useBlurHandler(onBlur, maskRef, useMaskedValue, name);
4752
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4895
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
4753
4896
  TextField,
4754
4897
  {
4755
4898
  ...textFieldProps,
@@ -4763,7 +4906,7 @@ var UncontrolledMaskedField = ({
4763
4906
  var MaskedField = ({ ref: forwardedRef, ...props }) => {
4764
4907
  const { value, defaultValue, ...rest } = props;
4765
4908
  if ("value" in props) {
4766
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4909
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
4767
4910
  ControlledMaskedField,
4768
4911
  {
4769
4912
  ...rest,
@@ -4772,7 +4915,7 @@ var MaskedField = ({ ref: forwardedRef, ...props }) => {
4772
4915
  }
4773
4916
  );
4774
4917
  } else {
4775
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
4918
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
4776
4919
  UncontrolledMaskedField,
4777
4920
  {
4778
4921
  ...rest,