@codecademy/gamut 72.2.3-alpha.c298d6.0 → 72.2.3-alpha.f0a032.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/agent-tools/skills/gamut-forms/SKILL.md +16 -0
- package/agent-tools/skills/gamut-select-dropdown/SKILL.md +236 -0
- package/dist/Button/IconButton.js +0 -1
- package/dist/Form/SelectDropdown/SelectDropdown.js +48 -100
- package/dist/Form/SelectDropdown/core/accessibility.d.ts +3 -0
- package/dist/Form/SelectDropdown/core/accessibility.js +12 -0
- package/dist/Form/SelectDropdown/core/constants.d.ts +13 -0
- package/dist/Form/SelectDropdown/core/constants.js +14 -0
- package/dist/Form/SelectDropdown/{styles.js → core/styles.js} +30 -12
- package/dist/Form/SelectDropdown/{utils.d.ts → core/utils.d.ts} +12 -2
- package/dist/Form/SelectDropdown/{utils.js → core/utils.js} +23 -0
- package/dist/Form/SelectDropdown/elements/constants.d.ts +0 -8
- package/dist/Form/SelectDropdown/elements/constants.js +1 -9
- package/dist/Form/SelectDropdown/elements/containers.d.ts +6 -2
- package/dist/Form/SelectDropdown/elements/containers.js +17 -1
- package/dist/Form/SelectDropdown/elements/controls.d.ts +1 -15
- package/dist/Form/SelectDropdown/elements/controls.js +2 -91
- package/dist/Form/SelectDropdown/elements/index.d.ts +2 -1
- package/dist/Form/SelectDropdown/elements/index.js +2 -1
- package/dist/Form/SelectDropdown/elements/options.d.ts +1 -0
- package/dist/Form/SelectDropdown/elements/options.js +5 -2
- package/dist/Form/SelectDropdown/hooks/useSelectHandlers.d.ts +22 -0
- package/dist/Form/SelectDropdown/hooks/useSelectHandlers.js +62 -0
- package/dist/Form/SelectDropdown/hooks/useSelectOptions.d.ts +14 -0
- package/dist/Form/SelectDropdown/hooks/useSelectOptions.js +39 -0
- package/dist/Form/SelectDropdown/types/component-props.d.ts +54 -6
- package/dist/Form/SelectDropdown/types/internal.d.ts +3 -3
- package/dist/Form/SelectDropdown/types/styles.d.ts +5 -1
- package/dist/Form/styles/index.d.ts +1 -1
- package/dist/Form/styles/index.js +1 -1
- package/dist/Tip/ToolTip/index.d.ts +2 -7
- package/dist/Tip/shared/FloatingTip.js +0 -15
- package/dist/Tip/shared/InlineTip.js +0 -17
- package/dist/Tip/shared/types.d.ts +0 -1
- package/package.json +6 -6
- /package/dist/Form/SelectDropdown/{styles.d.ts → core/styles.d.ts} +0 -0
|
@@ -15,14 +15,6 @@ export declare const indicatorIcons: {
|
|
|
15
15
|
size: number;
|
|
16
16
|
icon: import("react").ForwardRefExoticComponent<import("@codecademy/gamut-icons").GamutIconProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
17
17
|
};
|
|
18
|
-
smallSearchable: {
|
|
19
|
-
size: number;
|
|
20
|
-
icon: import("react").ForwardRefExoticComponent<import("@codecademy/gamut-icons").GamutIconProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
21
|
-
};
|
|
22
|
-
mediumSearchable: {
|
|
23
|
-
size: number;
|
|
24
|
-
icon: import("react").ForwardRefExoticComponent<import("@codecademy/gamut-icons").GamutIconProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
25
|
-
};
|
|
26
18
|
smallRemove: {
|
|
27
19
|
size: number;
|
|
28
20
|
icon: import("react").ForwardRefExoticComponent<import("@codecademy/gamut-icons").GamutIconProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArrowChevronDownIcon, CloseIcon, MiniChevronDownIcon, MiniDeleteIcon
|
|
1
|
+
import { ArrowChevronDownIcon, CloseIcon, MiniChevronDownIcon, MiniDeleteIcon } from '@codecademy/gamut-icons';
|
|
2
2
|
export const iconSize = {
|
|
3
3
|
small: 12,
|
|
4
4
|
medium: 16
|
|
@@ -16,14 +16,6 @@ export const indicatorIcons = {
|
|
|
16
16
|
size: iconSize.medium,
|
|
17
17
|
icon: ArrowChevronDownIcon
|
|
18
18
|
},
|
|
19
|
-
smallSearchable: {
|
|
20
|
-
size: iconSize.small,
|
|
21
|
-
icon: SearchIcon
|
|
22
|
-
},
|
|
23
|
-
mediumSearchable: {
|
|
24
|
-
size: iconSize.medium,
|
|
25
|
-
icon: SearchIcon
|
|
26
|
-
},
|
|
27
19
|
smallRemove: {
|
|
28
20
|
size: iconSize.small,
|
|
29
21
|
icon: MiniDeleteIcon
|
|
@@ -24,6 +24,10 @@ export declare const CustomValueContainer: ({ ...rest }: CustomSelectComponentPr
|
|
|
24
24
|
export declare const CustomInput: ({ ...rest }: CustomSelectComponentProps<typeof SelectDropdownElements.Input>) => import("react/jsx-runtime").JSX.Element;
|
|
25
25
|
/**
|
|
26
26
|
* Typed wrapper around react-select component.
|
|
27
|
-
*
|
|
27
|
+
* Renders CreatableSelect when isCreatable is true, ReactSelect otherwise.
|
|
28
|
+
* Creatable-only props (formatCreateLabel, isValidNewOption) are stripped from
|
|
29
|
+
* the non-creatable path so they don't reach ReactSelect. `onCreateOption` is
|
|
30
|
+
* handled in SelectDropdown's changeHandler — do not pass it to CreatableSelect
|
|
31
|
+
* or react-select will skip onChange on create.
|
|
28
32
|
*/
|
|
29
|
-
export declare function TypedReactSelect<OptionType, IsMulti extends boolean = false, GroupType extends GroupBase<OptionType> = GroupBase<OptionType>>({ selectRef, ...props }: Props<OptionType, IsMulti, GroupType> & TypedReactSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare function TypedReactSelect<OptionType, IsMulti extends boolean = false, GroupType extends GroupBase<OptionType> = GroupBase<OptionType>>({ selectRef, isCreatable, formatCreateLabel, isValidNewOption, ...props }: Props<OptionType, IsMulti, GroupType> & TypedReactSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, useLayoutEffect } from 'react';
|
|
2
2
|
import ReactSelect, { components as SelectDropdownElements } from 'react-select';
|
|
3
|
+
import CreatableSelect from 'react-select/creatable';
|
|
3
4
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
5
|
/**
|
|
5
6
|
* React context for sharing state between SelectDropdown components.
|
|
@@ -116,12 +117,27 @@ export const CustomInput = ({
|
|
|
116
117
|
|
|
117
118
|
/**
|
|
118
119
|
* Typed wrapper around react-select component.
|
|
119
|
-
*
|
|
120
|
+
* Renders CreatableSelect when isCreatable is true, ReactSelect otherwise.
|
|
121
|
+
* Creatable-only props (formatCreateLabel, isValidNewOption) are stripped from
|
|
122
|
+
* the non-creatable path so they don't reach ReactSelect. `onCreateOption` is
|
|
123
|
+
* handled in SelectDropdown's changeHandler — do not pass it to CreatableSelect
|
|
124
|
+
* or react-select will skip onChange on create.
|
|
120
125
|
*/
|
|
121
126
|
export function TypedReactSelect({
|
|
122
127
|
selectRef,
|
|
128
|
+
isCreatable,
|
|
129
|
+
formatCreateLabel,
|
|
130
|
+
isValidNewOption,
|
|
123
131
|
...props
|
|
124
132
|
}) {
|
|
133
|
+
if (isCreatable) {
|
|
134
|
+
return /*#__PURE__*/_jsx(CreatableSelect, {
|
|
135
|
+
...props,
|
|
136
|
+
formatCreateLabel: formatCreateLabel,
|
|
137
|
+
isValidNewOption: isValidNewOption,
|
|
138
|
+
ref: selectRef
|
|
139
|
+
});
|
|
140
|
+
}
|
|
125
141
|
return /*#__PURE__*/_jsx(ReactSelect, {
|
|
126
142
|
...props,
|
|
127
143
|
ref: selectRef
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ExtendedOption, SizedIndicatorProps } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* Generates accessible focus messages for screen readers.
|
|
5
|
-
* Provides detailed information about the currently focused option.
|
|
6
|
-
*
|
|
7
|
-
* @param params - Object containing the focused option details
|
|
8
|
-
* @returns Formatted accessibility message
|
|
9
|
-
*/
|
|
10
|
-
export declare const onFocus: AriaOnFocus<ExtendedOption>;
|
|
1
|
+
import { SizedIndicatorProps } from '../types';
|
|
11
2
|
/**
|
|
12
3
|
* Custom dropdown indicator that shows either a chevron or search icon.
|
|
13
4
|
* The icon type depends on whether the select is searchable or not.
|
|
14
5
|
*/
|
|
15
6
|
export declare const DropdownButton: (props: SizedIndicatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
-
/**
|
|
17
|
-
* Custom remove all button for multi-select mode.
|
|
18
|
-
* Provides keyboard navigation and accessible removal of all selected values.
|
|
19
|
-
*/
|
|
20
|
-
export declare const RemoveAllButton: (props: SizedIndicatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,50 +1,23 @@
|
|
|
1
|
-
import _styled from "@emotion/styled/base";
|
|
2
|
-
import { css, theme } from '@codecademy/gamut-styles';
|
|
3
|
-
import { useContext } from 'react';
|
|
4
1
|
import { components as SelectDropdownElements } from 'react-select';
|
|
5
2
|
import { indicatorIcons } from './constants';
|
|
6
|
-
import { SelectDropdownContext } from './containers';
|
|
7
3
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
4
|
const {
|
|
9
5
|
DropdownIndicator
|
|
10
6
|
} = SelectDropdownElements;
|
|
11
7
|
|
|
12
|
-
/**
|
|
13
|
-
* Generates accessible focus messages for screen readers.
|
|
14
|
-
* Provides detailed information about the currently focused option.
|
|
15
|
-
*
|
|
16
|
-
* @param params - Object containing the focused option details
|
|
17
|
-
* @returns Formatted accessibility message
|
|
18
|
-
*/
|
|
19
|
-
export const onFocus = ({
|
|
20
|
-
focused: {
|
|
21
|
-
label,
|
|
22
|
-
subtitle,
|
|
23
|
-
rightLabel,
|
|
24
|
-
disabled
|
|
25
|
-
}
|
|
26
|
-
}) => {
|
|
27
|
-
const formattedSubtitle = `, ${subtitle}`;
|
|
28
|
-
const formattedRightLabel = `, ${rightLabel}`;
|
|
29
|
-
const msg = `You are currently focused on option ${label}${subtitle ? formattedSubtitle : ''} ${rightLabel ? formattedRightLabel : ''}${disabled ? ', disabled' : ''}`;
|
|
30
|
-
return msg;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
8
|
/**
|
|
34
9
|
* Custom dropdown indicator that shows either a chevron or search icon.
|
|
35
10
|
* The icon type depends on whether the select is searchable or not.
|
|
36
11
|
*/
|
|
37
12
|
export const DropdownButton = props => {
|
|
38
13
|
const {
|
|
39
|
-
size
|
|
40
|
-
isSearchable
|
|
14
|
+
size
|
|
41
15
|
} = props.selectProps;
|
|
42
16
|
const color = props.isDisabled ? 'text-disabled' : 'text';
|
|
43
17
|
const iconSize = size ?? 'medium';
|
|
44
|
-
const iconType = isSearchable ? 'Searchable' : 'Chevron';
|
|
45
18
|
const {
|
|
46
19
|
...iconProps
|
|
47
|
-
} = indicatorIcons[`${iconSize}
|
|
20
|
+
} = indicatorIcons[`${iconSize}Chevron`];
|
|
48
21
|
const {
|
|
49
22
|
icon: IndicatorIcon
|
|
50
23
|
} = iconProps;
|
|
@@ -55,66 +28,4 @@ export const DropdownButton = props => {
|
|
|
55
28
|
color: color
|
|
56
29
|
})
|
|
57
30
|
});
|
|
58
|
-
};
|
|
59
|
-
const CustomStyledRemoveAllDiv = /*#__PURE__*/_styled('div', {
|
|
60
|
-
target: "e1xkmr70",
|
|
61
|
-
label: "CustomStyledRemoveAllDiv"
|
|
62
|
-
})(css({
|
|
63
|
-
'&:focus': {
|
|
64
|
-
outline: `2px solid ${theme.colors.primary}`
|
|
65
|
-
},
|
|
66
|
-
'&:focus-visible': {
|
|
67
|
-
outline: `2px solid ${theme.colors.primary}`
|
|
68
|
-
}
|
|
69
|
-
}), process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9Gb3JtL1NlbGVjdERyb3Bkb3duL2VsZW1lbnRzL2NvbnRyb2xzLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFxRGlDIiwiZmlsZSI6Ii4uLy4uLy4uLy4uL3NyYy9Gb3JtL1NlbGVjdERyb3Bkb3duL2VsZW1lbnRzL2NvbnRyb2xzLnRzeCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNzcywgdGhlbWUgfSBmcm9tICdAY29kZWNhZGVteS9nYW11dC1zdHlsZXMnO1xuaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnO1xuaW1wb3J0IHsgS2V5Ym9hcmRFdmVudCwgdXNlQ29udGV4dCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7XG4gIEFyaWFPbkZvY3VzLFxuICBjb21wb25lbnRzIGFzIFNlbGVjdERyb3Bkb3duRWxlbWVudHMsXG59IGZyb20gJ3JlYWN0LXNlbGVjdCc7XG5cbmltcG9ydCB7IEV4dGVuZGVkT3B0aW9uLCBTaXplZEluZGljYXRvclByb3BzIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgaW5kaWNhdG9ySWNvbnMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBTZWxlY3REcm9wZG93bkNvbnRleHQgfSBmcm9tICcuL2NvbnRhaW5lcnMnO1xuXG5jb25zdCB7IERyb3Bkb3duSW5kaWNhdG9yIH0gPSBTZWxlY3REcm9wZG93bkVsZW1lbnRzO1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhY2Nlc3NpYmxlIGZvY3VzIG1lc3NhZ2VzIGZvciBzY3JlZW4gcmVhZGVycy5cbiAqIFByb3ZpZGVzIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50bHkgZm9jdXNlZCBvcHRpb24uXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIE9iamVjdCBjb250YWluaW5nIHRoZSBmb2N1c2VkIG9wdGlvbiBkZXRhaWxzXG4gKiBAcmV0dXJucyBGb3JtYXR0ZWQgYWNjZXNzaWJpbGl0eSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBjb25zdCBvbkZvY3VzOiBBcmlhT25Gb2N1czxFeHRlbmRlZE9wdGlvbj4gPSAoe1xuICBmb2N1c2VkOiB7IGxhYmVsLCBzdWJ0aXRsZSwgcmlnaHRMYWJlbCwgZGlzYWJsZWQgfSxcbn0pID0+IHtcbiAgY29uc3QgZm9ybWF0dGVkU3VidGl0bGUgPSBgLCAke3N1YnRpdGxlfWA7XG4gIGNvbnN0IGZvcm1hdHRlZFJpZ2h0TGFiZWwgPSBgLCAke3JpZ2h0TGFiZWx9YDtcblxuICBjb25zdCBtc2cgPSBgWW91IGFyZSBjdXJyZW50bHkgZm9jdXNlZCBvbiBvcHRpb24gJHtsYWJlbH0ke1xuICAgIHN1YnRpdGxlID8gZm9ybWF0dGVkU3VidGl0bGUgOiAnJ1xuICB9ICR7cmlnaHRMYWJlbCA/IGZvcm1hdHRlZFJpZ2h0TGFiZWwgOiAnJ30ke2Rpc2FibGVkID8gJywgZGlzYWJsZWQnIDogJyd9YDtcblxuICByZXR1cm4gbXNnO1xufTtcblxuLyoqXG4gKiBDdXN0b20gZHJvcGRvd24gaW5kaWNhdG9yIHRoYXQgc2hvd3MgZWl0aGVyIGEgY2hldnJvbiBvciBzZWFyY2ggaWNvbi5cbiAqIFRoZSBpY29uIHR5cGUgZGVwZW5kcyBvbiB3aGV0aGVyIHRoZSBzZWxlY3QgaXMgc2VhcmNoYWJsZSBvciBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBEcm9wZG93bkJ1dHRvbiA9IChwcm9wczogU2l6ZWRJbmRpY2F0b3JQcm9wcykgPT4ge1xuICBjb25zdCB7IHNpemUsIGlzU2VhcmNoYWJsZSB9ID0gcHJvcHMuc2VsZWN0UHJvcHM7XG4gIGNvbnN0IGNvbG9yID0gcHJvcHMuaXNEaXNhYmxlZCA/ICd0ZXh0LWRpc2FibGVkJyA6ICd0ZXh0JztcbiAgY29uc3QgaWNvblNpemUgPSBzaXplID8/ICdtZWRpdW0nO1xuICBjb25zdCBpY29uVHlwZSA9IGlzU2VhcmNoYWJsZSA/ICdTZWFyY2hhYmxlJyA6ICdDaGV2cm9uJztcbiAgY29uc3QgeyAuLi5pY29uUHJvcHMgfSA9IGluZGljYXRvckljb25zW2Ake2ljb25TaXplfSR7aWNvblR5cGV9YF07XG4gIGNvbnN0IHsgaWNvbjogSW5kaWNhdG9ySWNvbiB9ID0gaWNvblByb3BzO1xuXG4gIHJldHVybiAoXG4gICAgPERyb3Bkb3duSW5kaWNhdG9yIHsuLi5wcm9wc30+XG4gICAgICA8SW5kaWNhdG9ySWNvbiB7Li4uaWNvblByb3BzfSBjb2xvcj17Y29sb3J9IC8+XG4gICAgPC9Ecm9wZG93bkluZGljYXRvcj5cbiAgKTtcbn07XG5cbmNvbnN0IEN1c3RvbVN0eWxlZFJlbW92ZUFsbERpdiA9IHN0eWxlZCgnZGl2JykoXG4gIGNzcyh7XG4gICAgJyY6Zm9jdXMnOiB7XG4gICAgICBvdXRsaW5lOiBgMnB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgICB9LFxuICAgICcmOmZvY3VzLXZpc2libGUnOiB7XG4gICAgICBvdXRsaW5lOiBgMnB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgICB9LFxuICB9KVxuKTtcblxuLyoqXG4gKiBDdXN0b20gcmVtb3ZlIGFsbCBidXR0b24gZm9yIG11bHRpLXNlbGVjdCBtb2RlLlxuICogUHJvdmlkZXMga2V5Ym9hcmQgbmF2aWdhdGlvbiBhbmQgYWNjZXNzaWJsZSByZW1vdmFsIG9mIGFsbCBzZWxlY3RlZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBSZW1vdmVBbGxCdXR0b24gPSAocHJvcHM6IFNpemVkSW5kaWNhdG9yUHJvcHMpID0+IHtcbiAgY29uc3Qge1xuICAgIGdldFN0eWxlcyxcbiAgICBpbm5lclByb3BzOiB7IC4uLnJlc3RJbm5lclByb3BzIH0sXG4gICAgc2VsZWN0UHJvcHM6IHsgc2l6ZSB9LFxuICB9ID0gcHJvcHM7XG5cbiAgY29uc3QgeyByZW1vdmVBbGxCdXR0b25SZWYsIHNlbGVjdElucHV0UmVmIH0gPSB1c2VDb250ZXh0KFxuICAgIFNlbGVjdERyb3Bkb3duQ29udGV4dFxuICApO1xuXG4gIGNvbnN0IGljb25TaXplID0gc2l6ZSA/PyAnbWVkaXVtJztcbiAgY29uc3QgeyAuLi5pY29uUHJvcHMgfSA9IGluZGljYXRvckljb25zW2Ake2ljb25TaXplfVJlbW92ZWBdO1xuICBjb25zdCB7IGljb246IEluZGljYXRvckljb24gfSA9IGljb25Qcm9wcztcblxuICBjb25zdCBvbktleVByZXNzID0gKGU6IEtleWJvYXJkRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgaWYgKGUua2V5ID09PSAnRW50ZXInICYmIHJlc3RJbm5lclByb3BzLm9uTW91c2VEb3duKSB7XG4gICAgICByZXN0SW5uZXJQcm9wcy5vbk1vdXNlRG93bihlIGFzIGFueSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgc2VsZWN0SW5wdXRSZWY/LmN1cnJlbnQgJiZcbiAgICAgIChlLmtleSA9PT0gJ0Fycm93UmlnaHQnIHx8IGUua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBlLmtleSA9PT0gJ0Fycm93RG93bicpXG4gICAgKSB7XG4gICAgICBzZWxlY3RJbnB1dFJlZj8uY3VycmVudC5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzdHlsZSA9IGdldFN0eWxlcygnY2xlYXJJbmRpY2F0b3InLCBwcm9wcykgYXMgUmVhY3QuQ1NTUHJvcGVydGllcztcblxuICByZXR1cm4gKFxuICAgIDxDdXN0b21TdHlsZWRSZW1vdmVBbGxEaXZcbiAgICAgIGFyaWEtbGFiZWw9XCJSZW1vdmUgYWxsIHNlbGVjdGVkXCJcbiAgICAgIHJvbGU9XCJidXR0b25cIlxuICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICB7Li4ucmVzdElubmVyUHJvcHN9XG4gICAgICByZWY9e3JlbW92ZUFsbEJ1dHRvblJlZn1cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnYW11dC9uby1pbmxpbmUtc3R5bGVcbiAgICAgIHN0eWxlPXtzdHlsZX1cbiAgICAgIG9uS2V5RG93bj17b25LZXlQcmVzc31cbiAgICA+XG4gICAgICA8SW5kaWNhdG9ySWNvbiB7Li4uaWNvblByb3BzfSBjb2xvcj1cInRleHRcIiAvPlxuICAgIDwvQ3VzdG9tU3R5bGVkUmVtb3ZlQWxsRGl2PlxuICApO1xufTtcbiJdfQ== */");
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Custom remove all button for multi-select mode.
|
|
73
|
-
* Provides keyboard navigation and accessible removal of all selected values.
|
|
74
|
-
*/
|
|
75
|
-
export const RemoveAllButton = props => {
|
|
76
|
-
const {
|
|
77
|
-
getStyles,
|
|
78
|
-
innerProps: {
|
|
79
|
-
...restInnerProps
|
|
80
|
-
},
|
|
81
|
-
selectProps: {
|
|
82
|
-
size
|
|
83
|
-
}
|
|
84
|
-
} = props;
|
|
85
|
-
const {
|
|
86
|
-
removeAllButtonRef,
|
|
87
|
-
selectInputRef
|
|
88
|
-
} = useContext(SelectDropdownContext);
|
|
89
|
-
const iconSize = size ?? 'medium';
|
|
90
|
-
const {
|
|
91
|
-
...iconProps
|
|
92
|
-
} = indicatorIcons[`${iconSize}Remove`];
|
|
93
|
-
const {
|
|
94
|
-
icon: IndicatorIcon
|
|
95
|
-
} = iconProps;
|
|
96
|
-
const onKeyPress = e => {
|
|
97
|
-
if (e.key === 'Enter' && restInnerProps.onMouseDown) {
|
|
98
|
-
restInnerProps.onMouseDown(e);
|
|
99
|
-
}
|
|
100
|
-
if (selectInputRef?.current && (e.key === 'ArrowRight' || e.key === 'ArrowLeft' || e.key === 'ArrowDown')) {
|
|
101
|
-
selectInputRef?.current.focus();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
const style = getStyles('clearIndicator', props);
|
|
105
|
-
return /*#__PURE__*/_jsx(CustomStyledRemoveAllDiv, {
|
|
106
|
-
"aria-label": "Remove all selected",
|
|
107
|
-
role: "button",
|
|
108
|
-
tabIndex: 0,
|
|
109
|
-
...restInnerProps,
|
|
110
|
-
ref: removeAllButtonRef
|
|
111
|
-
// eslint-disable-next-line gamut/no-inline-style
|
|
112
|
-
,
|
|
113
|
-
style: style,
|
|
114
|
-
onKeyDown: onKeyPress,
|
|
115
|
-
children: /*#__PURE__*/_jsx(IndicatorIcon, {
|
|
116
|
-
...iconProps,
|
|
117
|
-
color: "text"
|
|
118
|
-
})
|
|
119
|
-
});
|
|
120
31
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { iconSize, selectedIconSize, indicatorIcons } from './constants';
|
|
2
2
|
export { MultiValueWithColorMode, MultiValueRemoveButton, RemoveAllButton, } from './multi-value';
|
|
3
|
-
export { DropdownButton
|
|
3
|
+
export { DropdownButton } from './controls';
|
|
4
|
+
export { onFocus } from '../core/accessibility';
|
|
4
5
|
export { SelectDropdownContext, CustomContainer, CustomInput, CustomValueContainer, TypedReactSelect, } from './containers';
|
|
5
6
|
export { IconOption, AbbreviatedSingleValue, formatOptionLabel, formatGroupLabel, } from './options';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { iconSize, selectedIconSize, indicatorIcons } from './constants';
|
|
2
2
|
export { MultiValueWithColorMode, MultiValueRemoveButton, RemoveAllButton } from './multi-value';
|
|
3
|
-
export { DropdownButton
|
|
3
|
+
export { DropdownButton } from './controls';
|
|
4
|
+
export { onFocus } from '../core/accessibility';
|
|
4
5
|
export { SelectDropdownContext, CustomContainer, CustomInput, CustomValueContainer, TypedReactSelect } from './containers';
|
|
5
6
|
export { IconOption, AbbreviatedSingleValue, formatOptionLabel, formatGroupLabel } from './options';
|
|
@@ -3,6 +3,7 @@ import { CustomSelectComponentProps, ExtendedOption, SelectDropdownGroup } from
|
|
|
3
3
|
/**
|
|
4
4
|
* Custom option component that displays a check icon for selected items.
|
|
5
5
|
* Also manages ARIA attributes for accessibility.
|
|
6
|
+
* Skips the check icon for react-select/creatable's "Add" row (__isNew__).
|
|
6
7
|
*/
|
|
7
8
|
export declare const IconOption: ({ children, ...rest }: CustomSelectComponentProps<typeof SelectDropdownElements.Option>) => import("react/jsx-runtime").JSX.Element;
|
|
8
9
|
/**
|
|
@@ -44,6 +44,7 @@ const IconOptionLabel = ({
|
|
|
44
44
|
/**
|
|
45
45
|
* Custom option component that displays a check icon for selected items.
|
|
46
46
|
* Also manages ARIA attributes for accessibility.
|
|
47
|
+
* Skips the check icon for react-select/creatable's "Add" row (__isNew__).
|
|
47
48
|
*/
|
|
48
49
|
export const IconOption = ({
|
|
49
50
|
children,
|
|
@@ -54,15 +55,17 @@ export const IconOption = ({
|
|
|
54
55
|
} = rest.selectProps;
|
|
55
56
|
const {
|
|
56
57
|
isFocused,
|
|
57
|
-
innerProps
|
|
58
|
+
innerProps,
|
|
59
|
+
data
|
|
58
60
|
} = rest;
|
|
61
|
+
const isNew = data?.__isNew__;
|
|
59
62
|
return /*#__PURE__*/_jsxs(SelectDropdownElements.Option, {
|
|
60
63
|
...rest,
|
|
61
64
|
innerProps: {
|
|
62
65
|
...innerProps,
|
|
63
66
|
'aria-selected': isFocused
|
|
64
67
|
},
|
|
65
|
-
children: [children, rest?.isSelected && /*#__PURE__*/_jsx(CheckIcon, {
|
|
68
|
+
children: [children, !isNew && rest?.isSelected && /*#__PURE__*/_jsx(CheckIcon, {
|
|
66
69
|
size: selectedIconSize[size ?? 'medium']
|
|
67
70
|
})]
|
|
68
71
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { KeyboardEvent } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { ActionMeta, Options as OptionsType } from 'react-select';
|
|
4
|
+
import { SelectOptionBase } from '../../utils';
|
|
5
|
+
import { MultiSelectDropdownProps, OptionStrict, SelectDropdownGroup, SelectDropdownProps, SingleSelectDropdownProps } from '../types';
|
|
6
|
+
interface UseSelectHandlersArgs {
|
|
7
|
+
onChange?: SingleSelectDropdownProps['onChange'] | MultiSelectDropdownProps['onChange'];
|
|
8
|
+
multiple?: boolean;
|
|
9
|
+
onCreateOption?: (inputValue: string) => void;
|
|
10
|
+
selectOptions: SelectOptionBase[] | SelectDropdownGroup[];
|
|
11
|
+
value?: SelectDropdownProps['value'];
|
|
12
|
+
currentFocusedValue: unknown;
|
|
13
|
+
removeAllButtonRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
14
|
+
}
|
|
15
|
+
interface UseSelectHandlersReturn {
|
|
16
|
+
activated: boolean;
|
|
17
|
+
multiValues: OptionStrict[] | false;
|
|
18
|
+
changeHandler: (optionEvent: OptionStrict | OptionsType<OptionStrict>, actionMeta: ActionMeta<OptionStrict>) => void;
|
|
19
|
+
keyPressHandler: (e: KeyboardEvent<HTMLDivElement>) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare const useSelectHandlers: ({ onChange, multiple, onCreateOption, selectOptions, value, currentFocusedValue, removeAllButtonRef, }: UseSelectHandlersArgs) => UseSelectHandlersReturn;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { ON_CHANGE_ACTION } from '../core/constants';
|
|
3
|
+
import { filterValueFromOptions, getCreatedOptionValue, isMultipleSelectProps, isOptionsGrouped, isSingleSelectProps, removeValueFromSelectedOptions } from '../core/utils';
|
|
4
|
+
export const useSelectHandlers = ({
|
|
5
|
+
onChange,
|
|
6
|
+
multiple,
|
|
7
|
+
onCreateOption,
|
|
8
|
+
selectOptions,
|
|
9
|
+
value,
|
|
10
|
+
currentFocusedValue,
|
|
11
|
+
removeAllButtonRef
|
|
12
|
+
}) => {
|
|
13
|
+
const [activated, setActivated] = useState(false);
|
|
14
|
+
const [multiValues, setMultiValues] = useState(multiple ? filterValueFromOptions(selectOptions, value, isOptionsGrouped(selectOptions)) : false);
|
|
15
|
+
|
|
16
|
+
// Sync multi-select value from props when controlled (`value` is a string[]).
|
|
17
|
+
// Uncontrolled multi (`value` undefined or '') keeps selection in local state.
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!multiple || !Array.isArray(value)) return;
|
|
20
|
+
const newMultiValues = filterValueFromOptions(selectOptions, value, isOptionsGrouped(selectOptions));
|
|
21
|
+
if (newMultiValues !== multiValues) setMultiValues(newMultiValues);
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, [selectOptions, value, multiple]);
|
|
25
|
+
const changeHandler = useCallback((optionEvent, actionMeta) => {
|
|
26
|
+
setActivated(true);
|
|
27
|
+
if (actionMeta.action === 'create-option') {
|
|
28
|
+
const createdValue = getCreatedOptionValue(optionEvent, actionMeta, multiple);
|
|
29
|
+
if (createdValue) onCreateOption?.(createdValue);
|
|
30
|
+
}
|
|
31
|
+
const onChangeProps = {
|
|
32
|
+
onChange,
|
|
33
|
+
multiple
|
|
34
|
+
};
|
|
35
|
+
const forwardedMeta = actionMeta.action === 'create-option' ? actionMeta : {
|
|
36
|
+
action: ON_CHANGE_ACTION,
|
|
37
|
+
option: isMultipleSelectProps(onChangeProps) ? undefined : optionEvent
|
|
38
|
+
};
|
|
39
|
+
if (isSingleSelectProps(onChangeProps)) {
|
|
40
|
+
onChangeProps.onChange?.(optionEvent, forwardedMeta);
|
|
41
|
+
}
|
|
42
|
+
if (isMultipleSelectProps(onChangeProps)) {
|
|
43
|
+
setMultiValues(optionEvent);
|
|
44
|
+
onChangeProps.onChange?.(optionEvent, forwardedMeta);
|
|
45
|
+
}
|
|
46
|
+
}, [onChange, multiple, onCreateOption]);
|
|
47
|
+
const keyPressHandler = e => {
|
|
48
|
+
if (multiple && e.key === 'Enter' && currentFocusedValue && multiValues) {
|
|
49
|
+
const newMultiValues = removeValueFromSelectedOptions(multiValues, currentFocusedValue);
|
|
50
|
+
if (newMultiValues !== multiValues) setMultiValues(newMultiValues);
|
|
51
|
+
}
|
|
52
|
+
if (removeAllButtonRef.current !== null && e.key === 'ArrowRight' && multiValues && currentFocusedValue === multiValues[multiValues.length - 1].value) {
|
|
53
|
+
removeAllButtonRef.current.focus();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
activated,
|
|
58
|
+
multiValues,
|
|
59
|
+
changeHandler,
|
|
60
|
+
keyPressHandler
|
|
61
|
+
};
|
|
62
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SelectOptionBase } from '../../utils';
|
|
2
|
+
import { SelectDropdownGroup, SelectDropdownOptions, SelectDropdownSizes } from '../types';
|
|
3
|
+
interface UseSelectOptionsArgs {
|
|
4
|
+
options?: SelectDropdownOptions | SelectDropdownGroup[];
|
|
5
|
+
id?: string;
|
|
6
|
+
size?: SelectDropdownSizes['size'];
|
|
7
|
+
value?: string | string[];
|
|
8
|
+
}
|
|
9
|
+
interface UseSelectOptionsReturn {
|
|
10
|
+
selectOptions: SelectOptionBase[] | SelectDropdownGroup[];
|
|
11
|
+
parsedValue: SelectOptionBase | undefined;
|
|
12
|
+
}
|
|
13
|
+
export declare const useSelectOptions: ({ options, id, size, value, }: UseSelectOptionsArgs) => UseSelectOptionsReturn;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { parseOptions } from '../../utils';
|
|
3
|
+
import { isOptionsGrouped } from '../core/utils';
|
|
4
|
+
export const useSelectOptions = ({
|
|
5
|
+
options,
|
|
6
|
+
id,
|
|
7
|
+
size,
|
|
8
|
+
value
|
|
9
|
+
}) => {
|
|
10
|
+
const selectOptions = useMemo(() => {
|
|
11
|
+
if (!options || Array.isArray(options) && !options.length || typeof options === 'object' && !Array.isArray(options) && Object.keys(options).length === 0) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
if (isOptionsGrouped(options)) {
|
|
15
|
+
return options;
|
|
16
|
+
}
|
|
17
|
+
return parseOptions({
|
|
18
|
+
options,
|
|
19
|
+
id,
|
|
20
|
+
size
|
|
21
|
+
});
|
|
22
|
+
}, [options, id, size]);
|
|
23
|
+
const parsedValue = useMemo(() => {
|
|
24
|
+
if (isOptionsGrouped(selectOptions)) {
|
|
25
|
+
for (const group of selectOptions) {
|
|
26
|
+
if (group.options) {
|
|
27
|
+
const foundOption = group.options.find(option => option.value === value);
|
|
28
|
+
if (foundOption) return foundOption;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return selectOptions.find(option => option.value === value);
|
|
34
|
+
}, [selectOptions, value]);
|
|
35
|
+
return {
|
|
36
|
+
selectOptions,
|
|
37
|
+
parsedValue
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Ref, SelectHTMLAttributes } from 'react';
|
|
2
|
-
import { Props as NamedProps } from 'react-select';
|
|
2
|
+
import { Options as OptionsType, Props as NamedProps } from 'react-select';
|
|
3
3
|
import { SelectComponentProps } from '../../inputs/Select';
|
|
4
4
|
import { OptionStrict, SelectDropdownGroup, SelectDropdownOptions } from './options';
|
|
5
5
|
import { ReactSelectAdditionalProps, SelectDropdownSizes, SharedProps } from './styles';
|
|
@@ -28,7 +28,7 @@ export type SelectDropdownBaseProps = Omit<SelectComponentProps, 'onChange' | 'd
|
|
|
28
28
|
* Core props interface that defines the essential properties for SelectDropdown.
|
|
29
29
|
* This interface combines base props with react-select props and HTML select attributes.
|
|
30
30
|
*/
|
|
31
|
-
export interface SelectDropdownCoreProps extends SelectDropdownBaseProps, Omit<NamedProps<OptionStrict, boolean>, 'formatOptionLabel' | 'isDisabled' | 'value' | 'options' | 'components' | 'styles' | 'theme' | 'onChange' | 'multiple'>, Pick<SelectHTMLAttributes<HTMLSelectElement>, 'value' | 'disabled' | 'onClick'>, SharedProps {
|
|
31
|
+
export interface SelectDropdownCoreProps extends SelectDropdownBaseProps, Omit<NamedProps<OptionStrict, boolean>, 'formatOptionLabel' | 'isDisabled' | 'value' | 'options' | 'components' | 'styles' | 'theme' | 'onChange' | 'multiple' | 'isSearchable'>, Pick<SelectHTMLAttributes<HTMLSelectElement>, 'value' | 'disabled' | 'onClick'>, SharedProps {
|
|
32
32
|
/** Required name attribute for the select input */
|
|
33
33
|
name: string;
|
|
34
34
|
/** Placeholder text shown when no option is selected.
|
|
@@ -38,6 +38,39 @@ export interface SelectDropdownCoreProps extends SelectDropdownBaseProps, Omit<N
|
|
|
38
38
|
placeholder?: string;
|
|
39
39
|
/** Array of options or option groups to display in the dropdown */
|
|
40
40
|
options?: SelectDropdownOptions | SelectDropdownGroup[];
|
|
41
|
+
/**
|
|
42
|
+
* Allows users to create new options by typing a value not in the options list.
|
|
43
|
+
* When true, isSearchable is automatically set to true.
|
|
44
|
+
* Pair with onCreateOption to persist new options.
|
|
45
|
+
*/
|
|
46
|
+
isCreatable?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Called when the user confirms a new option via the "Add" row.
|
|
49
|
+
* Convenience callback for persisting the new value to your `options` list.
|
|
50
|
+
* Selection updates are delivered through `onChange` with `action: 'create-option'`.
|
|
51
|
+
*/
|
|
52
|
+
onCreateOption?: (inputValue: string) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Customises the label shown in the "Add" row.
|
|
55
|
+
* Defaults to: (inputValue) => `Add "${inputValue}"`.
|
|
56
|
+
*/
|
|
57
|
+
formatCreateLabel?: (inputValue: string) => React.ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Controls when the "Add" row is visible.
|
|
60
|
+
* Receives the current input, selected values, and all options.
|
|
61
|
+
* Defaults to react-select's built-in logic (hidden when input matches an existing option label).
|
|
62
|
+
* Use cases: minimum-length gating, pattern validation, case-insensitive dedup, max-items cap.
|
|
63
|
+
*/
|
|
64
|
+
isValidNewOption?: (inputValue: string, value: OptionsType<OptionStrict>, options: OptionsType<OptionStrict>) => boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Customizes the message shown inside the dropdown menu when no option matches
|
|
67
|
+
* the current input (react-select's "No options" state). Useful for surfacing
|
|
68
|
+
* validation/error text directly in the dropdown. Accepts a node, or a function
|
|
69
|
+
* receiving the current input value.
|
|
70
|
+
*/
|
|
71
|
+
validationMessage?: React.ReactNode | ((obj: {
|
|
72
|
+
inputValue: string;
|
|
73
|
+
}) => React.ReactNode);
|
|
41
74
|
}
|
|
42
75
|
/**
|
|
43
76
|
* Props for single-select mode.
|
|
@@ -59,11 +92,23 @@ export interface MultiSelectDropdownProps extends SelectDropdownCoreProps {
|
|
|
59
92
|
/** Callback fired when the selected values change */
|
|
60
93
|
onChange?: NamedProps<OptionStrict, true>['onChange'];
|
|
61
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Enforces that isSearchable cannot be false when isCreatable is true.
|
|
97
|
+
* Creatable mode requires the search input so users can type new option values.
|
|
98
|
+
*/
|
|
99
|
+
type CreatableConstraint = {
|
|
100
|
+
isCreatable?: false | undefined;
|
|
101
|
+
isSearchable?: boolean;
|
|
102
|
+
} | {
|
|
103
|
+
isCreatable: true;
|
|
104
|
+
isSearchable?: true;
|
|
105
|
+
};
|
|
62
106
|
/**
|
|
63
107
|
* Union type for all SelectDropdown prop variants.
|
|
64
|
-
* Supports both single and multi-select modes through discriminated union
|
|
108
|
+
* Supports both single and multi-select modes through discriminated union,
|
|
109
|
+
* intersected with CreatableConstraint to enforce isSearchable compatibility.
|
|
65
110
|
*/
|
|
66
|
-
export type SelectDropdownProps = SingleSelectDropdownProps | MultiSelectDropdownProps;
|
|
111
|
+
export type SelectDropdownProps = (SingleSelectDropdownProps | MultiSelectDropdownProps) & CreatableConstraint;
|
|
67
112
|
/**
|
|
68
113
|
* Base interface for onChange-related props.
|
|
69
114
|
* Used internally for type checking and prop validation.
|
|
@@ -76,9 +121,12 @@ export interface BaseOnChangeProps {
|
|
|
76
121
|
}
|
|
77
122
|
/**
|
|
78
123
|
* Props for the typed React Select component wrapper.
|
|
79
|
-
* Extends ReactSelectAdditionalProps with an optional ref.
|
|
124
|
+
* Extends ReactSelectAdditionalProps with an optional ref and creatable flag.
|
|
80
125
|
*/
|
|
81
|
-
export interface TypedReactSelectProps extends ReactSelectAdditionalProps {
|
|
126
|
+
export interface TypedReactSelectProps extends ReactSelectAdditionalProps, Pick<SelectDropdownCoreProps, 'formatCreateLabel' | 'isValidNewOption'> {
|
|
82
127
|
/** Optional ref to the underlying react-select component */
|
|
83
128
|
selectRef?: Ref<any>;
|
|
129
|
+
/** When true, renders CreatableSelect instead of ReactSelect */
|
|
130
|
+
isCreatable?: boolean;
|
|
84
131
|
}
|
|
132
|
+
export {};
|
|
@@ -14,7 +14,7 @@ export type InternalSelectProps = {
|
|
|
14
14
|
* Ref type for programmatic focus management.
|
|
15
15
|
* Used for managing focus on select input and remove all button.
|
|
16
16
|
*/
|
|
17
|
-
export type
|
|
17
|
+
export type ProgrammaticFocusRef = React.MutableRefObject<HTMLDivElement> | React.MutableRefObject<null>;
|
|
18
18
|
/**
|
|
19
19
|
* Context value for SelectDropdown internal state management.
|
|
20
20
|
* Provides access to focus state and refs for keyboard navigation.
|
|
@@ -25,9 +25,9 @@ export interface SelectDropdownContextValueTypes {
|
|
|
25
25
|
/** Function to update the currently focused value */
|
|
26
26
|
setCurrentFocusedValue?: React.Dispatch<React.SetStateAction<unknown>>;
|
|
27
27
|
/** Ref to the select input for programmatic focus */
|
|
28
|
-
selectInputRef?:
|
|
28
|
+
selectInputRef?: ProgrammaticFocusRef;
|
|
29
29
|
/** Ref to the remove all button for programmatic focus */
|
|
30
|
-
removeAllButtonRef?:
|
|
30
|
+
removeAllButtonRef?: ProgrammaticFocusRef;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* Props for sized indicator components (dropdown arrow, search icon, etc.).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StyleProps } from '@codecademy/variance';
|
|
2
|
-
import { conditionalBorderStates } from '../styles';
|
|
2
|
+
import { conditionalBorderStates } from '../core/styles';
|
|
3
3
|
import { InternalInputsProps } from './component-props';
|
|
4
4
|
/**
|
|
5
5
|
* Size variants for the SelectDropdown component.
|
|
@@ -69,5 +69,9 @@ export type ControlState = BaseSelectComponentProps & InteractionStates & {
|
|
|
69
69
|
export type OptionState = BaseSelectComponentProps & InteractionStates & {
|
|
70
70
|
/** Whether the option is selected */
|
|
71
71
|
isSelected: boolean;
|
|
72
|
+
/** Option data — includes __isNew__ for react-select/creatable's "Add" row */
|
|
73
|
+
data?: {
|
|
74
|
+
__isNew__?: boolean;
|
|
75
|
+
};
|
|
72
76
|
};
|
|
73
77
|
export {};
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { WithChildrenProp } from '../../utils';
|
|
2
|
-
import {
|
|
3
|
-
export type ToolTipProps =
|
|
2
|
+
import { TipBaseProps, TipCenterAlignment } from '../shared/types';
|
|
3
|
+
export type ToolTipProps = TipBaseProps & WithChildrenProp & {
|
|
4
4
|
alignment?: TipCenterAlignment;
|
|
5
|
-
/**
|
|
6
|
-
* If true, the tooltip closes immediately when the trigger is clicked or activated via keyboard.
|
|
7
|
-
* Pass `false` via `tipProps` on IconButton to opt out (e.g. copy → copied patterns).
|
|
8
|
-
*/
|
|
9
|
-
closeOnClick?: boolean;
|
|
10
5
|
/**
|
|
11
6
|
* Can be used for accessibility - the same id needs to be passed to the `aria-describedby` attribute of the element that the tooltip is describing.
|
|
12
7
|
*/
|
|
@@ -11,7 +11,6 @@ export const FloatingTip = ({
|
|
|
11
11
|
alignment,
|
|
12
12
|
avatar,
|
|
13
13
|
children,
|
|
14
|
-
closeOnClick,
|
|
15
14
|
escapeKeyPressHandler,
|
|
16
15
|
inheritDims,
|
|
17
16
|
info,
|
|
@@ -102,19 +101,6 @@ export const FloatingTip = ({
|
|
|
102
101
|
const isHoverType = type === 'tool' || type === 'preview';
|
|
103
102
|
const isPreviewType = type === 'preview';
|
|
104
103
|
const toolOnlyEventFunc = isHoverType ? e => handleShowHideAction(e) : undefined;
|
|
105
|
-
const handleClick = useCallback(() => {
|
|
106
|
-
if (hoverDelayRef.current) {
|
|
107
|
-
clearTimeout(hoverDelayRef.current);
|
|
108
|
-
hoverDelayRef.current = undefined;
|
|
109
|
-
}
|
|
110
|
-
if (focusDelayRef.current) {
|
|
111
|
-
clearTimeout(focusDelayRef.current);
|
|
112
|
-
focusDelayRef.current = undefined;
|
|
113
|
-
}
|
|
114
|
-
setIsOpen(false);
|
|
115
|
-
setIsFocused(false);
|
|
116
|
-
}, []);
|
|
117
|
-
const clickHandler = closeOnClick && isHoverType ? handleClick : undefined;
|
|
118
104
|
const contents = isPreviewType ? /*#__PURE__*/_jsx(PreviewTipContents, {
|
|
119
105
|
avatar: avatar,
|
|
120
106
|
info: info,
|
|
@@ -136,7 +122,6 @@ export const FloatingTip = ({
|
|
|
136
122
|
ref: ref,
|
|
137
123
|
width: inheritDims ? 'inherit' : undefined,
|
|
138
124
|
onBlur: toolOnlyEventFunc,
|
|
139
|
-
onClick: clickHandler,
|
|
140
125
|
onFocus: toolOnlyEventFunc,
|
|
141
126
|
onKeyDown: escapeKeyPressHandler,
|
|
142
127
|
onMouseDown: e => e.preventDefault(),
|