From e0c5895e9c6a48826fd045855041f0b640962cea Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 29 Feb 2024 10:44:25 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20add=20`onReset`=20?= =?UTF-8?q?prop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Calendar/Calendar.tsx | 41 ++++++++++++++----- .../shared/DatePicker/DatePicker.theme.ts | 2 +- .../shared/DatePicker/DatePicker.tsx | 25 +++++++---- .../components/shared/Select/Select.theme.ts | 2 +- .../src/components/shared/Select/Select.tsx | 14 +++---- .../shared/Select/SelectItem/SelectItem.tsx | 4 +- 6 files changed, 59 insertions(+), 29 deletions(-) diff --git a/packages/frontend/src/components/shared/Calendar/Calendar.tsx b/packages/frontend/src/components/shared/Calendar/Calendar.tsx index bf01dc06..1a67c34f 100644 --- a/packages/frontend/src/components/shared/Calendar/Calendar.tsx +++ b/packages/frontend/src/components/shared/Calendar/Calendar.tsx @@ -19,6 +19,7 @@ import { import './Calendar.css'; import { format } from 'date-fns'; +import { cn } from 'utils/classnames'; type ValuePiece = Date | null; export type Value = ValuePiece | [ValuePiece, ValuePiece]; @@ -63,6 +64,11 @@ export interface CalendarProps extends CustomReactCalendarProps, CalendarTheme { * @returns None */ onCancel?: () => void; + /** + * Optional callback function that is called when a reset action is triggered. + * @returns None + */ + onReset?: () => void; } /** @@ -80,6 +86,7 @@ export const Calendar = ({ actions, onSelect, onCancel, + onReset, onChange: onChangeProp, ...props }: CalendarProps): JSX.Element => { @@ -217,6 +224,11 @@ export const Calendar = ({ [setValue, setActiveDate, changeNavigationLabel, selectRange], ); + const handleReset = useCallback(() => { + setValue(null); + onReset?.(); + }, [setValue, onReset]); + return (
{actions ? ( actions ) : ( <> - - + {value && ( + + )} +
+ + +
)}
diff --git a/packages/frontend/src/components/shared/DatePicker/DatePicker.theme.ts b/packages/frontend/src/components/shared/DatePicker/DatePicker.theme.ts index 522bd348..ee1b7466 100644 --- a/packages/frontend/src/components/shared/DatePicker/DatePicker.theme.ts +++ b/packages/frontend/src/components/shared/DatePicker/DatePicker.theme.ts @@ -2,7 +2,7 @@ import { VariantProps, tv } from 'tailwind-variants'; export const datePickerTheme = tv({ slots: { - input: [], + input: ['w-full'], }, }); diff --git a/packages/frontend/src/components/shared/DatePicker/DatePicker.tsx b/packages/frontend/src/components/shared/DatePicker/DatePicker.tsx index 99fd82a5..bae4502a 100644 --- a/packages/frontend/src/components/shared/DatePicker/DatePicker.tsx +++ b/packages/frontend/src/components/shared/DatePicker/DatePicker.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { Input, InputProps } from 'components/shared/Input'; import * as Popover from '@radix-ui/react-popover'; import { datePickerTheme } from './DatePicker.theme'; @@ -27,6 +27,10 @@ export interface DatePickerProps * Whether to allow the selection of a date range. */ selectRange?: boolean; + /** + * Optional callback function that is called when the date picker is reset. + */ + onReset?: () => void; } /** @@ -39,6 +43,7 @@ export const DatePicker = ({ calendarProps, value, onChange, + onReset, selectRange = false, ...props }: DatePickerProps) => { @@ -50,16 +55,16 @@ export const DatePicker = ({ * Renders the value of the date based on the current state of `props.value`. * @returns {string | undefined} - The formatted date value or `undefined` if `props.value` is falsy. */ - const renderValue = useCallback(() => { - if (!value) return undefined; + const renderValue = useMemo(() => { + if (!value) return ''; if (Array.isArray(value)) { return value .map((date) => format(date as Date, 'dd/MM/yyyy')) .join(' - '); } return format(value, 'dd/MM/yyyy'); - }, [value]); - + }, [value, onReset]); + console.log(renderValue); /** * Handles the selection of a date from the calendar. */ @@ -71,15 +76,20 @@ export const DatePicker = ({ [setOpen, onChange], ); + const handleReset = useCallback(() => { + setOpen(false); + onReset?.(); + }, [setOpen, onReset]); + return ( - + setOpen(true)} />} readOnly placeholder="Select a date..." - value={renderValue()} + value={renderValue} className={input({ className })} onClick={() => setOpen(true)} /> @@ -93,6 +103,7 @@ export const DatePicker = ({ {...calendarProps} selectRange={selectRange} value={value} + onReset={handleReset} onCancel={() => setOpen(false)} onSelect={handleSelect} /> diff --git a/packages/frontend/src/components/shared/Select/Select.theme.ts b/packages/frontend/src/components/shared/Select/Select.theme.ts index 43d4b0f4..9c00a5c2 100644 --- a/packages/frontend/src/components/shared/Select/Select.theme.ts +++ b/packages/frontend/src/components/shared/Select/Select.theme.ts @@ -2,7 +2,7 @@ import { VariantProps, tv } from 'tailwind-variants'; export const selectTheme = tv({ slots: { - container: ['flex', 'flex-col', 'relative', 'gap-2'], + container: ['flex', 'flex-col', 'relative', 'gap-2', 'w-full'], label: ['text-sm', 'text-elements-high-em'], description: ['text-xs', 'text-elements-low-em'], inputWrapper: [ diff --git a/packages/frontend/src/components/shared/Select/Select.tsx b/packages/frontend/src/components/shared/Select/Select.tsx index 963cc0bb..b009e856 100644 --- a/packages/frontend/src/components/shared/Select/Select.tsx +++ b/packages/frontend/src/components/shared/Select/Select.tsx @@ -3,7 +3,6 @@ import React, { useState, ComponentPropsWithoutRef, useMemo, - useCallback, MouseEvent, useRef, useEffect, @@ -12,7 +11,7 @@ import { useMultipleSelection, useCombobox } from 'downshift'; import { SelectTheme, selectTheme } from './Select.theme'; import { ChevronDownIcon, - CrossIcon, + CrossCircleIcon, WarningIcon, } from 'components/shared/CustomIcon'; import { cloneIcon } from 'utils/cloneIcon'; @@ -270,11 +269,8 @@ export const Select = ({ itemToString: (item) => (item && !multiple ? item.label : ''), }); - const isSelected = useCallback( - (item: SelectOption) => - multiple ? selectedItems.includes(item) : selectedItem === item, - [selectedItems, selectedItem, multiple], - ); + const isSelected = (item: SelectOption) => + multiple ? selectedItems.includes(item) : selectedItem === item; const handleClear = (e: MouseEvent) => { e.stopPropagation(); @@ -306,7 +302,7 @@ export const Select = ({ return (
{clearable && (selectedItems.length > 0 || selectedItem) && ( - @@ -318,7 +314,7 @@ export const Select = ({ )}
); - }, [cloneIcon, theme, rightIcon]); + }, [cloneIcon, theme, rightIcon, selectedItem, selectedItems, clearable]); const renderHelperText = useMemo( () => ( diff --git a/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx b/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx index a6bbc487..8ac93774 100644 --- a/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx +++ b/packages/frontend/src/components/shared/Select/SelectItem/SelectItem.tsx @@ -62,7 +62,9 @@ const SelectItem = forwardRef(

{label}

- {orientation === 'horizontal' && } + {orientation === 'horizontal' && description && ( + + )} {description && (

{description}