) => {
81 | setDay(Number(e.target.value));
82 | }, []);
83 |
84 | const field: { day: JSX.Element; month: JSX.Element; year: JSX.Element } = useMemo(() => {
85 | return {
86 | day: (
87 |
100 | ),
101 | month: (
102 |
115 | ),
116 | year: (
117 |
130 | ),
131 | };
132 | }, [
133 | day,
134 | dayOptions,
135 | dayRef,
136 | disabled,
137 | handleDayChange,
138 | handleMonthChange,
139 | handleYearChange,
140 | hideLabels,
141 | labels.dayLabel,
142 | labels.dayPlaceholder,
143 | labels.monthLabel,
144 | labels.monthPlaceholder,
145 | labels.yearLabel,
146 | labels.yearPlaceholder,
147 | month,
148 | monthOptions,
149 | monthRef,
150 | year,
151 | yearOptions,
152 | yearRef,
153 | ]);
154 |
155 | useEffect(() => {
156 | if (selectedDate !== undefined && selectedDate !== null) {
157 | setDay(Number(selectedDate.getDate()));
158 | setMonth(Number(selectedDate.getMonth() + 1));
159 | setYear(Number(selectedDate.getFullYear()));
160 | }
161 | }, [selectedDate]);
162 |
163 | useEffect(() => {
164 | if (year !== -1 && month !== -1 && day !== -1) {
165 | onDateChange(new Date(`${month}/${day}/${year}`));
166 | } else {
167 | onDateChange(null);
168 | }
169 | // eslint-disable-next-line react-hooks/exhaustive-deps
170 | }, [day, month, year]);
171 |
172 | return (
173 |
180 | {orderArray.map((key, i) => {
181 | return (
182 |
183 | {field[key as 'day' | 'month' | 'year']}
184 |
185 | );
186 | })}
187 |
188 | );
189 | };
190 |
191 | export { SelectDatepicker };
192 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [
3 | 'airbnb-typescript',
4 | 'plugin:@typescript-eslint/recommended',
5 | 'plugin:eslint-comments/recommended',
6 | 'plugin:jest/recommended',
7 | 'plugin:import/react-native',
8 | 'plugin:react/recommended',
9 | 'plugin:react-hooks/recommended',
10 | 'plugin:storybook/recommended',
11 | 'plugin:prettier/recommended',
12 | ],
13 | plugins: [
14 | 'progress',
15 | '@typescript-eslint',
16 | 'import',
17 | 'json',
18 | 'html',
19 | 'jsx-a11y',
20 | 'prettier',
21 | 'unused-imports',
22 | ],
23 | env: {
24 | es6: true,
25 | 'jest/globals': true,
26 | node: true,
27 | },
28 | root: true,
29 | parser: '@typescript-eslint/parser',
30 | parserOptions: {
31 | ecmaFeatures: {
32 | jsx: true,
33 | },
34 | ecmaVersion: 8,
35 | sourceType: 'module',
36 | extraFileExtensions: ['.html', '.md', '.json', '.svg', '.tag'],
37 | project: ['./tsconfig.json'],
38 | },
39 | settings: {
40 | react: {
41 | version: 'detect',
42 | },
43 | 'html/html-extensions': ['.html'],
44 | 'import/core-modules': ['enzyme'],
45 | 'import/ignore': ['node_modules'],
46 | 'import/resolver': {
47 | node: {
48 | extensions: ['.js', '.ts', '.tsx', '.mjs', '.d.ts'],
49 | paths: ['node_modules/', 'node_modules/@types/'],
50 | },
51 | },
52 | },
53 | overrides: [
54 | {
55 | files: ['**/*.tsx', '**/*.ts'],
56 | rules: {
57 | 'react/require-default-props': 'off',
58 | 'react/prop-types': 'off', // we should use types
59 | 'react/forbid-prop-types': 'off', // we should use types
60 | },
61 | },
62 | {
63 | files: ['**/*.d.ts'],
64 | rules: {
65 | 'vars-on-top': 'off',
66 | 'no-var': 'off', // this is how typescript works
67 | 'spaced-comment': 'off',
68 | },
69 | },
70 | {
71 | files: ['**/*.stories.tsx'],
72 | rules: {
73 | 'import/no-default-export': 'off',
74 | },
75 | },
76 | ],
77 |
78 | rules: {
79 | '@typescript-eslint/ban-ts-ignore': 'off',
80 | '@typescript-eslint/camelcase': 'off',
81 | '@typescript-eslint/explicit-function-return-type': 'off',
82 | '@typescript-eslint/explicit-member-accessibility': 'off',
83 | '@typescript-eslint/explicit-module-boundary-types': 'off',
84 | '@typescript-eslint/interface-name-prefix': 'off',
85 | '@typescript-eslint/no-empty-function': 'off',
86 | '@typescript-eslint/no-explicit-any': 'off',
87 | '@typescript-eslint/no-object-literal-type-assertion': 'off',
88 | '@typescript-eslint/no-unused-vars': 'off',
89 | '@typescript-eslint/no-use-before-define': 'off',
90 | '@typescript-eslint/no-var-requires': 'off',
91 | 'progress/activate': 1,
92 | 'class-methods-use-this': 'off',
93 | 'import/default': 'error',
94 | 'import/extensions': [
95 | 'error',
96 | 'never',
97 | {
98 | ignorePackages: true,
99 | json: 'always',
100 | md: 'always',
101 | svg: 'always',
102 | tag: 'always',
103 | },
104 | ],
105 | 'import/named': 'error',
106 | 'import/namespace': 'error',
107 | 'import/no-extraneous-dependencies': [
108 | 'error',
109 | {
110 | devDependencies: [
111 | 'examples/**',
112 | 'examples-native/**',
113 | '**/example/**',
114 | '*.js',
115 | '**/*.test.js',
116 | '**/*.stories.*',
117 | '**/scripts/*.js',
118 | '**/stories/**/*.js',
119 | '**/stories/**/*.*',
120 | '**/__tests__/**/*.js',
121 | '**/.storybook/**/*.*',
122 | ],
123 | peerDependencies: true,
124 | },
125 | ],
126 | 'import/no-unresolved': [
127 | 'error',
128 | {
129 | ignore: ['@storybook'],
130 | },
131 | ],
132 | 'import/prefer-default-export': 'off',
133 | 'json/*': ['error', 'allowComments'],
134 | 'jsx-a11y/accessible-emoji': 'off',
135 | 'jsx-a11y/anchor-is-valid': [
136 | 'error',
137 | {
138 | components: ['A', 'LinkTo', 'Link'],
139 | specialLink: ['overrideParams', 'kind', 'story', 'to'],
140 | },
141 | ],
142 | 'jsx-a11y/label-has-associated-control': [
143 | 'warn',
144 | {
145 | controlComponents: ['CustomInput'],
146 | depth: 3,
147 | labelAttributes: ['label'],
148 | labelComponents: ['CustomInputLabel'],
149 | },
150 | ],
151 | 'jsx-a11y/label-has-for': [
152 | 'error',
153 | {
154 | required: {
155 | some: ['nesting', 'id'],
156 | },
157 | },
158 | ],
159 | 'max-classes-per-file': 'off',
160 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
161 | 'no-restricted-imports': [
162 | 'error',
163 | {
164 | paths: [
165 | {
166 | name: 'lodash.isequal',
167 | message:
168 | 'Lodash modularized (and lodash < 4.17.11) have CVE vulnerabilities. Please use tree-shakeable imports like lodash/xxx instead',
169 | },
170 | {
171 | name: 'lodash.uniqueId',
172 | message:
173 | 'Lodash modularized (and lodash < 4.17.11) have CVE vulnerabilities. Please use tree-shakeable imports like lodash/xxx instead',
174 | },
175 | {
176 | name: 'lodash.mergewith',
177 | message:
178 | 'Lodash modularized (and lodash < 4.17.11) have CVE vulnerabilities. Please use tree-shakeable imports like lodash/xxx instead',
179 | },
180 | {
181 | name: 'lodash.pick',
182 | message:
183 | 'Lodash modularized (and lodash < 4.17.11) have CVE vulnerabilities. Please use tree-shakeable imports like lodash/xxx instead',
184 | },
185 | ],
186 | // catch-all for any lodash modularized.
187 | // The CVE is listed against the entire family for lodash < 4.17.11
188 | patterns: ['lodash.*'],
189 | },
190 | ],
191 | 'no-underscore-dangle': [
192 | 'error',
193 | {
194 | allow: [
195 | '__STORYBOOK_CLIENT_API__',
196 | '__STORYBOOK_ADDONS_CHANNEL__',
197 | '__STORYBOOK_STORY_STORE__',
198 | ],
199 | },
200 | ],
201 | 'react/jsx-filename-extension': [
202 | 'warn',
203 | {
204 | extensions: ['.js', '.jsx', '.tsx'],
205 | },
206 | ],
207 | 'react/jsx-fragments': 'off',
208 | 'react/jsx-no-bind': [
209 | 'error',
210 | {
211 | allowArrowFunctions: true,
212 | allowBind: true,
213 | allowFunctions: true,
214 | ignoreDOMComponents: true,
215 | ignoreRefs: true,
216 | },
217 | ],
218 | 'react/jsx-props-no-spreading': 'off',
219 | 'react/no-unescaped-entities': 'off',
220 | 'react/sort-comp': [
221 | 'error',
222 | {
223 | groups: {
224 | staticLifecycle: ['displayName', 'propTypes', 'defaultProps', 'getDerivedStateFromProps'],
225 | },
226 | order: [
227 | 'staticLifecycle',
228 | 'static-methods',
229 | 'instance-variables',
230 | 'lifecycle',
231 | '/^on.+$/',
232 | '/^(get|set)(?!(DerivedStateFromProps|SnapshotBeforeUpdate$)).+$/',
233 | 'instance-methods',
234 | 'instance-variables',
235 | 'everything-else',
236 | 'render',
237 | ],
238 | },
239 | ],
240 | 'react/state-in-constructor': 'off',
241 | 'react/static-property-placement': 'off',
242 | 'prettier/prettier': [
243 | 'error',
244 | {
245 | endOfLine: 'auto',
246 | },
247 | ],
248 | '@typescript-eslint/no-unused-vars': 'off',
249 | 'unused-imports/no-unused-imports': 'error',
250 | 'unused-imports/no-unused-vars': [
251 | 'warn',
252 | { vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
253 | ],
254 | 'import/no-default-export': 'error',
255 | 'react/react-in-jsx-scope': 'error',
256 | },
257 | };
258 |
--------------------------------------------------------------------------------