diff --git a/README.md b/README.md index 2a11e89..0555f54 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ prompt( interface PromptModalProps { okButtonText?: string; cancelButtonText?: string; + valdiate?: (inputValue: string) => void; onOk?: ((inputVal?: string) => void) | ((inputVal: string) => Promise); onCancel?: (isSubmitLoading?: boolean) => any; canCancelOnLoading?: boolean; @@ -117,12 +118,13 @@ interface PromptModalProps { - `okButtonText`: Customize "OK" button text. - `cancelButtonText`: Customize "Cancel" button text. +- `validate`: Validate current input value. Disable OK button if validation fails. - `onOk`: Callback function when "OK" is clicked, receiving a string representing the user input. If `onOk` returns a `Promise`, "OK" button shows loading status until the promise finishes. - `onCancel`: Callback function when "Cancel" is clicked. If not provided, "Cancel" is disabled when "OK" is loading. - `canCancelOnLoading`: When `onCancel` is set, you can still use this option to force disable "Cancel" button. - `inputProps`: custom input properties, learn more information about `InputProps` from [here](https://rsuitejs.com/components/input#code-lt-input-gt-code) -## Testability +## Testing If you use `@rsuite/interactions` to call alert dialogs in your app, you can easily test it with `@testing-library/react`. diff --git a/index.d.ts b/index.d.ts index 202efd7..2aa7343 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,6 +17,7 @@ interface ConfirmModalProps { interface PromptModalProps { okButtonText?: string; cancelButtonText?: string; + validate?: (inputValue: string) => boolean; onOk?: ((inputVal?: string) => void) | ((inputVal: string) => Promise); onCancel?: (isSubmitLoading?: boolean) => any; canCancelOnLoading?: boolean; diff --git a/jest.config.js b/jest.config.js index 74bd3ec..dcd442b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,4 @@ module.exports = { setupFilesAfterEnv: ['./jest.setup.js'], + watchPathIgnorePatterns: ['node_modules'], }; diff --git a/src/InteractionModal.jsx b/src/InteractionModal.jsx index 725f11b..9c2c7e4 100644 --- a/src/InteractionModal.jsx +++ b/src/InteractionModal.jsx @@ -3,6 +3,7 @@ import { Button, Modal } from 'rsuite'; function InteractionModal({ okButtonText = '确定', + okButtonDisabled = false, onOk, showCancelButton = true, cancelButtonText = '取消', @@ -97,7 +98,12 @@ function InteractionModal({ {cancelButtonText} )} - diff --git a/src/__tests__/InteractionModal.test.js b/src/__tests__/InteractionModal.test.js index 869934a..bcef25f 100644 --- a/src/__tests__/InteractionModal.test.js +++ b/src/__tests__/InteractionModal.test.js @@ -56,6 +56,18 @@ it('renders custom button text', () => { expect(getByRole('button', { name: okButtonText })).toBeInTheDocument(); }); +it('disables ok button when okButtonDisabled=true', () => { + const { getByRole } = render( + Hey + ); + + expect( + within(getByRole('alertdialog')).getByRole('button', { + name: '确定', + }) + ).toBeDisabled(); +}); + it('hides dialog on clicking ok button', async () => { const { getByRole } = render(); diff --git a/src/__tests__/prompt.test.js b/src/__tests__/prompt.test.js index 65c5e06..d7b3181 100644 --- a/src/__tests__/prompt.test.js +++ b/src/__tests__/prompt.test.js @@ -68,6 +68,24 @@ it('renders custom button text', async () => { ).toBeInTheDocument(); }); +it('disable OK button if validation fails', () => { + prompt('Message', '', { + validate: () => false, + }); + + expect(screen.getByRole('button', { name: '确定' })).toBeDisabled(); +}); + +it('enable OK button when validation passes', () => { + prompt('Message', '', { + validate: (value) => value === 'expected', + }); + + userEvent.type(screen.getByRole('textbox'), 'expected'); + + expect(screen.getByRole('button', { name: '确定' })).not.toBeDisabled(); +}); + describe('resolves correctly', () => { const inputValue = 'Input value'; diff --git a/src/prompt.jsx b/src/prompt.jsx index 13eac96..18d5463 100644 --- a/src/prompt.jsx +++ b/src/prompt.jsx @@ -9,6 +9,7 @@ function PromptModal({ message, defaultResult = '', onOk, + validate, inputProps, style, ...props @@ -20,7 +21,11 @@ function PromptModal({ const handleOk = useCallback(() => onOk(result), [onOk, result]); return ( - +
{message}