@intility/bifrost-react-select 5.0.2 → 5.2.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,23 @@
1
1
  # @intility/bifrost-react-select
2
2
 
3
+ ## 5.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a161a0c: `<Select>` menu dropdown now uses bifrost `<Dropdown>` internally
8
+ - should fix layering issues (overlapping and/or scrollbars) when used inside
9
+ `<Modal>`, `<Nav.Group>`, and `<Dropdown>`
10
+
11
+ ## 5.1.0
12
+
13
+ ### Minor Changes
14
+
15
+ - c7e5540: Bump `react-select` dependency to `5.10.1`
16
+
17
+ ### Patch Changes
18
+
19
+ - 30fd9d3: Fix: Avoid wrapping `<Select isMulti>` with a single long-worded option selected. #178
20
+
3
21
  ## 5.0.2
4
22
 
5
23
  ### Patch Changes
@@ -44,7 +62,6 @@
44
62
  ### Minor Changes
45
63
 
46
64
  - 2703b98: Add support for `small` variants for most form field inputs, to match existing `small` button styling.
47
-
48
65
  - `<Input>`
49
66
  - `<DatePicker>`
50
67
  - `<FieldGroup.Item>`
@@ -73,7 +90,6 @@
73
90
  ### Patch Changes
74
91
 
75
92
  - 3434ad1: Update Select styling to match new bifrost Button
76
-
77
93
  - Increased `border-radius` (from xs to s)
78
94
  - Slight `border-color` tweaks
79
95
 
package/dist/Select.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { CSSProperties, ReactNode, RefAttributes } from "react";
2
1
  import { GroupBase, Props as ReactSelectProps, SelectInstance, components as originalComponents } from "react-select";
3
2
  import { AsyncProps as AsyncSelectProps } from "react-select/async";
4
3
  import { CreatableProps as CreatableSelectProps } from "react-select/creatable";
