Skip to content

Date Picker using react-dates#12016

Merged
cvializ merged 15 commits intoampproject:masterfrom
cvializ:feature/date-picker
Dec 11, 2017
Merged

Date Picker using react-dates#12016
cvializ merged 15 commits intoampproject:masterfrom
cvializ:feature/date-picker

Conversation

@cvializ
Copy link
Copy Markdown
Contributor

@cvializ cvializ commented Nov 10, 2017

Date picker effort

Closes #11218
Closes #11219

/to @erwinmombay could you please take a look at the build process and closure compiler pieces?
/to @aghassemi
/to @jridgewell

/cc @ericlindley-g @lswang1618

@cvializ
Copy link
Copy Markdown
Contributor Author

cvializ commented Nov 10, 2017

(still looking at good ways to write tests for this build process)

@cvializ cvializ force-pushed the feature/date-picker branch from 053b242 to ccabf0f Compare November 10, 2017 23:04
@ampprojectbot ampprojectbot added this to the Pending Triage milestone Nov 13, 2017
Copy link
Copy Markdown
Contributor

@aghassemi aghassemi left a comment

Choose a reason for hiding this comment

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

first half

'third_party/vega/**/*.js',
'third_party/d3/**/*.js',
'third_party/webcomponentsjs/ShadowCSS.js',
'third_party/rrule/rrule.js',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's file a security review ticket ( b/ -> Security > Consulting Services > Project Review . Assign to Gabor M) for all third-parties here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should I open one ticket per library, or just one ticket?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

b/69925010

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

All the dependencies passed security review

<p>Try to pick a date. This is a single-date picker</p>
<button on="tap:sdp.setDate(date='2017-10-22')">Set date</button>
<button on="tap:sdp.clear">Clear</button>
<amp-date
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

amp-date is too generic of a name IMO, could we rename to amp-date-input and amp-date-range-input if not too much work? (will be more consistent with date namespacing we have planned as well e.g. amp-date-display, amp-date-countdown, etc.. )

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

how about amp-date-picker and we distinguish range vs single with a type attribute?

<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
<h1><code>amp-date-picker</code> example</h1>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please add an experiment flag before merging and add a note here that it is under the flag.

@@ -0,0 +1,258 @@
<!doctype html>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/kayak/travel?

<span class="highlight-square"></span>
</template>
</amp-date-range>
<!-- <div [class]="!wow.show ? 'wow hidden' : 'wow'" class="wow hidden">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this section is commented out.


