Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react/DatePicker): add closeOnSelect prop to automatically close the date picker after a date is selected #903

Merged
merged 7 commits into from
Aug 4, 2024

Conversation

cheton
Copy link
Member

@cheton cheton commented Jul 31, 2024

Demo: https://trendmicro-frontend.github.io/tonic-ui-demo/react/pr-903/components/date-pickers/date-picker

Action Items:

PR Type

Enhancement, Documentation


Description

  • Added closeOnSelect prop to DatePicker component to automatically close the picker after a date is selected.
  • Updated range picker example to use onClose instead of closeMenu for better semantics.
  • Enhanced usage example with closeOnSelect state, toggle functionality, and UI control.
  • Documented the new closeOnSelect prop in the DatePicker API table.

Changes walkthrough 📝

Relevant files
Enhancement
range-picker.js
Add `closeOnSelect` prop and update close handler in range picker

packages/react-docs/pages/components/date-pickers/date-picker/range-picker.js

  • Added closeOnSelect prop to DatePicker component.
  • Replaced closeMenu with onClose for better semantics.
  • +4/-3     
    usage.js
    Add `closeOnSelect` state and UI control in usage example

    packages/react-docs/pages/components/date-pickers/date-picker/usage.js

  • Added closeOnSelect state and toggle functionality.
  • Included closeOnSelect prop in DatePicker component.
  • Added UI control for closeOnSelect in the form.
  • +12/-0   
    DatePicker.js
    Implement `closeOnSelect` prop in DatePicker component     

    packages/react/src/date-pickers/DatePicker/DatePicker.js

  • Introduced closeOnSelect prop with default value false.
  • Implemented logic to close date picker on selection if closeOnSelect
    is true.
  • +6/-1     
    Documentation
    index.page.mdx
    Document `closeOnSelect` prop in DatePicker API                   

    packages/react-docs/pages/components/date-pickers/date-picker/index.page.mdx

    • Documented closeOnSelect prop in DatePicker API table.
    +1/-0     

    💡 PR-Agent usage:
    Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    Copy link

    codesandbox bot commented Jul 31, 2024

    Review or Edit in CodeSandbox

    Open the branch in Web EditorVS CodeInsiders

    Open Preview

    Copy link

    changeset-bot bot commented Jul 31, 2024

    🦋 Changeset detected

    Latest commit: 07bca26

    The changes in this PR will be included in the next version bump.

    This PR includes changesets to release 1 package
    Name Type
    @tonic-ui/react Minor

    Not sure what this means? Click here to learn what changesets are.

    Click here if you're a maintainer who wants to add another changeset to this PR

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Key issues to review

    Default Prop Change Notice
    The comment on line 67 indicates a future change of the default value for closeOnSelect to true. This could potentially break existing implementations when upgraded. It's crucial to ensure that this change is clearly communicated in the release notes and documentation to avoid unexpected behavior in consumer applications.

    @cheton cheton changed the title feat(react/DatePicker): add closeOnSelect to automatically dismiss date picker after selection feat(react/DatePicker): add closeOnSelect prop to automatically close the date picker after a date is selected Jul 31, 2024
    Copy link
    Contributor

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Possible bug
    Add a type check for onClose to ensure it's a function before calling it

    Consider adding a check to ensure onClose is a function before calling it. This will
    prevent potential runtime errors if onClose is not provided or is not a function.

    packages/react/src/date-pickers/DatePicker/DatePicker.js [160]

    -if (closeOnSelect) {
    +if (closeOnSelect && typeof onClose === 'function') {
       onClose();
     }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 10

    Why: This suggestion prevents potential runtime errors by ensuring onClose is a function before calling it, which is crucial for robust code.

    10
    Possible issue
    Ensure consistency in function naming unless intentional changes were made

    Replace the onClose function with closeMenu in the callback to maintain consistency
    with the previous implementation, unless the change to onClose was intentional and
    closeMenu is no longer available.

    packages/react-docs/pages/components/date-pickers/date-picker/range-picker.js [362]

    -{({ onClose }) => (
    +{({ closeMenu }) => (
     
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: This suggestion addresses a potential inconsistency in function naming, which could lead to confusion or errors if closeMenu and onClose are not interchangeable.

    8
    Maintainability
    Improve variable naming for clarity and maintainability

    Consider using a more descriptive variable name for the toggleCloseOnSelect function
    to enhance code readability and maintainability.

    packages/react-docs/pages/components/date-pickers/date-picker/usage.js [114]

    -const [closeOnSelect, toggleCloseOnSelect] = useToggle(false);
    +const [closeOnSelect, setCloseOnSelect] = useToggle(false);
     
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    Why: The suggestion improves code readability and maintainability by using a more descriptive variable name, although it is a minor enhancement.

    6

    Copy link

    codesandbox-ci bot commented Jul 31, 2024

    This pull request is automatically built and testable in CodeSandbox.

    To see build info of the built libraries, click here or the icon next to each commit SHA.

    @trendmicro-frontend-bot
    Copy link
    Contributor

    trendmicro-frontend-bot commented Jul 31, 2024

    Copy link

    codecov bot commented Jul 31, 2024

    Codecov Report

    All modified and coverable lines are covered by tests ✅

    Project coverage is 78.92%. Comparing base (993100d) to head (07bca26).

    Additional details and impacted files
    @@            Coverage Diff             @@
    ##               v2     #903      +/-   ##
    ==========================================
    + Coverage   74.91%   78.92%   +4.01%     
    ==========================================
      Files         378      378              
      Lines        6166     6168       +2     
    ==========================================
    + Hits         4619     4868     +249     
    + Misses       1547     1300     -247     
    Flag Coverage Δ
    -base 78.92% <100.00%> (+4.01%) ⬆️
    -github 78.92% <100.00%> (+4.01%) ⬆️
    -hooks 78.92% <100.00%> (+4.01%) ⬆️
    -icons 78.92% <100.00%> (+4.01%) ⬆️
    -system 78.92% <100.00%> (+4.01%) ⬆️
    codemod 78.92% <100.00%> (+4.01%) ⬆️
    react 78.92% <100.00%> (+4.01%) ⬆️
    theme 78.92% <100.00%> (+4.01%) ⬆️
    utils 78.92% <100.00%> (+4.01%) ⬆️

    Flags with carried forward coverage won't be shown. Click here to find out more.

    ☔ View full report in Codecov by Sentry.
    📢 Have feedback on the report? Share it here.

    @cheton
    Copy link
    Member Author

    cheton commented Jul 31, 2024

    /ask Enhance the test coverage for the DatePicker component

    Copy link
    Contributor

    Ask

    Enhance the test coverage for the DatePicker components

    Answer:

    To enhance the test coverage for the DatePicker components, you can add more test cases to cover various scenarios and edge cases. Here are some suggestions:

    1. Test closeOnSelect Prop Functionality:

      • Verify that the date picker closes automatically when a date is selected if closeOnSelect is set to true.
      • Verify that the date picker does not close automatically when a date is selected if closeOnSelect is set to false.
    2. Test Different Input Formats:

      • Test the date picker with different inputFormat values to ensure it correctly parses and formats dates.
    3. Test firstDayOfWeek Prop:

      • Verify that the calendar correctly displays the first day of the week based on the firstDayOfWeek prop.
    4. Test Error Handling:

      • Ensure that the onError callback is called with the correct error message when an invalid date is entered.
    5. Test Accessibility:

      • Add accessibility tests to ensure that the date picker is accessible to users with disabilities.
    6. Test Custom Render Input:

      • Verify that the custom renderInput function works correctly and renders the input as expected.

    Here is an example of how you can enhance the test coverage:

    import { screen } from '@testing-library/react';
    import userEvent from '@testing-library/user-event';
    import { render } from '@tonic-ui/react/test-utils/render';
    import {
      Box,
      DatePicker,
      InputAdornment,
      InputControl,
      Text,
      useColorStyle,
    } from '@tonic-ui/react/src';
    import { CalendarIcon } from '@tonic-ui/react-icons/src';
    import * as dateFns from 'date-fns';
    import React, { useCallback } from 'react';
    
    describe('DatePicker', () => {
      const TestComponent = (props) => {
        const [colorStyle] = useColorStyle();
        const inputFormat = 'MM/dd/yyyy';
        const onChange = jest.fn();
        const onError = jest.fn();
        const inputError = false;
        const value = new Date();
        const formatDate = useCallback((date, format) => {
          return dateFns.format(date, format);
        }, []);
        const renderInput = useCallback(({ error, inputProps }) => {
          return (
            <Box>
              <InputControl
                {...inputProps}
                startAdornment={(
                  <InputAdornment color={colorStyle.color.secondary}>
                    <CalendarIcon />
                  </InputAdornment>
                )}
                data-testid="date-picker-input"
                error={inputError}
                placeholder={inputFormat}
              />
              {inputError && (
                <Text mt="1x" color="red:50">Invalid date</Text>
              )}
            </Box>
          );
        }, [colorStyle, inputError, inputFormat]);
    
        return (
          <DatePicker
            data-testid="date-picker"
            closeOnSelect={props.closeOnSelect}
            firstDayOfWeek={0}
            formatDate={formatDate}
            onChange={onChange}
            onError={onError}
            value={value}
            inputFormat={inputFormat}
            renderInput={renderInput}
          />
        );
      };
    
      it('should render correctly', async () => {
        const user = userEvent.setup();
        const renderOptions = {
          useCSSVariables: true,
        };
        const { container } = render((
          <TestComponent closeOnSelect={true} />
        ), renderOptions);
    
        const datePicker = screen.getByTestId('date-picker');
        const datePickerInput = screen.getByTestId('date-picker-input');
    
        // The date picker and date picker input should be in the document
        expect(datePicker).toBeInTheDocument();
        expect(datePickerInput).toBeInTheDocument();
    
        // Open the date picker
        await user.click(datePickerInput);
    
        // The "menu" role should be in the document
        expect(await screen.findByRole('menu')).toBeInTheDocument();
    
        expect(container).toMatchSnapshot();
      });
    
      it('should close the date picker when a date is selected and closeOnSelect is true', async () => {
        const user = userEvent.setup();
        render(<TestComponent closeOnSelect={true} />);
    
        const datePickerInput = screen.getByTestId('date-picker-input');
    
        // Open the date picker
        await user.click(datePickerInput);
    
        // Select a date
        const dateButton = screen.getByText('15'); // Assuming 15th is a selectable date
        await user.click(dateButton);
    
        // The "menu" role should not be in the document
        expect(screen.queryByRole('menu')).not.toBeInTheDocument();
      });
    
      it('should not close the date picker when a date is selected and closeOnSelect is false', async () => {
        const user = userEvent.setup();
        render(<TestComponent closeOnSelect={false} />);
    
        const datePickerInput = screen.getByTestId('date-picker-input');
    
        // Open the date picker
        await user.click(datePickerInput);
    
        // Select a date
        const dateButton = screen.getByText('15'); // Assuming 15th is a selectable date
        await user.click(dateButton);
    
        // The "menu" role should still be in the document
        expect(screen.getByRole('menu')).toBeInTheDocument();
      });
    
      // Add more tests for different input formats, firstDayOfWeek, error handling, etc.
    });

    These tests cover the new closeOnSelect prop functionality and ensure that the date picker behaves as expected in different scenarios. You can add more tests to cover other props and edge cases as needed.

    @cheton cheton merged commit 4bb6350 into v2 Aug 4, 2024
    7 checks passed
    @cheton cheton deleted the tonic-ui-900 branch August 4, 2024 12:53
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    2 participants