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

chore: Datepicker Widget #36605

Closed
wants to merge 12 commits into from
Closed

chore: Datepicker Widget #36605

wants to merge 12 commits into from

Conversation

jsartisan
Copy link
Contributor

@jsartisan jsartisan commented Sep 30, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new Calendar component for enhanced date selection.
    • Added a DatePicker component with customizable options and validation.
    • Implemented a FieldCalendarPopover for displaying calendars in a dialog format.
    • New icons and thumbnails for the DatePicker have been added.
  • Bug Fixes

    • Improved validation logic for date selection in the DatePicker.
  • Documentation

    • Added Storybook stories for the DatePicker component to demonstrate various use cases.
  • Style

    • Introduced new styles for the calendar and date picker components for better UI presentation.
  • Chores

    • Updated configuration files for the new DatePicker widget to enhance functionality and accessibility.

Warning

Tests have not run on the HEAD 4daa071 yet


Mon, 30 Sep 2024 12:26:29 UTC

Copy link
Contributor

coderabbitai bot commented Sep 30, 2024

Walkthrough

The changes introduce several new components and configurations related to calendar and date picker functionalities within the design system. Key additions include the Calendar, DatePicker, and FieldCalenderPopover components, along with their respective styles, types, and configuration files. The updates enhance the widget capabilities, providing a more robust interface for date selection and calendar interactions.

Changes

Files Change Summary
app/client/packages/design-system/widgets/src/components/Calender/... New components: Calendar, CalendarCell, CalendarHeaderCell, CalendarHeading, and their respective styles and types added. Exports consolidated in index.ts.
app/client/packages/design-system/widgets/src/components/DatePicker/... New DatePicker component introduced, along with related types and configuration files. Exports added for DatePicker and DateValue.
app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/... New FieldCalenderPopover component created, re-exporting all entities from its source module.
app/client/packages/icons/src/components/... New icons: DatePickerIcon and DatePickerThumbnail added.
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/... New configurations and properties for WDSDatePickerWidget, including propertyPaneConfig for enhanced customization.

Possibly related PRs

Suggested labels

Task, Enhancement, Widgets Product, ok-to-test, Widgets & Accelerators Pod

Suggested reviewers

  • ApekshaBhosale
  • sagar-qa007
  • KelvinOm
  • rahulbarwal

🎉 In the realm of code so bright,
New widgets dance in pure delight.
Calendars and pickers, side by side,
In harmony, they now abide.
With each new line, a feature grows,
A joyful tale of code that flows! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Sep 30, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 34

🧹 Outside diff range and nitpick comments (34)
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/settersConfig.ts (1)

1-12: Class, let's review this new configuration file.

Alright, students, gather 'round! Today, we're examining a new addition to our codebase. This settersConfig object is like a well-organized lesson plan for our DatePicker widget. It clearly outlines how we can control the widget's visibility and whether it's disabled or not.

I'm pleased to see such a structured approach. It's as if you've created a perfect seating chart for your class! The use of __setters as a nested object is particularly clever - it leaves room for our class to grow, just like we might add more desks to accommodate new students.

However, to make our code even more readable - because clear handwriting is important, children - we could consider adding a type annotation to our settersConfig constant. It's like labeling our supply closet so everyone knows what's inside!

Here's a small suggestion to improve our code's clarity:

