@jobber/components 6.14.1-aidenfix--e9ec00c.0 → 6.15.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.
@@ -1,50 +1,6 @@
1
- import React from "react";
2
- import { XOR } from "ts-xor";
3
- import { GroupOption, Option } from "./Option";
1
+ import { Ref, RefAttributes } from "react";
2
+ import { AnyOption, AutocompleteProps, Option } from "./Autocomplete.types";
4
3
  import { InputTextRef } from "../InputText";
5
- import { FormFieldProps } from "../FormField";
6
- type OptionCollection = XOR<Option[], GroupOption[]>;
7
- interface AutocompleteProps extends Pick<FormFieldProps, "clearable" | "description" | "invalid" | "name" | "onBlur" | "onFocus" | "prefix" | "size" | "suffix" | "validations"> {
8
- /**
9
- * @deprecated
10
- * Use `ref` instead.
11
- */
12
- readonly inputRef?: FormFieldProps["inputRef"];
13
- /**
14
- * Initial options to show when user first focuses the Autocomplete
15
- */
16
- readonly initialOptions?: OptionCollection;
17
- /**
18
- * Set Autocomplete value.
19
- */
20
- readonly value: Option | undefined;
21
- /**
22
- * Allow the autocomplete to use values not from the drop down menu.
23
- *
24
- * @default true
25
- */
26
- readonly allowFreeForm?: boolean;
27
- /**
28
- * Debounce in milliseconds for getOptions
29
- *
30
- * @default 300
31
- */
32
- readonly debounce?: number;
33
- /**
34
- * Simplified onChange handler that only provides the new value.
35
- * @param newValue
36
- */
37
- onChange(newValue?: Option): void;
38
- /**
39
- * Called as the user types in the input. The autocomplete will display what
40
- * is returned from this method to the user as available options.
41
- * @param newInputText
42
- */
43
- getOptions(newInputText: string): OptionCollection | Promise<OptionCollection>;
44
- /**
45
- * Hint text that goes above the value once the form is filled out.
46
- */
47
- readonly placeholder: string;
48
- }
49
- export declare const Autocomplete: React.ForwardRefExoticComponent<AutocompleteProps & React.RefAttributes<InputTextRef>>;
4
+ declare function AutocompleteInternal<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option, GenericGetOptionsValue extends AnyOption = AnyOption>({ initialOptions, value, allowFreeForm, size, debounce: debounceRate, onChange, getOptions, placeholder, onBlur, onFocus, validations, customRenderMenu, ...inputProps }: AutocompleteProps<GenericOption, GenericOptionValue, GenericGetOptionsValue>, ref: Ref<InputTextRef>): JSX.Element;
5
+ export declare const Autocomplete: <GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option, GenericGetOptionsValue extends AnyOption = AnyOption>(props: AutocompleteProps<GenericOption, GenericOptionValue, GenericGetOptionsValue> & RefAttributes<InputTextRef>) => ReturnType<typeof AutocompleteInternal>;
50
6
  export {};
