Skip to content

Commit

Permalink
Merge branch 'main' into stepper-input
Browse files Browse the repository at this point in the history
  • Loading branch information
lilyvc authored May 22, 2024
2 parents 9a859b6 + 8c8966e commit c43b828
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { composeStories } from "@storybook/react";
import { ChangeEvent } from "react";
import * as datePickerStories from "@stories/date-picker/date-picker.stories";
import { checkAccessibility } from "../../../../../../cypress/tests/checkAccessibility";
import {
Expand Down Expand Up @@ -82,6 +81,11 @@ describe("GIVEN a DatePicker", () => {
cy.mount(<Default defaultStartDate={testDate} disabled />);
cy.findByRole("button").should("be.disabled");
});
it("THEN render read only when prop is passed", () => {
cy.mount(<Default defaultStartDate={testDate} readOnly />);
cy.findByRole("textbox").should("have.attr", "readonly");
cy.findByRole("button").should("be.disabled");
});
it("THEN it should update the selected month when changing selected date", () => {
cy.mount(<Default defaultStartDate={testDate} />);
cy.findByRole("textbox").click().clear().type(testInput);
Expand All @@ -95,7 +99,6 @@ describe("GIVEN a DatePicker", () => {
cy.mount(
<Default
defaultStartDate={testDate}
// @ts-ignore
CalendarProps={{ visibleMonth: testDate }}
/>
);
Expand Down
1 change: 0 additions & 1 deletion packages/lab/src/date-input/DateInput.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
padding: 0;
text-align: left;
width: min-content;
flex-grow: 1;
}

/* Reset in the class */
Expand Down
32 changes: 24 additions & 8 deletions packages/lab/src/date-picker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ import { flip, useDismiss, useInteractions } from "@floating-ui/react";
import { DateInput } from "../date-input";
import { DateValue, getLocalTimeZone, today } from "@internationalized/date";
import { CalendarIcon } from "@salt-ds/icons";
import {
UseRangeSelectionCalendarProps,
UseSingleSelectionCalendarProps,
} from "../calendar";
import { CalendarProps } from "../calendar";

const withBaseName = makePrefixer("saltDatePicker");

Expand Down Expand Up @@ -55,9 +52,15 @@ export interface DatePickerProps
/**
* Props to be passed to the Calendar component.
*/
CalendarProps?:
| UseRangeSelectionCalendarProps
| UseSingleSelectionCalendarProps;
CalendarProps?: Partial<
Omit<
CalendarProps,
| "selectionVariant"
| "selectedDate"
| "defaultSelectedDate"
| "onSelectedDateChange"
>
>;
/**
* Function to format the input value.
*/
Expand All @@ -70,6 +73,14 @@ export interface DatePickerProps
* Display or hide the component.
*/
open?: boolean;
/**
* Helper text to display in the panel
*/
helperText?: string;
/**
* If `true`, the component is read only.
*/
readOnly?: boolean;
}

export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
Expand All @@ -87,6 +98,8 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
className,
open: openProp,
onOpenChange: onOpenChangeProp,
helperText,
readOnly: readOnlyProp,
...rest
},
ref
Expand Down Expand Up @@ -142,6 +155,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
]);
const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } =
useFormFieldProps();
const isReadOnly = readOnlyProp || formFieldReadOnly;

