diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index ed472b8..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules -/dist -/rollup diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f5dc757..0000000 --- a/.eslintrc +++ /dev/null @@ -1,39 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint", "react-hooks", "simple-import-sort", "prettier"], - "extends": [ - "plugin:playwright/recommended", - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:react-hooks/recommended", - "prettier" - ], - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "rules": { - "prettier/prettier": "error", - "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error", - "no-var": 0 - }, - "overrides": [ - { - "files": ["*.test.ts", "*.test.tsx"], - "rules": { - // Allow testing runtime errors to suppress TS errors - "@typescript-eslint/ban-ts-comment": "off" - } - } - ], - "settings": { - "react": { - "pragma": "React", - "version": "detect" - } - } -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0eccb7a..f32f701 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ Here is a quick guide to doing code contributions to the library. 5. Run all packages in dev mode: - > pnpm i + > pnpm dev 6. If you've added a code that should be tested, ensure the test suite still passes. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..7b4fa3d --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,67 @@ +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat"; +import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import reactHooks from "eslint-plugin-react-hooks"; +import simpleImportSort from "eslint-plugin-simple-import-sort"; +import prettier from "eslint-plugin-prettier"; +import tsParser from "@typescript-eslint/parser"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [{ + ignores: ["node_modules", "dist", "rollup"], +}, ...fixupConfigRules(compat.extends( + "plugin:playwright/recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended", + "prettier", +)), { + plugins: { + "@typescript-eslint": fixupPluginRules(typescriptEslint), + "react-hooks": fixupPluginRules(reactHooks), + "simple-import-sort": simpleImportSort, + prettier, + }, + + languageOptions: { + parser: tsParser, + ecmaVersion: 2020, + sourceType: "module", + + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + + settings: { + react: { + pragma: "React", + version: "detect", + }, + }, + + rules: { + "prettier/prettier": "error", + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error", + "no-var": 0, + }, +}, { + files: ["**/*.test.ts", "**/*.test.tsx"], + + rules: { + "@typescript-eslint/ban-ts-comment": "off", + }, +}]; \ No newline at end of file diff --git a/package.json b/package.json index afd52f3..a5e0a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datepicker", - "version": "6.6.1", + "version": "6.6.6", "description": "The ultimate tool to create a date, range and time picker in your React applications.", "scripts": { "clean": "rimraf node_modules", @@ -40,6 +40,7 @@ }, "homepage": "https://github.com/rehookify/datepicker#readme", "devDependencies": { + "@eslint/compat": "^1.1.1", "@testing-library/react": "^16.0.0", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", @@ -62,6 +63,6 @@ ] }, "engines": { - "node": ">=16" + "node": ">=18" } } diff --git a/packages/datepicker/package.json b/packages/datepicker/package.json index 72fa994..844b592 100644 --- a/packages/datepicker/package.json +++ b/packages/datepicker/package.json @@ -1,6 +1,6 @@ { "name": "@rehookify/datepicker", - "version": "6.6.5", + "version": "6.6.6", "description": "The ultimate tool to create a date, range and time picker in your React applications.", "main": "dist/index.cjs.js", "module": "dist/index.esm.mjs", @@ -83,6 +83,6 @@ "access": "public" }, "engines": { - "node": ">=16" + "node": ">=18" } } diff --git a/packages/datepicker/src/utils/create-months.ts b/packages/datepicker/src/utils/create-months.ts index b851d91..8705fb9 100644 --- a/packages/datepicker/src/utils/create-months.ts +++ b/packages/datepicker/src/utils/create-months.ts @@ -1,5 +1,5 @@ import type { DPDatesConfig, DPLocaleConfig, DPMonth } from '../types'; -import { formatMonthName, getDateParts, newDate } from './date'; +import { daysInMonth, formatMonthName, getDateParts, newDate } from './date'; import { isAfterMaxMonth, isBeforeMinMonth, @@ -13,14 +13,16 @@ export var createMonths = ( locale: DPLocaleConfig, { minDate, maxDate }: DPDatesConfig, ): DPMonth[] => { - // 12 is a number of months in the year const { M, Y, D } = getDateParts(offsetDate); const { Y: nY, M: nM } = getDateParts(newDate()); + // 12 is a number of months in the year return Array(12) .fill(0) .map((_, i) => { - const $date = newDate(Y, i, D); + // Prevent situation when previous month has less days than current March -> February + const maxMonthDate = daysInMonth(newDate(Y, i, 1)); + const $date = newDate(Y, i, D > maxMonthDate ? maxMonthDate : D); return { $date, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca34c34..21366fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: devDependencies: + '@eslint/compat': + specifier: ^1.1.1 + version: 1.1.1 '@testing-library/react': specifier: ^16.0.0 version: 16.0.0(@testing-library/dom@10.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) @@ -1690,6 +1693,11 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true + /@eslint/compat@1.1.1: + resolution: {integrity: sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + /@eslint/config-array@0.17.0: resolution: {integrity: sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}