Skip to content

Commit 46ecbbf

Browse files
authored
Merge pull request #418 from mashmatrix/fix-key-handler
Fix public handlers behavior of components
2 parents e3198a3 + c0e9bd4 commit 46ecbbf

File tree

12 files changed

+80
-82
lines changed

12 files changed

+80
-82
lines changed

src/scripts/CheckboxGroup.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { FormElementProps } from './FormElement';
1111
import { FieldSetColumnContext } from './FieldSet';
1212
import { useEventCallback } from './hooks';
1313
import { createFC } from './common';
14+
import { Bivariant } from './typeUtils';
1415

1516
/**
1617
*
@@ -32,7 +33,7 @@ export type CheckboxGroupProps = {
3233
name?: string;
3334
cols?: number;
3435
elementRef?: Ref<HTMLFieldSetElement>;
35-
onValueChange?: (values: CheckboxValueType[]) => void;
36+
onValueChange?: Bivariant<(values: CheckboxValueType[]) => void>;
3637
} & FieldsetHTMLAttributes<HTMLFieldSetElement>;
3738

3839
/**

src/scripts/ComponentSettings.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const ComponentSettingsContext = createContext<
1919
/**
2020
*
2121
*/
22-
const ComponentSettings_: FC<ComponentSettingsProps> = (props) => {
22+
export const ComponentSettings: FC<ComponentSettingsProps> = (props) => {
2323
const {
2424
assetRoot,
2525
portalClassName,
@@ -35,5 +35,3 @@ const ComponentSettings_: FC<ComponentSettingsProps> = (props) => {
3535
</ComponentSettingsContext.Provider>
3636
);
3737
};
38-
39-
export const ComponentSettings = React.memo(ComponentSettings_);

src/scripts/DateInput.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import React, {
77
FC,
88
useRef,
99
useState,
10-
useEffect,
1110
useContext,
1211
} from 'react';
1312
import classnames from 'classnames';
@@ -184,6 +183,13 @@ export const DateInput = createFC<DateInputProps, { isFormElement: boolean }>(
184183

185184
const { getActiveElement } = useContext(ComponentSettingsContext);
186185

186+
const onChangeValue = useEventCallback((newValue: string | null) => {
187+
if (newValue !== value) {
188+
onValueChange?.(newValue, value);
189+
setValue(newValue);
190+
}
191+
});
192+
187193
const setValueFromInput = useEventCallback((inputValue: string) => {
188194
let newValue = value;
189195
if (!inputValue) {
@@ -196,7 +202,7 @@ export const DateInput = createFC<DateInputProps, { isFormElement: boolean }>(
196202
newValue = '';
197203
}
198204
}
199-
setValue(newValue);
205+
onChangeValue(newValue);
200206
setInputValue(null);
201207
});
202208

@@ -217,15 +223,9 @@ export const DateInput = createFC<DateInputProps, { isFormElement: boolean }>(
217223
}
218224
}
219225
setOpened(true);
220-
setValue(newValue);
226+
onChangeValue(newValue);
221227
});
222228

