Skip to content

Commit

Permalink
feat(form)!: use native events for primitive components
Browse files Browse the repository at this point in the history
Removed the HoC withinput on all primitive input components:
- Checkbox
- Date
- Number
- Pass
- Radio
- Select
- Text
- TextArea

BREAKING CHANGE: these components now use `React.SyntheticEvent` in onchange prop parameter
  • Loading branch information
PIERMÉ Jean-Lou authored and MartinWeb committed Aug 9, 2024
1 parent b042ccc commit ce0c8ea
Show file tree
Hide file tree
Showing 37 changed files with 9,084 additions and 29,226 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ const config: Config.InitialOptions = {
'<rootDir>/__mocks__/fileMock.js',
'\\.(scss|css|less|md)$': '<rootDir>/__mocks__/styleMock.js',
},
snapshotSerializers: ['@emotion/jest/serializer'],
};
export default config;
36,670 changes: 8,161 additions & 28,509 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "@axa-fr/react-toolkit",
"version": "0.0.0",
"private": true,
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/AxaFrance/react-toolkit.git"
Expand All @@ -17,7 +18,7 @@
"build": "lerna run build && npm run style",
"postversion": "rimraf package-lock.json && npm i --force --ignore-scripts && git add package-lock.json && git commit --amend --no-edit",
"style": "node ./scripts/style.js",
"storybook": "start-storybook -p 9009 -s storybook-public",
"storybook": "set NODE_OPTIONS=--openssl-legacy-provider && start-storybook -p 9009 -s storybook-public",
"storybook:build": "build-storybook -s storybook-public -c .storybook -o storybook-static && node ./scripts/inject-version.js",
"test": "jest",
"cover": "jest --no-cache --config ./jest.config.ts --coverage",
Expand All @@ -41,6 +42,7 @@
"@babel/plugin-transform-runtime": "7.12.1",
"@babel/preset-env": "7.12.1",
"@babel/preset-react": "7.12.5",
"@emotion/jest": "11.10.5",
"@storybook/addon-a11y": "6.5.9",
"@storybook/addon-actions": "6.5.9",
"@storybook/addon-essentials": "6.5.9",
Expand Down Expand Up @@ -79,7 +81,7 @@
"markdown-loader": "6.0.0",
"npmlog": "4.1.2",
"package-lock-sanitizer": "1.0.1",
"postcss": "8.1.4",
"postcss": "8.4.21",
"prettier": "2.4.1",
"react": "17.0.2",
"react-dom": "17.0.2",
Expand Down
80 changes: 37 additions & 43 deletions packages/Form/Input/card/src/CardGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { ComponentProps } from 'react';
import { getComponentClassName } from '@axa-fr/react-toolkit-core';
import { withInput } from '@axa-fr/react-toolkit-form-core';
import { withIsVisible } from '@axa-fr/react-toolkit-form-core';
import CardGroupStateless from './CardGroupStateless';