@@ -0,0 +1,111 @@
1
+ import { RefObject } from "react";
2
+ import { FormFieldProps } from "../FormField";
3
+ import { InputTextRef } from "../InputText";
4
+ type OptionValue = string | number;
5
+ export interface BaseOption {
6
+ label: string;
7
+ }
8
+ export interface Option extends BaseOption {
9
+ value?: OptionValue;
10
+ description?: string;
11
+ details?: string;
12
+ }
13
+ export interface GroupOption extends BaseOption {
14
+ options: Option[];
15
+ }
16
+ export type OptionCollection = AnyOption[];
17
+ export type AnyOption<GenericOption extends Option | GroupOption = Option | GroupOption> = GenericOption;
18
+ export type OptionInGroup<T extends AnyOption> = T extends GroupOption ? T["options"][number] : T;
19
+ export interface AutocompleteProps<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option, GenericGetOptionsValue extends AnyOption = AnyOption> extends Pick<FormFieldProps, "clearable" | "description" | "invalid" | "name" | "onBlur" | "onFocus" | "prefix" | "size" | "suffix" | "validations"> {
20
+ /**
21
+ * @deprecated
22
+ * Use `ref` instead.
23
+ */
24
+ readonly inputRef?: FormFieldProps["inputRef"];
25
+ readonly initialOptions?: GenericOption[];
26
+ /**
27
+ * Set Autocomplete value.
28
+ */
29
+ readonly value: GenericOptionValue | undefined;
30
+ /**
31
+ * Allow the autocomplete to use values not from the drop down menu.
32
+ *
33
+ * @default true
34
+ */
35
+ readonly allowFreeForm?: boolean;
36
+ /**
37
+ * Debounce in milliseconds for getOptions
38
+ *
39
+ * @default 300
40
+ */
41
+ readonly debounce?: number;
42
+ /**
43
+ * Simplified onChange handler that only provides the new value.
44
+ * @param newValue
45
+ */
46
+ onChange(newValue?: GenericOptionValue): void;
47
+ /**
48
+ * Called as the user types in the input. The autocomplete will display what
49
+ * is returned from this method to the user as available options.
50
+ * @param newInputText
51
+ */
52
+ getOptions(newInputText: string): Array<GenericGetOptionsValue | GenericOption> | Promise<Array<GenericGetOptionsValue | GenericOption>>;
53
+ /**
54
+ * Hint text that goes above the value once the form is filled out.
55
+ */
56
+ readonly placeholder: string;
57
+ /**
58
+ * Override the content rendered in the menu.
59
+ */
60
+ readonly customRenderMenu?: (props: CustomOptionsMenuProp<GenericOption | GenericGetOptionsValue, GenericOptionValue>) => React.ReactElement;
61
+ }
62
+ export type CustomOptionsMenuType<GenericOption extends AnyOption = AnyOption> = (props: CustomOptionsMenuProp<GenericOption>) => React.ReactElement;
63
+ export interface MenuProps<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option> {
64
+ readonly options: GenericOption[];
65
+ readonly selectedOption?: GenericOptionValue;
66
+ readonly inputFocused: boolean;
67
+ /**
68
+ * Element that the menu is attached to when the menu opens.
69
+ */
70
+ readonly attachTo: RefObject<Element | null>;
71
+ /**
72
+ * Ref to the TextInput element.
73
+ */
74
+ readonly inputRef: RefObject<InputTextRef | null>;
75
+ onOptionSelect(chosenOption?: GenericOptionValue): void;
76
+ readonly customRenderMenu?: (props: CustomOptionsMenuProp<GenericOption, GenericOptionValue>) => React.ReactElement;
77
+ }
78
+ export interface CustomOptionsMenuProp<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option> {
79
+ /**
80
+ * The options to display in the menu
81
+ */
82
+ options: Array<OptionInGroup<GenericOption> | GenericOption>;
83
+ /**
84
+ * The currently selected option
85
+ */
86
+ selectedOption?: GenericOptionValue;
87
+ /**
88
+ * The HTML element that wraps the menu content. Used for handling keyboard scroll behavior.
89
+ */
90
+ readonly menuRef: HTMLElement | null | undefined;
91
+ /**
92
+ * Callback to select an option
93
+ */
94
+ readonly onOptionSelect: (chosenOption?: GenericOptionValue) => void;
95
+ /**
96
+ * Determine if the input is focused. Can be used to conditionally render the menu.
97
+ */
98
+ readonly inputFocused: boolean;
99
+ /**
100
+ * Ref to the TextInput element.
101
+ */
102
+ readonly inputRef: RefObject<InputTextRef | null>;
103
+ /**
104
+ * Component that wraps the menu content. Used for handling keyboard scroll behavior.
105
+ */
106
+ readonly MenuWrapper: (props: {
107
+ children: React.ReactNode;
108
+ visible: boolean;
109
+ }) => React.ReactElement;
110
+ }
111
+ export {};
@@ -0,0 +1,8 @@
1
+ import { AnyOption, GroupOption, Option } from "./Autocomplete.types";
2
+ export declare function isOptionSelected(selectedOption: Option | undefined, option: Option): boolean;
3
+ /**
4
+ * Helper function to determine if the option is a group. This is used to
5
+ * determine if the option contains a list of options for rendering Section
6
+ * Labels in the Autocomplete component.
7
+ */
8
+ export declare function isOptionGroup<T extends AnyOption>(option: T): option is Extract<T, GroupOption>;
@@ -0,0 +1,16 @@
1
+ import { RefObject } from "react";
2
+ import { AnyOption, Option } from "../Autocomplete.types";
3
+ export interface DefaultMenuProps {
4
+ readonly options: AnyOption[];
5
+ readonly selectedOption?: Option;
6
+ /**
7
+ * Element that it's attached to when the menu opens.
8
+ */
9
+ readonly attachTo: RefObject<Element | null>;
10
+ onOptionSelect(chosenOption?: Option): void;
11
+ readonly visible?: boolean;
12
+ }
13
+ /**
14
+ * Renders the default Menu for the Autocomplete component.
15
+ */
16
+ export declare function DefaultMenu({ options, selectedOption, onOptionSelect, attachTo, visible, }: DefaultMenuProps): JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { AnyOption, MenuProps, Option } from "../Autocomplete.types";
2
+ export declare function Menu<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option>({ options, selectedOption, onOptionSelect, inputFocused, attachTo, inputRef, customRenderMenu, }: MenuProps<GenericOption, GenericOptionValue>): JSX.Element | null;
@@ -0,0 +1,23 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ import { UseRepositionMenu } from "../useRepositionMenu";
3
+ export interface BaseAutocompleteMenuWrapperInternalProps {
4
+ readonly setMenuRef: UseRepositionMenu["setMenuRef"];
5
+ readonly popperStyles: UseRepositionMenu["styles"];
6
+ readonly attributes: UseRepositionMenu["attributes"];
7
+ readonly targetWidth: UseRepositionMenu["targetWidth"];
8
+ readonly visible?: boolean;
9
+ }
10
+ /**
11
+ * Provides a wrapper for the Autocomplete menu that handles positioning and visibility.
12
+ * @param attachTo - The element that the menu should be attached to.
13
+ */
14
+ export declare function useAutocompleteMenu({ attachTo, }: {
15
+ attachTo: React.RefObject<Element | null>;
16
+ }): {
17
+ MenuWrapper: ({ children, visible, }: {
18
+ children?: React.ReactNode;
19
+ visible: boolean;
20
+ }) => React.ReactElement;
21
+ menuRef: HTMLElement | null;
22
+ };
23
+ export declare function BaseAutocompleteMenuWrapper(props: PropsWithChildren<BaseAutocompleteMenuWrapperInternalProps>): JSX.Element;
@@ -1,15 +1,77 @@
1
- import { XOR } from "ts-xor";
2
- type OptionValue = string | number;
3
- interface BaseOption {
4
- label: string;
1
+ import React, { PropsWithChildren } from "react";
2
+ import { AnyOption, Option } from "./Autocomplete.types";
3
+ export interface MenuOptionProps {
4
+ readonly isHighlighted: boolean;
5
+ readonly option: AnyOption;
6
+ readonly onOptionSelect: (option?: AnyOption) => void;
7
+ /**
8
+ * Whether to add separators between the options.
9
+ */
10
+ readonly addSeparators: boolean;
11
+ readonly isSelected: boolean;
12
+ readonly UNSAFE_className?: {
13
+ option?: BaseMenuOptionProps["UNSAFE_className"];
14
+ content?: MenuOptionContentProps["UNSAFE_className"];
15
+ groupOption?: MenuGroupOptionProps["UNSAFE_className"];
16
+ };
17
+ readonly UNSAFE_style?: {
18
+ option?: BaseMenuOptionProps["UNSAFE_style"];
19
+ content?: MenuOptionContentProps["UNSAFE_style"];
20
+ groupOption?: MenuGroupOptionProps["UNSAFE_style"];
21
+ };
5
22
  }
6
- export interface Option extends BaseOption {
7
- value?: OptionValue;
8
- description?: string;
9
- details?: string;
23
+ /**
24
+ * The rendering of the default MenuOption
25
+ */
26
+ export declare function MenuOption({ isHighlighted, option, onOptionSelect, isSelected, addSeparators, UNSAFE_className, UNSAFE_style, }: MenuOptionProps): JSX.Element;
27
+ interface MenuOptionContentProps {
28
+ readonly UNSAFE_className?: {
29
+ readonly icon?: string;
30
+ readonly text?: string;
31
+ readonly details?: string;
32
+ readonly label?: string;
33
+ };
34
+ readonly UNSAFE_style?: {
35
+ readonly icon?: React.CSSProperties;
36
+ readonly text?: React.CSSProperties;
37
+ readonly label?: React.CSSProperties;
38
+ readonly details?: React.CSSProperties;
39
+ };
40
+ readonly option: Option;
41
+ readonly isSelected: boolean;
10
42
  }
11
- export interface GroupOption extends BaseOption {
12
- options: Option[];
43
+ export declare function MenuOptionContent({ option, isSelected, UNSAFE_className, UNSAFE_style, }: MenuOptionContentProps): JSX.Element;
44
+ export interface MenuGroupOptionProps {
45
+ readonly option: AnyOption;
46
+ readonly UNSAFE_className?: {
47
+ heading?: string;
48
+ };
49
+ readonly UNSAFE_style?: {
50
+ heading?: React.CSSProperties;
51
+ };
13
52
  }
14
- export type AnyOption = XOR<Option, GroupOption>;
53
+ /**
54
+ * The rendering of the default MenuGroupOption
55
+ */
56
+ export declare function MenuGroupOptions({ option, UNSAFE_className, UNSAFE_style, }: MenuGroupOptionProps): JSX.Element;
57
+ /**
58
+ * The base component for the MenuGroupOption
59
+ */
60
+ export interface BaseMenuGroupOptionProps extends PropsWithChildren {
61
+ readonly UNSAFE_className?: string;
62
+ readonly UNSAFE_style?: React.CSSProperties;
63
+ }
64
+ export declare function BaseMenuGroupOption({ children, UNSAFE_className, UNSAFE_style, }: BaseMenuGroupOptionProps): JSX.Element;
65
+ export interface BaseMenuOptionProps<GenericOption extends AnyOption = AnyOption> extends PropsWithChildren {
66
+ readonly option?: GenericOption;
67
+ readonly onOptionSelect?: (option?: GenericOption) => void;
68
+ readonly isHighlighted: boolean;
69
+ readonly addSeparators: boolean;
70
+ readonly UNSAFE_className?: string;
71
+ readonly UNSAFE_style?: React.CSSProperties;
72
+ }
73
+ /**
74
+ * Renders the base option component. The component takes children and renders them inside a button.
75
+ */
76
+ export declare function BaseMenuOption<GenericOption extends AnyOption = AnyOption>({ option, isHighlighted, onOptionSelect, addSeparators, children, UNSAFE_className, UNSAFE_style, }: BaseMenuOptionProps<GenericOption>): JSX.Element;
15
77
  export {};
@@ -4,16 +4,16 @@ var Autocomplete = require('../Autocomplete-cjs.js');
4
4
  require('../tslib.es6-cjs.js');
5
5
  require('react');
6
6
  require('classnames');
7
+ require('../useIsMounted-cjs.js');
8
+ require('../useSafeLayoutEffect-cjs.js');
7
9
  require('react-dom');
8
10
  require('react-popper');
9
- require('../useOnKeyDown-cjs.js');
10
- require('../useSafeLayoutEffect-cjs.js');
11
- require('../useIsMounted-cjs.js');
12
- require('../Text-cjs.js');
11
+ require('../Heading-cjs.js');
13
12
  require('../Typography-cjs.js');
13
+ require('../Text-cjs.js');
14
14
  require('../Icon-cjs.js');
15
15
  require('@jobber/design');
16
- require('../Heading-cjs.js');
16
+ require('../useOnKeyDown-cjs.js');
17
17
  require('../InputText/index.cjs');
18
18
  require('../FormField-cjs.js');
19
19
  require('framer-motion');
@@ -40,3 +40,18 @@ require('../debounce-cjs.js');
40
40
 
41
41
 
42
42
  exports.Autocomplete = Autocomplete.Autocomplete;
43
+ exports.BaseAutocompleteMenuWrapper = Autocomplete.BaseAutocompleteMenuWrapper;
44
+ exports.BaseMenuGroupOption = Autocomplete.BaseMenuGroupOption;
45
+ exports.BaseMenuOption = Autocomplete.BaseMenuOption;
46
+ Object.defineProperty(exports, "KeyboardAction", {
47
+ enumerable: true,
48
+ get: function () { return Autocomplete.KeyboardAction; }
49
+ });
50
+ exports.MenuOption = Autocomplete.MenuOption;
51
+ exports.getRequestedIndexChange = Autocomplete.getRequestedIndexChange;
52
+ exports.isOptionGroup = Autocomplete.isOptionGroup;
53
+ exports.isOptionSelected = Autocomplete.isOptionSelected;
54
+ exports.useAutocompleteMenu = Autocomplete.useAutocompleteMenu;
55
+ exports.useCustomKeyboardNavigation = Autocomplete.useCustomKeyboardNavigation;
56
+ exports.useKeyboardNavigation = Autocomplete.useKeyboardNavigation;
57
+ exports.useRepositionMenu = Autocomplete.useRepositionMenu;
@@ -1,2 +1,7 @@
1
1
  export { Autocomplete } from "./Autocomplete";
2
- export * from "./Option";
2
+ export { MenuOptionProps, BaseMenuOption, BaseMenuOptionProps, MenuOption, BaseMenuGroupOption, BaseMenuGroupOptionProps, } from "./Option";
3
+ export { AnyOption, AutocompleteProps, BaseOption, CustomOptionsMenuProp, GroupOption, OptionCollection, Option, } from "./Autocomplete.types";
4
+ export { KeyboardAction, getRequestedIndexChange, useKeyboardNavigation, useCustomKeyboardNavigation, } from "./useKeyboardNavigation";
5
+ export { useRepositionMenu } from "./useRepositionMenu";
6
+ export { BaseAutocompleteMenuWrapper, useAutocompleteMenu, } from "./Menu/MenuWrapper";
7
+ export { isOptionSelected, isOptionGroup } from "./Autocomplete.utils";
@@ -1,17 +1,17 @@
1
- export { A as Autocomplete } from '../Autocomplete-es.js';
1
+ export { A as Autocomplete, d as BaseAutocompleteMenuWrapper, a as BaseMenuGroupOption, B as BaseMenuOption, K as KeyboardAction, M as MenuOption, g as getRequestedIndexChange, f as isOptionGroup, i as isOptionSelected, e as useAutocompleteMenu, b as useCustomKeyboardNavigation, u as useKeyboardNavigation, c as useRepositionMenu } from '../Autocomplete-es.js';
2
2
  import '../tslib.es6-es.js';
3
3
  import 'react';
4
4
  import 'classnames';
5
+ import '../useIsMounted-es.js';
6
+ import '../useSafeLayoutEffect-es.js';
5
7
  import 'react-dom';
6
8
  import 'react-popper';
7
- import '../useOnKeyDown-es.js';
8
- import '../useSafeLayoutEffect-es.js';
9
- import '../useIsMounted-es.js';
10
- import '../Text-es.js';
9
+ import '../Heading-es.js';
11
10
  import '../Typography-es.js';
11
+ import '../Text-es.js';
12
12
  import '../Icon-es.js';
13
13
  import '@jobber/design';
14
- import '../Heading-es.js';
14
+ import '../useOnKeyDown-es.js';
15
15
  import '../InputText/index.mjs';
16
16
  import '../FormField-es.js';
17
17
  import 'framer-motion';
@@ -0,0 +1,35 @@
1
+ import { AnyOption, Option } from "./Autocomplete.types";
2
+ export declare enum KeyboardAction {
3
+ Previous = -1,
4
+ Next = 1,
5
+ Select = 0
6
+ }
7
+ /**
8
+ * Hook to handle custom keyboard navigation for the Autocomplete component.
9
+ * Use this hook if you are using components in the menu that aren't MenuOption or BaseMenuOption.
10
+ */
11
+ export declare function useCustomKeyboardNavigation({ onRequestHighlightChange, }: {
12
+ onRequestHighlightChange?: (event: KeyboardEvent, direction: KeyboardAction) => void;
13
+ }): void;
14
+ /**
15
+ * Hook to handle keyboard navigation for the Menu in the Autocomplete component.
16
+ * If using components in the menu that aren't MenuOption or BaseMenuOption, you should use the `useCustomKeyboardNavigation` hook.
17
+ */
18
+ export declare function useKeyboardNavigation<GenericOption extends AnyOption = AnyOption, GenericOptionValue extends Option = Option>({ options, onOptionSelect, menuRef, visible, }: {
19
+ options: GenericOption[];
20
+ visible?: boolean;
21
+ menuRef?: HTMLElement | null;
22
+ onOptionSelect: (option?: GenericOptionValue) => void;
23
+ }): {
24
+ highlightedIndex: number;
25
+ };
26
+ /**
27
+ * Function to get the requested index change based on the current highlighted index and the direction of the keyboard action.
28
+ * Accounts for groups in the options array.
29
+ */
30
+ export declare function getRequestedIndexChange<T extends AnyOption>({ event, options, direction, highlightedIndex, }: {
31
+ event: KeyboardEvent;
32
+ direction: KeyboardAction;
33
+ options: T[];
34
+ highlightedIndex: number;
35
+ }): number;
@@ -0,0 +1,23 @@
1
+ import { usePopper } from "react-popper";
2
+ import { MenuProps } from "./Autocomplete.types";
3
+ export interface UseRepositionMenu extends ReturnType<typeof usePopper> {
4
+ readonly menuRef: HTMLElement | null;
5
+ readonly setMenuRef: (ref: HTMLElement | null) => void;
6
+ readonly targetWidth: number | undefined;
7
+ }
8
+ export declare function useRepositionMenu(attachTo: MenuProps["attachTo"], visible?: boolean): {
9
+ menuRef: HTMLElement | null;
10
+ setMenuRef: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
11
+ targetWidth: number | undefined;
12
+ styles: {
13
+ [key: string]: React.CSSProperties;
14
+ };
15
+ attributes: {
16
+ [key: string]: {
17
+ [key: string]: string;
18
+ } | undefined;
19
+ };
20
+ state: import("@popperjs/core").State | null;
21
+ update: import("@popperjs/core").Instance["update"] | null;
22
+ forceUpdate: import("@popperjs/core").Instance["forceUpdate"] | null;
23
+ };