-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
chore: Datepicker Widget #36605
Conversation
WalkthroughThe changes introduce several new components and configurations related to calendar and date picker functionalities within the design system. Key additions include the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this 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 likewidth
,height
, andcolor
. 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
andstroke-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 toHeadlessCalendarHeaderCell
. 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 yourCalendarHeading
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 usingTextProps
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
toCalendarHeading
. 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:
- External libraries (React, react-aria-components)
- Internal modules (@appsmith/wds)
- 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 theHeadlessCalendar
. 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:
- Dirty state checks
- Null date handling
- Required field validation
- Date range validation
- 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.
- The background color change to
var(--color-bg-accent)
draws attention to the focused input.- Changing the text color to
var(--color-fg-on-accent)
ensures readability against the new background.- 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 ourWDS_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:
- 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");
- 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:
DatePickerThumbnail
from "./components/Thumbnails/DatePickerThumbnail"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:
- We start with an empty object called
derivedProperties
. This is where we'll store our translated properties.- We then loop through each property in the input object. It's like going through each student in the class, one by one.
- 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.
withthis.
. 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:
- Error handling: What happens if the function body can't be extracted? We should add a safety net for that.
- 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.
- 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 ValidationBy default,
moment.isBetween()
excludes the start and end dates from the range. If your intention is to includeminDate
andmaxDate
as valid selections, you need to define the inclusivity.To include both
minDate
andmaxDate
, 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
: UseisSameOrAfter
for Inclusive Minimum Date ComparisonTo include
minDate
as a valid option, it's preferable to useisSameOrAfter
instead ofisAfter
. This ensures thatparsedSelectedDate
is either on or after theminDate
.Update the code to:
- return parsedSelectedDate.isAfter(parsedMinDate); + return parsedSelectedDate.isSameOrAfter(parsedMinDate);
31-31
: UseisSameOrBefore
for Inclusive Maximum Date ComparisonSimilarly, if you wish to include
maxDate
as a valid selection,isSameOrBefore
should be used instead ofisBefore
. This will allowparsedSelectedDate
to be on or before themaxDate
.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 toDatePicker
When you spread
...rest
into theDatePicker
component, all remaining props fromthis.props
are passed down. This might include props unintended forDatePicker
, potentially causing unexpected behaviors or warnings. It's better practice to explicitly pass only the props thatDatePicker
needs.Also applies to: 133-145
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ 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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 56-56: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 60-60: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
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 thecontentConfig
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:
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!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!
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:
We're exporting the
DatePicker
component. This is like sharing your favorite toy with your classmates so they can use it too!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 theDatePicker
.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
andThumbnailCmp
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:
- Organization: Just like how we arrange our classroom, this file neatly organizes our Calendar components.
- Accessibility: These exports make our components easily accessible, much like having all our school supplies in one place.
- 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 theanvilConfig
object, students!Your
anvilConfig
object is well-structured and follows theAnvilConfig
type correctly. Let's break it down:
isLargeWidget: false
- This is appropriate for a date picker, which typically doesn't require a large amount of space.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 theWidgetProps
interface in your newWDSDatePickerWidgetProps
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 extendingWidgetProps
, 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:
- We have a wildcard export for propertyPaneConfig.
- 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:
- metaConfig
- anvilConfig
- defaultsConfig
- settersConfig
- methodsConfig
- 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:
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.
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 thegit diff
command to review the changes made to theComboboxSelectIcon.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 theorigin/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.htmlLength 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.tsxLength of output: 148
Script:
#!/bin/bash # Description: List all remote branches to identify the correct base branch git fetch --all git branch -rLength 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.tsxLength 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 theHeadlessCalendarCell
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
andWidgetDefaultProps
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:
- Being more explicit with prop spreading to avoid unintended prop pollution.
- 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 usingforwardRef
, 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:
- Is this naming convention documented in the project guidelines?
- Does it provide any benefits in terms of code organization or clarity?
- 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 theCalendarHeading
component exists and verify its implementation. Could you please run the following command to search for any references toCalendarHeading
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.tsxLength of output: 231
Script:
#!/bin/bash # Description: Search for references to CalendarHeading component in the codebase rg 'CalendarHeading' --type tsx --type tsLength 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 afterchildren
, 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:
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!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.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?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 thechildren
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, andSubTextPosition
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:
- The use of
display: flex
creates a flexible container for our date input elements.- The
gap
property ensures consistent spacing between child elements.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:
- Proper import practices
- Consistent component integration
- 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:
- We've imported the new thumbnail components correctly.
- We've added them to our Icons component in the right order.
- 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 ourWDSWidgets
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"; |
There was a problem hiding this comment.
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-existentpropertyPaneConfig.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>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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!
export function validateInput(props: WDSDatePickerWidgetProps) { | ||
if (!props.isValid) { | ||
return { | ||
validationStatus: "invalid", | ||
errorMessage: "Please select a valid date", | ||
}; | ||
} | ||
|
||
return { | ||
validationStatus: "valid", | ||
errorMessage: "", | ||
}; | ||
} |
There was a problem hiding this comment.
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:
- Error Handling: What happens if
props
is undefined? Let's add a safety check. - Localization: The error message is hardcoded. Consider using a localization function for better internationalization.
- Type Assertion: Let's be extra careful and assert that
isValid
exists onprops
.
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?
export function FieldCalenderPopover() { | ||
const root = document.body.querySelector( | ||
"[data-theme-provider]", | ||
) as HTMLButtonElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
- We're assuming the existence of an element with
[data-theme-provider]
. What if it's not there? - We're casting the result to
HTMLButtonElement
. Are we certain it's always a button? - 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?
return ( | ||
<Popover UNSTABLE_portalContainer={root}> | ||
<Dialog> | ||
<Calendar /> | ||
</Dialog> | ||
</Popover> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
helpText: "when a date is selected in the calendar", | |
helpText: "Triggered when a date is selected in the calendar.", |
const parsedDerivedProperties = parseDerivedProperties(derivedPropertyFns); | ||
|
||
return merge(super.getDerivedPropertiesMap(), { | ||
isValid: `{{(() => {${derivedProperties.isValid}})()}}`, | ||
isValid: `{{(() => {${parsedDerivedProperties.isValid}})()}}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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, |
There was a problem hiding this comment.
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>) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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` |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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
📒 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:
- The date format selection using a dropdown is an excellent choice. It ensures consistency and prevents user errors.
- The default date configuration with a date picker control is spot-on. It provides an intuitive interface for users.
- 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:
- The
isRequired
property ensures that users provide input when necessary.- The
minDate
andmaxDate
properties allow for setting date ranges, which is crucial for many applications.- You've used the appropriate DATE_PICKER control type for both
minDate
andmaxDate
, 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:
- Your Data section is thorough and provides great flexibility for users.
- The Validations section ensures data integrity, which is crucial in any application.
- The General section covers important widget behaviors.
- 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!
{ | ||
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 }, | ||
}, | ||
], | ||
}, |
There was a problem hiding this comment.
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.
{ | ||
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 }, | ||
}, | ||
], | ||
}, |
There was a problem hiding this comment.
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!
{ | ||
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, | ||
}, | ||
], | ||
}, |
There was a problem hiding this comment.
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:
-
Let's make the label more descriptive:
label: "When Date Selected",
-
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!
/build-deploy-preview skip-tests=true |
Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11104242240. |
Deploy-Preview-URL: https://ce-36605.dp.appsmith.com |
3de191f
to
733f523
Compare
There was a problem hiding this 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:
We're now using
parsedDerivedProperties
instead ofderivedProperties
. This is a good practice as it ensures our derived properties are properly parsed before use.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:
We've added strict input validation for numeric input. This is excellent defensive programming!
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:
- It prevents non-numeric values from being pasted into numeric input fields.
- 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
⛔ 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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 56-56: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 60-60: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
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:
- Always check your spelling, especially in component names.
- Keep components independent by not sharing style files.
- Simplify boolean logic by removing unnecessary
Boolean()
calls.- Maintain consistency in naming throughout your code.
For your homework, I'd like you to:
- Fix the spelling errors we found.
- Create a separate styles file for the DatePicker component.
- 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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 56-56: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 60-60: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
1-7
:⚠️ Potential issueClass, 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:
We now update
parsedText
wheneverrawText
orinputType
changes. This ensures our derived state is always in sync with the input.We've added logic to reset
isDirty
whendefaultText
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
whendefaultText
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 /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
<FieldCalenderPopover /> | |
<FieldCalendarPopover /> |
<Button | ||
color={Boolean(isLoading) ? "neutral" : "accent"} | ||
icon="calendar-month" | ||
isLoading={isLoading} | ||
size={size === "medium" ? "small" : "xSmall"} | ||
variant={Boolean(isLoading) ? "ghost" : "filled"} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
<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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 60-60: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
/build-deploy-preview skip-tests=true |
Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11105124883. |
/build-deploy-preview skip-tests=true |
Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11105481618. |
Deploy-Preview-URL: https://ce-36605.dp.appsmith.com |
/build-deploy-preview skip-tests=true |
Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11106073734. |
There was a problem hiding this 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
📒 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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 58-58: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 62-62: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
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 DatePickerWell done, everyone! We've had a productive lesson today reviewing our new DatePicker component. Let's recap what we've learned:
- We corrected spelling errors in both our imports and component usage.
- We simplified our Boolean logic by removing unnecessary
Boolean()
calls.- 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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 58-58: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
[error] 62-62: Avoid redundant
Boolean
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
67-67
:⚠️ Potential issueOops! 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 issueClass, 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.
export function FieldCalenderPopover() { | ||
const root = document.body.querySelector( | ||
"[data-theme-provider]", | ||
) as HTMLButtonElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's correct our spelling and improve our code, shall we?
-
There's a small spelling mistake in our component name. It should be "Calendar", not "Calender". Remember, spelling is important in coding too!
-
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! -
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.
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."); | |
} |
return ( | ||
<Popover UNSTABLE_portalContainer={root}> | ||
<Dialog> | ||
<Calendar /> | ||
</Dialog> | ||
</Popover> | ||
); |
There was a problem hiding this comment.
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:
-
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. -
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"; |
There was a problem hiding this comment.
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"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
callIt is not necessary to use
Boolean
call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundantBoolean
call(lint/complexity/noExtraBooleanCast)
Deploy-Preview-URL: https://ce-36605.dp.appsmith.com |
@ichik Can you check if everything is ok visually here? |
@jsartisan
Bugs and other observations:
|
This PR has not seen activitiy for a while. It will be closed in 7 days unless further activity is detected. |
This PR has been closed because of inactivity. |
Summary by CodeRabbit
New Features
Calendar
component for enhanced date selection.DatePicker
component with customizable options and validation.FieldCalendarPopover
for displaying calendars in a dialog format.Bug Fixes
Documentation
Style
Chores
Warning
Tests have not run on the HEAD 4daa071 yet
Mon, 30 Sep 2024 12:26:29 UTC