Skip to content
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

[datetime] remove moment dependency #2117

Merged
merged 21 commits into from
Feb 10, 2018
Merged

[datetime] remove moment dependency #2117

merged 21 commits into from
Feb 10, 2018

Conversation

giladgray
Copy link
Contributor

@giladgray giladgray commented Feb 9, 2018

Fixes #1930

⚠️ This PR is still a work-in-progress. Expecting test failures, but I'd like to start getting feedback on API changes.

Checklist

  • Fix DateInput tests
  • Fix DateRangeInput tests
  • Add tests for new methods
  • Update documentation
  • format.placeholder or top-level placeholder prop, etc.
  • can I remove any component state fields? if it ain't broke
    • lots of strings stored in state, but we can probably just formatDate() at render time

Changes proposed in this pull request:

  • new IDateFormatProps interface extended by DateInput and DateRangeInput
    • 🔥 new required formatDate and parseDate callbacks
    • 🔥 format prop is now just an optional string that is passed to callbacks above
    • 🔥 placeholder prop is now on the component itself (nee format.placeholder)
  • remove moment dependency from datetime package
    • docs-app still brings it in and uses it in examples
  • delete all moment-based DateUtils
  • refactor DateInput and DateRangeInput to use IDateFormatter instead of moment

Reviewers should focus on:

@blueprint-bot
Copy link

refactor DateRangeInput to use formatter instead of moment

Preview: documentation | landing | table

@themadcreator
Copy link
Contributor

What's the total bundle size reduction?

@giladgray
Copy link
Contributor Author

giladgray commented Feb 9, 2018

@adidahiya thoughts on borrowing r-d-p's DayPickerInput API? http://react-day-picker.js.org/api/DayPickerInput#formatDate

format?: string, formatDate: fn, parseDate: fn as top-level props, instead of object.

update: i did this. it's nice.

@@ -49,7 +49,7 @@ export interface IRadioGroupProps extends IProps {
options?: IOptionProps[];

/** Value of the selected radio. The child with this value will be `:checked`. */
selectedValue?: string;
selectedValue?: string | number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove unrelated change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh but it is related, or i wouldn't have pushed it. for FormatSelect, which uses the index in an array. Radio supports number values, so RadioGroup should do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

separate PR please

dateToString: date => date.toLocaleString(),
placeholder: "enter date",
stringToDate: str => new Date(Date.parse(str)),
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

big problems with this formatter. Date.parse(str) uses UTC timezone for "YYYY-MM-DD" strings, so some dates come out a day earlier than expected. should I just use a moment formatter in these tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Date("2/1/2015")
> "Sun Feb 01 2015 00:00:00 GMT-0800 (PST)"

new Date("2015-02-01")
> "Sat Jan 31 2015 16:00:00 GMT-0800 (PST)"

@giladgray
Copy link
Contributor Author

@themadcreator there's no immediate change in bundle size as datetime isn't bundled with its dependencies and moment is still used in docs-app.

this change makes moment not required when using datetime, and according to their website moment is 16.3kb gzipped.

@blueprint-bot
Copy link

quick-fix DRI (still needs attention)

Preview: documentation | landing | table

Copy link
Contributor

@adidahiya adidahiya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general direction lgtm. I think we should also apply this kind of change to the timezonepicker and require new timezone-related props for that component. then we can pull it back into @blueprintjs/datetime and remove the new package we made.

valueString: null,
};
}
public state: IDateInputState = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure it's ok to move this to the static member? why did we have it in the constructor before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am quite sure. typescript always inline state init in the constructor that it generates (before all the other => bound methods), so you can actually safely use this.props in public state initialization.

if (this.props.timePrecision == null) {
return false;
}
// TODO: getTime()?
Copy link
Contributor

@adidahiya adidahiya Feb 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • resolve this TODO in this PR

* Return `false` if the string is an invalid date.
* Return `null` to represent the absence of a date.
*/
parseDate(str: string, format?: string, locale?: string): Date | false | null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a huge blocker, but curious about this API decision: why would a consumer expect format in this function? if they're providing format as a prop, they already know the format they're interested in. in the usage of props.parseDate() it seems like you're passing props.format directly anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prior art: http://react-day-picker.js.org/api/DayPickerInput#formatDate.

this is the only place the format prop gets used, so we could drop it from the API and push it to the user. but the nice thing about this usage is that only one set of moment utils for format/parseDate could be used for all formats.

@@ -8,9 +8,18 @@ const React = require("react");
const DateTime = require("../lib/cjs");

describe("DateTime isomorphic rendering", () => {
const format = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: formatProps

@adidahiya
Copy link
Contributor

I didn't look at the logic very closely but I assume it's covered by the extensive test suite

@blueprint-bot
Copy link

fix most DRI tests

Preview: documentation | landing | table

@blueprint-bot
Copy link

fix all the DRI tests!

Preview: documentation | landing | table

/**
* Date format string, passed to `formatDate` and `parseDate`.
*/
format?: string;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adidahiya what's your take on this prop? worth keeping?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer to keep it simple and add it later if it's desired

@adidahiya
Copy link
Contributor

code looks fine but this radio doesn't work for me:

image

@giladgray
Copy link
Contributor Author

@adidahiya not sure what you mean with format screenshot, works for me. i just removed the (def broken) "from now" option.

@blueprint-bot
Copy link

remove format prop, add formatting tests

Preview: documentation | landing | table

Copy link
Contributor

@adidahiya adidahiya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice docs

@adidahiya
Copy link
Contributor

we should probably still add a @blueprintjs/datetime-moment package after this PR

@blueprint-bot
Copy link

add docs section about "Date formatting"

Preview: documentation | landing | table

@blueprint-bot
Copy link

add imports to docs

Preview: documentation | landing | table

Copy link
Contributor

@cmslewis cmslewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exciting stuff!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants