Skip to content

Commit

Permalink
Locales without globals (Hacker0x01#1660)
Browse files Browse the repository at this point in the history
* Allow using locales without passing them through a global variable

* Add an example of using locales without a global variable
  • Loading branch information
whatisaphone authored and aij committed Mar 12, 2019
1 parent faa5a34 commit 5e39708
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 6 deletions.
5 changes: 5 additions & 0 deletions docs-site/src/example_components.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CustomDayClassNames from "./examples/custom_day_class_names";
import PlaceholderText from "./examples/placeholder_text";
import SpecificDateRange from "./examples/specific_date_range";
import Locale from "./examples/locale";
import LocaleWithoutGlobalVariable from "./examples/locale_without_global_variable";
import ExcludeDates from "./examples/exclude_dates";
import HighlightDates from "./examples/highlight_dates";
import HighlightDatesRanges from "./examples/highlight_dates_with_ranges";
Expand Down Expand Up @@ -125,6 +126,10 @@ export default class exampleComponents extends React.Component {
title: "Locale",
component: <Locale />
},
{
title: "Locale without global variables",
component: <LocaleWithoutGlobalVariable />
},
{
title: "Exclude dates",
component: <ExcludeDates />
Expand Down
57 changes: 57 additions & 0 deletions docs-site/src/examples/locale_without_global_variable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from "react";
import DatePicker, { registerLocale } from "react-datepicker";
import fi from "date-fns/locale/fi";

export default class LocaleWithoutGlobalVariable extends React.Component {
state = {
startDate: null
};

handleChange = date => {
this.setState({
startDate: date
});
};

render() {
return (
<div className="row">
<pre className="column example__code">
<code className="jsx">
{
"// Note: Make sure to npm install the right version of date-fns as"
}
<br />
{
"// specified in packaged.json. The default one may not be compatiable"
}
<br />
{"// npm install --save date-fns@version"}
<br />
{"import DatePicker from 'react-datepicker';"}
<br />
{"import fi from 'date-fns/locale/fi';"}
<br />
<br />
{"<DatePicker"}
<br />
{" selected={this.state.startDate}"}
<br />
{" onChange={this.handleChange}"}
<br />
<strong>{" locale={fi}"}</strong>
<br />
{"/>"}
</code>
</pre>
<div className="column">
<DatePicker
selected={this.state.startDate}
onChange={this.handleChange}
locale={fi}
/>
</div>
</div>
);
}
}
5 changes: 4 additions & 1 deletion src/calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export default class Calendar extends React.Component {
includeTimes: PropTypes.array,
injectTimes: PropTypes.array,
inline: PropTypes.bool,
locale: PropTypes.string,
locale: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({ locale: PropTypes.object })
]),
maxDate: PropTypes.instanceOf(Date),
minDate: PropTypes.instanceOf(Date),
monthsShown: PropTypes.number,
Expand Down
10 changes: 8 additions & 2 deletions src/date_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,14 @@ export function getDefaultLocale() {
return window.__localeId__;
}

export function getLocaleObject(localeName) {
return window.__localeData__ ? window.__localeData__[localeName] : null;
export function getLocaleObject(localeSpec) {
if (typeof localeSpec === "string") {
// Treat it as a locale name registered by registerLocale
return window.__localeData__ ? window.__localeData__[localeSpec] : null;
} else {
// Treat it as a raw date-fns locale object
return localeSpec;
}
}

export function getFormattedWeekdayInLocale(date, formatFunc, locale) {
Expand Down
5 changes: 4 additions & 1 deletion src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ export default class DatePicker extends React.Component {
injectTimes: PropTypes.array,
inline: PropTypes.bool,
isClearable: PropTypes.bool,
locale: PropTypes.string,
locale: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({ locale: PropTypes.object })
]),
maxDate: PropTypes.instanceOf(Date),
minDate: PropTypes.instanceOf(Date),
monthsShown: PropTypes.number,
Expand Down
5 changes: 4 additions & 1 deletion src/month.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export default class Month extends React.Component {
highlightDates: PropTypes.instanceOf(Map),
includeDates: PropTypes.array,
inline: PropTypes.bool,
locale: PropTypes.string,
locale: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({ locale: PropTypes.object })
]),
maxDate: PropTypes.instanceOf(Date),
minDate: PropTypes.instanceOf(Date),
onDayClick: PropTypes.func,
Expand Down
5 changes: 4 additions & 1 deletion src/week.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export default class Week extends React.Component {
highlightDates: PropTypes.instanceOf(Map),
includeDates: PropTypes.array,
inline: PropTypes.bool,
locale: PropTypes.string,
locale: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({ locale: PropTypes.object })
]),
maxDate: PropTypes.instanceOf(Date),
minDate: PropTypes.instanceOf(Date),
month: PropTypes.number,
Expand Down
15 changes: 15 additions & 0 deletions test/calendar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import DatePicker from "../src/index.jsx";
import { shallow, mount } from "enzyme";
import sinon from "sinon";
import * as utils from "../src/date_utils";
import eo from "date-fns/locale/eo";
import fi from "date-fns/locale/fi";

// TODO Possibly rename
Expand Down Expand Up @@ -983,6 +984,20 @@ describe("Calendar", function() {
utils.setDefaultLocale("");
});

it("should accept a raw date-fns locale object", function() {
// Note that we explicitly do not call `registerLocale`, because that
// would create a global variable, which we want to avoid.
const locale = eo;
const selected = utils.newDate();

const calendar = getCalendar({ selected, locale });
testLocale(calendar, selected, locale);

// Other tests touch this global, so it will always be present, but at the
// very least we can make sure the test worked without 'eo' being added.
expect(window.__localeData__).not.to.haveOwnProperty("eo");
});

it("should render empty custom header", function() {
const calendar = getCalendar({ renderCustomHeader: () => {} });

Expand Down

0 comments on commit 5e39708

Please sign in to comment.