@@ -13,7 +12,6 @@ export declare const selectStyles: {
13
12
  clearIndicator: (provided: any) => any;
14
13
  dropdownIndicator: (provided: any, state: any) => any;
15
14
  input: (provided: any) => any;
16
- menuPortal: (provided: any) => any;
17
15
  menu: (provided: any) => any;
18
16
  menuList: (provided: any) => any;
19
17
  placeholder: (provided: any) => any;
@@ -30,15 +28,15 @@ export declare const selectComponents: typeof originalComponents;
30
28
  export type SelectState = "default" | "alert";
31
29
  export type SelectProps = {
32
30
  /** Required label text */
33
- label: ReactNode;
31
+ label: React.ReactNode;
34
32
  /** Hide label text, will add label prop as aria-label for screen readers */
35
33
  hideLabel?: boolean;
36
34
  /** Description text to show more information */
37
- description?: ReactNode;
35
+ description?: React.ReactNode;
38
36
  /** Available states: `default` and `alert` */
39
37
  state?: SelectState;
40
38
  /** Feedback text below the Select component */
41
- feedback?: ReactNode;
39
+ feedback?: React.ReactNode;
42
40
  /** Required prop indicating mandatory field */
43
41
  required?: boolean;
44
42
  /** Bool to mark Select component required, but hides the required label */
@@ -46,7 +44,7 @@ export type SelectProps = {
46
44
  /** Marks Select component as optional */
47
45
  optional?: boolean;
48
46
  /** Inline CSS styles */
49
- style?: CSSProperties;
47
+ style?: React.CSSProperties;
50
48
  /** Displays a loading spinner */
51
49
  loading?: boolean;
52
50
  /** Decrease height of the input from `40px` to `32px` */
@@ -56,7 +54,7 @@ export type SelectType = {
56
54
  <OptionType = {
57
55
  label: string;
58
56
  value: string;
59
- }, IsMulti extends boolean = false, Group extends GroupBase<OptionType> = GroupBase<OptionType>>(props: ReactSelectProps<OptionType, IsMulti, Group> & RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
57
+ }, IsMulti extends boolean = false, Group extends GroupBase<OptionType> = GroupBase<OptionType>>(props: ReactSelectProps<OptionType, IsMulti, Group> & React.RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
60
58
  displayName?: string;
61
59
  };
62
60
  /**
@@ -70,7 +68,7 @@ export type AsyncType = {
70
68
  }, IsMulti extends boolean = false, Group extends GroupBase<OptionType> = {
71
69
  options: OptionType[];
72
70
  label?: string;
73
- }>(props: AsyncSelectProps<OptionType, IsMulti, Group> & RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
71
+ }>(props: AsyncSelectProps<OptionType, IsMulti, Group> & React.RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
74
72
  displayName?: string;
75
73
  };
76
74
  declare const AsyncSelect: AsyncType;
@@ -81,7 +79,7 @@ export type CreatableType = {
81
79
  }, IsMulti extends boolean = false, Group extends GroupBase<OptionType> = {
82
80
  options: OptionType[];
83
81
  label?: string;
84
- }>(props: CreatableSelectProps<OptionType, IsMulti, Group> & RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
82
+ }>(props: CreatableSelectProps<OptionType, IsMulti, Group> & React.RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
85
83
  displayName?: string;
86
84
  };
87
85
  declare const CreatableSelect: CreatableType;
@@ -92,7 +90,7 @@ export type AsyncCreatableType = {
92
90
  }, IsMulti extends boolean = false, Group extends GroupBase<OptionType> = {
93
91
  options: OptionType[];
94
92
  label?: string;
95
- }>(props: AsyncCreatableSelectProps<OptionType, IsMulti, Group> & RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
93
+ }>(props: AsyncCreatableSelectProps<OptionType, IsMulti, Group> & React.RefAttributes<SelectInstance<OptionType, IsMulti, Group>> & SelectProps): React.ReactElement | null;
96
94
  displayName?: string;
97
95
  };
98
96
  declare const AsyncCreatableSelect: AsyncCreatableType;
package/dist/Select.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/ban-ts-comment */ "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { forwardRef } from "react";
3
+ import { forwardRef, useState } from "react";
4
4
  import ReactSelectDefaultExport, { components as originalComponents } from "react-select";
5
5
  import AsyncReactSelect from "react-select/async";
6
6
  import CreatableReactSelect from "react-select/creatable";
@@ -17,6 +17,7 @@ import CustomMenuList from "./overrides/CustomMenuList.internal.js";
17
17
  import ClearIndicator from "./overrides/ClearIndicator.internal.js";
18
18
  import CustomOption from "./overrides/CustomOption.internal.js";
19
19
  import LoadingIndicator from "./overrides/LoadingIndicator.internal.js";
20
+ import Menu, { SelectRefCtx } from "./overrides/Menu.internal.js";
20
21
  const ReactSelect = ReactSelectDefaultExport.default ?? ReactSelectDefaultExport;
21
22
  export const selectStyles = {
22
23
  container: (provided)=>({
@@ -55,7 +56,7 @@ export const selectStyles = {
55
56
  borderBottomRightRadius: "var(--bf-radius-s)"
56
57
  },
57
58
  backgroundColor: state.isDisabled ? "var(--bfc-base-dimmed)" : "var(--bfc-base-3)",
58
- borderWidth: "1px",
59
+ borderWidth: 1,
59
60
  borderStyle: "solid",
60
61
  borderColor: state.isFocused ? "var(--bfc-base-c-inverted)" : state.isDisabled ? "transparent" : "var(--bfc-base-c-wcag)",
61
62
  boxShadow: state.isFocused ? "inset 0 0 0 1px var(--bfc-base-c-inverted)" : "none",
@@ -81,7 +82,7 @@ export const selectStyles = {
81
82
  },
82
83
  color: "var(--bfc-base-c-2)",
83
84
  cursor: "pointer",
84
- padding: "var(--bfs4)",
85
+ padding: 4,
85
86
  margin: "1px 4px 0px 0px"
86
87
  }),
87
88
  dropdownIndicator: (provided, state)=>({
@@ -91,28 +92,24 @@ export const selectStyles = {
91
92
  },
92
93
  color: state.isFocused ? "var(--bfc-base-c)" : "var(--bfc-base-c-2)",
93
94
  cursor: "pointer",
94
- padding: "var(--bfs4)",
95
+ padding: 4,
95
96
  marginRight: 8
96
97
  }),
97
98
  input: (provided)=>({
98
99
  ...provided,
99
- ".bf-select-small &": {
100
- marginBlock: 0
101
- },
102
100
  color: "var(--bfc-base-c)",
103
101
  fontFamily: "inherit",
104
- fontSize: "var(--bf-font-size-l)"
105
- }),
106
- menuPortal: (provided)=>({
107
- ...provided,
108
- zIndex: 9999
102
+ fontSize: "var(--bf-font-size-l)",
103
+ margin: 0,
104
+ padding: 0
109
105
  }),
110
106
  menu: (provided)=>({
111
107
  ...provided,
108
+ position: "static",
109
+ margin: 0,
112
110
  backgroundColor: "transparent",
113
111
  boxShadow: "none",
114
- borderRadius: "none",
115
- zIndex: 3
112
+ borderRadius: "none"
116
113
  }),
117
114
  menuList: (provided)=>({
118
115
  ...provided,
@@ -148,7 +145,7 @@ export const selectStyles = {
148
145
  color: state.isDisabled ? "var(--bfc-base-c-2)" : "var(--bfc-base-c)",
149
146
  "& .bf-select-selected-icon": {
150
147
  color: "var(--bfc-base-c)",
151
- marginLeft: "var(--bfs4)"
148
+ marginLeft: 4
152
149
  },
153
150
  "&:hover": {
154
151
  backgroundColor: state.isDisabled ? "var(--bfc-base-dimmed)" : "var(--bfc-base)",
@@ -164,7 +161,8 @@ export const selectStyles = {
164
161
  backgroundColor: "var(--bfc-base)",
165
162
  borderRadius: "var(--bf-radius-xs)",
166
163
  border: state.isDisabled ? "1px solid var(--bfc-base-c-disabled)" : "var(--bf-border)",
167
- opacity: state.isDisabled ? 0.5 : 1
164
+ opacity: state.isDisabled ? 0.5 : 1,
165
+ maxWidth: "calc(100% - 10px)"
168
166
  }),
169
167
  multiValueLabel: (provided)=>({
170
168
  ...provided,
@@ -177,7 +175,7 @@ export const selectStyles = {
177
175
  color: "var(--bfc-base-c-2)",
178
176
  paddingLeft: 5,
179
177
  paddingRight: 5,
180
- background: state.isFocused && "var(--bfc-theme-2)",
178
+ background: state.isFocused ? "var(--bfc-theme-2)" : undefined,
181
179
  "&:hover": {
182
180
  color: "var(--bfc-base-c)",
183
181
  cursor: "pointer",
@@ -187,14 +185,14 @@ export const selectStyles = {
187
185
  background: "var(--bfc-base-3)"
188
186
  },
189
187
  svg: {
190
- marginTop: "1px"
188
+ marginTop: 1
191
189
  }
192
190
  }),
193
191
  group: (provided)=>({
194
192
  ...provided,
195
- padding: "var(--bfs6) 0",
193
+ padding: "6px 0",
196
194
  "&:first-of-type": {
197
- marginTop: "var(--bfs4)"
195
+ marginTop: 4
198
196
  }
199
197
  }),
200
198
  groupHeading: (provided)=>({
@@ -202,7 +200,7 @@ export const selectStyles = {
202
200
  textTransform: "capitalize",
203
201
  color: "var(--bfc-base-c-2)",
204
202
  fontSize: "var(--bf-font-size-s)",
205
- marginBottom: "var(--bfs2)"
203
+ marginBottom: 2
206
204
  })
207
205
  };
208
206
  export const selectComponents = {
@@ -210,6 +208,8 @@ export const selectComponents = {
210
208
  DropdownIndicator,
211
209
  Input: CustomInput,
212
210
  MenuList: CustomMenuList,
211
+ // @ts-ignore
212
+ Menu,
213
213
  ClearIndicator,
214
214
  Option: CustomOption,
215
215
  LoadingIndicator
@@ -222,48 +222,59 @@ export const selectComponents = {
222
222
  const GeneratedSelect = /*#__PURE__*/ forwardRef(({ label, hideLabel = false, isDisabled = false, state, feedback, required = false, description, requiredNoLabel = false, optional = false, inputId, className, style, loading = false, components, small = false, ...props }, ref)=>{
223
223
  const selectId = useUniqueId(inputId);
224
224
  const locale = useLocale();
225
- return /*#__PURE__*/ _jsxs("div", {
226
- className: classNames(className, "bf-select-container", "bf-open-sans", {
227
- "bf-select-disabled": isDisabled,
228
- "bf-select-alert": !isDisabled && state === "alert",
229
- "bf-select-small": small
230
- }),
231
- style: style,
232
- "data-testid": "bf-select-container",
233
- children: [
234
- !hideLabel && /*#__PURE__*/ _jsx(Label, {
235
- htmlFor: selectId,
236
- required: !isDisabled && required && !requiredNoLabel,
237
- optional: optional,
238
- disabled: isDisabled,
239
- children: label
240
- }),
241
- /*#__PURE__*/ _jsx(Description, {
242
- children: description
243
- }),
244
- /*#__PURE__*/ _jsx(Selector, {
245
- ref: ref,
246
- inputId: selectId,
247
- placeholder: "",
248
- components: {
249
- ...selectComponents,
250
- ...components
251
- },
252
- styles: selectStyles,
253
- isDisabled: isDisabled,
254
- classNamePrefix: "bf-select",
255
- required: !isDisabled && (required || requiredNoLabel),
256
- "aria-label": label,
257
- hideSelectedOptions: false,
258
- closeMenuOnSelect: props.isMulti ? false : true,
259
- isLoading: loading ?? props.isLoading,
260
- loadingMessage: ()=>locale.loading + "...",
261
- ...props
225
+ const [controlElement, setControlElement] = useState(null);
226
+ return /*#__PURE__*/ _jsx(SelectRefCtx.Provider, {
227
+ value: controlElement,
228
+ children: /*#__PURE__*/ _jsxs("div", {
229
+ className: classNames(className, "bf-select-container", "bf-open-sans", {
230
+ "bf-select-disabled": isDisabled,
231
+ "bf-select-alert": !isDisabled && state === "alert",
232
+ "bf-select-small": small
262
233
  }),
263
- /*#__PURE__*/ _jsx(Feedback, {
264
- children: feedback
265
- })
266
- ]
234
+ style: style,
235
+ "data-testid": "bf-select-container",
236
+ children: [
237
+ !hideLabel && /*#__PURE__*/ _jsx(Label, {
238
+ htmlFor: selectId,
239
+ required: !isDisabled && required && !requiredNoLabel,
240
+ optional: optional,
241
+ disabled: isDisabled,
242
+ children: label
243
+ }),
244
+ /*#__PURE__*/ _jsx(Description, {
245
+ children: description
246
+ }),
247
+ /*#__PURE__*/ _jsx(Selector, {
248
+ ref: (r)=>{
249
+ setControlElement(r?.controlRef ?? null);
250
+ if (typeof ref === "function") {
251
+ ref(r);
252
+ } else if (ref != null) {
253
+ ref.current = r;
254
+ }
255
+ },
256
+ inputId: selectId,
257
+ placeholder: "",
258
+ components: {
259
+ ...selectComponents,
260
+ ...components
261
+ },
262
+ styles: selectStyles,
263
+ isDisabled: isDisabled,
264
+ classNamePrefix: "bf-select",
265
+ required: !isDisabled && (required || requiredNoLabel),
266
+ "aria-label": label,
267
+ hideSelectedOptions: false,
268
+ closeMenuOnSelect: props.isMulti ? false : true,
269
+ isLoading: loading ?? props.isLoading,
270
+ loadingMessage: ()=>locale.loading + "...",
271
+ ...props
272
+ }),
273
+ /*#__PURE__*/ _jsx(Feedback, {
274
+ children: feedback
275
+ })
276
+ ]
277
+ })
267
278
  });
268
279
  });
269
280
  return GeneratedSelect;
@@ -0,0 +1,3 @@
1
+ import { components } from "react-select";
2
+ export declare const SelectRefCtx: import("react").Context<HTMLDivElement | null>;
3
+ export default function Menu(props: React.ComponentProps<typeof components.Menu>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Dropdown } from "@intility/bifrost-react";
3
+ import useResizeObserver from "@intility/bifrost-react/hooks/useResizeObserver";
4
+ import { createContext, useContext, useRef } from "react";
5
+ import { components } from "react-select";
6
+ export const SelectRefCtx = /*#__PURE__*/ createContext(null);
7
+ export default function Menu(props) {
8
+ const { menuPlacement, menuPosition } = props;
9
+ const controlElement = useContext(SelectRefCtx);
10
+ // Keep width of dropdown in sync with select control
11
+ const divRef = useRef(null);
12
+ useResizeObserver(controlElement, (entry)=>{
13
+ if (!divRef.current) return;
14
+ divRef.current.style.width = entry.borderBoxSize[0].inlineSize + "px";
15
+ });
16
+ return /*#__PURE__*/ _jsx(Dropdown, {
17
+ unstyled: true,
18
+ noArrow: true,
19
+ visible: true,
20
+ reference: controlElement,
21
+ placement: menuPlacement === "auto" ? "bottom" : menuPlacement,
22
+ strategy: menuPosition,
23
+ offset: [
24
+ 0,
25
+ 4
26
+ ],
27
+ content: /*#__PURE__*/ _jsx("div", {
28
+ ref: divRef,
29
+ style: {
30
+ width: controlElement?.offsetWidth
31
+ },
32
+ children: /*#__PURE__*/ _jsx(components.Menu, {
33
+ ...props
34
+ })
35
+ })
36
+ });
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intility/bifrost-react-select",
3
- "version": "5.0.2",
3
+ "version": "5.2.0",
4
4
  "description": "React select component for Intility's design system, Bifrost.",
5
5
  "type": "module",
6
6
  "main": "dist/Select.js",
@@ -44,14 +44,14 @@
44
44
  "react-dom": ">=17.0.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@intility/bifrost-react": "^5.2.1"
47
+ "@intility/bifrost-react": "^5.7.0"
48
48
  },
49
49
  "dependencies": {
50
50
  "@fortawesome/fontawesome-svg-core": "^6.4.2",
51
51
  "@fortawesome/free-solid-svg-icons": "^6.4.2",
52
52
  "@fortawesome/react-fontawesome": "^0.2.0",
53
53
  "classnames": "^2.2.6",
54
- "react-select": "^5.7.7"
54
+ "react-select": "^5.10.1"
55
55
  },
56
56
  "files": [
57
57
  "CHANGELOG.md",