diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 084ced7..8121c33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [20.x, 22.x] + node-version: [20.x, 22.x, 24.x] + react-version: [^18.2.0, ^19.0.0] steps: - uses: actions/checkout@v4 @@ -84,6 +85,7 @@ jobs: cache: "yarn" - run: yarn --frozen-lockfile + - run: yarn add react@${{ matrix.react-version }} react-dom@${{ matrix.react-version }} --dev - run: yarn lint - run: yarn build - run: yarn prettier-check diff --git a/.gitignore b/.gitignore index 5c91a66..8f13566 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ storybook-static terraform .npmrc +*storybook.log # Ignore vs folder -.vs \ No newline at end of file +.vs diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index a65f689..0000000 --- a/.storybook/main.js +++ /dev/null @@ -1,16 +0,0 @@ -const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); - -module.exports = { - stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], - addons: ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions"], - framework: "@storybook/react", - webpackFinal: async (config) => { - config.resolve.plugins = [ - ...(config.resolve.plugins || []), - new TsconfigPathsPlugin({ - extensions: config.resolve.extensions, - }), - ]; - return config; - }, -}; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..f99af31 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,23 @@ +import type { StorybookConfig } from "@storybook/react-webpack5"; +import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin"; + +const config: StorybookConfig = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: ["@storybook/addon-webpack5-compiler-swc", "@storybook/addon-docs"], + framework: { + name: "@storybook/react-webpack5", + options: {}, + }, + webpackFinal: (config) => { + if (config && config.resolve) { + config.resolve.plugins = [ + ...(config.resolve.plugins || []), + new TsconfigPathsPlugin({ + extensions: config.resolve.extensions, + }), + ]; + } + return config; + }, +}; +export default config; diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c5f0e..c325159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,7 +129,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - :boom: `AsyncTypeAheadInput` based on MUI Autocomplete component. - :boom: renamed `AsyncTypeaheadProps` to `AsyncTypeaheadInputProps`. - 1. The component is by default **form** controlled. However, updating values using form methods could lead to an unexpected behavior because MUI library requires consistency between options and value. In order to manually to control the input, a ref is exposed which allows to mutually modify input value and form value. 2. `inputRef` is exposed to clear, reset or set new selected options, as mentioned in point 1. 3. `defaultSelected` options is still needed as in previous version. @@ -139,7 +138,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 7. `onInputChange` exposes the reason why the input-text changes. Check whether reason is `input` for checking only the typing event. - :boom: `StaticTypeAheadInput` based on MUI Autocomplete component. - 1. The component is fully **form** controlled. 2. In order to control input value, use form methods being sure to be consistent between the set value and available options. Therefore, any input ref is exposed anymore. 3. No need to specify a `defaultSelected` option according to point 1. The input automatically select options based on form value. diff --git a/cypress/cypress/component/AutoSubmit/AutoSumbit.cy.tsx b/cypress/cypress/component/AutoSubmit/AutoSumbit.cy.tsx index c9ba15f..bd2c1f8 100644 --- a/cypress/cypress/component/AutoSubmit/AutoSumbit.cy.tsx +++ b/cypress/cypress/component/AutoSubmit/AutoSumbit.cy.tsx @@ -3,6 +3,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import { Form, Input } from "react-hook-form-components"; import * as yup from "yup"; import { generateOptions } from "../../helpers/typeahead"; +import { mount } from "cypress/react"; it("radio button multiple autosave works", () => { const name1 = faker.random.alpha(10); @@ -17,7 +18,7 @@ it("radio button multiple autosave works", () => { const { objectOptions: options1 } = generateOptions(faker.datatype.number({ min: 1, max: 10 })); const { objectOptions: options2 } = generateOptions(faker.datatype.number({ min: 1, max: 10 })); - cy.mount( + mount( <>
, @@ -83,7 +84,7 @@ it("text input autosave only once", () => { const randomText = faker.random.alphaNumeric(10); - cy.mount( + mount( , diff --git a/cypress/cypress/component/ClassName/ClassName.cy.tsx b/cypress/cypress/component/ClassName/ClassName.cy.tsx index dcfa059..4354925 100644 --- a/cypress/cypress/component/ClassName/ClassName.cy.tsx +++ b/cypress/cypress/component/ClassName/ClassName.cy.tsx @@ -1,7 +1,7 @@ import { Form, Input, DatePickerInput, AsyncTypeaheadInput, StaticTypeaheadInput, FormattedInput } from "react-hook-form-components"; import { faker } from "@faker-js/faker"; import { fetchMock, generateOptions } from "../../helpers/typeahead"; -import { mount } from "cypress/react18"; +import { mount } from "cypress/react"; it("input has correct classname", () => { const name = faker.random.alpha(10); diff --git a/cypress/cypress/component/ColorPicker/ColorPicker.cy.tsx b/cypress/cypress/component/ColorPicker/ColorPicker.cy.tsx index a53744d..2f52181 100644 --- a/cypress/cypress/component/ColorPicker/ColorPicker.cy.tsx +++ b/cypress/cypress/component/ColorPicker/ColorPicker.cy.tsx @@ -1,6 +1,6 @@ import { Form, ColorPickerInput } from "react-hook-form-components"; import { faker } from "@faker-js/faker"; -import { mount } from "cypress/react18"; +import { mount } from "cypress/react"; it("select correct color by specific format", () => { const hexName = faker.random.alpha(10); diff --git a/cypress/cypress/component/Datepicker/DatePickerInput.cy.tsx b/cypress/cypress/component/Datepicker/DatePickerInput.cy.tsx index 3d8e656..668efd1 100644 --- a/cypress/cypress/component/Datepicker/DatePickerInput.cy.tsx +++ b/cypress/cypress/component/Datepicker/DatePickerInput.cy.tsx @@ -1,12 +1,13 @@ /* eslint-disable max-lines */ import { DatePickerInput, Form, getUtcTimeZeroDate } from "react-hook-form-components"; -import "react-datepicker/dist/react-datepicker.css"; +import "react-hook-form-components/styles.css"; import { faker } from "@faker-js/faker"; import * as yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; -import { faCalendar } from "@fortawesome/free-solid-svg-icons"; +import { faCalendar, faClock } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button, InputGroupText } from "reactstrap"; +import { mount } from "cypress/react"; import { SinonSpy } from "cypress/types/sinon"; import { useRef, useEffect, FC } from "react"; @@ -19,7 +20,7 @@ it("selecting today works", () => { [name]: yup.date().required(), }); - cy.mount( + mount(