Skip to content

added timeClassName prop #1795

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

Merged
merged 7 commits into from
Jan 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ We're always trying to stay compatible with the latest version of React. We can'

Latest compatible versions:

- React 16 or newer: React-datepicker v2.9.4 and newer
- React 16 or newer: React-datepicker v2.9.4 and newer
- React 15.5: React-datepicker v2.9.3
- React 15.4.1: needs React-datepicker v0.40.0, newer won't work (due to react-onclickoutside dependencies)
- React 0.14 or newer: All above React-datepicker v0.13.0
Expand Down
5 changes: 5 additions & 0 deletions docs-site/src/components/Examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import CustomDateFormat from "../../examples/customDateFormat";
import CustomClassName from "../../examples/customClassName";
import CustomCalendarClassName from "../../examples/customCalendarClassName";
import CustomDayClassName from "../../examples/customDayClassName";
import CustomTimeClassName from "../../examples/customTimeClassName";
import Today from "../../examples/today";
import PlaceholderText from "../../examples/placeholderText";
import SpecificDateRange from "../../examples/specificDateRange";
Expand Down Expand Up @@ -125,6 +126,10 @@ export default class exampleComponents extends React.Component {
title: "Custom day class name",
component: CustomDayClassName
},
{
title: "Custom time class name",
component: CustomTimeClassName
},
{
title: "Today button",
component: Today
Expand Down
8 changes: 8 additions & 0 deletions docs-site/src/components/Examples/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,11 @@ input {
box-shadow: inset 0 2px 2px #e9e9e9, 0 0 10px 0 rgba(73, 107, 125, 0.3);
}
}

.text-error {
color: red;
}

.text-success {
color: green;
}
9 changes: 2 additions & 7 deletions docs-site/src/examples/children.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
() => {
const [startDate, setStartDate] = useState(new Date());
return (
<DatePicker
selected={startDate}
onChange={date => setStartDate(date)}
>
<div style={{ color: "red" }}>
Don't forget to check the weather!
</div>
<DatePicker selected={startDate} onChange={date => setStartDate(date)}>
<div style={{ color: "red" }}>Don't forget to check the weather!</div>
</DatePicker>
);
};
16 changes: 16 additions & 0 deletions docs-site/src/examples/customTimeClassName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
() => {
const [startDate, setStartDate] = useState(new Date());

let handleColor = time => {
return time.getHours() > 12 ? "text-success" : "text-error";
};

return (
<DatePicker
showTimeSelect
selected={startDate}
onChange={date => setStartDate(date)}
timeClassName={handleColor}
/>
);
};
3 changes: 2 additions & 1 deletion docs/datepicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ General datepicker component.
| `clearButtonTitle` | `string` | | |
| `customInput` | `element` | | |
| `customInputRef` | `string` | `'ref'` | The property used to pass the ref callback |
| `dateFormat` | `union(string\|array)` | `'MM/dd/yyyy'` | |
| `dateFormat` | `union(string\|array)` | `'MM/dd/yyyy'` | |
| `dateFormatCalendar` | `string` | `'LLLL yyyy'` | |
| `dayClassName` | `func` | | |
| `disabled` | `bool` | `false` | |
Expand Down Expand Up @@ -74,6 +74,7 @@ General datepicker component.
| `startDate` | `instanceOf(Date)` | | |
| `startOpen` | `bool` | | |
| `tabIndex` | `number` | | |
| `timeClassName` | `func` | | |
| `timeFormat` | `string` | | |
| `timeIntervals` | `number` | `30` | |
| `title` | `string` | | |
Expand Down
20 changes: 10 additions & 10 deletions scripts/buildDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
* e.g. react-docgen components/* | buildDocs.sh
*/

var fs = require('fs');
var generateMarkdown = require('./generateMarkdown');
var path = require('path');
var fs = require("fs");
var generateMarkdown = require("./generateMarkdown");
var path = require("path");