-export const settersConfig = {
+export const settersConfig: {
+  __setters: {
+    [key: string]: {
+      path: string;
+      type: string;
+    };
+  };
+} = {
   __setters: {
     // ... rest of the code remains the same
   },
 };

This way, future students... I mean, developers, will know exactly what to expect in our settersConfig object. Remember, clear expectations lead to better results!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/metaConfig.ts (1)

7-13: Your search tags are a treasure trove of terms!

Well done, class! Your searchTags are like a well-stocked vocabulary list for our DatePicker. You've covered singular terms, combined terms, and even considered date and time functionality. It's comprehensive and will help users find this widget easily.

Here's a gold star suggestion: How about adding "calendar" to your list? Some students might think of a date picker as a calendar first. It's like adding another helpful signpost to guide people to our DatePicker widget.

Consider adding "calendar" to the searchTags array:

 searchTags: [
   "date",
   "picker",
   "date picker",
   "date time",
   "date time picker",
+  "calendar",
 ],
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/types.ts (1)

4-10: A round of applause for your interface properties, class!

You've done a splendid job defining the properties for your date picker widget. The use of required and optional properties is well thought out. However, let's have a quick pop quiz:

Q: What type would be more appropriate for the onDateSelected property?

A: Instead of string, consider using a function type like (date: string) => void. This would better represent an event handler.

Here's a suggested improvement:

onDateSelected: (date: string) => void;

This change will make your code more type-safe and self-documenting. Remember, in TypeScript, we always strive for the most accurate types!

app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (2)

2-2: Excellent work on the component declaration, students!

Your DatePickerIcon component is well-defined as a functional component and properly exported. However, let's think about making our icon more flexible. Consider accepting props like width, height, and color. This would allow the icon to be customized when used in different contexts. Here's a little homework for you:

export const DatePickerIcon = ({ width = 16, height = 16, color = "#000" }: IconProps) => {
  // Use these props in the SVG
}

interface IconProps {
  width?: number;
  height?: number;
  color?: string;
}

This way, we're teaching our icon to be more adaptable!


2-2: A gold star for your SVG work, class!

Your SVG is efficiently structured with a single path element, which is excellent for keeping the file size small. The use of stroke-linecap and stroke-linejoin shows attention to visual detail.

However, let's think about making our icon more accessible. Can anyone tell me what's missing? That's right, we need an aria-label! Here's how we can improve it:

<svg aria-label="Date Picker" role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
  {/* ... rest of the SVG ... */}
</svg>

This way, we're ensuring our icon is understandable to all users, including those using screen readers. Remember, in web development, we always strive for inclusivity!

app/client/packages/design-system/widgets/src/components/Calender/src/types.ts (1)

1-10: Overall, an A+ performance on your type definitions!

You've demonstrated a clear understanding of type extensions and consistency in your code. It's like you've written a perfect essay with great structure and content. To make it even better, consider adding JSDoc comments to each type. This would be like adding explanatory notes to your essay, making it even easier for others to understand your brilliant work!

Here's an example of how you could add JSDoc comments:

/**
 * Represents the properties for a calendar cell, extending the headless component props
 * and including React ref attributes for the HTML table cell element.
 */
export type CalendarCellProps = HeadlessCalendarCellProps &
  React.RefAttributes<HTMLTableCellElement>;

/**
 * Represents the properties for a calendar header cell, extending the headless component props
 * and including React ref attributes for the HTML table cell element.
 */
export type CalendarHeaderCellProps = HeadlessCalendarHeaderCellProps &
  React.RefAttributes<HTMLTableCellElement>;
app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeaderCell.tsx (1)

7-17: Good job on your component structure, but let's improve it a bit!

Class, your CalendarHeaderCell component is well-structured. You've used a function component and properly passed down props. However, let's talk about prop spreading.

While using {...props} is convenient, it can sometimes lead to unintended props being passed down. Consider being more explicit about which props you pass to HeadlessCalendarHeaderCell. For example:

const { children, ...restProps } = props;
return (
  <HeadlessCalendarHeaderCell {...restProps}>
    <Text color="neutral" fontWeight={700} textAlign="center">
      {children}
    </Text>
  </HeadlessCalendarHeaderCell>
);

This way, you're being more intentional about which props are passed down. It's like making sure you only hand out the right worksheets to your students!

app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeading.tsx (2)

5-17: Excellent work on your CalendarHeading component, students!

Your component is well-structured and follows good React practices. I'm particularly impressed with how you've used the useContextProps hook – it's like you're expertly juggling context and props!

However, let's make one small improvement to help your future self and your classmates. Can you think of a way to make your prop types more specific?

Consider defining a more specific prop type for CalendarHeading. Instead of using TextProps directly, you could create a custom type:

type CalendarHeadingProps = Omit<TextProps, 'color'>;

Then use it like this:

function CalendarHeading(
  props: CalendarHeadingProps,
  ref: ForwardedRef<HTMLHeadingElement>,
) {
  // ... rest of the component
}

This way, we're telling future readers that the color prop is handled internally and shouldn't be passed from outside. It's like putting a "Do Not Touch" sign on the classroom aquarium!


21-21: Clever export statement, students!

You've done a good job with your export, renaming _CalendarHeading to CalendarHeading. It's like giving your project a stage name – keeping things tidy behind the scenes but presenting a clean facade to the audience.

However, let's make this even clearer for your classmates who might read this later. Can you think of a way to make the intention more explicit?

Consider adding a brief comment above the export to explain the renaming:

// Export without underscore for clean public API
export { _CalendarHeading as CalendarHeading };

This way, anyone reading the code will understand immediately why we're doing this renaming dance. It's like leaving a note on the blackboard for the next class!

app/client/packages/design-system/widgets/src/components/Calender/src/Calendar.tsx (2)

1-19: Well done on the imports and type definitions, class!

You've done a splendid job organizing your imports and defining the necessary types. The use of a type alias for CalendarProps<T> is particularly commendable, as it enhances code readability.

However, I'd like to see you go the extra mile. Consider grouping your imports for better organization:

  1. External libraries (React, react-aria-components)
  2. Internal modules (@appsmith/wds)
  3. Local components and styles

This small change will make your code even more organized and easier to maintain. Keep up the good work!


21-23: Excellent use of generics, students!

Your Calendar component definition shows a good understanding of TypeScript's generic types. This approach allows for flexibility in the date value type, which is very thoughtful.

However, let's think about how we can make this even better. While spreading props (...props) is convenient, it might pass unnecessary props to the HeadlessCalendar. Consider destructuring the props you actually need:

export const Calendar = <T extends DateValue>({ className, ...props }: CalendarProps<T>) => {
  return (
    <HeadlessCalendar {...props} className={`${styles.calendar} ${className}`}>
      {/* ... */}
    </HeadlessCalendar>
  );
};

This approach allows you to combine the custom class with any passed className, and only pass the necessary props to HeadlessCalendar. It's like double-checking your homework before turning it in!

app/client/packages/design-system/widgets/src/components/Calender/src/styles.module.css (6)

1-9: Well done, class! Your calendar container styles are on the right track.

The use of flexbox for the table layout is a modern and flexible approach. I'm pleased to see you're using CSS variables for padding. However, let's make sure we're being consistent with our spacing.

Consider adding some margin to the table to ensure consistent spacing:

 .calendar table {
   display: flex;
   flex-direction: column;
-  margin: 0;
+  margin: var(--outer-spacing-3) 0 0 0;
 }

This will create a bit of breathing room between the calendar container and its content. Remember, good design is all about consistency and readability!


11-20: Excellent work on your row styles, students!

Your use of flexbox for both header and body rows shows a good understanding of modern CSS layout techniques. The different justification methods are appropriate for their respective purposes.

For consistency, let's apply padding to both header and body rows:

 .calendar tbody tr {
   display: flex;
   justify-content: space-between;
+  padding-block-start: var(--inner-spacing-1);
 }

This will ensure a uniform appearance throughout the calendar. Remember, consistency is key in design!


22-32: A gold star for your cell styles, class!

Your use of flexbox for centering content in header cells and fixed dimensions for both header and body cells shows attention to detail and ensures a uniform appearance.

To improve accessibility, let's add a hover effect to the body cells:

 .calendar tbody td {
   padding: var(--inner-spacing-1);
+  transition: background-color 0.2s ease;
 }

+.calendar tbody td:hover {
+  background-color: var(--color-bg-accent-subtle-hover);
+  cursor: pointer;
+}

This will provide visual feedback to users when interacting with the calendar, enhancing the user experience. Remember, good design is not just about looks, but also about usability!


34-43: Impressive button styles, students!

Your use of flexbox for centering button content and the application of fixed dimensions show a good grasp of layout techniques. The transparent border is a clever touch for managing focus states without causing layout shifts.

To align more closely with design system best practices, let's use a CSS custom property for the button size:

+:root {
+  --calendar-button-size: var(--sizing-9);
+}

 .calendar tbody [role="button"] {
   display: flex;
   align-items: center;
   justify-content: center;
-  inline-size: var(--sizing-9);
-  block-size: var(--sizing-9);
+  inline-size: var(--calendar-button-size);
+  block-size: var(--calendar-button-size);
   border-radius: var(--border-radius-elevation-3);
   border: var(--border-width-2) solid transparent;
   text-align: center;
 }

This approach allows for easier maintenance and consistency across the design system. Remember, a well-organized codebase is a happy codebase!


45-61: Excellent work on your button state styles, class!

Your use of data attributes for managing states and the clear visual differentiation between states show a good understanding of interactive design principles. The use of CSS variables for colors is commendable and promotes maintainability.

To enhance consistency and reduce repetition, let's create a mixin-like structure using a CSS custom property:

+.calendar tbody [role="button"] {
+  --button-bg-color: transparent;
+  background-color: var(--button-bg-color);
+  transition: background-color 0.2s ease;
+}

 .calendar tbody [role="button"][data-disabled] {
   opacity: var(--opacity-disabled);
 }

 .calendar tbody [role="button"][data-hovered] {
-  background-color: var(--color-bg-accent-subtle-hover);
+  --button-bg-color: var(--color-bg-accent-subtle-hover);
   cursor: pointer;
 }

 .calendar tbody [role="button"][data-pressed] {
-  background-color: var(--color-bg-accent-subtle-active);
+  --button-bg-color: var(--color-bg-accent-subtle-active);
 }

 .calendar tbody [role="button"][data-selected] {
-  background-color: var(--color-bg-accent);
+  --button-bg-color: var(--color-bg-accent);
   color: var(--color-fg-on-accent);
 }

This approach reduces repetition and makes it easier to manage background colors across different states. Remember, DRY (Don't Repeat Yourself) is a principle we should always strive for in our code!


63-66: Well done on your focus styles, students!

Your attention to both focus-visible and focused states demonstrates a commitment to keyboard accessibility. The border color change provides clear visual feedback, which is crucial for users navigating with keyboards.

To further enhance accessibility, let's add an outline to make the focus state even more visible:

 .calendar tbody [role="button"][data-focus-visible],
 .calendar tbody [role="button"][data-focused] {
   border-color: var(--color-bd-accent);
+  outline: 2px solid var(--color-bd-accent);
+  outline-offset: 2px;
 }

This addition will make the focus state more prominent, especially for users with visual impairments. Remember, accessibility is not just a feature, it's a responsibility!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.test.js (5)

4-6: Excellent test setup, students!

Your description of the test suite is clear, and the mockMoment function is a smart way to wrap the moment library. However, let's make it even better!

Consider adding a brief comment explaining the purpose of the mockMoment function. This will help future readers understand its role more quickly. Here's a suggestion:

 describe("isValid function", () => {
+  // Wrapper for moment to allow easy mocking in future if needed
   const mockMoment = (date) => moment(date);

13-23: Excellent work on your null date scenarios, students!

You've thoughtfully covered both cases where the selectedDate is null - when it's required and when it's not. This attention to detail will help prevent bugs in the future.

To make these tests even more robust, consider adding a test case where selectedDate is an empty string. In some cases, empty strings might be treated differently from null values. Here's an example:

it("should return true when selectedDate is an empty string and not required", () => {
  const props = { isDirty: true, isRequired: false, selectedDate: "" };
  expect(derived.isValid(props, mockMoment)).toBe(true);
});

25-54: Bravo on your date range validation tests, class!

You've done an excellent job covering the main scenarios for date range validation. Your tests check for dates within the range, before the minimum, and after the maximum. This is crucial for ensuring the function works correctly in various situations.

To make your test suite even more comprehensive, consider adding tests for edge cases, such as when the selectedDate is exactly equal to minDate or maxDate. Here's an example:

it("should return true when selectedDate is exactly equal to minDate", () => {
  const props = {
    isDirty: true,
    minDate: "2023-01-01",
    selectedDate: "2023-01-01",
  };
  expect(derived.isValid(props, mockMoment)).toBe(true);
});

it("should return true when selectedDate is exactly equal to maxDate", () => {
  const props = {
    isDirty: true,
    maxDate: "2023-12-31",
    selectedDate: "2023-12-31",
  };
  expect(derived.isValid(props, mockMoment)).toBe(true);
});

These additional tests will ensure that the boundary conditions are correctly handled.


56-64: Well done on your final test case, students!

You've correctly included a test for when there are no date constraints. This is an important scenario that could easily be overlooked.

To make this test even more robust, consider adding an assertion to check that the isRequired property doesn't affect the result when a valid date is provided. Here's how you could modify the test:

 it("should return true when selectedDate is valid and no min/max dates are set", () => {
   const props = {
     isDirty: true,
     selectedDate: "2023-06-15",
+    isRequired: true, // Add this line
   };

   expect(derived.isValid(props, mockMoment)).toBe(true);
+  
+  // Test with isRequired set to false
+  props.isRequired = false;
+  expect(derived.isValid(props, mockMoment)).toBe(true);
 });

This modification will ensure that the isRequired property doesn't unexpectedly influence the result when a valid date is provided.


1-64: Excellent work on your test suite, class! You've earned an A+!

Your test file for the isValid function is comprehensive and well-structured. You've covered a wide range of scenarios, including:

  1. Dirty state checks
  2. Null date handling
  3. Required field validation
  4. Date range validation
  5. Unconstrained date validation

Your test descriptions are clear and your expectations are well-defined. This will make it easy for future developers to understand and maintain these tests.

To improve consistency across your test suite, consider using a consistent format for your test case titles. For example, you could start all test descriptions with "should" or use present tense throughout. Here's an example of how you could modify the first test case:

-it("should return true when isDirty is false", () => {
+it("returns true when isDirty is false", () => {

Apply this change to all your test case titles for improved consistency. Keep up the great work, students!

app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css (1)

40-44: Excellent work on the focused state styles, students! Let's review what we've learned.

  1. The background color change to var(--color-bg-accent) draws attention to the focused input.
  2. Changing the text color to var(--color-fg-on-accent) ensures readability against the new background.
  3. The box shadow adds a nice touch, emphasizing the focused state.

However, let's consider our friends with visual impairments. Can anyone suggest how we might improve accessibility?

To enhance accessibility, consider adding an outline in addition to the box shadow. This can be done by adding:

outline: 2px solid var(--color-bd-focus);
outline-offset: 2px;

This ensures that the focus state is clearly visible, even for users who might have difficulty perceiving subtle color changes or shadows.

app/client/src/modules/ui-builder/ui/wds/constants.ts (1)

62-62: Well done, class! Let's add a little something extra.

Good job on adding the WDS_DATEPICKER_WIDGET to our WDS_V2_WIDGET_MAP. It's like adding a new crayon to our box of colors! Now, to make our code even prettier, let's consider grouping similar widgets together. How about we move this new datepicker widget next to other input-related widgets? It'll make our code easier to read, just like organizing our crayons by color!

Here's a little homework for you:

   WDS_SELECT_WIDGET: "WDS_SELECT_WIDGET",
   WDS_COMBOBOX_WIDGET: "WDS_COMBOBOX_WIDGET",
+  WDS_DATEPICKER_WIDGET: "WDS_DATEPICKER_WIDGET",
   
   // Anvil layout widgets
   ZONE_WIDGET: anvilWidgets.ZONE_WIDGET,
-  WDS_DATEPICKER_WIDGET: "WDS_DATEPICKER_WIDGET",

Remember, keeping our code tidy is like keeping our classroom clean. It makes everything easier to find!

app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx (4)

19-26: Excellent start with your Main story, students!

Your basic instance of the DatePicker is well-structured. The Flex container is a smart choice for consistent layout. However, let's make it even better!

Consider adding a label to make the purpose of this DatePicker clearer:

export const Main: Story = {
-  args: {},
+  args: {
+    label: "Select a date",
+  },
  render: (args) => (
    <Flex width="sizing-60">
      <DatePicker {...args} />
    </Flex>
  ),
};

This will help users understand the component's purpose at a glance.


41-54: Your Sizes story is coming along nicely, class!

You've done a good job demonstrating the different sizes available for the DatePicker. The use of objectKeys and filter is clever.

However, let's make the size filtering more explicit:

export const Sizes: Story = {
  render: () => (
    <Flex direction="column" gap="spacing-4" width="sizing-60">
      {objectKeys(SIZES)
-        .filter((size) => !["xSmall", "large"].includes(size))
+        .filter((size) => ["small", "medium"].includes(size))
        .map((size) => (
          <DatePicker key={size} placeholder={size} size={size} />
        ))}
    </Flex>
  ),
};

This change makes it clearer which sizes are being used, rather than which ones are being excluded.


63-81: Your Validation story is on the right track, students!

You've done a good job demonstrating form validation with the DatePicker. The use of the isRequired prop and the form submission handling are excellent touches.

However, let's consider a few improvements:

  1. Instead of using an alert, consider using a more user-friendly notification method:
-        alert("Form submitted");
+        // Use a toast notification or update state to show a success message
+        console.log("Form submitted");
  1. Add error handling to show what happens when the form is submitted without a date:
export const Validation: Story = {
+  args: {
+    onSubmit: (date) => console.log("Selected date:", date),
+  },
-  render: () => (
+  render: ({ onSubmit }) => (
    <form
      onSubmit={(e) => {
        e.preventDefault();
-        alert("Form submitted");
+        const formData = new FormData(e.target as HTMLFormElement);
+        const date = formData.get('date');
+        if (date) {
+          onSubmit(date);
+        } else {
+          console.error("Date is required");
+        }
      }}
    >
      <Flex direction="column" gap="spacing-5" width="sizing-60">
        <DatePicker
          description="Please select a date"
          isRequired
          label="Validation"
+         name="date"
        />
        <Button type="submit">Submit</Button>
      </Flex>
    </form>
  ),
};

These changes will make the Validation story more informative and closer to real-world usage.


91-105: Your MaxDate and MinDate stories are progressing well, students!

You've done a good job demonstrating how to set maximum and minimum selectable dates for the DatePicker. The use of the parseDate function is commendable.

However, let's consider combining these stories to make our code more efficient:

-export const MaxDate: Story = {
-  args: {
-    label: "Date",
-    placeholder: "Select a date",
-    maxValue: parseDate("2023-06-15"),
-  },
-};
-
-export const MinDate: Story = {
+export const DateLimits: Story = {
   args: {
     label: "Date",
     placeholder: "Select a date",
-    minValue: parseDate("2023-06-15"),
   },
+  render: (args) => (
+    <Flex direction="column" gap="spacing-5" width="sizing-60">
+      <DatePicker {...args} maxValue={parseDate("2023-12-31")} label="Max Date (End of 2023)" />
+      <DatePicker {...args} minValue={parseDate("2023-01-01")} label="Min Date (Start of 2023)" />
+      <DatePicker
+        {...args}
+        minValue={parseDate("2023-01-01")}
+        maxValue={parseDate("2023-12-31")}
+        label="Date Range (2023)"
+      />
+    </Flex>
+  ),
 };

This combined story showcases both individual limits and a date range, providing a more comprehensive example.

app/client/packages/icons/src/index.ts (1)

6-6: Well done, class! These additions look splendid.

Now, let's take a moment to appreciate the new exports you've added:

  1. DatePickerThumbnail from "./components/Thumbnails/DatePickerThumbnail"
  2. DatePickerIcon from "./components/Icons/DatePickerIcon"

These new exports are perfectly in line with our existing naming conventions and file structure. It's like you've been paying attention in class! The alphabetical order is maintained, which shows excellent organization skills.

As a little homework assignment, consider this: Would it be beneficial to group related exports together? For instance, all Thumbnail exports in one section and all Icon exports in another? This could make our code even easier to read and maintain. What do you think?

Here's a little example of what I mean:

// Thumbnails
export { ButtonThumbnail } from "./components/Thumbnails/ButtonThumbnail";
export { CheckboxGroupThumbnail } from "./components/Thumbnails/CheckboxGroupThumbnail";
// ... other Thumbnail exports ...
export { DatePickerThumbnail } from "./components/Thumbnails/DatePickerThumbnail";

// Icons
export { ButtonIcon } from "./components/Icons/ButtonIcon";
export { CheckboxGroupIcon } from "./components/Icons/CheckboxGroupIcon";
// ... other Icon exports ...
export { DatePickerIcon } from "./components/Icons/DatePickerIcon";

Remember, organization is key in coding, just like keeping your desk tidy helps you study better!

Also applies to: 34-34

app/client/src/widgets/WidgetUtils.ts (1)

992-1033: Class, let's examine this new function, shall we?

Alright, students, gather 'round! We have a new addition to our codebase, the parseDerivedProperties function. Let's break it down and see what we can learn from it.

First, let's look at its purpose. This function is like a translator for our widget properties. It takes complex property functions and simplifies them into a format our widgets can understand more easily. Isn't that clever?

Now, let's examine the implementation:

  1. We start with an empty object called derivedProperties. This is where we'll store our translated properties.
  2. We then loop through each property in the input object. It's like going through each student in the class, one by one.
  3. For each property that's a function (raise your hand if you remember what a function is!), we do something special:
    • We extract the body of the function using a regular expression. It's like finding the important part of a sentence.
    • We then clean up this function body by trimming whitespace and replacing props. with this.. This is a key step in making our properties work correctly in their new home.

Overall, this function is doing a good job, but there's always room for improvement! Here are a few suggestions:

  1. Error handling: What happens if the function body can't be extracted? We should add a safety net for that.
  2. Comments: While the function has a good explanatory comment at the top, adding a few inline comments would help future students (I mean, developers) understand each step better.
  3. Type safety: We're using Record<string, unknown>, but we could be more specific about the type of functions we expect.

Remember, class, clear and maintainable code is the key to success in the programming world!

Here's a little homework assignment for you. Try improving the function like this:

export function parseDerivedProperties(propertyFns: Record<string, unknown>): Record<string, string> {
  const derivedProperties: Record<string, string> = {};

  for (const [key, value] of Object.entries(propertyFns)) {
    if (typeof value === "function") {
      const functionBody = value.toString().match(/(?<=\{)(.|\n)*(?=\})/)?.[0];

      if (functionBody) {
        // Clean up the function body
        derivedProperties[key] = functionBody
          .trim()
          .replace(/props\./g, "this.");
      } else {
        console.warn(`Could not parse function body for property: ${key}`);
      }
    }
  }

  return derivedProperties;
}

This version adds a warning when we can't parse a function body. It's like raising your hand when you don't understand something in class - always a good practice!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.js (3)

23-23: Specify Inclusivity in Date Range Validation

By default, moment.isBetween() excludes the start and end dates from the range. If your intention is to include minDate and maxDate as valid selections, you need to define the inclusivity.

To include both minDate and maxDate, update your code as follows:

-      return parsedSelectedDate.isBetween(parsedMinDate, parsedMaxDate);
+      return parsedSelectedDate.isBetween(parsedMinDate, parsedMaxDate, null, '[]');

Here, the '[]' option includes both boundary dates in the comparison.


27-27: Use isSameOrAfter for Inclusive Minimum Date Comparison

To include minDate as a valid option, it's preferable to use isSameOrAfter instead of isAfter. This ensures that parsedSelectedDate is either on or after the minDate.

Update the code to:

-      return parsedSelectedDate.isAfter(parsedMinDate);
+      return parsedSelectedDate.isSameOrAfter(parsedMinDate);

31-31: Use isSameOrBefore for Inclusive Maximum Date Comparison

Similarly, if you wish to include maxDate as a valid selection, isSameOrBefore should be used instead of isBefore. This will allow parsedSelectedDate to be on or before the maxDate.

Modify the code accordingly:

-      return parsedSelectedDate.isBefore(parsedMaxDate);
+      return parsedSelectedDate.isSameOrBefore(parsedMaxDate);
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/index.tsx (1)

128-130: Be cautious with spreading props to DatePicker

When you spread ...rest into the DatePicker component, all remaining props from this.props are passed down. This might include props unintended for DatePicker, potentially causing unexpected behaviors or warnings. It's better practice to explicitly pass only the props that DatePicker needs.

Also applies to: 133-145

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 73d3960 and 017bea0.

⛔ Files ignored due to path filters (3)
  • app/client/packages/icons/src/icons/Icons/ComboboxSelect.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Icons/DatePicker.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Thumbnails/DatePicker.svg is excluded by !**/*.svg
📒 Files selected for processing (46)
  • app/client/packages/design-system/widgets/src/components/Calender/index.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/Calendar.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarCell.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeaderCell.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeading.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/styles.module.css (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/index.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/FieldCalenderPopover.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Text/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/index.ts (1 hunks)
  • app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/index.ts (2 hunks)
  • app/client/packages/icons/src/stories/Icons.mdx (2 hunks)
  • app/client/packages/icons/src/stories/Thumbnails.mdx (2 hunks)
  • app/client/packages/storybook/.storybook/preview-head.html (0 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/anvilConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/autocompleteConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/defaultsConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/metaConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/methodsConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/contentConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/settersConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/constants.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.js (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.test.js (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/helpers.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/index.tsx (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/types.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx (2 hunks)
  • app/client/src/modules/ui-builder/ui/wds/constants.ts (1 hunks)
  • app/client/src/widgets/WidgetUtils.ts (1 hunks)
  • app/client/src/widgets/index.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • app/client/packages/storybook/.storybook/preview-head.html
✅ Files skipped from review due to trivial changes (3)
  • app/client/packages/design-system/widgets/src/components/Calender/index.tsx
  • app/client/packages/design-system/widgets/src/components/DatePicker/index.ts
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/index.tsx
🧰 Additional context used
📓 Learnings (1)
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/anvilConfig.ts (1)
Learnt from: riodeuno
PR: appsmithorg/appsmith#30351
File: app/client/src/widgets/wds/WDSModalWidget/config/anvilConfig.ts:1-6
Timestamp: 2024-01-24T23:57:40.361Z
Learning: The `anvilConfig` is optional for widgets that do not participate in the main container's layout flow, such as the modal widget in the current context.
🪛 Biome
app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx

[error] 35-35: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 56-56: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 60-60: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx

[error] 58-58: Using super in a static context can be confusing.

super refers to a parent class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (63)
app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/index.ts (1)

1-1: Excellent work, class! Let's examine this code.

Now, children, what we have here is a perfect example of how we make our code accessible to others. This line is like opening the door to our classroom and inviting everyone to see what we've created inside.

By using export * from "./FieldCalenderPopover", we're telling our program to share everything from our FieldCalenderPopover module. It's as if we're putting all our wonderful datepicker creations on display for the whole school to see and use!

Remember, sharing is caring in the world of coding. This practice allows other parts of our application to import and use the FieldCalenderPopover component, just like how we share our crayons during art class.

Keep up the good work! You're all becoming excellent little programmers.

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/index.ts (1)

1-1: Very good, class! Let's examine this export statement.

Now, children, what we have here is a perfect example of how to make our code more accessible to other parts of our project. By exporting propertyPaneContentConfig from the contentConfig module, we're essentially opening the door for other modules to easily use this configuration. It's like sharing your toys in the playground - it makes everything more fun and efficient!

Remember, class, when we export something like this, it means other parts of our code can import it directly from this file. This is a very good practice in organizing our code structure. Well done!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/index.ts (1)

1-3: Well done, class! This code snippet deserves a gold star!

Now, let's review what we've learned today:

  1. We've imported the WDSDatePickerWidget from a local file. Can anyone tell me why we use relative imports like "./widget"? That's right, it's because the file is in the same directory!

  2. We've then exported this component. Who can tell me why we might want to do this? Correct! It's to make our component available to other parts of our application. It's like sharing your toys with your classmates - very considerate!

  3. This pattern of importing and then immediately exporting is called re-exporting. It's a very neat and tidy way to organize our code. Just like how we keep our classroom organized, right?

Remember, class: clean and organized code is happy code! Keep up the good work!

app/client/packages/design-system/widgets/src/components/DatePicker/src/index.ts (1)

1-2: Excellent work on organizing your exports, class!

Now, let's review what we've learned from these two lines:

  1. We're exporting the DatePicker component. This is like sharing your favorite toy with your classmates so they can use it too!

  2. We're also exporting a type called DateValue. Think of this as a special label that tells everyone what kind of information they can expect when they play with the DatePicker.

By putting these exports in one file, you're making it easy for others to find and use your DatePicker. It's like creating a neat little package of knowledge that your classmates can easily pick up and use in their own projects.

Remember, class: good organization makes for happy coding! Keep up the great work!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/methodsConfig.ts (3)

1-1: Well done, class! The import statement is correct.

You've successfully imported the necessary components from the "appsmith-icons" module. This is a good practice as it keeps our code organized and modular.


3-6: Excellent work on the configuration object, students!

Your methodsConfig object is well-structured and clearly defines the components for the icon and thumbnail. This approach will make it easy for other parts of the application to use these components consistently.

Remember, class, using descriptive names like IconCmp and ThumbnailCmp helps your fellow developers understand the purpose of each property at a glance. Keep up the good work!


1-6: A+ for this file, class!

You've created a clean, focused configuration file for the date picker widget. It imports the necessary components and exports them in a well-structured object. This approach will make it easier for other parts of the application to use these components consistently.

Remember, keeping your code modular and well-organized like this makes our entire codebase easier to understand and maintain. Great job!

app/client/packages/design-system/widgets/src/components/Calender/src/index.ts (1)

1-4: Well done, class! This index file is a gold star example of modular design.

Now, let's take a moment to appreciate the educational value of this code:

  1. Organization: Just like how we arrange our classroom, this file neatly organizes our Calendar components.
  2. Accessibility: These exports make our components easily accessible, much like having all our school supplies in one place.
  3. Consistency: The naming convention here is as consistent as our daily routine. Well done!

Remember, children, index files like this one are the backbone of a well-structured codebase. They help us keep our code tidy and make it easier for others to find what they need.

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/anvilConfig.ts (3)

1-1: Well done, class! The import statement is correct.

You've properly imported the AnvilConfig type from the "WidgetProvider/constants" module. This is essential for ensuring type safety in our code. Keep up the good work!


3-11: Excellent job structuring the anvilConfig object, students!

Your anvilConfig object is well-structured and follows the AnvilConfig type correctly. Let's break it down:

  1. isLargeWidget: false - This is appropriate for a date picker, which typically doesn't require a large amount of space.
  2. widgetSize.minWidth - You've provided both a base value and a responsive value, which is great for ensuring flexibility across different screen sizes.

Keep up the good work in maintaining a clear and organized configuration!


3-11: Pop quiz: Does the date picker widget participate in the main layout flow?

Class, we've learned that anvilConfig is optional for widgets that don't participate in the main container's layout flow. Let's think about whether this applies to our date picker widget.

To help us answer this question, let's do a little research. Run the following script to check how the date picker widget is typically used in the codebase:

Based on the results, we'll be able to determine if the date picker typically participates in the main layout flow or if it's used in a way that doesn't affect the main layout.

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/metaConfig.ts (4)

1-1: Well done, class! A gold star for your import statement!

The import of WIDGET_TAGS from "constants/WidgetConstants" is spot-on. It's like bringing the right textbook to class – you've got just what you need for today's lesson on DatePicker widgets.


3-4: A+ for naming, students!

Your choice of "DatePicker" for the name property is as clear as a bell ringing for recess. It perfectly describes what this widget does, and you've even remembered to use PascalCase. Keep up the good work!


5-5: Excellent categorization, class!

Your tags property is like a well-organized library catalog. By using WIDGET_TAGS.INPUTS, you've correctly shelved our DatePicker in the 'Inputs' section. This will make it easy for others to find and use. Bravo!


6-6: Good thinking on metadata, but let's dot our i's and cross our t's!

Setting needsMeta to true is like remembering to bring extra pencils to an exam – always a good idea! For a DatePicker, this likely refers to additional configuration options.

However, class, let's make sure we're leaving clear instructions for the next group. Could we add a comment or update the documentation to explain what kind of metadata this widget needs? It's like leaving a note for the next class – it's just good manners!

Let's check if there's any existing documentation for this widget:

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/types.ts (2)

1-1: Well done, class! The import statement is spot on.

You've correctly imported the WidgetProps type from the "widgets/BaseWidget" module. This is essential for extending the WidgetProps interface in your new WDSDatePickerWidgetProps interface. Keep up the good work!


3-3: Excellent work on your interface declaration, students!

Your WDSDatePickerWidgetProps interface is well-named, following the component name convention. By extending WidgetProps, you've ensured that your date picker widget will have all the common widget properties. This is a textbook example of good TypeScript practices!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/index.ts (2)

1-7: Class, let's examine the structure of this configuration file.

Good morning, students! Today, we're going to analyze a well-organized configuration file. This file serves as a central hub for exporting various configurations related to our WDSDatePickerWidget. It's like a table of contents for a textbook, guiding us to different chapters of our widget's configuration.

Let's break it down:

  1. We have a wildcard export for propertyPaneConfig.
  2. We have individual named exports for other configurations.

This structure allows for easy import of specific configurations in other parts of our codebase. It's a prime example of modular code organization, which we've discussed in our previous lessons on clean code practices.


2-7: Excellent organization of configuration exports, class!

Now, let's turn our attention to lines 2-7. What do you notice about these export statements?

That's right! They're all named exports for specific configurations. This is a fantastic example of clear and explicit code organization. Each export represents a different aspect of our widget's configuration:

  1. metaConfig
  2. anvilConfig
  3. defaultsConfig
  4. settersConfig
  5. methodsConfig
  6. autocompleteConfig

Notice how they all follow the same naming convention, ending with 'Config'. This consistency makes our code more readable and predictable. It's like having a well-organized bookshelf where each book's spine follows the same format!

This separation of concerns into different configuration files is a prime example of the Single Responsibility Principle we discussed in our SOLID principles lesson. Each file likely focuses on one aspect of the widget's configuration.

For your group project, I want you to think about how you might apply this organization pattern in your own code. How could this improve your project's structure?

app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (1)

1-1: Well done, class! The import statement is correct.

You've properly imported React, which is necessary for JSX syntax. This follows best practices for React components. Keep up the good work!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/helpers.ts (2)

1-1: Good job on importing the necessary type, class!

The import statement is clean and precise. It shows that you're paying attention to type safety, which is crucial in our TypeScript classroom.


1-15: Class, let's summarize our lesson on input validation!

You've done a commendable job creating this validateInput function. It's a good start, but remember, in the world of software development, we always strive for improvement. The suggestions I've provided will make your code more robust and internationally friendly.

Keep up the good work, and don't forget to apply these principles in your future assignments. Learning is a journey, and you're making excellent progress!

app/client/packages/design-system/widgets/src/components/Calender/src/types.ts (3)

1-4: Excellent work on the import statement, class!

Your use of named imports with type aliases is a stellar example of clear and organized code. It's like labeling your pencil case compartments – everything has its place!


6-7: A gold star for your CalendarCellProps type definition!

You've done a marvelous job extending the HeadlessCalendarCellProps and incorporating React's RefAttributes. It's like adding an extra subject to your curriculum – it broadens the capabilities of your calendar cells!


9-10: Bravo on your consistent approach with CalendarHeaderCellProps!

Just like your CalendarCellProps, you've extended the base type and added RefAttributes. This consistency is like using the same formatting in all your essays – it makes your code easy to read and understand. Keep up the excellent work!

app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/FieldCalenderPopover.tsx (1)

1-3: Well done, class! Your imports are in order.

I'm pleased to see that you've organized your imports neatly. You've brought in React, followed by the necessary components from external libraries. This shows good attention to detail and follows best practices.

app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1)

2-2: Class, let's examine the changes to our SVG icon!

Now, pay attention to the subtle modifications in our ComboboxSelectIcon component:

  1. The circle's radius has been adjusted from 2 to 2.079. This slight increase will make the circle a tad larger, potentially improving visibility.

  2. The path data for the filled path has been modified. These changes in coordinates and path commands will alter the shape of our icon.

These adjustments, while small, can have a significant impact on the overall appearance of our icon. It's crucial to ensure these changes align with our design guidelines and improve the icon's clarity and aesthetics.

To verify these changes, let's run a quick visual inspection:

After running this script, please review the icon in your browser to ensure the changes have the desired effect.

✅ Verification successful

Alright, let's proceed by examining the exact changes made to the SVG icon code.

To accurately identify the modifications, please run the following script. It will compare the current version of ComboboxSelectIcon.tsx with the base branch, highlighting any differences in the SVG elements:

After executing this script, review the output to see the specific changes made to the SVG code. This will help determine if the adjustments align with our design requirements.


Great job so far! Let's take the next step to identify the correct base branch for our comparison.

To ensure we're comparing the right branches, please run the following script. It will list all remote branches, helping us identify the correct base branch to use for the git diff:

Once you've identified the correct base branch (for example, origin/master), you can use it in the git diff command to review the changes made to the ComboboxSelectIcon.tsx file.


Excellent progress! Now that we've identified origin/release as the correct base branch, let's compare your current changes against it to pinpoint the exact modifications made to the SVG icon.

Please execute the following script to perform the comparison:

This script will display the differences between your current ComboboxSelectIcon.tsx file and the one in the origin/release branch. Review the output to identify the specific changes made to the SVG elements and ensure they align with our design guidelines.


**Well done!

The updates to the ComboboxSelectIcon component have been carefully reviewed. The subtle increase in the circle's radius from 2 to 2.079 and the slight modifications to the path data effectively enhance the icon's clarity and aesthetics without introducing any issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Generate a visual representation of the icon for review

# Test: Create an HTML file with the SVG and open it in the default browser
cat << EOF > icon_preview.html
<!DOCTYPE html>
<html>
<body>
<h2>ComboboxSelectIcon Preview</h2>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7M14.5 7.5l-1 1-1-1"/><circle cx="5.5" cy="7.5" r="2.079" stroke="#000"/><path fill="#000" d="m7.534 8.685-.424-.424-.849.849.424.424zm.042 1.74a.6.6 0 0 0 .848-.85zm-.89-.891.89.89.848-.848-.89-.89z"/></svg>
</body>
</html>
EOF

# Open the HTML file in the default browser (this command may vary depending on the OS)
xdg-open icon_preview.html || open icon_preview.html || start icon_preview.html

Length of output: 309


Script:

#!/bin/bash
# Description: Compare the current SVG icon with the base branch to identify changes

# Ensure we're on the correct branch
git fetch origin
git diff origin/main -- app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx

Length of output: 148


Script:

#!/bin/bash
# Description: List all remote branches to identify the correct base branch

git fetch --all
git branch -r

Length of output: 82


Script:

#!/bin/bash
# Description: Compare the current SVG icon with the origin/release branch to identify changes

# Fetch the latest changes from the remote repository
git fetch origin

# Compare the current file with the origin/release branch
git diff origin/release -- app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx

Length of output: 1366

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/autocompleteConfig.ts (1)

1-1: Very good, class! Let's examine our import statement.

I see you've imported DefaultAutocompleteDefinitions from "widgets/WidgetUtils". This is a smart choice for our DatePicker widget configuration. It shows you're thinking ahead and using our existing utilities. Well done!

app/client/packages/design-system/widgets/src/components/Calender/src/CalendarCell.tsx (3)

1-6: Well done on your import statements, class!

You've shown a good understanding of how to properly import dependencies. Your use of named imports and local modules demonstrates excellent organization skills.


8-16: Excellent work on your component structure, students!

Your CalendarCell component is well-organized and follows React best practices. The use of props destructuring and leveraging the HeadlessCalendarCell for accessibility is commendable.


18-18: A gold star for your export statement!

Your use of a named export for the CalendarCell component is spot-on. This approach promotes clear and explicit imports, which is excellent for maintaining readable and maintainable code.

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/defaultsConfig.ts (2)

1-2: Well done on your imports, class!

You've correctly imported the necessary modules for our DatePicker widget configuration. The ResponsiveBehavior and WidgetDefaultProps will serve us well in defining our widget's behavior and ensuring type safety.


7-7: Let's discuss our date format, shall we?

The current dateFormat of "YYYY-MM-DD HH:mm" includes both date and time. Is this intentional for our DatePicker? If we're only picking dates, we might want to consider using just "YYYY-MM-DD". Remember, clarity in our UI is key!

app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeaderCell.tsx (3)

1-5: Well done on your imports, class!

I'm pleased to see you've organized your imports neatly. You've brought in React, the necessary components, and even remembered to import your prop types. Keep up the good work!


19-19: Excellent work on your export, class!

You've correctly used a named export for your CalendarHeaderCell component. This is the preferred approach in modern JavaScript modules. It makes importing specific components easier and helps with code splitting. Keep up the good work!


1-19: Class, let's summarize our lesson on the CalendarHeaderCell component!

Overall, you've done an excellent job creating this new React component. Your code is well-structured, uses appropriate imports, and follows React best practices. The use of a design system component for styling is commendable.

We've identified a few areas for improvement:

  1. Being more explicit with prop spreading to avoid unintended prop pollution.
  2. Considering making style properties customizable for increased flexibility.

These suggestions are like fine-tuning your teaching methods - they'll make your already good component even better!

Remember, in coding as in teaching, there's always room for improvement. Keep up the great work, and don't hesitate to ask if you have any questions!

app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (2)

1-1: Very good, class! The import statement is correct.

You've properly imported React, which is essential for creating our React component. Keep up the good work!


2-2: Excellent job on the component declaration!

You've used a named export constant arrow function, which is a great way to define our React component. The naming convention is spot-on, and you've made it available for use throughout our application. Well done!

app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeading.tsx (2)

1-3: Well done on your import statements, class!

I'm pleased to see you've used named imports, which makes our code more readable. It's like labeling your pencil case – everything is easy to find! The imports you've chosen are just right for what we're building. Keep up the good work!


19-19: Good job using forwardRef, class!

You've correctly wrapped your component with forwardRef. It's like putting a stamp on an envelope – it ensures your component can be properly "delivered" with its ref intact.

Now, about that underscore in _CalendarHeading... Can anyone tell me why we might use an underscore prefix? It's typically used for internal or private variables. Is that what we intend here?

Let's check if this naming convention is consistent in our project:

If we find other instances, it might be a pattern. If not, we might want to reconsider this naming convention.

✅ Verification successful

Let's adjust our approach to search for underscore-prefixed exports in TypeScript files.


Let's revise our search strategy to locate underscore-prefixed exports in TypeScript files.


Alright, class, let's review what we've discovered about our _CalendarHeading export!

It seems that using an underscore prefix for exports is quite common in this project. We've found our line of interest:

export { _CalendarHeading as CalendarHeading };

This is an interesting pattern, isn't it? The underscore usually suggests something is private or internal, but here we're exporting it and giving it a public-facing name without the underscore.

Now, let's think about this. Is this a good practice? Well, it depends on the project's conventions. It could be a way to mark the original implementation as "internal" while providing a clean public interface. However, it might also be a bit confusing for newcomers to the codebase.

Here's what I'd like you to consider:

  1. Is this naming convention documented in the project guidelines?
  2. Does it provide any benefits in terms of code organization or clarity?
  3. Could it potentially lead to confusion for other developers?

Remember, consistency is key in coding standards. If this is the agreed-upon convention for the project, then it's fine to keep it. However, if it's not, we might want to suggest standardizing the approach across the codebase.

What do you think, class? Should we keep this convention or consider an alternative approach? Let's have a discussion about it!

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other instances of underscore-prefixed exports

# Test: Search for export statements with underscore-prefixed identifiers
rg --type typescript "export.*_[A-Z]"

Length of output: 74


Script:

#!/bin/bash
# Description: Check for export statements with underscore-prefixed identifiers in TypeScript files

# Test: Search for export statements with underscore-prefixed identifiers
rg "export\s+.*_[A-Z]" --glob "*.ts" --glob "*.tsx"

Length of output: 212742


Script:

#!/bin/bash
# Description: Check for export statements with underscore-prefixed identifiers in TypeScript files

# Test: Search for export statements with underscore-prefixed identifiers
rg "export\s+.*_[A-Z]" --glob "*.ts" --glob "*.tsx"

Length of output: 212742

app/client/packages/design-system/widgets/src/components/DatePicker/src/types.ts (3)

1-7: Well done on your import statements, class!

You've shown a good understanding of how to import the necessary types for our DatePicker component. I particularly like how you've renamed DatePickerProps to SpectrumDatePickerProps to avoid any confusion. Keep up the good work!


8-27: Excellent work on your DatePickerProps interface, students!

Your interface is well-structured and clearly documented. The use of JSDoc comments for each property is exemplary and will greatly help other developers understand how to use this component. I'm particularly impressed with how you've handled the 'errorMessage' property, allowing for both simple strings and more complex validation functions.


29-29: A gold star for your type export, class!

Re-exporting the DateValue type is a smart move. It shows you're thinking about how other parts of the application will use these types. This kind of forward-thinking approach will serve you well in your coding journey!

app/client/packages/design-system/widgets/src/components/Calender/src/Calendar.tsx (2)

29-37: An organized calendar grid structure, students!

Your use of the HeadlessCalendarGrid components shows a good understanding of the react-aria-components library. The implementation of custom CalendarHeaderCell and CalendarCell components is a smart approach for tailored styling and behavior.

To ensure everything is in order, let's take a look at the implementation of these custom cell components. Run the following command:

#!/bin/bash
# Description: Find the implementation of CalendarCell and CalendarHeaderCell components
fd -e tsx -e ts "CalendarCell|CalendarHeaderCell"

This will help us verify that these components are properly implemented. Remember, just like in a science experiment, we need to examine all the parts to understand the whole!


24-28: A well-structured calendar header, class!

Your use of the Flex component for layout shows good understanding of modern CSS techniques. The placement of navigation buttons with appropriate slots is correct, and the inclusion of a CalendarHeading is a nice touch.

However, I'd like to see more about the CalendarHeading component. Can you show me its implementation? Let's use this command to find it:

This will help us ensure that the CalendarHeading component is properly implemented and styled. Remember, in coding as in the classroom, it's important to show your work!

✅ Verification successful

Great attention to detail! However, it seems we couldn't locate a CalendarHeading.tsx file. Let's ensure that the CalendarHeading component exists and verify its implementation. Could you please run the following command to search for any references to CalendarHeading within the codebase?


It looks like the previous command encountered an issue recognizing the .tsx file type. Let's adjust our approach to ensure we search within the correct file extensions.


CalendarHeading Component Verified

The CalendarHeading component is correctly implemented and properly integrated within the calendar header.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find the implementation of CalendarHeading component
fd -e tsx -e ts CalendarHeading.tsx

Length of output: 231


Script:

#!/bin/bash
# Description: Search for references to CalendarHeading component in the codebase
rg 'CalendarHeading' --type tsx --type ts

Length of output: 69


Script:

#!/bin/bash
# Description: Search for references to CalendarHeading component in .ts and .tsx files
rg 'CalendarHeading' -g '*.ts' -g '*.tsx'

Length of output: 834

app/client/packages/design-system/widgets/src/components/Text/src/types.ts (1)

38-38: Class, let's examine this change carefully.

Now, children, we've made an interesting modification to our TextProps interface. By adding that little question mark after children, we've turned it from a required field into an optional one. This is quite a significant change, wouldn't you agree?

Let's think about the implications:

  1. Flexibility: This change allows us to create Text components without necessarily providing children. It's like allowing a book to exist without any pages - unusual, but sometimes necessary!

  2. Potential misuse: We must be cautious, though. Just as a book without pages might confuse readers, a Text component without content might perplex our users. We should ensure that our fellow developers understand when and why they might use this option.

  3. Default behavior: We should consider what happens when no children are provided. Does our Text component handle this gracefully, or might it cause unexpected behavior?

  4. Documentation: It would be wise to update our documentation to reflect this change. We want to make sure everyone in our class understands this new flexibility.

Remember, class, with great power comes great responsibility. This change gives us more options, but we must use them wisely!

Let's do a little homework to make sure we understand how this change affects our codebase:

Class, let's run this script and see what we find. It will help us understand if developers are already anticipating this change!

✅ Verification successful

Great job, class!

After running our checks, it looks like there are no instances where the Text component is used without children or with empty strings. This means making the children property optional won't introduce any issues in our current codebase.

Keep up the excellent work!

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of Text component without children

# Test: Search for Text component usage without children
echo "Searching for Text component usage without children:"
rg --type typescript --type javascript 'Text[^>]*>[[:space:]]*</Text>' -g '!**/node_modules/**'

# Test: Search for Text component usage with empty string as children
echo "Searching for Text component usage with empty string as children:"
rg --type typescript --type javascript 'Text[^>]*>""</Text>' -g '!**/node_modules/**'

Length of output: 511


Script:

#!/bin/bash
# Description: Check for usage of Text component without children

# Test: Search for Text component usage without children
echo "Searching for Text component usage without children:"
rg 'Text[^>]*>[[:space:]]*</Text>' -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx" -g "!**/node_modules/**"

# Test: Search for Text component usage with empty string as children
echo "Searching for Text component usage with empty string as children:"
rg 'Text[^>]*>""</Text>' -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx" -g "!**/node_modules/**"

Length of output: 453

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.test.js (2)

1-2: Well done on your import statements, class!

You've correctly imported the necessary modules for your test file. The moment library will be useful for date manipulation, and the derived module contains the function we're testing. Keep up the good work!


7-11: A gold star for your first test case!

This test effectively checks the behavior when isDirty is false. It's an important edge case to cover, and you've done it well. Remember, class, always start with the simplest cases and build up from there!

app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/constants.ts (1)

1-2: Well done on your imports, class!

You've correctly imported the necessary modules for our date formatting lesson. The moment library will be our trusty tool for working with dates, and SubTextPosition will help us organize our information neatly.

app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css (1)

34-38: Well done, class! These new styles for date input are a step in the right direction.

Let's examine what we've learned here:

  1. The use of display: flex creates a flexible container for our date input elements.
  2. The gap property ensures consistent spacing between child elements.
  3. align-items: center keeps everything neatly aligned vertically.

These changes will result in a more organized and visually appealing date input field. Keep up the good work!

app/client/packages/icons/src/stories/Icons.mdx (3)

3-3: Well done, class! Your import statements are in perfect order.

I'm pleased to see that you've added the new icon imports while maintaining the alphabetical order. This attention to detail makes our code more organized and easier to read. Keep up the good work!

Also applies to: 9-9


41-41: Excellent job incorporating the new icons, students!

I'm impressed by how you've seamlessly integrated the new AIChatIcon and DatePickerIcon into our Icons component. Your adherence to alphabetical order shows a commendable understanding of code organization. This consistency will make it easier for your classmates to find and use these icons in the future.

Also applies to: 47-47


3-3: Class, let's recap our lesson on adding new icons!

Today, we've learned how to expand our icon library with two new additions: AIChatIcon and DatePickerIcon. These changes demonstrate:

  1. Proper import practices
  2. Consistent component integration
  3. Maintaining alphabetical order

Remember, children, these small details in code organization make a big difference in the long run. It's like keeping your desk tidy – it helps you find what you need quickly and makes your work more efficient.

Great job on this assignment! You've shown a good understanding of how to contribute to our growing icon collection.

Also applies to: 9-9, 41-41, 47-47

app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx (5)

1-17: Well done, class! Your imports and metadata are spot on!

You've correctly imported all the necessary dependencies and components. The metadata for the Storybook component is also properly defined. Keep up the good work!


28-39: A gold star for your WithDefaultValue story!

You've done an excellent job demonstrating how to set a default value and placeholder for the DatePicker. The use of the parseDate function is particularly commendable - it ensures that the date is correctly formatted. Keep up this attention to detail!


56-61: Your Loading story deserves an A+!

You've done an excellent job demonstrating the loading state of the DatePicker. The use of a placeholder during loading is a great touch - it helps users understand that the component is in a loading state. This is a prime example of good user experience design. Well done!


83-89: Your ContextualHelp story is a shining example, class!

You've done an excellent job demonstrating the use of contextual help with the DatePicker. The combination of a clear label, helpful placeholder, and informative contextual help text creates a user-friendly experience. This is exactly the kind of thoughtful design we want to see. Keep up the great work!


107-116: Your Granularity story deserves a round of applause!

You've done an outstanding job demonstrating the different granularity settings for the DatePicker. The clear presentation of day, hour, minute, and second granularities provides a comprehensive overview of the component's capabilities. The use of a Flex container with appropriate spacing ensures a clean and organized layout. This story will be incredibly helpful for users to understand and choose the right granularity for their needs. Excellent work!

app/client/packages/icons/src/stories/Thumbnails.mdx (3)

3-3: Well done, class! Let's examine these new imports.

I'm pleased to see that you've added two new thumbnail components to our collection. The AIChatThumbnail and DatePickerThumbnail are excellent additions to our widget family. Your import statements are neat and tidy, following the same pattern as the existing ones. Keep up the good work!

Also applies to: 9-9


42-42: Excellent job integrating the new thumbnails!

I'm impressed with how you've seamlessly incorporated the AIChatThumbnail and DatePickerThumbnail into our Icons component. Your placement of these new elements shows a good understanding of alphabetical order and maintains the clean, organized structure of our code. This will make it easy for your classmates to find and use these new widgets. Keep up this attention to detail!

Also applies to: 48-48


Line range hint 1-74: Class, let's recap today's lesson on adding new thumbnails!

Today, we've learned how to expand our widget library by adding two exciting new thumbnails: AIChatThumbnail and DatePickerThumbnail. These additions will enrich our user interface and provide more options for our developers.

Here's what we've accomplished:

  1. We've imported the new thumbnail components correctly.
  2. We've added them to our Icons component in the right order.
  3. We've maintained the consistency and readability of our code.

Remember, class, when adding new components, always follow these steps to keep our codebase organized and easy to understand. Great job on this assignment!

app/client/src/widgets/index.ts (2)

90-90: Excellent addition, class! Let's review this import statement.

Now, students, pay attention to line 90. We've added a new import statement for the WDSDatePickerWidget. This is a crucial step in expanding our widget library. Can anyone tell me why this import is important? That's right! It allows us to use the new Datepicker Widget in our application.


189-189: Well done on updating the WDSWidgets array!

Class, let's turn our attention to line 189. Here, we've added WDSDatePickerWidget to our WDSWidgets array. This is like adding a new tool to our toolbox. Can anyone explain why this step is necessary? Correct! By including it in this array, we're making the widget available for use throughout our application.

Remember, students, always keep your widget arrays up-to-date. It's as important as keeping your pencils sharpened!

@@ -0,0 +1,7 @@
export * from "./propertyPaneConfig";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Attention: Missing propertyPaneConfig.ts File

It appears that the export statement in WDSDatePickerWidget/config/index.ts is referencing a propertyPaneConfig.ts file that does not exist in the specified path. This could lead to import errors and disrupt the functionality of the widget. Please verify if the file has been renamed, moved, or needs to be created.

  • File in Question:

    • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/index.ts
  • Issue:

    • export * from "./propertyPaneConfig"; references a non-existent propertyPaneConfig.ts.
🔗 Analysis chain

Let's discuss the use of wildcard export, class.

Now, pay attention to line 1. We see a wildcard export for propertyPaneConfig. Can anyone tell me why we might use a wildcard export instead of named exports?

While wildcard exports can be convenient, they can sometimes lead to naming conflicts or make our code less explicit. However, in this case, it might be intentional if propertyPaneConfig exports multiple items that are frequently used together.

For your homework, I want you to consider: What are the pros and cons of using wildcard exports in this context? How might it affect code maintainability and readability?

Let's verify the contents of the propertyPaneConfig file:


Let's investigate further to locate the propertyPaneConfig.ts file.


Alright class, let's take a closer look to understand why the propertyPaneConfig.ts file is missing. We'll search the entire codebase for any references to propertyPaneConfig to see if it has been moved or renamed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the contents of propertyPaneConfig.ts

# Test: Display the contents of propertyPaneConfig.ts
cat app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig.ts

Length of output: 217


Script:

#!/bin/bash
# Description: Search for propertyPaneConfig.ts in the codebase

fd 'propertyPaneConfig.ts'

Length of output: 26


Script:

#!/bin/bash
# Description: Search for any references to 'propertyPaneConfig' in the codebase

rg 'propertyPaneConfig'

Length of output: 11810

@@ -0,0 +1,2 @@
import React from "react";
export const DatePickerIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M12.5 1.5h-10a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-10a1 1 0 0 0-1-1M9.5 5.5v8M5.5 5.5v8M1.5 5.5h12M1.5 9.5h12M4.5 3.5v-3m6 3v-3"/></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Let's make our icon accessible to everyone, class!

While your SVG looks great visually, we need to ensure it's understandable to all users, including those using assistive technologies. Can anyone tell me what we're missing? That's right, we need to add accessibility attributes!

Here's how we can improve our SVG:

<svg aria-label="Date Picker" role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
  {/* ... rest of the SVG ... */}
</svg>

By adding aria-label="Date Picker" and role="img", we're ensuring that screen readers can properly interpret our icon. Remember, in our classroom and in web development, we always strive for inclusivity!

Comment on lines 3 to 15
export function validateInput(props: WDSDatePickerWidgetProps) {
if (!props.isValid) {
return {
validationStatus: "invalid",
errorMessage: "Please select a valid date",
};
}

return {
validationStatus: "valid",
errorMessage: "",
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's examine our function structure, shall we?

Class, your validateInput function is well-structured and exported correctly. However, I have a few points for you to consider:

  1. Error Handling: What happens if props is undefined? Let's add a safety check.
  2. Localization: The error message is hardcoded. Consider using a localization function for better internationalization.
  3. Type Assertion: Let's be extra careful and assert that isValid exists on props.

Here's how we could improve our function:

import { t } from "i18next"; // Assuming you're using i18next for localization

export function validateInput(props?: WDSDatePickerWidgetProps) {
  if (!props) {
    return {
      validationStatus: "invalid",
      errorMessage: t("common.errors.invalidProps"),
    };
  }

  if (!("isValid" in props) || !props.isValid) {
    return {
      validationStatus: "invalid",
      errorMessage: t("datePicker.errors.invalidDate"),
    };
  }

  return {
    validationStatus: "valid",
    errorMessage: "",
  };
}

This version adds error handling for undefined props, uses a localization function, and checks if isValid exists on props. What do you think about these improvements?

Comment on lines 5 to 8
export function FieldCalenderPopover() {
const root = document.body.querySelector(
"[data-theme-provider]",
) as HTMLButtonElement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Let's review our root element selection, shall we?

While your component declaration is spot-on, I have a few concerns about how we're selecting our root element:

  1. We're assuming the existence of an element with [data-theme-provider]. What if it's not there?
  2. We're casting the result to HTMLButtonElement. Are we certain it's always a button?
  3. This selection happens on every render. That's like checking the attendance every minute!

Let's consider using useRef and useEffect to select this element once and store it. Also, let's be more flexible with our type casting.

Here's a suggestion to improve this:

import React, { useRef, useEffect } from "react";

export function FieldCalenderPopover() {
  const rootRef = useRef<HTMLElement | null>(null);

  useEffect(() => {
    rootRef.current = document.body.querySelector("[data-theme-provider]");
  }, []);

  if (!rootRef.current) return null;

  return (
    <Popover UNSTABLE_portalContainer={rootRef.current}>
      {/* ... rest of your component ... */}
    </Popover>
  );
}

This approach is more efficient and safer. What do you think?

Comment on lines 10 to 16
return (
<Popover UNSTABLE_portalContainer={root}>
<Dialog>
<Calendar />
</Dialog>
</Popover>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Add a TODO to Replace UNSTABLE_portalContainer When Stable Alternative Is Available

Currently, there are no stable alternatives to the UNSTABLE_portalContainer prop in the Popover component. Please add a TODO comment to revisit this implementation once a stable version becomes available.

🔗 Analysis chain

Let's discuss your component structure and that intriguing prop name.

Your component structure is well-organized, like a neatly arranged classroom. The use of Dialog from react-aria-components shows good consideration for accessibility. Gold star for that!

However, I'm a bit concerned about the UNSTABLE_portalContainer prop. Using unstable APIs is like building a house on shaky ground. It might work now, but what about the future?

Let's investigate this further. Can you run this command to check if there's a stable alternative?

If there's no stable alternative, we should add a TODO comment to revisit this when a stable version becomes available. Remember, good code is like a good lesson plan - it should be reliable and future-proof!


Let's refine our approach to find a stable alternative for the UNSTABLE_portalContainer prop in the Popover component. I'll run a corrected search to gather the necessary information.


Let's take another shot at narrowing down those Popover component usages. We'll adjust our search to look directly for TypeScript files. Let's run the following script to gather the necessary information:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for stable alternatives to UNSTABLE_portalContainer in Popover component

# Test: Search for Popover component usage and props
rg --type typescript -A 10 'Popover.*?{' ./app/client/packages/design-system

Length of output: 164


Script:

#!/bin/bash
# Description: Check for stable alternatives to UNSTABLE_portalContainer in Popover component

# Corrected regex to search for Popover component usage and its props
rg --type typescript 'Popover\s*\{' ./app/client/packages/design-system --context 10

Length of output: 121


Script:

#!/bin/bash
# Description: Check for stable alternatives to UNSTABLE_portalContainer in Popover component

# Search for Popover component usage in .ts and .tsx files with context
rg 'Popover\s*\{' --glob '*.ts*' ./app/client/packages/design-system --context 10

Length of output: 7641

sectionName: "Label",
children: [
{
helpText: "Sets the label text of the options widget",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure the correct widget name in the help text

The help text refers to the "options widget," but this configuration is for the date picker widget. Let's update it for accuracy.

Suggested modification:

-helpText: "Sets the label text of the options widget",
+helpText: "Sets the label text of the date picker widget",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
helpText: "Sets the label text of the options widget",
helpText: "Sets the label text of the date picker widget",

children: [
{
helpText: "Show help text or details about current input",
propertyName: "labelTooltip",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve the grammar in the help text

For better readability, let's correct the grammar in the help text.

Recommended adjustment:

-helpText: "Show help text or details about current input",
+helpText: "Shows help text or details about the current input.",

Committable suggestion was skipped due to low confidence.

propertyName: "timePrecision",
label: "Time Precision",
controlType: "DROP_DOWN",
helpText: "Sets the different time picker or hide.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Let's improve the clarity of the help text for 'timePrecision'

The current help text is a bit unclear. Consider rephrasing it to better convey its purpose.

Here's a suggested change:

-helpText: "Sets the different time picker or hide.",
+helpText: "Sets the time precision or hides the time picker.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
helpText: "Sets the different time picker or hide.",
helpText: "Sets the time precision or hides the time picker.",

{
propertyName: "onDateSelected",
label: "onDateSelected",
helpText: "when a date is selected in the calendar",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure consistency in help text formatting

Help text should start with a capital letter and be a complete sentence. Let's adjust it accordingly.

Suggested revision:

-helpText: "when a date is selected in the calendar",
+helpText: "Triggered when a date is selected in the calendar.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
helpText: "when a date is selected in the calendar",
helpText: "Triggered when a date is selected in the calendar.",

Comment on lines +56 to +59
const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns);

return merge(super.getDerivedPropertiesMap(), {
isValid: `{{(() => {${derivedProperties.isValid}})()}}`,
isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Understanding the use of super in static methods

Students, it's important to note that using super inside a static method can sometimes be confusing. In JavaScript and TypeScript, super in a static context refers to the parent class. While it's technically allowed, for clarity and maintainability, it's often better to use the class name directly. This makes the code more explicit and easier to understand.

Let's consider updating the code to reference the parent class by its name:

- return merge(super.getDerivedPropertiesMap(), {
+ return merge(WDSBaseInputWidget.getDerivedPropertiesMap(), {
    isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`,
});

This change enhances readability and makes it clear which class's method is being called.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns);
return merge(super.getDerivedPropertiesMap(), {
isValid: `{{(() => {${derivedProperties.isValid}})()}}`,
isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`,
const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns);
return merge(WDSBaseInputWidget.getDerivedPropertiesMap(), {
isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`,
🧰 Tools
🪛 Biome

[error] 58-58: Using super in a static context can be confusing.

super refers to a parent class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

@@ -11,16 +11,6 @@
font-family: var(--font-family) !important;
}

th, td,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this as it was interfering with calender cells styles.

* @param propertyFns
* @returns
*/
export function parseDerivedProperties(propertyFns: Record<string, unknown>) {
Copy link
Contributor Author

@jsartisan jsartisan Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@riodeuno Need your review on this.
So, in all widgets, we used to use parseDerivedProperties.js file and copy it to almost every widget ( A sign that it must be abstracted to a common function. ). I tried to abstract that logic to a separate function that can be re-used. Instead of loading the derived.js file with raw loader, we can just simply load it and parse it. What do you think of this approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsartisan I really appreciate this change.
Let's make sure that this is used across all widgets in a separate PR and cleanup our code.

This function may find itself in another file in the future, but for now this looks fine to me.

@@ -52,8 +53,10 @@ class WDSInputWidget extends WDSBaseInputWidget<InputWidgetProps, WidgetState> {
}

static getDerivedPropertiesMap(): DerivedPropertiesMap {
const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@riodeuno This is how we can use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need this component because calender consumes HeadingContext to display the months in popover header. so had to create this so that I could wrap the text in our Text component.

} from "react-aria-components";

import type { DatePickerProps } from "./types";
import styles from "../../ComboBox/src/styles.module.css";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just reusing the styels from combobox.

Copy link
Contributor Author

@jsartisan jsartisan Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, this component is just useless. I created it because we created FieldListPopover I get it we did so that we can reuse the same component in select as well right? We should have just created our ListBox and add our styles and use it in Select and Comobox.

* }
* ```
*
* Main rule to remember is don't use deconstruct the props like `const { value } = props;` in the derived property function. Directly access props like `props.value`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we write a test for this? Or at a lint rule?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can add a guard with a test. The lint rule would be better. I'll pick that up as a separate task.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 017bea0 and 7e14ef0.

📒 Files selected for processing (2)
  • app/client/packages/icons/src/stories/Icons.mdx (2 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/contentConfig.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/packages/icons/src/stories/Icons.mdx
🔇 Additional comments (3)
app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/contentConfig.ts (3)

4-70: Well done on the Data section configuration, class!

I'm pleased to see such a comprehensive setup for the Data section. You've covered all the essential aspects:

  1. The date format selection using a dropdown is an excellent choice. It ensures consistency and prevents user errors.
  2. The default date configuration with a date picker control is spot-on. It provides an intuitive interface for users.
  3. The time precision property is a thoughtful addition, allowing for flexible time selection granularity.

Keep up the good work! Your attention to detail is commendable.


86-122: Excellent work on the Validations section, students!

I'm impressed with your thorough approach to input validation. Let's review what you've done well:

  1. The isRequired property ensures that users provide input when necessary.
  2. The minDate and maxDate properties allow for setting date ranges, which is crucial for many applications.
  3. You've used the appropriate DATE_PICKER control type for both minDate and maxDate, making it easy for users to set these values.

Your attention to these details will help prevent user errors and ensure data integrity. Well done!


1-183: Excellent work on your Date Picker Widget configuration, class!

You've done a commendable job in creating a comprehensive and well-structured configuration for the Date Picker Widget. Let's recap our lesson:

  1. Your Data section is thorough and provides great flexibility for users.
  2. The Validations section ensures data integrity, which is crucial in any application.
  3. The General section covers important widget behaviors.
  4. The Events section, while simple, captures the essential interaction.

We've identified a few areas for improvement, mainly in labeling and help text. These are minor adjustments that will greatly enhance the clarity and professionalism of your work.

Remember, in programming, as in any discipline, it's not just about functionality - it's also about creating a clear, intuitive experience for your users. The changes we've discussed today will help achieve that goal.

Keep up the excellent work, and don't forget to implement the suggested improvements. I look forward to seeing your revised configuration!

Comment on lines +71 to +85
{
sectionName: "Label",
children: [
{
helpText: "Sets the label text of the date picker widget",
propertyName: "label",
label: "Text",
controlType: "INPUT_TEXT",
placeholderText: "Label",
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.TEXT },
},
],
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's make a small improvement to our label, shall we?

Class, I noticed a small area where we can enhance our work. In the Label section:

{
  helpText: "Sets the label text of the date picker widget",
  propertyName: "label",
  label: "Text",
  // ... other properties
}

It would be more intuitive if we changed the label from "Text" to "Label". This small change will make it clearer for our users. Let's update it like this:

label: "Label",

Remember, clarity is key in user interface design. This minor adjustment will help our users understand the purpose of this field more easily.

Comment on lines +123 to +168
{
sectionName: "General",
children: [
{
helpText: "Shows help text or details about the current input",
propertyName: "labelTooltip",
label: "Tooltip",
controlType: "INPUT_TEXT",
placeholderText: "",
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.TEXT },
},
{
helpText: "Controls the visibility of the widget",
propertyName: "isVisible",
label: "Visible",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.BOOLEAN },
},
{
propertyName: "isDisabled",
label: "Disabled",
helpText: "Disables input to this widget",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.BOOLEAN },
},
{
propertyName: "animateLoading",
label: "Animate loading",
controlType: "SWITCH",
helpText: "Controls the loading of the widget",
defaultValue: true,
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.BOOLEAN },
},
],
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's polish our grammar, class!

In our General section, we have a small opportunity to improve. Take a look at the labelTooltip property:

{
  helpText: "Shows help text or details about the current input",
  propertyName: "labelTooltip",
  // ... other properties
}

To make our helpText more polished, let's adjust it slightly:

helpText: "Shows help text or details about the current input.",

Notice the added period at the end. It's a small change, but it makes our text more grammatically correct and professional. Remember, attention to these small details can make a big difference in the overall quality of our work!

Comment on lines +169 to +182
{
sectionName: "Events",
children: [
{
propertyName: "onDateSelected",
label: "onDateSelected",
helpText: "when a date is selected in the calendar",
controlType: "ACTION_SELECTOR",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: true,
},
],
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's make our Events section more user-friendly, class!

In our Events section, we have an opportunity to make things clearer for our users. Let's look at the onDateSelected property:

{
  propertyName: "onDateSelected",
  label: "onDateSelected",
  helpText: "when a date is selected in the calendar",
  // ... other properties
}

We can improve this in two ways:

  1. Let's make the label more descriptive:

    label: "When Date Selected",
  2. Let's capitalize the first letter of the helpText and end it with a period:

    helpText: "Triggered when a date is selected in the calendar.",

These changes will make our configuration more professional and easier to understand. Remember, clear communication is key in programming!

@jsartisan
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11104242240.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36605.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-36605.dp.appsmith.com

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (3)
app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx (3)

56-59: Let's examine our derived properties map!

Class, turn your attention to the getDerivedPropertiesMap method. We've made some interesting changes here:

  1. We're now using parsedDerivedProperties instead of derivedProperties. This is a good practice as it ensures our derived properties are properly parsed before use.

  2. However, we need to discuss the use of super in this static method. While it works, it can be confusing. Remember, in static contexts, super refers to the parent class, not an instance.

Let's improve this code to make it clearer:

static getDerivedPropertiesMap(): DerivedPropertiesMap {
  const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns);

  return merge(WDSBaseInputWidget.getDerivedPropertiesMap(), {
    isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`,
  });
}

By explicitly referencing the parent class WDSBaseInputWidget, we make our code more readable and avoid potential confusion. Who can tell me why this might be important in a team setting?

🧰 Tools
🪛 Biome

[error] 58-58: Using super in a static context can be confusing.

super refers to a parent class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


Line range hint 123-159: Let's analyze our key handling logic!

Students, I want you to focus on the onKeyDown method. We've made some significant improvements here:

  1. We've added strict input validation for numeric input. This is excellent defensive programming!

  2. We've implemented increment/decrement functionality using arrow keys. This enhances user experience for numeric inputs.

However, I'd like you to consider a small improvement. Instead of checking for numeric keys twice, we could simplify our logic:

if (
  !(
    /^\d$/.test(e.key) ||
    e.key === "Backspace" ||
    e.key === "Tab" ||
    e.key === "Enter" ||
    e.key === "ArrowUp" ||
    e.key === "ArrowDown" ||
    e.key === "ArrowLeft" ||
    e.key === "ArrowRight" ||
    e.key === "Delete" ||
    e.ctrlKey ||
    e.metaKey ||
    e.altKey
  )
) {
  e.preventDefault();
}

This uses a regular expression to check for numeric keys, making our code more concise. Can anyone explain why this might be a better approach?


Line range hint 220-228: Let's examine our new paste handling!

Students, I'd like to draw your attention to the new onPaste method. This is an excellent addition to our input validation strategy:

  1. It prevents non-numeric values from being pasted into numeric input fields.
  2. This complements our keydown handling, ensuring all input methods are properly validated.

However, I have a small suggestion to make this even better:

onPaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
  if (this.props.inputType === INPUT_TYPES.NUMBER) {
    const pastedValue = e.clipboardData.getData("text");
    if (!/^-?\d*\.?\d*$/.test(pastedValue)) {
      e.preventDefault();
    }
  }
};

This regular expression allows for negative numbers and decimals, which might be desirable for numeric input. Can anyone explain why we might want to allow these in certain scenarios?

Remember, thorough input validation is crucial for maintaining data integrity and preventing potential security issues. Excellent work on adding this extra layer of protection!

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3de191f and 733f523.

⛔ Files ignored due to path filters (3)
  • app/client/packages/icons/src/icons/Icons/ComboboxSelect.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Icons/DatePicker.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Thumbnails/DatePicker.svg is excluded by !**/*.svg
📒 Files selected for processing (46)
  • app/client/packages/design-system/widgets/src/components/Calender/index.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/Calendar.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarCell.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeaderCell.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeading.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/styles.module.css (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Calender/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/index.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/FieldCalenderPopover.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/components/Text/src/types.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/index.ts (1 hunks)
  • app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/index.ts (2 hunks)
  • app/client/packages/icons/src/stories/Icons.mdx (2 hunks)
  • app/client/packages/icons/src/stories/Thumbnails.mdx (2 hunks)
  • app/client/packages/storybook/.storybook/preview-head.html (0 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/anvilConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/autocompleteConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/defaultsConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/metaConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/methodsConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/contentConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/settersConfig.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/constants.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/index.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.js (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.test.js (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/helpers.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/index.tsx (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/types.ts (1 hunks)
  • app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx (2 hunks)
  • app/client/src/modules/ui-builder/ui/wds/constants.ts (1 hunks)
  • app/client/src/widgets/WidgetUtils.ts (1 hunks)
  • app/client/src/widgets/index.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • app/client/packages/storybook/.storybook/preview-head.html
🚧 Files skipped from review as they are similar to previous changes (43)
  • app/client/packages/design-system/widgets/src/components/Calender/index.tsx
  • app/client/packages/design-system/widgets/src/components/Calender/src/Calendar.tsx
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarCell.tsx
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeaderCell.tsx
  • app/client/packages/design-system/widgets/src/components/Calender/src/CalendarHeading.tsx
  • app/client/packages/design-system/widgets/src/components/Calender/src/index.ts
  • app/client/packages/design-system/widgets/src/components/Calender/src/styles.module.css
  • app/client/packages/design-system/widgets/src/components/Calender/src/types.ts
  • app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css
  • app/client/packages/design-system/widgets/src/components/DatePicker/index.ts
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/index.ts
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/types.ts
  • app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/index.tsx
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/FieldCalenderPopover.tsx
  • app/client/packages/design-system/widgets/src/components/FieldCalenderPopover/src/index.ts
  • app/client/packages/design-system/widgets/src/components/Text/src/types.ts
  • app/client/packages/design-system/widgets/src/index.ts
  • app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx
  • app/client/packages/icons/src/index.ts
  • app/client/packages/icons/src/stories/Icons.mdx
  • app/client/packages/icons/src/stories/Thumbnails.mdx
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/anvilConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/autocompleteConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/defaultsConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/index.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/metaConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/methodsConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/contentConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/propertyPaneConfig/index.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/config/settersConfig.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/constants.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/index.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.js
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/derived.test.js
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/helpers.ts
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/index.tsx
  • app/client/src/modules/ui-builder/ui/wds/WDSDatePickerWidget/widget/types.ts
  • app/client/src/modules/ui-builder/ui/wds/constants.ts
  • app/client/src/widgets/WidgetUtils.ts
  • app/client/src/widgets/index.ts
🧰 Additional context used
🪛 Biome
app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx

[error] 35-35: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 56-56: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 60-60: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx

[error] 58-58: Using super in a static context can be confusing.

super refers to a parent class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (4)
app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx (2)

1-70: Class dismissed, but remember your homework!

Excellent work today, class! We've reviewed our new DatePicker component and found a few areas for improvement. Let's recap our main lessons:

  1. Always check your spelling, especially in component names.
  2. Keep components independent by not sharing style files.
  3. Simplify boolean logic by removing unnecessary Boolean() calls.
  4. Maintain consistency in naming throughout your code.

For your homework, I'd like you to:

  1. Fix the spelling errors we found.
  2. Create a separate styles file for the DatePicker component.
  3. Remove the redundant Boolean() calls.

Remember, clean and clear code is happy code! Keep up the good work, and I look forward to seeing your improved DatePicker in our next class!

🧰 Tools
🪛 Biome

[error] 35-35: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 56-56: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 60-60: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


1-7: ⚠️ Potential issue

Class, let's correct our spelling!

Dear students, I've noticed a small error in our import statement. Can anyone spot the misspelling? That's right! 'FieldCalenderPopover' should be 'FieldCalendarPopover'. Remember, attention to detail is crucial in coding, just as it is in your essays!

Let's fix this together:

 import {
   FieldError,
   FieldDescription,
   FieldLabel,
-  FieldCalenderPopover,
+  FieldCalendarPopover,
   Button,
 } from "@appsmith/wds";

Now, doesn't that look much better? Always proofread your code, class!

Likely invalid or redundant comment.

app/client/src/modules/ui-builder/ui/wds/WDSInputWidget/widget/index.tsx (2)

16-17: Class, let's discuss the new imports!

Students, pay attention to lines 16-17. We've added two new imports:

import { parseDerivedProperties } from "widgets/WidgetUtils";
import derivedPropertyFns from "./derived";

These imports are crucial for our lesson on code organization. By separating the parsing of derived properties and the actual property functions, we're applying the principle of separation of concerns. This makes our code more modular and easier to maintain. Can anyone tell me why this might be beneficial in a large project?


Line range hint 161-189: Time to discuss component lifecycle management!

Class, let's examine the componentDidUpdate method. We've made some crucial improvements:

  1. We now update parsedText whenever rawText or inputType changes. This ensures our derived state is always in sync with the input.

  2. We've added logic to reset isDirty when defaultText changes. This is an important detail that maintains the correct state of our widget.

These changes demonstrate the importance of carefully managing component updates. Can anyone tell me why it's crucial to keep derived state in sync with props? And why might we want to reset isDirty when defaultText changes?

Remember, in React, proper lifecycle management is key to creating robust and predictable components. Great job on these improvements!

</Group>
<FieldError errorMessage={errorMessage} />
<FieldDescription description={description} isInvalid={isInvalid} />
<FieldCalenderPopover />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Oops! We've made the same spelling mistake twice!

Class, do you remember the spelling error we corrected earlier in our import statement? Well, it looks like we've made the same mistake here in using the component. This is a great lesson in why we should use consistent naming throughout our code.

Let's correct this line:

- <FieldCalenderPopover />
+ <FieldCalendarPopover />

Now, can anyone tell me why it's important to be consistent with our naming? That's right! It helps prevent errors and makes our code easier to understand and maintain. Always double-check your spelling, especially when using custom components!

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<FieldCalenderPopover />
<FieldCalendarPopover />

Comment on lines +55 to +61
<Button
color={Boolean(isLoading) ? "neutral" : "accent"}
icon="calendar-month"
isLoading={isLoading}
size={size === "medium" ? "small" : "xSmall"}
variant={Boolean(isLoading) ? "ghost" : "filled"}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Time for a Boolean logic pop quiz!

Alright, class, let's examine this Button component. Can anyone spot the redundant operations here? Yes, you in the back! Exactly right, we have two unnecessary Boolean() calls. Let's clean these up:

 <Button
-  color={Boolean(isLoading) ? "neutral" : "accent"}
+  color={isLoading ? "neutral" : "accent"}
   icon="calendar-month"
   isLoading={isLoading}
   size={size === "medium" ? "small" : "xSmall"}
-  variant={Boolean(isLoading) ? "ghost" : "filled"}
+  variant={isLoading ? "ghost" : "filled"}
 />

Excellent work! Remember, in conditional statements, variables are automatically coerced to booleans. We don't need to explicitly convert them. This makes our code cleaner and more efficient. Keep an eye out for these opportunities to simplify!

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button
color={Boolean(isLoading) ? "neutral" : "accent"}
icon="calendar-month"
isLoading={isLoading}
size={size === "medium" ? "small" : "xSmall"}
variant={Boolean(isLoading) ? "ghost" : "filled"}
/>
<Button
color={isLoading ? "neutral" : "accent"}
icon="calendar-month"
isLoading={isLoading}
size={size === "medium" ? "small" : "xSmall"}
variant={isLoading ? "ghost" : "filled"}
/>
🧰 Tools
🪛 Biome

[error] 56-56: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 60-60: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

@jsartisan
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11105124883.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36605.
recreate: .

@jsartisan
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11105481618.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36605.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-36605.dp.appsmith.com

@jsartisan
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11106073734.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36605.
recreate: .

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 733f523 and 4daa071.

📒 Files selected for processing (8)
  • app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css (2 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/index.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/src/FieldCalendarPopover.tsx (1 hunks)
  • app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/src/index.ts (1 hunks)
  • app/client/packages/design-system/widgets/src/index.ts (1 hunks)
  • app/client/src/widgets/WidgetUtils.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/index.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • app/client/packages/design-system/widgets/src/components/ComboBox/src/styles.module.css
  • app/client/packages/design-system/widgets/src/components/DatePicker/stories/DatePicker.stories.tsx
  • app/client/packages/design-system/widgets/src/index.ts
  • app/client/src/widgets/WidgetUtils.ts
🧰 Additional context used
🪛 Biome
app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx

[error] 36-36: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 58-58: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 62-62: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

🔇 Additional comments (5)
app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/src/index.ts (1)

1-1: Excellent work, class! Let's review this code together.

Now, children, what we have here is a perfect example of how to make our code more accessible to others. This line is like opening the door to our classroom and inviting everyone to see all the wonderful things we've created inside.

By using export *, we're saying, "Come on in and use any of the tools we've made in our FieldCalendarPopover workshop!" This is a very polite and efficient way to share our work with others.

Remember, class, sharing is caring in the world of coding!

app/client/packages/design-system/widgets/src/components/FieldCalendarPopover/src/FieldCalendarPopover.tsx (1)

1-3: Well done on your imports, class!

You've correctly imported the necessary components for our React lesson. Remember, importing is like packing your backpack for school - you want to bring everything you need, but not too much extra weight!

app/client/packages/design-system/widgets/src/components/DatePicker/src/DatePicker.tsx (3)

1-72: Class dismissed: Final thoughts on our DatePicker

Well done, everyone! We've had a productive lesson today reviewing our new DatePicker component. Let's recap what we've learned:

  1. We corrected spelling errors in both our imports and component usage.
  2. We simplified our Boolean logic by removing unnecessary Boolean() calls.
  3. We discussed the importance of component independence and suggested creating separate styles for our DatePicker.

Overall, this DatePicker component is well-structured and implements good practices such as accessibility features and conditional rendering based on props. After applying our suggested changes, the code will be more consistent, efficient, and maintainable.

Remember, class: attention to detail, simplicity, and independence are key principles in writing good code. Keep up the excellent work!

🧰 Tools
🪛 Biome

[error] 36-36: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 58-58: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


[error] 62-62: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)


67-67: ⚠️ Potential issue

Oops! We've made the same spelling mistake twice!

Class, do you remember the spelling error we corrected earlier in our import statement? Well, it looks like we've made the same mistake here in using the component. This is a great lesson in why we should use consistent naming throughout our code.

Let's correct this line:

- <FieldCalenderPopover />
+ <FieldCalendarPopover />

Now, can anyone tell me why it's important to be consistent with our naming? That's right, Jessica! It helps prevent errors and makes our code easier to understand and maintain. Always double-check your spelling, especially when using custom components!

Likely invalid or redundant comment.


1-7: ⚠️ Potential issue

Class, let's correct our spelling!

Good morning, students! Today, we're going to learn about the importance of correct spelling in our code. Can anyone spot the spelling mistake in our imports? That's right, Johnny! The word "Calendar" is misspelled in "FieldCalenderPopover". Let's fix that right away!

 import {
   FieldError,
   FieldDescription,
   FieldLabel,
-  FieldCalenderPopover,
+  FieldCalendarPopover,
   Button,
 } from "@appsmith/wds";

Remember, class: attention to detail is crucial in programming. One small typo can lead to big problems down the road!

Likely invalid or redundant comment.

Comment on lines +5 to +8
export function FieldCalenderPopover() {
const root = document.body.querySelector(
"[data-theme-provider]",
) as HTMLButtonElement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Let's correct our spelling and improve our code, shall we?

  1. There's a small spelling mistake in our component name. It should be "Calendar", not "Calender". Remember, spelling is important in coding too!

  2. Using document.body.querySelector might cause problems if we try to use this on the server. It's like trying to find a book in the library before the library is even built!

  3. We're telling TypeScript that our root element is definitely a button (HTMLButtonElement), but that might not always be true. It's like saying all animals in the zoo are lions - it's just not accurate!

Let's fix these issues to make our code more robust and reliable.

Here's how we can improve it:

-export function FieldCalenderPopover() {
+export function FieldCalendarPopover() {
   const root = document.body.querySelector(
     "[data-theme-provider]",
-  ) as HTMLButtonElement;
+  ) as HTMLElement | null;

+  if (!root) {
+    console.warn("No theme provider found. The calendar might not be positioned correctly.");
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function FieldCalenderPopover() {
const root = document.body.querySelector(
"[data-theme-provider]",
) as HTMLButtonElement;
export function FieldCalendarPopover() {
const root = document.body.querySelector(
"[data-theme-provider]",
) as HTMLElement | null;
if (!root) {
console.warn("No theme provider found. The calendar might not be positioned correctly.");
}

Comment on lines +10 to +16
return (
<Popover UNSTABLE_portalContainer={root}>
<Dialog>
<Calendar />
</Dialog>
</Popover>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's discuss our component structure, class!

You've done a good job setting up the basic structure of our calendar popover. It's like building a house - we have the foundation (Popover), the walls (Dialog), and the furniture (Calendar). However, there are a few things we should consider:

  1. We're using something called UNSTABLE_portalContainer. In the coding world, "unstable" is like a "wet paint" sign - it means things might change! We should be careful with this and maybe look for a more stable alternative.

  2. Our Calendar component doesn't have any props. It's like giving someone a blank notebook - useful, but it could be so much more with some guidelines or structure!

Let's think about how we can make this more robust and flexible. Could we pass some props to customize the Calendar? Maybe add some error handling if the root element isn't found?

Here's a suggestion to improve our component:

 export function FieldCalendarPopover() {
   const root = document.body.querySelector(
     "[data-theme-provider]",
-  ) as HTMLButtonElement;
+  ) as HTMLElement | null;

+  if (!root) {
+    console.warn("No theme provider found. The calendar might not be positioned correctly.");
+    return null;
+  }

   return (
     <Popover UNSTABLE_portalContainer={root}>
       <Dialog>
-        <Calendar />
+        <Calendar
+          // Add props here, for example:
+          // defaultValue={new Date()}
+          // onChange={(date) => console.log(date)}
+        />
       </Dialog>
     </Popover>
   );
 }

Committable suggestion was skipped due to low confidence.

} from "react-aria-components";

import type { DatePickerProps } from "./types";
import styles from "../../ComboBox/src/styles.module.css";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Today's lesson: Component Independence

Now, let's talk about component design. Who can tell me what's unusual about this line?

import styles from "../../ComboBox/src/styles.module.css";

That's correct, Sarah! We're importing styles from a different component. Can anyone tell me why this might not be the best practice?

Excellent point, Michael! It creates a dependency between components that should ideally be independent. For your homework, I want you all to think about how we could create a separate styles file for our DatePicker. This way, if we ever need to change the ComboBox styles, we won't accidentally affect our DatePicker!

Remember, class: in component design, independence is key!


return (
<HeadlessDatePicker
aria-label={Boolean(label) ? undefined : "DatePicker"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Pop quiz: Boolean logic!

Alright, class, it's time for a pop quiz on Boolean logic! Can anyone spot the unnecessary operations in these lines?

aria-label={Boolean(label) ? undefined : "DatePicker"}
color={Boolean(isLoading) ? "neutral" : "accent"}
variant={Boolean(isLoading) ? "ghost" : "filled"}

Excellent observation, Emily! The Boolean() calls are redundant here. In JavaScript, values are automatically coerced to booleans in conditional statements. Let's clean up our code:

- aria-label={Boolean(label) ? undefined : "DatePicker"}
+ aria-label={label ? undefined : "DatePicker"}
- color={Boolean(isLoading) ? "neutral" : "accent"}
+ color={isLoading ? "neutral" : "accent"}
- variant={Boolean(isLoading) ? "ghost" : "filled"}
+ variant={isLoading ? "ghost" : "filled"}

Remember, class: simpler code is often clearer code. Always look for opportunities to remove redundant operations!

Also applies to: 58-58, 62-62

🧰 Tools
🪛 Biome

[error] 36-36: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

Copy link

Deploy-Preview-URL: https://ce-36605.dp.appsmith.com

@jsartisan
Copy link
Contributor Author

@ichik Can you check if everything is ok visually here?

@ichik
Copy link
Contributor

ichik commented Sep 30, 2024

@jsartisan
Suggestion (design-wise):

  1. Switch the inner button to ghost perhaps even with neutral color instead of accent
  2. Date selection should show up on focus by default (optionally turning that off with widget settings)
  3. Dates in previous/next months should have -subtle color
  4. The widget should be put into Time category in the widget insert panel

Bugs and other observations:

  1. There's no way to select the time in the dropdown, only keyboard entry
  2. Date format seems to have no effect on the widget until you start interacting with precision prop (precision prop settings take priority over format and may even contradict it)
  3. Date range selection: will we do a separate widget or add it to this one as a prop?
  4. Related to the previous functionality: would be good to have access to a prop that controls how many months are shown in the dropdown

@jsartisan jsartisan marked this pull request as draft October 3, 2024 12:15
Copy link

This PR has not seen activitiy for a while. It will be closed in 7 days unless further activity is detected.

@github-actions github-actions bot added the Stale label Oct 10, 2024
Copy link

This PR has been closed because of inactivity.

@github-actions github-actions bot closed this Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip-changelog Adding this label to a PR prevents it from being listed in the changelog Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants