Skip to content

Commit d2739bc

Browse files
authored
Merge pull request #970 from data-driven-forms/common-typings
Common typings
2 parents 716faa0 + c9e0fad commit d2739bc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1348
-649
lines changed

.eslintrc.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"parser": "babel-eslint",
2+
"parser": "@babel/eslint-parser",
33
"parserOptions": {
44
"ecmaVersion": 6,
55
"sourceType": "module",
@@ -22,7 +22,7 @@
2222
"arguments": true
2323
},
2424
"plugins": ["prettier"],
25-
"extends": ["react-app", "eslint:recommended", "plugin:react/recommended", "plugin:prettier/recommended", "prettier/react"],
25+
"extends": ["react-app", "eslint:recommended", "plugin:react/recommended"],
2626
"env": {
2727
"es6": true,
2828
"browser": true,

babel.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const camelToSnake = (string) => {
77
};
88

99
module.exports = {
10-
presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
10+
presets: ["@babel/preset-env", "@babel/preset-react", ["@babel/preset-typescript", {allowNamespaces: true}]],
1111
plugins: [
1212
"@babel/plugin-transform-runtime",
1313
"@babel/plugin-syntax-dynamic-import",

package.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"release": "semantic-release",
1717
"codecov": "codecov",
1818
"start-demo": "lerna run start --scope=@data-driven-forms/react-render-demo",
19-
"lint": "yarn eslint ./packages/*/src",
19+
"lint": "yarn eslint ./packages/*/src --ext .js",
2020
"lint:ts": "tslint -c ./tslint.json 'packages/**/*.d.ts'",
2121
"generate-template": "node ./scripts/generate-mapper.js",
2222
"clean-build": "node ./scripts/clean-build.js",
@@ -52,8 +52,9 @@
5252
"globalSetup": "<rootDir>/config/globalSetup.js"
5353
},
5454
"devDependencies": {
55-
"@babel/plugin-transform-runtime": "^7.9.0",
56-
"@babel/preset-typescript": "^7.9.0",
55+
"@babel/eslint-parser": "^7.13.8",
56+
"@babel/plugin-transform-runtime": "^7.13.9",
57+
"@babel/preset-typescript": "^7.13.0",
5758
"@khala/commit-analyzer-wildcard": "^2.4.1",
5859
"@khala/npm-release-monorepo": "^2.4.1",
5960
"@khala/wildcard-release-notes": "^2.4.1",
@@ -67,17 +68,16 @@
6768
"atob-lite": "^2.0.0",
6869
"babel-plugin-transform-imports": "^2.0.0",
6970
"dtslint": "^3.6.4",
70-
"eslint": "^6.8.0",
71-
"eslint-config-i-am-meticulous": "^12.0.0",
72-
"eslint-config-prettier": "^6.10.0",
73-
"eslint-config-react-app": "^5.2.0",
74-
"eslint-loader": "^3.0.3",
75-
"eslint-plugin-flowtype": "^4.6.0",
76-
"eslint-plugin-import": "^2.20.1",
77-
"eslint-plugin-jsx-a11y": "^6.2.3",
78-
"eslint-plugin-prettier": "^3.1.2",
79-
"eslint-plugin-react": "^7.18.3",
80-
"eslint-plugin-react-hooks": "^2.4.0",
71+
"eslint": "^7.21.0",
72+
"eslint-config-prettier": "^8.1.0",
73+
"eslint-config-react-app": "^6.0.0",
74+
"eslint-loader": "^4.0.2",
75+
"eslint-plugin-flowtype": "^5.3.1",
76+
"eslint-plugin-import": "^2.22.1",
77+
"eslint-plugin-jsx-a11y": "^6.4.1",
78+
"eslint-plugin-prettier": "^3.3.1",
79+
"eslint-plugin-react": "^7.22.0",
80+
"eslint-plugin-react-hooks": "^4.2.0",
8181
"fs-extra": "^9.0.1",
8282
"glob": "^7.1.6",
8383
"identity-obj-proxy": "^3.0.0",

packages/common/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
"main": "index.js",
77
"module": "esm/index.js",
88
"scripts": {
9-
"build": "yarn build:cjs && yarn build:esm",
9+
"build": "yarn build:cjs && yarn build:esm && yarn build:typings && yarn build:packages",
1010
"build:cjs": "BABEL_ENV=cjs babel src --out-dir ./",
11-
"build:esm": "BABEL_ENV=esm babel src --out-dir ./esm"
11+
"build:esm": "BABEL_ENV=esm babel src --out-dir ./esm",
12+
"build:typings": "node ../../scripts/generate-typings.js",
13+
"build:packages": "node ../../scripts/generate-packages.js"
1214
},
1315
"repository": "[email protected]:data-driven-forms/react-forms.git",
1416
"devDependencies": {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Schema } from "@data-driven-forms/react-form-renderer";
2+
3+
declare const demoschema: Schema;
4+
5+
export default demoschema;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './demoschema';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './demoschema';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { AnyObject, Input } from "@data-driven-forms/react-form-renderer";
2+
3+
export type DualListSelectCommonProps<
4+
FieldValue,
5+
SelectProps = {}
6+
> = {
7+
DualListSelect: React.ComponentType;
8+
options: {
9+
[key: string]: any;
10+
label: React.ReactNode,
11+
value: any
12+
}[];
13+
input: Input<FieldValue>;
14+
} & SelectProps & AnyObject;
15+
16+
declare const DualListSelectCommon: React.ComponentType<DualListSelectCommonProps<any, {}>>;
17+
18+
export default DualListSelectCommon;
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useReducer } from 'react';
2+
import PropTypes from 'prop-types';
3+
import isEqual from 'lodash/isEqual';
4+
5+
import { useFieldApi } from '@data-driven-forms/react-form-renderer';
6+
7+
import reducer, { initialState } from './reducer';
8+
9+
const getOptionsGroup = (value, lastClicked, options) => {
10+
const lastIndex = options.map(({ value }) => value.toString()).indexOf(lastClicked.toString());
11+
const currentIndex = options.map(({ value }) => value.toString()).indexOf(value);
12+
const startIndex = Math.min(lastIndex, currentIndex);
13+
const endIndex = Math.max(lastIndex, currentIndex) + 1;
14+
return [...options.slice(startIndex, endIndex).map(({ value }) => value.toString())];
15+
};
16+
17+
const handleOptionClick = (event, value, options, isRight, dispatch, state) => {
18+
const selectedKey = isRight ? 'selectedLeftValues' : 'selectedRightValues';
19+
const lastKey = isRight ? 'lastLeftClicked' : 'lastRightClicked';
20+
if (event.shiftKey && state[lastKey]) {
21+
dispatch({ type: 'setSelectedValue', value, values: getOptionsGroup(value, state[lastKey], options), isRight });
22+
} else if (event.ctrlKey && state[lastKey]) {
23+
const selectedValues = state[selectedKey].includes(value) ? state[selectedKey].filter((item) => item !== value) : [...state[selectedKey], value];
24+
25+
dispatch({ type: 'setSelectedValue', value, values: selectedValues, isRight });
26+
} else {
27+
dispatch({ type: 'setSelectedValue', value, values: [value], isRight });
28+
}
29+
};
30+
31+
const DualListSelectCommon = (props) => {
32+
const [state, dispatch] = useReducer(reducer, initialState);
33+
34+
const { DualListSelect, ...rest } = useFieldApi({
35+
...props,
36+
isEqual: (current, initial) => isEqual([...(current || [])].sort(), [...(initial || [])].sort())
37+
});
38+
39+
const leftValues = rest.options
40+
.filter((option) => !rest.input.value.includes(option.value) && option.label.includes(state.filterOptions))
41+
.sort((a, b) => (state.sortLeftDesc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label)));
42+
const rightValues = rest.options
43+
.filter((option) => rest.input.value.includes(option.value) && option.label.includes(state.filterValue))
44+
.sort((a, b) => (state.sortRightDesc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label)));
45+
46+
const handleOptionsClick = (event, value) => handleOptionClick(event, value, leftValues, true, dispatch, state);
47+
48+
const handleValuesClick = (event, value) => handleOptionClick(event, value, rightValues, false, dispatch, state);
49+
50+
const handleMoveRight = () => {
51+
rest.input.onChange([...rest.input.value, ...state.selectedLeftValues]);
52+
dispatch({ type: 'clearLeftOptions' });
53+
};
54+
55+
const handleMoveLeft = () => {
56+
rest.input.onChange(rest.input.value.filter((value) => !state.selectedRightValues.includes(value)));
57+
dispatch({ type: 'clearRightValues' });
58+
};
59+
60+
const sortOptions = () => dispatch({ type: 'sortOptions' });
61+
62+
const sortValues = () => dispatch({ type: 'sortValue' });
63+
64+
const filterOptions = (value) => dispatch({ type: 'setFilterOptions', value });
65+
66+
const filterValues = (value) => dispatch({ type: 'setFilterValue', value });
67+
68+
const handleClearLeftValues = () => {
69+
dispatch({ type: 'clearLeftValues' });
70+
rest.input.onChange([...rest.input.value, ...leftValues.map(({ value }) => value)]);
71+
};
72+
73+
const handleClearRightValues = () => {
74+
dispatch({ type: 'clearRightValue' });
75+
rest.input.onChange([...rest.input.value.filter((val) => !rightValues.find(({ value }) => val === value))]);
76+
};
77+
78+
return (
79+
<DualListSelect
80+
{...rest}
81+
leftValues={leftValues}
82+
rightValues={rightValues}
83+
handleOptionsClick={handleOptionsClick}
84+
handleValuesClick={handleValuesClick}
85+
handleMoveRight={handleMoveRight}
86+
handleMoveLeft={handleMoveLeft}
87+
sortOptions={sortOptions}
88+
sortValues={sortValues}
89+
filterOptions={filterOptions}
90+
filterValues={filterValues}
91+
handleClearLeftValues={handleClearLeftValues}
92+
handleClearRightValues={handleClearRightValues}
93+
state={state}
94+
/>
95+
);
96+
};
97+
98+
DualListSelectCommon.propTypes = {
99+
DualListSelect: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
100+
};
101+
102+
export default DualListSelectCommon;

0 commit comments

Comments
 (0)