@jobber/components 4.56.0 → 4.57.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.
@@ -3,12 +3,14 @@ import { ComboboxProps } from "./Combobox.types";
3
3
  import { ComboboxContent } from "./components/ComboboxContent";
4
4
  import { ComboboxAction } from "./components/ComboboxAction";
5
5
  import { ComboboxTriggerButton, ComboboxTriggerChip } from "./components/ComboboxTrigger";
6
+ import { ComboboxOption } from "./components/ComboboxOption";
6
7
  import { ComboboxActivator } from "./components/ComboboxActivator";
7
- export declare function Combobox(props: ComboboxProps): JSX.Element;
8
+ export declare function Combobox({ multiSelect, selected, ...props }: ComboboxProps): JSX.Element;
8
9
  export declare namespace Combobox {
9
10
  var TriggerButton: typeof ComboboxTriggerButton;
10
11
  var TriggerChip: typeof ComboboxTriggerChip;
11
12
  var Activator: typeof ComboboxActivator;
12
13
  var Content: typeof ComboboxContent;
13
14
  var Action: typeof ComboboxAction;
15
+ var Option: typeof ComboboxOption;
14
16
  }
@@ -1,7 +1,7 @@
1
1
  import { Dispatch, ReactElement, SetStateAction } from "react";
2
2
  import { XOR } from "ts-xor";
3
3
  import { ButtonProps } from "../Button";
