🏗 Allow rendering plain DOM using JSX#36640
Conversation
| } | ||
|
|
||
| return drawerEl; | ||
| return <BlockingNotification logoSrc={logoSrc} />; |
There was a problem hiding this comment.
It's optional to enable this syntax by using Capitalized function names and taking a props object. Conversely, renderNotificationElement() is called as a normal function below.
Using <Component> syntax does come with some niceties, like the ability to nest components and receive children.
There was a problem hiding this comment.
Still reviewing, but do we provide the ESLinting rules that would make these situations super clear and less prone to subtle errors?
e.g someone attempts to return <blockingNotification> instead of <BlockingNotification>.
Not a blocker, but good to enhance quickly if we dont already provide.
9aa01dd to
8845b51
Compare
|
Hey @erwinmombay! These files were changed: Hey @jridgewell! These files were changed: |
8845b51 to
385b183
Compare
gmajoulet
left a comment
There was a problem hiding this comment.
Thank you for writing an example this is super helpful!
| <div class="i-amphtml-story-access-header"> | ||
| <div | ||
| class="i-amphtml-story-access-logo" | ||
| style={logoSrc ? `background-image: url(${logoSrc});` : null} |
There was a problem hiding this comment.
+1000
This makes templating so easy/readable.
|
Are we expecting any major diff in bundle size? |
processprocess
left a comment
There was a problem hiding this comment.
This is awesome.
Approved with a couple of nits/questions.
A previous comment from @alanorozco :
We will go with the jsx-dom util, so it will add |
In short, bundles that use this get a |
/amp-story*
10ce52f to
734787d
Compare
There was a problem hiding this comment.
This is super cool. Almost all LGTM, just had a few questions mostly FMI.
Definitely wait for a review from @jridgewell though, since I know he's also implemented his own version of jsx and is a SME here
src/core/dom/jsx.js
Outdated
| return; | ||
| } | ||
| if (name.startsWith('on') && name.length > 2) { | ||
| element.addEventListener(name.toLowerCase().substr(2), value); |
There was a problem hiding this comment.
note: I double checked to confirm that all event names are lower case 👍
| it('attaches event handlers from attributes', () => { | ||
| const onFooBar = env.sandbox.spy(); | ||
| const element = <div onFooBar={onFooBar} />; | ||
| expect(element).to.not.have.attribute('onfoobar'); |
There was a problem hiding this comment.
awesome. I wanted to ensure that <div onclick={onClick}/> wouldn't result in registering two event handlers, but since you don't keep the attribute in the final output, LGTM
kristoferbaxter
left a comment
There was a problem hiding this comment.
Seems good to me, but I'd like to see @jridgewell's review too before proceeding.
| * @return {!Element} | ||
| */ | ||
| const getNotificationTemplate = (element) => { | ||
| return htmlFor(element)` |
There was a problem hiding this comment.
If we like this approach, a cleanup PR for the entire repo would be a great first task.
| } | ||
|
|
||
| return drawerEl; | ||
| return <BlockingNotification logoSrc={logoSrc} />; |
There was a problem hiding this comment.
Still reviewing, but do we provide the ESLinting rules that would make these situations super clear and less prone to subtle errors?
e.g someone attempts to return <blockingNotification> instead of <BlockingNotification>.
Not a blocker, but good to enhance quickly if we dont already provide.
| * These features are omitted for the sake of bundle size: | ||
| * | ||
| * 🚫 Attribute names are not re-mapped. | ||
| * - Use standard HTML attribute names on elements (`class`, not `className`). |
There was a problem hiding this comment.
If we plan to use this long term, a followup could include linting rules to prevent these features from being accidentally relied on.
| @@ -1,3 +1,4 @@ | |||
| import * as Preact from '#core/dom/jsx'; | |||
There was a problem hiding this comment.
Nit: I'm a bit worried we'll confuse this with actual Preact (and the ability to diff). Can we use a different name and @jsxPragma?
// input
/** @jsx StaticTree.createElement */
<div/>
// output
StaticTree.createElement("div");There was a problem hiding this comment.
Using JsxStaticTree, with the rule enforcing Jsx if not Preact for the sake of simplicity. (Without the prefix we'd need to parse the pragma annotation, which would be fragile.)
There was a problem hiding this comment.
I really wanted to do this but Closure is not playing nice.
WARNING - [JSC_BAD_JSDOC_ANNOTATION] Parse error. illegal use of unknown JSDoc tag "jsx"; ignoring it.
Place another character before the @ to stop JSCompiler from parsing it as an annotation.
Tracking: #36680
b8b69fd to
a8b45bc
Compare
/amp-story*
Related to #36459
Provides a replacement for existing rendering methods that's more powerful and convenient:
htmlForsimple-template(Stories)A minimal implementation of JSX is included as
#core/dom/jsx.This library adds ~0.22K of size to any given bundle. By replacing callsites of previous rendering methods, the overall size of a bundle is roughly neutral or smaller.
This change does not change any implementation code. A migration of existing templates and renderers will follow-up.