diff --git a/components/component-docs.json b/components/component-docs.json
index 07279911a4..ce750c286d 100644
--- a/components/component-docs.json
+++ b/components/component-docs.json
@@ -5771,6 +5771,17 @@
"computed": false
}
},
+ "disabledSelection": {
+ "type": {
+ "name": "array"
+ },
+ "required": false,
+ "description": "An array of objects of rows that selection is disabled. See `items` prop for shape of objects.",
+ "defaultValue": {
+ "value": "[]",
+ "computed": false
+ }
+ },
"selectRows": {
"type": {
"name": "union",
@@ -6309,6 +6320,13 @@
"params": [],
"returns": null
},
+ {
+ "name": "handleResetDate",
+ "docblock": null,
+ "modifiers": [],
+ "params": [],
+ "returns": null
+ },
{
"name": "openDialogFromIcon",
"docblock": null,
diff --git a/components/date-picker/__docs__/storybook-stories.jsx b/components/date-picker/__docs__/storybook-stories.jsx
index 4d59f300fd..b8f2b4e67b 100644
--- a/components/date-picker/__docs__/storybook-stories.jsx
+++ b/components/date-picker/__docs__/storybook-stories.jsx
@@ -13,6 +13,7 @@ import CustomInput from '../__examples__/custom-input';
import SnaphotDefault from '../__examples__/snapshot-default';
import WeekdayPicker from '../__examples__/weekday-picker';
import ErrorPicker from '../__examples__/error-picker';
+import Clearable from '../__examples__/clearable';
// eslint-disable-next-line camelcase
import UNSAFE_DirectionSettings from '../../utilities/UNSAFE_direction';
@@ -52,4 +53,5 @@ storiesOf(DATE_PICKER, module)
))
.add('DOM Snapshot', () => )
.add('Weekday picker', () => )
- .add('Error', () => );
+ .add('Error', () => )
+ .add('Clearable', () => );
diff --git a/components/date-picker/__examples__/clearable.jsx b/components/date-picker/__examples__/clearable.jsx
new file mode 100644
index 0000000000..1f687d7cfe
--- /dev/null
+++ b/components/date-picker/__examples__/clearable.jsx
@@ -0,0 +1,71 @@
+/* eslint-disable no-console, react/prop-types */
+import React from 'react';
+import moment from 'moment';
+
+import IconSettings from '~/components/icon-settings';
+import Datepicker from '~/components/date-picker';
+import Button from '~/components/button';
+
+class Example extends React.Component {
+ static displayName = 'DatepickerExample';
+
+ constructor() {
+ super();
+ this.state = {
+ value: undefined,
+ };
+ }
+
+ handleChange = (event, data) => {
+ this.setState({ value: data.date });
+ };
+
+ render() {
+ return (
+
+ {
+ this.handleChange(event, data);
+
+ if (this.props.action) {
+ const dataAsArray = Object.keys(data).map((key) => data[key]);
+ this.props.action('onChange')(event, data, ...dataAsArray);
+ } else if (console) {
+ console.log('onChange', event, data);
+ }
+ }}
+ onCalendarFocus={(event, data) => {
+ if (this.props.action) {
+ const dataAsArray = Object.keys(data).map((key) => data[key]);
+ this.props.action('onCalendarFocus')(event, data, ...dataAsArray);
+ } else if (console) {
+ console.log('onCalendarFocus', event, data);
+ }
+ }}
+ formatter={(date) => {
+ return date ? moment(date).format('M/D/YYYY') : '';
+ }}
+ parser={(dateString) => {
+ return moment(dateString, 'MM-DD-YYYY').toDate();
+ }}
+ value={this.state.value}
+ />
+
+ );
+ }
+}
+
+export default Example; // export is replaced with `ReactDOM.render(, mountNode);` at runtime
diff --git a/components/date-picker/__tests__/date-picker.browser-test.jsx b/components/date-picker/__tests__/date-picker.browser-test.jsx
index a44c29c473..80527dc5d8 100644
--- a/components/date-picker/__tests__/date-picker.browser-test.jsx
+++ b/components/date-picker/__tests__/date-picker.browser-test.jsx
@@ -494,4 +494,28 @@ describe('SLDSDatepicker', function describeFunction() {
trigger.simulate('click', {});
});
});
+
+ describe('Clearing controlled input', () => {
+ afterEach(() => wrapper.unmount());
+
+ it('clears input on null value', () => {
+ wrapper = mount();
+
+ const input = wrapper.find('input');
+ expect(input).not.to.have.value('');
+
+ wrapper.setProps({ value: null });
+ expect(input).to.have.value('');
+ });
+
+ it('does not clear input on non-null value', () => {
+ wrapper = mount();
+
+ const input = wrapper.find('input');
+ expect(input).not.to.have.value('');
+
+ wrapper.setProps({ value: undefined });
+ expect(input).not.to.have.value('');
+ });
+ });
});
diff --git a/components/date-picker/date-picker.d.ts b/components/date-picker/date-picker.d.ts
index 1f69ffdbab..fa2215e0ed 100644
--- a/components/date-picker/date-picker.d.ts
+++ b/components/date-picker/date-picker.d.ts
@@ -140,7 +140,7 @@ declare module '@salesforce/design-system-react/components/date-picker/date-pick
/**
* Sets date with a `Date` ECMAScript object. _Tested with snapshot testing._
*/
- value?: Date;
+ value?: Date | null;
};
/**
* A date picker is a non-text input form element. You can select a single date from a popup calendar. Please use an external library such as [MomentJS](https://github.com/moment/moment/) for date formatting and parsing and internationalization. You will want to use your date library within the `parser` and `formatter` callbacks.
diff --git a/components/date-picker/date-picker.jsx b/components/date-picker/date-picker.jsx
index ee8ee069e0..a517bebe68 100644
--- a/components/date-picker/date-picker.jsx
+++ b/components/date-picker/date-picker.jsx
@@ -279,6 +279,13 @@ class Datepicker extends React.Component {
checkProps(DATE_PICKER, props, componentDoc);
}
+ componentDidUpdate(prevProps) {
+ // clear controlled input when value is set to null
+ if (this.props.value === null && prevProps.value !== this.props.value) {
+ this.handleResetDate();
+ }
+ }
+
getDatePicker = ({ labels, assistiveText }) => {
let date;
// Use props if present. Otherwise, use state.
@@ -572,6 +579,14 @@ class Datepicker extends React.Component {
}
};
+ handleResetDate = () => {
+ this.setState({
+ value: undefined,
+ formattedValue: '',
+ inputValue: '',
+ });
+ };
+
openDialogFromIcon = () => {
this.setState({ isOpenFromIcon: true });
this.openDialog(true);