4
- export interface ComboboxProps {
4
+ export interface ComboboxProps extends Partial<Omit<ComboboxContentBaseProps, "options">> {
5
5
  readonly children: ReactElement | ReactElement[];
6
6
  /**
7
7
  * When `true`, `Combobox` will allow for multiple selections
@@ -13,6 +13,8 @@ export interface ComboboxProps {
13
13
  * The Chip heading for the trigger
14
14
  */
15
15
  readonly heading: string;
16
+ readonly onSelect?: (selection: ComboboxOption[]) => void;
17
+ readonly onClose?: (selection: ComboboxOption[]) => void;
16
18
  }
17
19
  export interface ComboboxTriggerProps {
18
20
  /**
@@ -1,11 +1,8 @@
1
1
  import React, { RefObject } from "react";
2
- import { ComboboxOption } from "./Combobox.types";
3
2
  export declare const ComboboxContext: React.Context<{
4
3
  multiselect: boolean;
5
4
  open: boolean;
6
5
  setOpen: (open: boolean) => void;
7
- selected: ComboboxOption[];
8
- setSelected: (open: ComboboxOption[]) => void;
9
6
  wrapperRef: RefObject<HTMLDivElement>;
10
7
  }>;
11
8
  export interface ComboboxProviderProps {
@@ -0,0 +1,2 @@
1
+ import { ComboboxOption as ComboboxOptionType } from "../../Combobox.types";
2
+ export declare function ComboboxOption(_: ComboboxOptionType): null;
@@ -0,0 +1 @@
1
+ export * from "./ComboboxOption";
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
- interface ComboboxTriggerProps {
2
+ import { ComboboxContentProps } from "../../Combobox.types";
3
+ interface ComboboxTriggerProps extends Pick<ComboboxContentProps, "selected"> {
3
4
  readonly heading: string;
4
5
  }
5
- export declare function ComboboxTrigger(props: ComboboxTriggerProps): JSX.Element;
6
+ export declare function ComboboxTrigger({ selected, ...props }: ComboboxTriggerProps): JSX.Element;
6
7
  export {};
@@ -1,7 +1,10 @@
1
- import { ReactNode } from "react";
1
+ import { ReactElement, ReactNode } from "react";
2
+ import { ComboboxActionProps, ComboboxOption as ComboboxOptionProps } from "../Combobox.types";
2
3
  export declare const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox can only have one Trigger or Activator element";
3
- export declare const COMBOBOX_REQUIRED_CHILDREN_ERROR_MESSAGE = "Combobox must have a Combobox.Content element";
4
+ export declare const COMBOBOX_OPTION_AND_CONTENT_EXISTS_ERROR = "Combobox prefers using Combobox.Option and Combobox.Action as the direct child of Combobox instead of Combobox.Content";
4
5
  export declare function useComboboxValidation(children: ReactNode): {
5
6
  triggerElement: ReactNode;
6
- contentElement: ReactNode;
7
+ contentElement: ReactNode | undefined;
8
+ optionElements: ReactElement<ComboboxOptionProps>[];
9
+ actionElements: ReactElement<ComboboxActionProps>[];
7
10
  };
@@ -2,6 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var tslib_es6 = require('../tslib.es6-5b8768b7.js');
5
6
  var React = require('react');
6
7
  var classnames = require('classnames');
7
8
  var ReactDOM = require('react-dom');
@@ -127,9 +128,8 @@ const ComboboxContext = React__default["default"].createContext({});
127
128
  function ComboboxContextProvider(props) {
128
129
  const multiselect = props.multiselect || false;
129
130
  const [open, setOpen] = React.useState(false);
130
- const [selected, setSelected] = React.useState([]);
131
131
  const wrapperRef = React.useRef(null);
132
- return (React__default["default"].createElement(ComboboxContext.Provider, { value: { multiselect, open, setOpen, wrapperRef, selected, setSelected } },
132
+ return (React__default["default"].createElement(ComboboxContext.Provider, { value: { multiselect, open, setOpen, wrapperRef } },
133
133
  React__default["default"].createElement("div", { ref: wrapperRef },
134
134
  open && (React__default["default"].createElement("div", { className: styles$2.overlay, onClick: () => setOpen(false), "data-testid": "ATL-Combobox-Overlay" })),
135
135
  props.children)));
@@ -248,10 +248,7 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
248
248
  }
249
249
 
250
250
  function ComboboxContent(props) {
251
- const { open, setOpen, setSelected, wrapperRef, multiselect } = React__default["default"].useContext(ComboboxContext);
252
- React.useEffect(() => {
253
- setSelected(props.selected);
254
- }, [props.selected]);
251
+ const { open, setOpen, wrapperRef, multiselect } = React__default["default"].useContext(ComboboxContext);
255
252
  const optionsExist = props.options.length > 0;
256
253
  const { searchValue, setSearchValue, setFirstSelectedElement, filteredOptions, optionsListRef, selectedOptions, optionsSelectionHandler, } = useComboboxContent(props.options, open, props.selected, props.onClose, props.onSelect);
257
254
  const { popperRef, popperStyles, attributes } = useComboboxAccessibility(handleSelection, filteredOptions, optionsListRef, open, setOpen, wrapperRef);
@@ -319,8 +316,9 @@ function ComboboxTriggerChip(props) {
319
316
  React__default["default"].createElement(Icon.Icon, { color: "surfaceReverse", name: "add", size: "small" }))));
320
317
  }
321
318
 
322
- function ComboboxTrigger(props) {
323
- const { open, setOpen, selected, multiselect } = React__default["default"].useContext(ComboboxContext);
319
+ function ComboboxTrigger(_a) {
320
+ var { selected } = _a, props = tslib_es6.__rest(_a, ["selected"]);
321
+ const { open, setOpen, multiselect } = React__default["default"].useContext(ComboboxContext);
324
322
  const hasSelection = selected.length;
325
323
  const selectedLabel = selected.map(option => option.label).join(", ");
326
324
  const renderHeading = multiselect || !hasSelection;
@@ -339,11 +337,19 @@ function ComboboxActivator(props) {
339
337
  return props.children;
340
338
  }
341
339
 
340
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
341
+ function ComboboxOption(_) {
342
+ useAssert.useAssert(true, "Combobox.Option can only be used inside a Combobox component");
343
+ return null;
344
+ }
345
+
342
346
  const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox can only have one Trigger or Activator element";
343
- const COMBOBOX_REQUIRED_CHILDREN_ERROR_MESSAGE = "Combobox must have a Combobox.Content element";
347
+ const COMBOBOX_OPTION_AND_CONTENT_EXISTS_ERROR = "Combobox prefers using Combobox.Option and Combobox.Action as the direct child of Combobox instead of Combobox.Content";
344
348
  function useComboboxValidation(children) {
345
349
  const childrenArray = React__default["default"].Children.toArray(children);
346
350
  let triggerElement, contentElement, multipleTriggersFound = false;
351
+ const optionElements = [];
352
+ const actionElements = [];
347
353
  childrenArray.forEach(child => {
348
354
  if (isTriggerElement(child)) {
349
355
  if (triggerElement) {
@@ -354,12 +360,20 @@ function useComboboxValidation(children) {
354
360
  if (isContentElement(child)) {
355
361
  contentElement = child;
356
362
  }
363
+ if (isOptionElement(child)) {
364
+ optionElements.push(child);
365
+ }
366
+ if (isActionElement(child)) {
367
+ actionElements.push(child);
368
+ }
357
369
  });
358
370
  useAssert.useAssert(multipleTriggersFound, COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE);
359
- useAssert.useAssert(!contentElement, COMBOBOX_REQUIRED_CHILDREN_ERROR_MESSAGE);
371
+ useAssert.useAssert(Boolean((optionElements.length || actionElements.length) && contentElement), COMBOBOX_OPTION_AND_CONTENT_EXISTS_ERROR);
360
372
  return {
361
373
  contentElement,
362
374
  triggerElement,
375
+ optionElements,
376
+ actionElements,
363
377
  };
364
378
  }
365
379
  function isTriggerElement(child) {
@@ -371,12 +385,25 @@ function isTriggerElement(child) {
371
385
  function isContentElement(child) {
372
386
  return React__default["default"].isValidElement(child) && child.type === ComboboxContent;
373
387
  }
388
+ function isOptionElement(child) {
389
+ return React__default["default"].isValidElement(child) && child.type === ComboboxOption;
390
+ }
391
+ function isActionElement(child) {
392
+ return React__default["default"].isValidElement(child) && child.type === ComboboxAction;
393
+ }
374
394
 
375
- function Combobox(props) {
376
- const { contentElement, triggerElement } = useComboboxValidation(props.children);
377
- return (React__default["default"].createElement(ComboboxContextProvider, { multiselect: props.multiSelect },
378
- triggerElement || React__default["default"].createElement(ComboboxTrigger, { heading: props.heading }),
379
- contentElement));
395
+ function Combobox(_a) {
396
+ var { multiSelect = false, selected = [] } = _a, props = tslib_es6.__rest(_a, ["multiSelect", "selected"]);
397
+ const { contentElement, triggerElement, optionElements, actionElements } = useComboboxValidation(props.children);
398
+ const buildOptions = optionElements.map(option => ({
399
+ id: option.props.id,
400
+ label: option.props.label,
401
+ }));
402
+ return (React__default["default"].createElement(ComboboxContextProvider, { multiselect: multiSelect },
403
+ triggerElement || (React__default["default"].createElement(ComboboxTrigger, { heading: props.heading, selected: selected })),
404
+ contentElement || (
405
+ // @ts-expect-error - Suppress the XOR error with onClose|onSelect until we finish the refactor on JOB-81416
406
+ React__default["default"].createElement(ComboboxContent, Object.assign({ options: buildOptions, selected: selected }, props), actionElements))));
380
407
  }
381
408
  /**
382
409
  * @deprecated Use Combobox.Activator instead
@@ -387,8 +414,12 @@ Combobox.TriggerButton = ComboboxTriggerButton;
387
414
  */
388
415
  Combobox.TriggerChip = ComboboxTriggerChip;
389
416
  Combobox.Activator = ComboboxActivator;
417
+ /**
418
+ * @deprecated Use individual Combobox.Option instead
419
+ */
390
420
  Combobox.Content = ComboboxContent;
391
421
  Combobox.Action = ComboboxAction;
422
+ Combobox.Option = ComboboxOption;
392
423
 
393
424
  exports.Combobox = Combobox;
394
425
  exports.ComboboxContextProvider = ComboboxContextProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.56.0",
3
+ "version": "4.57.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -84,5 +84,5 @@
84
84
  "> 1%",
85
85
  "IE 10"
86
86
  ],
87
- "gitHead": "cf05d6bdcd54dac5f44bea4d3f1c4213a0975c4a"
87
+ "gitHead": "d8214fde2dedb50cebe48fe7967019660a1933bd"
88
88
  }