type Props = ComponentProps<typeof CardGroupStateless>;
type Props = ComponentProps<typeof CardGroupStateless> &
OnChange & { id: string };
const CardGroup = ({
type,
title,
Expand All @@ -13,6 +14,8 @@ const CardGroup = ({
name = 'defaultName',
values,
value,
id,
onChange,
...otherProps
}: Props) => {
const componentClassName = getComponentClassName(
Expand All @@ -31,6 +34,35 @@ const CardGroup = ({
isActive ? 'af-rccard-group--active' : ''
}`;

const handleOnChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
if (type === 'checkbox') {
let newValues = [] as string[];
if (values) {
newValues = [...values];
}

const index = newValues.indexOf(e.target.value);
const checked = index <= -1;
if (checked) {
newValues.push(e.target.value);
} else {
newValues.splice(index, 1);
}
onChange &&
onChange({
values: newValues,
target: {
value: e.target.value,
checked,
},
name,
id,
});
} else {
onChange && onChange({ value: e.target.value, name, id });
}
};

return (
<CardGroupStateless
type={type}
Expand All @@ -39,7 +71,8 @@ const CardGroup = ({
values={values}
value={value}
className={cardGroupClassName}
{...otherProps}>
{...otherProps}
onChange={handleOnChange}>
{children}
</CardGroupStateless>
);
Expand All @@ -55,45 +88,6 @@ type OnChange = {
}) => void;
};

const handlers = {
onChange:
({
type,
values,
name,
id,
onChange,
}: Omit<Props, 'onChange'> & OnChange) =>
(e: any) => {
if (type === 'checkbox') {
let newValues = [] as string[];
if (values) {
newValues = [...values];
}

const index = newValues.indexOf(e.value);
const checked = index <= -1;
if (checked) {
newValues.push(e.value);
} else {
newValues.splice(index, 1);
}
onChange &&
onChange({
values: newValues,
target: {
value: e.value,
checked,
},
name,
id,
});
} else {
onChange && onChange({ value: e.value, name, id });
}
},
};

const EnhancedComponent = withInput(handlers)(CardGroup);
const EnhancedComponent = withIsVisible(CardGroup);

export default EnhancedComponent;
5 changes: 4 additions & 1 deletion packages/Form/Input/card/src/CardGroupStateless.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ const formatTitle = (titleParam: ReactNode) => {
);
};
type Card = typeof import('./Card').default;
type Props = Omit<ComponentProps<Card>, 'nbCards' | 'children' | 'title'> & {
type Props = Omit<
ComponentProps<Card>,
'nbCards' | 'children' | 'title' | 'id'
> & {
title?: ReactNode | string;
propClassName?: string;
values?: string[];
Expand Down
117 changes: 52 additions & 65 deletions packages/Form/Input/checkbox/src/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,71 @@
import React, { ComponentProps, ReactNode } from 'react';
import { Option, withInput } from '@axa-fr/react-toolkit-form-core';
import { Option, withIsVisible } from '@axa-fr/react-toolkit-form-core';
import CheckBoxModes from './CheckboxModes';
import CheckboxItem from './CheckboxItem';

type OnChange = {
onChange: (data: {
values: string[];
target: { value: string; checked: boolean };
name: string;
id: string;
}) => void;
};

type Props = Omit<
ComponentProps<typeof CheckboxItem>,
'value' | 'label' | 'checked'
'value' | 'label' | 'checked' | 'onChange'
> & {
options: Option[];
values?: string[];
children?: ReactNode;
};
mode?: keyof typeof CheckBoxModes;
} & OnChange;

const Checkbox = ({
id,
name,
options,
disabled,
children,
values,
mode = CheckBoxModes.default,
onChange,
...otherProps
}: Props) => (
<>
{options.map((option) => {
const isChecked = values ? values.indexOf(option.value) >= 0 : false;
return (
<CheckboxItem
{...otherProps}
key={option.value}
id={option.id}
value={option.value}
label={option.label}
isChecked={isChecked}
disabled={option.disabled || disabled}>
{children}
</CheckboxItem>
);
})}
</>
);
}: Props) => {
const className = defaultClassName(mode);

const handleOnChange: React.ChangeEventHandler<HTMLInputElement> = ({
target: { value, checked },
}) => {
const newValues = checked
? [...values, value]
: values.filter((v) => v !== value);
onChange({ values: newValues, target: { value, checked }, id, name });
};
return (
<>
{options.map((option) => {
const isChecked = values ? values.indexOf(option.value) >= 0 : false;
return (
<CheckboxItem
{...otherProps}
onChange={handleOnChange}
key={option.value}
className={className}
id={option.id}
value={option.value}
label={option.label}
isChecked={isChecked}
name={name}
disabled={option.disabled || disabled}>
{children}
</CheckboxItem>
);
})}
</>
);
};

const defaultClassName = (mode: string) => {
switch (mode) {
Expand All @@ -49,48 +78,6 @@ const defaultClassName = (mode: string) => {
}
};

type OnChange = {
onChange: (data: {
values: string[];
target: { value: string; checked: boolean };
name: string;
id: string;
}) => void;
};

const handlersOverride = {
onChange:
({ onChange, name, values, id }: Omit<Props, 'onChange'> & OnChange) =>
(e: any) => {
let newValues: typeof values = [];
if (values) {
newValues = [...values];
}
const index = newValues.indexOf(e.value);
const checked = index <= -1;
if (checked) {
newValues.push(e.value);
} else {
newValues.splice(index, 1);
}
onChange &&
onChange({
values: newValues,
target: { value: e.value, checked },
name,
id,
});
},
};

const propsOverride = ({
mode = CheckBoxModes.default,
}: {
mode?: keyof typeof CheckBoxModes;
}) => ({
className: defaultClassName(mode),
});

Checkbox.displayName = 'EnhancedInputCheckbox';

export default withInput(handlersOverride, propsOverride)(Checkbox);
export default withIsVisible(Checkbox);
1 change: 0 additions & 1 deletion packages/Form/Input/checkbox/src/CheckboxInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const CheckboxInput = ({
classNameContainerInput={classNameContainerInput}>
<Checkbox
mode={mode}
isVisible={isVisible}
options={newOptions}
classModifier={classModifier}
{...checkboxProps}
Expand Down
37 changes: 13 additions & 24 deletions packages/Form/Input/checkbox/src/CheckboxItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, {
ReactNode,
} from 'react';
import { useId } from '@axa-fr/react-toolkit-core';
import { getOptionClassName, withInput } from '@axa-fr/react-toolkit-form-core';
import { getOptionClassName } from '@axa-fr/react-toolkit-form-core';

type Props = Omit<ComponentPropsWithoutRef<'input'>, 'type' | 'label'> & {
classModifier?: string;
Expand All @@ -16,20 +16,27 @@ type Props = Omit<ComponentPropsWithoutRef<'input'>, 'type' | 'label'> & {
};

const CheckboxItem = ({
disabled = true,
disabled,
value = '',
id,
children,
label,
isChecked,
optionClassName,
inputRef,
className: _className,
classModifier: _classModifier,
className,
classModifier,
...otherProps
}: Props) => {
const newLabel = children || label;
const newId = useId(id); // id is require on this component

const optionClassName = getOptionClassName(
className,
classModifier,
'af-form__checkbox',
disabled
);

return (
<div className={optionClassName}>
<input
Expand All @@ -52,22 +59,4 @@ const CheckboxItem = ({
);
};

type PropsOverride = {
className?: string;
classModifier?: string;
disabled?: boolean;
};
const propsOverrides = ({
className,
classModifier,
disabled,
}: PropsOverride) => ({
optionClassName: getOptionClassName(
className,
classModifier,
'af-form__checkbox',
disabled
),
});

export default withInput({}, propsOverrides)(CheckboxItem);
export default CheckboxItem;
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { render } from '@testing-library/react';
import CheckboxInput from '../CheckboxInput';

describe('<DateInput>', () => {
it('renders DateInput correctly', () => {
describe('<CheckboxInput>', () => {
it('renders CheckboxInput correctly', () => {
const { asFragment } = render(
<CheckboxInput
label="Image *"
Expand Down
Loading

0 comments on commit ce0c8ea

Please sign in to comment.