const getPanelPosition = () => ({
top: y ?? 0,
Expand Down Expand Up @@ -200,11 +214,12 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
endInputRef={endInputRef}
placeholder={placeholder}
dateFormatter={dateFormatter}
readOnly={isReadOnly}
endAdornment={
<Button
variant="secondary"
onClick={handleCalendarButton}
disabled={disabled || formFieldReadOnly || formFieldDisabled}
disabled={disabled || isReadOnly || formFieldDisabled}
aria-label="Open Calendar"
>
<CalendarIcon aria-hidden />
Expand All @@ -217,6 +232,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
{...getFloatingProps()}
onSelect={handleSelect}
CalendarProps={CalendarProps}
helperText={helperText}
/>
</DatePickerContext.Provider>
);
Expand Down
8 changes: 8 additions & 0 deletions packages/lab/src/date-picker/DatePickerPanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@
box-sizing: border-box;
display: flex;
}
.saltDatePickerPanel-container {
width: min-content;
gap: 1px;
}

.saltDatePickerPanel-header {
padding: var(--salt-spacing-100);
}
12 changes: 10 additions & 2 deletions packages/lab/src/date-picker/DatePickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
useState,
} from "react";
import {
FlexItem,
FlexLayout,
FormFieldHelperText,
makePrefixer,
StackLayout,
useFloatingComponent,
Expand All @@ -26,6 +28,7 @@ import { DateValue, endOfMonth, startOfMonth } from "@internationalized/date";

export interface DatePickerPanelProps extends ComponentPropsWithoutRef<"div"> {
onSelect?: () => void;
helperText?: string;
CalendarProps?: Partial<
Omit<
CalendarProps,
Expand All @@ -41,7 +44,7 @@ const withBaseName = makePrefixer("saltDatePickerPanel");

export const DatePickerPanel = forwardRef<HTMLDivElement, DatePickerPanelProps>(
function DatePickerPanel(props, ref) {
const { className, onSelect, CalendarProps, ...rest } = props;
const { className, onSelect, helperText, CalendarProps, ...rest } = props;

const targetWindow = useWindow();
useComponentCssInjection({
Expand Down Expand Up @@ -141,7 +144,12 @@ export const DatePickerPanel = forwardRef<HTMLDivElement, DatePickerPanelProps>(
{...a11yProps}
{...rest}
>
<StackLayout separators gap={0}>
<StackLayout separators gap={0} className={withBaseName("container")}>
{helperText && (
<FlexItem className={withBaseName("header")}>
<FormFieldHelperText>{helperText}</FormFieldHelperText>
</FlexItem>
)}
<FlexLayout>
<Calendar
visibleMonth={startVisibleMonth}
Expand Down
16 changes: 16 additions & 0 deletions packages/lab/stories/date-picker/date-picker.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { DatePicker, DatePickerProps } from "@salt-ds/lab";
import { Meta, StoryFn } from "@storybook/react";
import {
FormField,
FormFieldHelperText as FormHelperText,
FormFieldLabel as FormLabel,
} from "@salt-ds/core";

export default {
title: "Lab/Date Picker",
Expand All @@ -17,3 +22,14 @@ export const Range = DatePickerTemplate.bind({});
Range.args = {
selectionVariant: "range",
};

export const WithFormField: StoryFn<DatePickerProps> = (args) => {
const helperText = "Date format DD MMM YYYY (e.g. 09 Jun 2021)";
return (
<FormField style={{ width: "200px" }}>
<FormLabel>Pick a date</FormLabel>
<DatePicker {...args} helperText={helperText} />
<FormHelperText>{helperText}</FormHelperText>
</FormField>
);
};
2 changes: 1 addition & 1 deletion site/docs/components/date-picker/accessibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ data:
</KeyboardControl>
<KeyboardControl keyOrCombos="Shift + Left Arrow / Shift + Right Arrow">

Drags selection over text characters, one at a time.
When the input area has focus, drags selection over text characters, one at a time.

</KeyboardControl>
<KeyboardControl keyOrCombos="Backspace">
Expand Down
6 changes: 5 additions & 1 deletion site/docs/components/date-picker/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ data:
---

<LivePreviewControls>
<LivePreview componentName="date-picker" exampleName="Default">
<LivePreview componentName="date-picker" exampleName="SingleSelect">

## Single select

Expand All @@ -21,12 +21,16 @@ The default date picker allows the user to pick a single date, which is committe
## With form field

This date picker has a form field label and is configured with validation logic. If an invalid date is entered, the error is detected and a tooltip advises the user of the correct format.
The default date picker format is "DD MMM YYYY"

</LivePreview>
<LivePreview componentName="date-picker" exampleName="Range">
## Date range

The Date Range Picker enables selection of start and end dates, using the input fields or two calendars displayed. The range is only committed when the user clicks ‘Apply’, and can be reset if the user wants to start again.

</LivePreview>
<LivePreview componentName="date-picker" exampleName="WithDisabledDates">
## With disabled dates
</LivePreview>
</LivePreviewControls>
2 changes: 1 addition & 1 deletion site/docs/components/date-picker/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Use a Date Picker when enabling users to filter data that’s displayed on scree

### Best practices

To improve consistency and simplify your messaging, consider recommending just one acceptable date format in the label and/or tooltip – ideally, the one most frequently used in your application.
To improve consistency and simplify your messaging, consider recommending just one acceptable date format in the form field label and helper text – ideally, the one most frequently used in your application.

## Import

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactElement } from "react";
import { DatePicker } from "@salt-ds/lab";

export const Default = (): ReactElement => (
export const SingleSelect = (): ReactElement => (
<DatePicker style={{ width: "200px" }} />
);
13 changes: 13 additions & 0 deletions site/src/examples/date-picker/WithDisabledDates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ReactElement } from "react";
import { DatePicker } from "@salt-ds/lab";
import { DateValue, getDayOfWeek } from "@internationalized/date";

const currentLocale = navigator.languages[0];
const isDayDisabled = (date: DateValue) =>
getDayOfWeek(date, currentLocale) >= 5;
export const WithDisabledDates = (): ReactElement => (
<DatePicker
style={{ width: "200px" }}
CalendarProps={{ isDayDisabled: isDayDisabled }}
/>
);
5 changes: 3 additions & 2 deletions site/src/examples/date-picker/WithFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import {
FormFieldHelperText as FormHelperText,
FormFieldLabel as FormLabel,
} from "@salt-ds/core";
const helperText = "Date format DD MMM YYYY (e.g. 09 Jun 2021)";

export const WithFormField = (): ReactElement => (
<FormField style={{ width: "200px" }}>
<FormLabel>Pick a date</FormLabel>
<DatePicker />
<FormHelperText>Date format DD MMM YYYY (e.g. 09 Jun 2021)</FormHelperText>
<DatePicker helperText={helperText} />
<FormHelperText>{helperText}</FormHelperText>
</FormField>
);
3 changes: 2 additions & 1 deletion site/src/examples/date-picker/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./Default";
export * from "./SingleSelect";
export * from "./WithFormField";
export * from "./Range";
export * from "./WithDisabledDates";

0 comments on commit c43b828

Please sign in to comment.