Skip to content

Commit 7025932

Browse files
authored
feat: add dateformat and placeholder prop for datepicker input [DSSUP-199] (#2472)
* fix: showLevelChangeLink only if picker is not defined * feat: added dateFormat and placeholder props * feat: added default values * feat: add changeset * chore: review changes * chore: update date formats * chore: update picker * chore: updated types * chore: udpdate jsdocs comments
1 parent a9e46af commit 7025932

File tree

6 files changed

+103
-30
lines changed

6 files changed

+103
-30
lines changed

.changeset/yellow-cameras-knock.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@razorpay/blade': patch
3+
---
4+
5+
feat(blade): add dateformat and placeholder prop for datepicker input
6+
fix(blade): Removed the chevron icon when the picker prop is used.

packages/blade/src/components/DatePicker/Calendar.web.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ const Calendar = <Type extends DateSelectionType>({
2828
onNext,
2929
onPrevious,
3030
presets,
31+
showLevelChangeLink,
3132
...props
3233
}: CalendarProps<Type> & {
3334
date?: Date;
3435
defaultDate?: Date;
3536
onDateChange?: (date: DateValue) => void;
37+
showLevelChangeLink?: boolean;
3638
}): React.ReactElement => {
3739
const isRange = selectionType === 'range';
3840

@@ -125,6 +127,7 @@ const Calendar = <Type extends DateSelectionType>({
125127
onPreviousDecade={handlePreviousDecade}
126128
onNextYear={handleNextYear}
127129
onPreviousYear={handlePreviousYear}
130+
showLevelChangeLink={showLevelChangeLink}
128131
/>
129132
<CalendarGradientStyles isRange={isRange} date={currentDate}>
130133
<DatePicker

packages/blade/src/components/DatePicker/CalendarHeader.web.tsx

+45-25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type CalendarHeaderProps = {
1414
isRange: boolean;
1515
date: DateValue | DatesRangeValue;
1616
pickerType: PickerType;
17+
showLevelChangeLink?: boolean;
1718
onNextMonth: () => void;
1819
onPreviousMonth: () => void;
1920
onNextYear: () => void;
@@ -22,6 +23,35 @@ type CalendarHeaderProps = {
2223
onPreviousDecade: () => void;
2324
onLevelChange: (level: MantineCalendarLevel) => void;
2425
};
26+
const CalendarLevelIndicator = ({
27+
onClick,
28+
showLevelChangeLink,
29+
accessibilityLabel,
30+
text,
31+
}: {
32+
onClick: () => void;
33+
showLevelChangeLink?: boolean;
34+
accessibilityLabel: string;
35+
text: string;
36+
}): React.ReactElement => {
37+
return showLevelChangeLink ? (
38+
<Link
39+
onClick={onClick}
40+
size="large"
41+
variant="button"
42+
color="neutral"
43+
iconPosition="right"
44+
icon={ChevronDownIcon}
45+
accessibilityLabel={accessibilityLabel}
46+
>
47+
{text}
48+
</Link>
49+
) : (
50+
<Text size="large" weight="medium" color="interactive.text.neutral.normal">
51+
{text}
52+
</Text>
53+
);
54+
};
2555

2656
const CalendarHeader = ({
2757
isRange,
@@ -34,7 +64,10 @@ const CalendarHeader = ({
3464
onPreviousYear,
3565
onPreviousDecade,
3666
onLevelChange,
37-
}: CalendarHeaderProps): React.ReactElement => {
67+
showLevelChangeLink,
68+
}: CalendarHeaderProps & {
69+
showLevelChangeLink?: boolean;
70+
}): React.ReactElement => {
3871
const { i18nState } = useI18nContext();
3972
const locale = convertIntlToDayjsLocale(i18nState?.locale ?? 'en-IN');
4073

@@ -135,34 +168,21 @@ const CalendarHeader = ({
135168
) : (
136169
<Box display="flex" gap="spacing.5" alignItems="center">
137170
{pickerType === 'day' && (
138-
<Link
139-
onClick={() => {
140-
onLevelChange('year');
141-
}}
142-
size="large"
143-
variant="button"
144-
color="neutral"
145-
iconPosition="right"
146-
icon={ChevronDownIcon}
171+
<CalendarLevelIndicator
172+
onClick={() => onLevelChange('month')}
173+
showLevelChangeLink={showLevelChangeLink}
147174
accessibilityLabel="Change month"
148-
>
149-
{month} {year}
150-
</Link>
175+
text={`${month} ${year}`}
176+
/>
151177
)}
178+
152179
{pickerType === 'month' && (
153-
<Link
154-
onClick={() => {
155-
onLevelChange('decade');
156-
}}
157-
size="large"
158-
variant="button"
159-
color="neutral"
160-
iconPosition="right"
161-
icon={ChevronDownIcon}
180+
<CalendarLevelIndicator
181+
onClick={() => onLevelChange('decade')}
182+
showLevelChangeLink={showLevelChangeLink}
162183
accessibilityLabel="Change decade"
163-
>
164-
{year}
165-
</Link>
184+
text={year}
185+
/>
166186
)}
167187
{pickerType === 'year' && (
168188
<Text size="large" weight="medium" color="interactive.text.neutral.normal">

packages/blade/src/components/DatePicker/DateInput.web.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,13 @@ const _DatePickerInput = (
9292
successText,
9393
errorText,
9494
helpText,
95+
format,
96+
placeholder,
9597
...props
9698
}: DatePickerInputProps,
9799
ref: React.ForwardedRef<any>,
98100
): React.ReactElement => {
99101
const isMobile = useIsMobile();
100-
const format = 'DD/MM/YYYY';
101102
const isLarge = size === 'large';
102103
const hasLabel = typeof label === 'string' ? Boolean(label) : Boolean(label?.start || label?.end);
103104
const isLabelPositionLeft = labelPosition === 'left';
@@ -127,7 +128,7 @@ const _DatePickerInput = (
127128
id="start-date"
128129
labelPosition={labelPosition}
129130
label={label}
130-
placeholder={format}
131+
placeholder={placeholder || format}
131132
popupId={referenceProps['aria-controls']}
132133
isPopupExpanded={referenceProps['aria-expanded']}
133134
size={size}
@@ -197,7 +198,7 @@ const _DatePickerInput = (
197198
leadingIcon={CalendarIcon}
198199
label={label?.start}
199200
labelPosition={labelPosition}
200-
placeholder={format}
201+
placeholder={placeholder}
201202
popupId={referenceProps['aria-controls']}
202203
isPopupExpanded={referenceProps['aria-expanded']}
203204
size={size}
@@ -235,7 +236,7 @@ const _DatePickerInput = (
235236
/>
236237
<DateInput
237238
id="end-date"
238-
placeholder={format}
239+
placeholder={placeholder}
239240
leadingIcon={CalendarIcon}
240241
label={shouldRenderEndLabel()}
241242
labelPosition={isLabelPositionLeft ? undefined : labelPosition}

packages/blade/src/components/DatePicker/DatePicker.web.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ const DatePicker = <Type extends DateSelectionType = 'single'>({
6666
picker,
6767
onPickerChange,
6868
zIndex = componentZIndices.popover,
69+
format = 'DD/MM/YYYY',
70+
inputPlaceHolder,
6971
...props
7072
}: DatePickerProps<Type> & StyledPropsBlade & DataAnalyticsAttribute): React.ReactElement => {
7173
const { i18nState } = useI18nContext();
@@ -83,6 +85,31 @@ const DatePicker = <Type extends DateSelectionType = 'single'>({
8385
onPickerChange?.(picker);
8486
},
8587
});
88+
const finalFormat = React.useMemo(() => {
89+
if (format) {
90+
return format;
91+
}
92+
if (picker === 'month') {
93+
return 'MMMM';
94+
}
95+
if (picker === 'year') {
96+
return 'YYYY';
97+
}
98+
return 'DD/MM/YYYY';
99+
}, [format, picker]);
100+
101+
const finalInputPlaceHolder = React.useMemo(() => {
102+
if (inputPlaceHolder) {
103+
return inputPlaceHolder;
104+
}
105+
if (picker === 'month') {
106+
return 'Month';
107+
}
108+
if (picker === 'year') {
109+
return 'Year';
110+
}
111+
return 'DD/MM/YYYY';
112+
}, [inputPlaceHolder, picker]);
86113

87114
const {
88115
onDateChange,
@@ -237,6 +264,7 @@ const DatePicker = <Type extends DateSelectionType = 'single'>({
237264
forceRerender();
238265
}}
239266
picker={_picker}
267+
showLevelChangeLink={!picker}
240268
onPickerChange={(picker) => {
241269
setPicker(() => picker);
242270
forceRerender();
@@ -303,6 +331,8 @@ const DatePicker = <Type extends DateSelectionType = 'single'>({
303331
validationState={validationState}
304332
autoFocus={autoFocus}
305333
necessityIndicator={necessityIndicator}
334+
format={finalFormat}
335+
placeholder={finalInputPlaceHolder}
306336
{...makeAnalyticsAttribute(props)}
307337
/>
308338
{isMobile ? (

packages/blade/src/components/DatePicker/types.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ type DatePickerProps<Type extends DateSelectionType> = Omit<
162162
*/
163163
onApply?: Type extends 'single' ? (value: DateValue) => void : (value: DatesRangeValue) => void;
164164
labelPosition?: BaseInputProps['labelPosition'];
165+
/**
166+
* Sets the date format to be displayed in the input field.
167+
* @default 'DD/MM/YYYY' if pickerType is 'month' then 'MMMM', 'YYYY' if pickerType is 'year'
168+
*/
169+
format?: 'DD/MM/YYYY' | 'MMM' | 'MMMM' | 'YYYY';
170+
/**
171+
* Placeholder text for the datepicker input , when no date is selected.
172+
* @default 'DD/MM/YYYY' if pickerType is 'month' then 'MMMM', 'YYYY' if pickerType is 'year'
173+
*/
174+
inputPlaceHolder?: string;
165175
};
166176

167177
type DatePickerRangeInputProps = {
@@ -195,7 +205,10 @@ type DatePickerCommonInputProps = {
195205
FormInputValidationProps;
196206

197207
type DatePickerInputProps = DatePickerCommonInputProps &
198-
(DatePickerRangeInputProps | DatePickerSingleInputProps);
208+
(DatePickerRangeInputProps | DatePickerSingleInputProps) & {
209+
format: string;
210+
placeholder?: string;
211+
};
199212

200213
export type {
201214
CalendarProps,

0 commit comments

Comments
 (0)