var json = '';
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
var json = "";
process.stdin.setEncoding("utf8");
process.stdin.on("readable", function() {
var chunk = process.stdin.read();
if (chunk !== null) {
json += chunk;
}
});

process.stdin.on('end', function() {
process.stdin.on("end", function() {
buildDocs(JSON.parse(json));
});

Expand All @@ -27,9 +27,9 @@ function buildDocs(api) {
for (var filepath in api) {
var name = getComponentName(filepath);
var markdown = generateMarkdown(name, api[filepath]);
var outputLocation = './docs/';
fs.writeFileSync(outputLocation + name + '.md', markdown);
process.stdout.write(filepath + ' -> ' + outputLocation + name + '.md\n');
var outputLocation = "./docs/";
fs.writeFileSync(outputLocation + name + ".md", markdown);
process.stdout.write(filepath + " -> " + outputLocation + name + ".md\n");
}
}

Expand Down
63 changes: 40 additions & 23 deletions scripts/generateMarkdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,83 @@
"use strict";

function stringOfLength(string, length) {
var newString = '';
var newString = "";
for (var i = 0; i < length; i++) {
newString += string;
}
return newString;
}

function generateTitle(name) {
var title = '`' + name + '` (component)';
return title + '\n' + stringOfLength('=', title.length) + '\n';
var title = "`" + name + "` (component)";
return title + "\n" + stringOfLength("=", title.length) + "\n";
}

function generateDesciption(description) {
if (description) return description + '\n';
if (description) return description + "\n";

return '';
return "";
}

function generatePropType(type) {
var values;
if (Array.isArray(type.value)) {
values = '(' +
type.value.map(function(typeValue) {
return typeValue.name || typeValue.value;
}).join('\\|') +
')';
values =
"(" +
type.value
.map(function(typeValue) {
return typeValue.name || typeValue.value;
})
.join("\\|") +
")";
} else {
values = type.value;
}

return '`' + type.name + (values ? values: '') + '`';
return "`" + type.name + (values ? values : "") + "`";
}

function generatePropDefaultValue(value) {
return '`' + value.value + '`';
return "`" + value.value + "`";
}

function generateProp(propName, prop) {
return (
'|`' + propName + '`' + (prop.required ? ' (required)' : '') +
'|' + (prop.type ? generatePropType(prop.type) : '') +
'|' + (prop.defaultValue ? generatePropDefaultValue(prop.defaultValue) : '') +
'|' + (prop.description ? prop.description + '\n\n' : '') + '|'
"|`" +
propName +
"`" +
(prop.required ? " (required)" : "") +
"|" +
(prop.type ? generatePropType(prop.type) : "") +
"|" +
(prop.defaultValue ? generatePropDefaultValue(prop.defaultValue) : "") +
"|" +
(prop.description ? prop.description + "\n\n" : "") +
"|"
);
}

function generateProps(props) {
return (
'| name | type | default value | description |' + '\n' +
'|---|---|---|---|' + '\n' +
Object.keys(props).sort().map(function(propName) {
return generateProp(propName, props[propName]);
}).join('\n')
"| name | type | default value | description |" +
"\n" +
"|---|---|---|---|" +
"\n" +
Object.keys(props)
.sort()
.map(function(propName) {
return generateProp(propName, props[propName]);
})
.join("\n")
);
}

function generateMarkdown(name, reactAPI) {
var markdownString =
generateTitle(name) + '\n' +
generateDesciption(reactAPI.description) + '\n' +
generateTitle(name) +
"\n" +
generateDesciption(reactAPI.description) +
"\n" +
generateProps(reactAPI.props);

return markdownString;
Expand Down
6 changes: 5 additions & 1 deletion src/calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export default class Calendar extends React.Component {
dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.array])
.isRequired,
dayClassName: PropTypes.func,
timeClassName: PropTypes.func,
disabledKeyboardNavigation: PropTypes.bool,
dropdownMode: PropTypes.oneOf(["scroll", "select"]),
endDate: PropTypes.instanceOf(Date),
Expand Down Expand Up @@ -552,7 +553,9 @@ export default class Calendar extends React.Component {
<div className="react-datepicker__header">
{this.renderCurrentMonth(monthDate)}
<div
className={`react-datepicker__header__dropdown react-datepicker__header__dropdown--${this.props.dropdownMode}`}
className={`react-datepicker__header__dropdown react-datepicker__header__dropdown--${
this.props.dropdownMode
}`}
onFocus={this.handleDropdownFocus}
>
{this.renderMonthDropdown(i !== 0)}
Expand Down Expand Up @@ -708,6 +711,7 @@ export default class Calendar extends React.Component {
selected={this.props.selected}
openToDate={this.props.openToDate}
onChange={this.props.onTimeChange}
timeClassName={this.props.timeClassName}
format={this.props.timeFormat}
includeTimes={this.props.includeTimes}
intervals={this.props.timeIntervals}
Expand Down
2 changes: 2 additions & 0 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export default class DatePicker extends React.Component {
dateFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
dateFormatCalendar: PropTypes.string,
dayClassName: PropTypes.func,
timeClassName: PropTypes.func,
disabled: PropTypes.bool,
disabledKeyboardNavigation: PropTypes.bool,
dropdownMode: PropTypes.oneOf(["scroll", "select"]).isRequired,
Expand Down Expand Up @@ -691,6 +692,7 @@ export default class DatePicker extends React.Component {
onMonthChange={this.props.onMonthChange}
onYearChange={this.props.onYearChange}
dayClassName={this.props.dayClassName}
timeClassName={this.props.timeClassName}
showTimeSelect={this.props.showTimeSelect}
showTimeSelectOnly={this.props.showTimeSelectOnly}
onTimeChange={this.handleTimeChange}
Expand Down
8 changes: 7 additions & 1 deletion src/time.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default class Time extends React.Component {
selected: PropTypes.instanceOf(Date),
openToDate: PropTypes.instanceOf(Date),
onChange: PropTypes.func,
timeClassName: PropTypes.func,
todayButton: PropTypes.node,
minTime: PropTypes.instanceOf(Date),
maxTime: PropTypes.instanceOf(Date),
Expand Down Expand Up @@ -82,7 +83,12 @@ export default class Time extends React.Component {
};

liClasses = (time, currH, currM) => {
let classes = ["react-datepicker__time-list-item"];
let classes = [
"react-datepicker__time-list-item",
this.props.timeClassName
? this.props.timeClassName(time, currH, currM)
: undefined
];

if (
this.props.selected &&
Expand Down
33 changes: 33 additions & 0 deletions test/timepicker_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,39 @@ describe("TimePicker", () => {
expect(datePicker.state.open).to.be.true;
});

it("should show different colors for times", () => {
const handleTimeColors = (time, currH, currM) => {
if (!Number.isInteger(currH) || !Number.isInteger(currM)) {
return "wrong";
}
return time.getHours() < 12 ? "red" : "green";
};
const timePicker = TestUtils.renderIntoDocument(
<DatePicker
showTimeSelect
showTimeSelectOnly
timeClassName={handleTimeColors}
onChange={() => console.log("changed")}
open
focus
/>
);
let redItems = TestUtils.scryRenderedDOMComponentsWithClass(
timePicker,
"react-datepicker__time-list-item red"
);
let greenItems = TestUtils.scryRenderedDOMComponentsWithClass(
timePicker,
"react-datepicker__time-list-item green"
);
assert.isTrue(
redItems !== undefined &&
redItems.length === 24 &&
greenItems !== undefined &&
greenItems.length === 24
);
});

function setManually(string) {
TestUtils.Simulate.focus(datePicker.input);
TestUtils.Simulate.change(datePicker.input, { target: { value: string } });
Expand Down