223-
const prevValueRef = useRef<typeof value>(value);
224-
useEffect(() => {
225-
onValueChange?.(value, prevValueRef.current);
226-
prevValueRef.current = value;
227-
}, [value, onValueChange]);
228-
229229
const onDateIconClick = useEventCallback(() => {
230230
inputElRef.current?.focus();
231231
setTimeout(() => {
@@ -281,7 +281,7 @@ export const DateInput = createFC<DateInputProps, { isFormElement: boolean }>(
281281

282282
const onDatepickerSelect = useEventCallback((dvalue: string) => {
283283
const value = moment(dvalue).format(valueFormat);
284-
setValue(value);
284+
onChangeValue(value);
285285
setInputValue(null);
286286
setTimeout(() => {
287287
setOpened(false);

src/scripts/DropdownButton.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import React, {
77
useContext,
88
useEffect,
99
Ref,
10+
EventHandler,
1011
} from 'react';
1112
import classnames from 'classnames';
1213
import { Button, ButtonProps } from './Button';
@@ -15,6 +16,7 @@ import { registerStyle, isElInChildren } from './util';
1516
import { ComponentSettingsContext } from './ComponentSettings';
1617
import { ButtonGroupContext } from './ButtonGroup';
1718
import { useControlledValue, useEventCallback, useMergeRefs } from './hooks';
19+
import { Bivariant } from './typeUtils';
1820

1921
export type DropdownMenuAlign = 'left' | 'right';
2022
export type DropdownMenuSize = 'small' | 'medium' | 'large';
@@ -77,9 +79,9 @@ export type DropdownButtonProps = {
7779
hoverPopup?: boolean;
7880
menuStyle?: CSSProperties;
7981
dropdownRef?: Ref<HTMLDivElement>;
80-
onClick?: (e: SyntheticEvent<HTMLButtonElement>) => void;
82+
onClick?: EventHandler<SyntheticEvent<HTMLButtonElement>>;
8183
onBlur?: () => void;
82-
onMenuSelect?: (eventKey: EventKey) => void;
84+
onMenuSelect?: Bivariant<(eventKey: EventKey) => void>;
8385
} & Omit<ButtonProps, 'onClick' | 'onBlur'>;
8486

8587
/**

src/scripts/DropdownMenu.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import classnames from 'classnames';
1515
import { Icon } from './Icon';
1616
import { AutoAlign, AutoAlignInjectedProps, AutoAlignProps } from './AutoAlign';
1717
import { useEventCallback, useMergeRefs } from './hooks';
18+
import { Bivariant } from './typeUtils';
1819

1920
/**
2021
*
@@ -55,7 +56,7 @@ export const MenuHeader = DropdownMenuHeader;
5556
*
5657
*/
5758
type DropdownMenuHandler = {
58-
onMenuSelect?: (eventKey: EventKey) => void;
59+
onMenuSelect?: Bivariant<(eventKey: EventKey) => void>;
5960
onMenuFocus?: (e: FocusEvent<HTMLElement>) => void;
6061
onMenuBlur?: (e: FocusEvent<HTMLElement>) => void;
6162
};
@@ -200,7 +201,7 @@ export type DropdownMenuProps = HTMLAttributes<HTMLElement> & {
200201
| 'auto';
201202
nubbinTop?: boolean; // for backward compatibility. use nubbin instead
202203
hoverPopup?: boolean;
203-
onMenuSelect?: (eventKey: EventKey) => void;
204+
onMenuSelect?: Bivariant<(eventKey: EventKey) => void>;
204205
onMenuClose?: () => void;
205206
elementRef?: Ref<HTMLDivElement>;
206207
};

src/scripts/Lookup.tsx

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import React, {
1010
useContext,
1111
useState,
1212
useEffect,
13+
EventHandler,
1314
} from 'react';
1415
import classnames from 'classnames';
1516
import { AutoAlign, AutoAlignInjectedProps, AutoAlignProps } from './AutoAlign';
@@ -30,11 +31,12 @@ import {
3031
useMergeRefs,
3132
} from './hooks';
3233
import { createFC } from './common';
34+
import { Bivariant } from './typeUtils';
3335

3436
/**
3537
*
3638
*/
37-
type Entry = {
39+
export type LookupEntry = {
3840
label: string;
3941
value: string;
4042
icon?: string;
@@ -43,9 +45,7 @@ type Entry = {
4345
meta?: string;
4446
};
4547

46-
export type LookupEntry = Entry;
47-
48-
export type LookupSelectionProps<LookupEntry extends Entry> = {
48+
export type LookupSelectionProps = {
4949
id?: string;
5050
selected?: LookupEntry;
5151
hidden?: boolean;
@@ -56,9 +56,7 @@ export type LookupSelectionProps<LookupEntry extends Entry> = {
5656
/**
5757
*
5858
*/
59-
export const LookupSelection = <LookupEntry extends Entry>(
60-
props: LookupSelectionProps<LookupEntry>
61-
) => {
59+
export const LookupSelection: FC<LookupSelectionProps> = (props) => {
6260
const { id, hidden, selected, lookupSelectionRef, onResetSelection } = props;
6361
const pillRef = useRef<HTMLElement | null>(null);
6462

@@ -130,7 +128,7 @@ export type LookupSearchProps = Omit<
130128
disabled?: boolean;
131129
onBlur?: () => void;
132130
onSearchTextChange?: (searchText: string) => void;
133-
onScopeMenuClick?: (e: SyntheticEvent<HTMLButtonElement>) => void;
131+
onScopeMenuClick?: EventHandler<SyntheticEvent<HTMLButtonElement>>;
134132
onScopeSelect?: (value: string) => void;
135133
onPressDown?: () => void;
136134
onSubmit?: () => void;
@@ -351,7 +349,7 @@ export const LookupSearch: FC<LookupSearchProps> = (props) => {
351349
/**
352350
*
353351
*/
354-
type LookupCandidateListProps<LookupEntry extends Entry> = {
352+
type LookupCandidateListProps = {
355353
data?: LookupEntry[];
356354
focus?: boolean;
357355
loading?: boolean;
@@ -370,9 +368,9 @@ function trueFilter() {
370368
/**
371369
*
372370
*/
373-
const LookupCandidateListInner = <LookupEntry extends Entry>(
374-
props: LookupCandidateListProps<LookupEntry> & AutoAlignInjectedProps
375-
) => {
371+
const LookupCandidateListInner: FC<
372+
LookupCandidateListProps & AutoAlignInjectedProps
373+
> = (props) => {
376374
const {
377375
data = [],
378376
loading,
@@ -528,13 +526,10 @@ const LookupCandidateListInner = <LookupEntry extends Entry>(
528526
/**
529527
*
530528
*/
531-
const LookupCandidateList = <LookupEntry extends Entry>({
532-
align,
533-
portalClassName,
534-
portalStyle,
535-
...props
536-
}: LookupCandidateListProps<LookupEntry> &
537-
Pick<AutoAlignProps, 'align' | 'portalClassName' | 'portalStyle'>) => (
529+
const LookupCandidateList: FC<
530+
LookupCandidateListProps &
531+
Pick<AutoAlignProps, 'align' | 'portalClassName' | 'portalStyle'>
532+
> = ({ align, portalClassName, portalStyle, ...props }) => (
538533
<AutoAlign
539534
triggerSelector='.slds-lookup'
540535
alignmentStyle='menu'
@@ -551,10 +546,7 @@ const LookupCandidateList = <LookupEntry extends Entry>({
551546
/**
552547
*
553548
*/
554-
export type LookupProps<
555-
LookupEntry extends Entry,
556-
SelectedEntry extends LookupEntry
557-
> = {
549+
export type LookupProps = {
558550
label?: string;
559551
disabled?: boolean;
560552
required?: boolean;
@@ -564,8 +556,8 @@ export type LookupProps<
564556
value?: string | null;
565557
defaultValue?: string | null;
566558

567-
selected?: SelectedEntry | null;
568-
defaultSelected?: SelectedEntry | null;
559+
selected?: LookupEntry | null;
560+
defaultSelected?: LookupEntry | null;
569561

570562
opened?: boolean;
571563
defaultOpened?: boolean;
@@ -575,11 +567,9 @@ export type LookupProps<
575567

576568
loading?: boolean;
577569
data?: LookupEntry[];
578-
lookupFilter?: (
579-
entry: LookupEntry,
580-
searchText?: string,
581-
targetScope?: string
582-
) => boolean;
570+
lookupFilter?: Bivariant<
571+
(entry: LookupEntry, searchText?: string, targetScope?: string) => boolean
572+
>;
583573
listHeader?: JSX.Element;
584574
listFooter?: JSX.Element;
585575
scopes?: LookupScope[];
@@ -593,12 +583,12 @@ export type LookupProps<
593583
selectionRef?: Ref<HTMLDivElement>;
594584

595585
onSearchTextChange?: (searchText: string) => void;
596-
onScopeMenuClick?: (e: SyntheticEvent<HTMLButtonElement>) => void;
586+
onScopeMenuClick?: EventHandler<SyntheticEvent<HTMLButtonElement>>;
597587
onScopeSelect?: (targetScope: string) => void;
598588
onLookupRequest?: (searchText: string) => void;
599589
onBlur?: () => void;
600590
onFocus?: () => void;
601-
onSelect?: (entry: LookupEntry | null) => void;
591+
onSelect?: Bivariant<(entry: LookupEntry | null) => void>;
602592
onValueChange?: (value: string | null, prevValue?: string | null) => void;
603593
onComplete?: (cancel?: boolean) => void;
604594
} & Omit<
@@ -609,10 +599,8 @@ export type LookupProps<
609599
/**
610600
*
611601
*/
612-
export const Lookup = createFC(
613-
<LookupEntry extends Entry, SelectedEntry extends LookupEntry>(
614-
props: LookupProps<LookupEntry, SelectedEntry>
615-
) => {
602+
export const Lookup = createFC<LookupProps, { isFormElement: boolean }>(
603+
(props) => {
616604
const {
617605
id: id_,
618606
value: value_,
@@ -685,7 +673,7 @@ export const Lookup = createFC(
685673
const dropdownRef = useMergeRefs([dropdownElRef, dropdownRef_]);
686674

687675
const onScopeMenuClick = useEventCallback(
688-
(e: SyntheticEvent<HTMLButtonElement>) => {
676+
(e: MouseEvent<HTMLButtonElement>) => {
689677
setOpened(false);
690678
onScopeMenuClick_?.(e);
691679
}

src/scripts/Notification.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { MouseEvent, HTMLAttributes } from 'react';
1+
import React, { MouseEvent, HTMLAttributes, EventHandler } from 'react';
22
import classnames from 'classnames';
33
import { Button } from './Button';
44
import { Icon, IconSize } from './Icon';
@@ -17,7 +17,7 @@ export type NotificationProps = {
1717
icon?: string;
1818
iconSize?: IconSize;
1919
alertTexture?: boolean;
20-
onClose?: (e: MouseEvent<HTMLButtonElement>) => void;
20+
onClose?: EventHandler<MouseEvent<HTMLButtonElement>>;
2121
} & HTMLAttributes<HTMLDivElement>;
2222

2323
export const Notification: React.FC<NotificationProps> = (props) => {

src/scripts/Picklist.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
useMergeRefs,
2626
} from './hooks';
2727
import { createFC } from './common';
28+
import { Bivariant } from './typeUtils';
2829

2930
/**
3031
*
@@ -63,11 +64,13 @@ export type PicklistProps<MultiSelect extends boolean | undefined> = {
6364
menuStyle?: CSSProperties;
6465
elementRef?: Ref<HTMLDivElement>;
6566
dropdownRef?: Ref<HTMLDivElement>;
66-
onValueChange?: (
67-
newValue: PicklistValueType<MultiSelect>,
68-
prevValue: PicklistValueType<MultiSelect>
69-
) => void;
70-
onSelect?: (value: PicklistValue) => void;
67+
onValueChange?: Bivariant<
68+
(
69+
newValue: PicklistValueType<MultiSelect>,
70+
prevValue: PicklistValueType<MultiSelect>
71+
) => void
72+
>;
73+
onSelect?: Bivariant<(value: PicklistValue) => void>;
7174
onKeyDown?: (e: React.KeyboardEvent) => void;
7275
onBlur?: () => void;
7376
onComplete?: () => void;
@@ -79,10 +82,10 @@ export type PicklistProps<MultiSelect extends boolean | undefined> = {
7982
/**
8083
*
8184
*/
82-
export const Picklist = createFC(
83-
<MultiSelect extends boolean | undefined>(
84-
props: PicklistProps<MultiSelect>
85-
) => {
85+
export const Picklist: (<MultiSelect extends boolean | undefined>(
86+
props: PicklistProps<MultiSelect>
87+
) => ReturnType<FC>) & { isFormElement: boolean } = createFC(
88+
(props) => {
8689
const {
8790
className,
8891
id: id_,
@@ -149,16 +152,15 @@ export const Picklist = createFC(
149152
const dropdownRef = useMergeRefs([dropdownElRef, dropdownRef_]);
150153

151154
const setPicklistValues = useEventCallback((newValues: PicklistValue[]) => {
152-
type PV = PicklistValueType<MultiSelect>;
153155
const prevValues = values;
154156
setValues(newValues);
155157
if (onValueChange && prevValues !== newValues) {
156158
if (multiSelect) {
157-
onValueChange(newValues as PV, prevValues as PV);
159+
onValueChange(newValues, prevValues);
158160
} else {
159161
onValueChange(
160-
(newValues.length > 0 ? newValues[0] : null) as PV,
161-
(prevValues.length > 0 ? prevValues[0] : null) as PV
162+
newValues.length > 0 ? newValues[0] : null,
163+
prevValues.length > 0 ? prevValues[0] : null
162164
);
163165
}
164166
}

0 commit comments

Comments
 (0)