/**
* Create an array of objects mapping dates to templates.
* @param {?Promise<!JsonObject|!Array<JsonObject>>} srcTemplatePromise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

seems to be a void method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It mutates this.srcTemplates_ and this.srcDefaultTemplates_, but if you'd prefer it as a pure function I would be glad to do that


/** @return {!Promise<string>} */
renderInfoTemplate_() {
const template = scopedQuerySelector(this.element, '[info-template]');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

scopedQuerySelector is an overkill for all cases I have noticed. normal queryselector should do.

if (!this.infoTemplatePromise_) {
this.infoTemplatePromise_ = this.renderInfoTemplate_();
}
this.scanForBindings_([this.container_]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

how about other template types? would it make sense to move this to renderTemplate_?

const data = opt_data || /** @type {!JsonObject} */ ({});
return this.templates_.renderTemplate(template, data)
.then(rendered => {
rendered.setAttribute('i-amphtml-rendered', '');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you probably don't need to set this unless you need to know which once have been rendered to clear them,

rendered.setAttribute('i-amphtml-rendered', '');
const renderedEvent = createCustomEvent(
this.win_,
AmpEvents.DOM_UPDATE,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

interesting, amp-bind is listening to this, now I don't see a need for scanForBindings_ at all. Can you test and see if scanForBindings_ is needed? (if so, why? looks like bind should be re-scanning on dom mutations anyway)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It looks like scanForBindings is not needed, I was dispatching the event on the wrong element. It was incorrectly dispatched on the template element, which of course doesn't contain any elements with bindings.

@cvializ cvializ force-pushed the feature/date-picker branch from b8f02dd to 64e140d Compare November 30, 2017 22:41
@cvializ cvializ force-pushed the feature/date-picker branch 2 times, most recently from adb138e to dd12a10 Compare December 1, 2017 23:15
@cvializ cvializ force-pushed the feature/date-picker branch from dd12a10 to dee99e8 Compare December 1, 2017 23:27
@cvializ cvializ force-pushed the feature/date-picker branch from 9efd70d to 7c41aa2 Compare December 6, 2017 18:50
@cvializ
Copy link
Copy Markdown
Contributor Author

cvializ commented Dec 6, 2017

@aghassemi This should be ready for further review now!

},
{
filesMatching: '**/*.js',
mustNotDependOn: 'src/module.js',
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do you think this is helpful, or unnecessary? I thought it might make sense to explicitly opt-in to this pattern.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I like it, good thinking.

Copy link
Copy Markdown
Contributor

@aghassemi aghassemi left a comment

Choose a reason for hiding this comment

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

Amazing PR Carlos.
Few small requests and some suggestions.

For testing (can be after this PR), I suggest unit tests for the utils and util-like functions and then e-2-e integration tests for the rest. The integration tests can be simple to write and can cover a huge portion of the code.

css/amp.css Outdated
}

amp-date,
amp-date-range {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

element was renamed, so these need updating.

Overall I really like the idea of forcing container and having these to make sure pre-attach and post-attach are the same. Maybe also add a comment here explaining why these are here.

For default style changes, I hope we can make most of the changes (for the input part) here instead of date-picker.css so we don't end up duplicating them.

error: (RTC_ERROR_ENUM|undefined)}} */
var rtcResponseDef;

/** @type {!function(string):?} */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: short summary comment on why we have this

},
{
filesMatching: '**/*.js',
mustNotDependOn: 'src/module.js',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I like it, good thinking.

@@ -0,0 +1,135 @@
/**
* Copyright 2017 The AMP HTML Authors. All Rights Reserved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/cc @erwinmombay @rsimha-amp for the build setup.

gulpfile.js Outdated
'third_party/react-dates/bundle.js',
]);
} else if (srcFilename === 'amp-viz-vega.js') {
bundle = concatFilesToString([
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

awesome.

.filter(t => t.dates)
.map(t => ({
dates: new DatesList(t.dates),
template: this.ampdoc_.getRootNode().querySelector(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I assume templates can't be outside of <amp-date-picker> (mostly due to validator restrictions)., unless I am mistaken we should be able to use this.element for the query.

Copy link
Copy Markdown
Contributor Author

@cvializ cvializ Dec 8, 2017

Choose a reason for hiding this comment

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

I think template-impl.js supports templates outside the parent element via the template="" attribute, which queries for the id in the whole document, so I think it shouldn't be too problematic for the validator to do it for the date-picker too.

maybeFindTemplate_(parent) {
const templateId = parent.getAttribute('template');
if (templateId) {
return parent.ownerDocument.getElementById(templateId);
} else {
return childElementByTag(parent, 'template');
}
}


const defaultTemplate = templates
.filter(t => t.dates == null)
.map(t => this.ampdoc_.getElementById(t.id))[0];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ditto for getElementById, scoping to this element via querySelector.

(although ids have to be unique, we don't restrict it and I have seen bugs in AMP pages caused by duplicated ids, this sort of scoping can help be more forgiving of such user mistakes)

return rendered./*REVIEW*/outerHTML;
});
} else {
return Promise.resolve(opt_fallback || '');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

might be worth calling sanitizeFormattingHtml from sanitizer.js on fallback anyway for additional protection.

}
}

AMP.extension(TAG, '0.1', AMP => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nicely organized extension! awesome job.

* Find a specified template inside the parent. Fail if the template is
* not present.
* @param {!Element} parent
* @param {string=} opt_queryString
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: Maybe querySelector?, queryString makes me think of Urls

@cvializ cvializ merged commit 768fad0 into ampproject:master Dec 11, 2017
@rsimha
Copy link
Copy Markdown
Contributor

rsimha commented Dec 13, 2017

@cvializ @aghassemi After this PR was landed, I'm seeing the following warnings when I run yarn on linux. Could it be that some implicit dependencies weren't added to package.json?

warning "react-dates@13.0.6" has unmet peer dependency "react@>=0.14".
warning "react-dates@13.0.6" has unmet peer dependency "react-dom@>=0.14".
warning "airbnb-prop-types@2.8.1" has unmet peer dependency "react@^0.14 || ^15.0.0 || ^16.0.0-alpha".
warning "react-with-styles@2.3.0" has unmet peer dependency "react@>=0.14".
warning "react-with-styles@2.3.0" has unmet peer dependency "react-with-direction@^1.1.0".
warning "react-with-direction@1.1.0" has unmet peer dependency "react@^0.14 || ^15 || ^16".
warning "react-with-direction@1.1.0" has unmet peer dependency "react-dom@^0.14 || ^15 || ^16".

@cvializ
Copy link
Copy Markdown
Contributor Author

cvializ commented Dec 13, 2017

Ah yeah, thanks for looking out! I was aware of these warnings, and I looked for a way to remove just those warnings, but I didn't find a good way. This PR used preact instead of react, but I am about to submit another PR that will use react since the license issues were resolved and there are some bugs with how preact and react-dates interact. That new PR should resolve these peer dependency errors.

gzgogo pushed a commit to gzgogo/amphtml that referenced this pull request Jan 26, 2018
* Initial wip commit for react-dates date picker

Date picker with dist build working

* Type lint and type checking mostly working

* Fix presubmit errors

* Update whitelist

* First set of fixes for review feedback

* Remove scanForBindings_

* Add experiment

* Add externalRequire helper. Remove global library references. Types.

* Rename. Remove unnecessary node_modules and changes

* Remove need for additional globals like require.

* Fix presubmit check

* Add experiment flag to example

* Address review feedback. Phrasing.

* whitelist sanitizer
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