Examples basic form #59

Merged
merged 47 commits into from May 10, 2017

Conversation

Projects
None yet
3 participants
Contributor

lloydwheeler commented May 1, 2017

PR for a new example combining DOM elements and React primitives. The idea was to see how easy it'd be for me to create of PoC of a (semi) working web-component and then render its various states to a sketch document.

The main hurdle was (as far as I'm aware) there not being a react-primitives textbox so that's the reasoning behind having a TextBox component that has primitive and web components inside it, with shared styles across the two.

I imagine there's more than a few changes to be made here and there so let me know where I can look to improve things!

lloydwheeler added some commits May 1, 2017

@lloydwheeler lloydwheeler initial commit 2a9329e
@lloydwheeler lloydwheeler add type checking for session 697a375
@lloydwheeler lloydwheeler add dummy session data dc4e9bf
@lloydwheeler lloydwheeler add register component 129ba30
@lloydwheeler lloydwheeler create design system 7433842
@lloydwheeler lloydwheeler add nwb as dependency for web rendering 2ceded6
@lloydwheeler lloydwheeler add web entry point fb8b29c
@lloydwheeler lloydwheeler add button component 08a1fc3
@lloydwheeler lloydwheeler add strength meter component 1a4ca00
@lloydwheeler lloydwheeler add border-box to button styles 7084ab6
@lloydwheeler lloydwheeler add prop-types package 80c35fd
@lloydwheeler lloydwheeler add a few more states to sessions 1651c6b
@lloydwheeler lloydwheeler add default font family to design system and components 8e4dec2
@lloydwheeler lloydwheeler unifying styling between sketch and web 3132e7d
@lloydwheeler lloydwheeler add spacing component e31d52b
@lloydwheeler lloydwheeler layout set of components in sketch and web 6216194
@lloydwheeler lloydwheeler add password state to web component 110292f
@lloydwheeler lloydwheeler all textbox primitives to render child components 1bb2351
@lloydwheeler lloydwheeler remove render targets from the Register component into their correspo…
…nding entry points
c2d832f
@lloydwheeler lloydwheeler remove unnecessary dependencies 180a6dc
@lloydwheeler lloydwheeler remove destructing of styles 718f800
@lloydwheeler lloydwheeler remove magic numbers from text box styling 0504a74
@lloydwheeler lloydwheeler remove whitespace 81610c4
@lloydwheeler lloydwheeler add some basic instructions 65ec75c
@lloydwheeler lloydwheeler add border to textbox 14dfb0c
@lloydwheeler lloydwheeler remove magic numbers from strength meter 839c80b
@lloydwheeler lloydwheeler fix margin bug on web version e6f3917
@lloydwheeler lloydwheeler update heading 9b7dea8
@lloydwheeler lloydwheeler add screenshot of example abbe401

jongold self-requested a review May 1, 2017

@jongold

This is awesome, thanks so much for submitting it!

There's some duplication that I'd love to see removed (to fully showcase the power of primitives), but it's super close 🙏

If you're still unclear on architecture let me know.

I mentioned that flow Props were missing in a few components - if you'd prefer to use prop-types that's totally cool, but just make sure that every component has propTypes

Also, please make sure that eslint passes when you're ready to merge :)

examples/basic-form/package.json
+ "react-test-renderer": "^15.4.1"
+ },
+ "devDependencies": {
+ "skpm": "^0.8.0"
@jongold

jongold May 1, 2017

Member

Can you update to ^0.9.0? I've been meaning to do this to the rest of them

+}
+
+
+const Button = ({ label, backgroundColor }: Props) => (
@jongold

jongold May 1, 2017

Member

Looks like you're missing Props in this file

+import React from 'react';
+import { View } from 'react-primitives';
+
+const Register = ({ children }: Props) => (
@jongold

jongold May 1, 2017

Member

I think this could be called something more generic - it's not a 'registration component' per se, it's more like a 'column wrapper' — <Columns>?

+ return 'strong';
+}
+
+const StrengthMeter = ({ password }: Props) => (
@jongold

jongold May 1, 2017

Member

Props is missing

@@ -0,0 +1,19 @@
+import React from 'react';
@jongold

jongold May 1, 2017

Member

The main hurdle was (as far as I'm aware) there not being a react-primitives textbox so that's the reasoning behind having a TextBox component that has primitive and web components inside it, with shared styles across the two.

You don't have to explicitly import primitive.js & web.js

  • rename TextBox/primitive.js to TextBox/index.sketch.js
  • rename TextBox/web.js to TextBox/index.js

Then, import TextBox from './components/TextBox' will just work - Sketch will find the .sketch.js file, web will find the .web.js file

+import styles from './style';
+import StrengthMeter from '../StrengthMeter';
+
+const TextBox = ({ label, value, type }: Props) => (
@jongold

jongold May 1, 2017

Member

Props is missing

+ <View style={styles.formElement}>
+ <Text style={styles.label}>{label}</Text>
+ <View style={styles.textbox}>{value}</View>
+ {type === "password" && value.length > 0 &&
@jongold

jongold May 1, 2017

Member

You could also render StrengthMeter directly in your form - it doesn't need to live inside TextBox explicitly —

~=

<View>
  <TextBox />
  <TextBox />
  <StrengthMeter />
  <Button />
</View>

Alternatively, if you wanted it to be attached to the TextBox,

<View>
  <TextBox />
  <TextBox>
    <StrengthMeter />
  </TextBox>
  <Button />
</View>

& then in TextBox,

{ children && props.children }
examples/basic-form/src/main.js
+ <Register>
+ {sessions.map(session => (
+ <Space key={session.password} h={spacing.Large} v={spacing.Large}>
+ <View style={styles.register}>
@jongold

jongold May 1, 2017

Member

I'd extract this whole thing to a new component ~= <RegistrationForm> that takes an email & password - then you could reuse it in the web version too

examples/basic-form/src/web.js
+ <Register>
+ <div style={styles.register}>
+ <Text style={{...styles.heading}}>Register an Account</Text>
+ <TextBox
@jongold

jongold May 1, 2017

Member

See my comment on src/main - you shouldn't have to build this form twice :)

@jongold

jongold May 1, 2017

Member

you can use getDefaultProps for this 🤔

Contributor

lloydwheeler commented May 1, 2017

Thanks for taking the time to look through this, I'll take another look with your suggestions and resubmit!

Contributor

lloydwheeler commented May 2, 2017

Thanks for the pointers, I've spent some time refactoring the example.

  • In particular being able to just use index.js and index.sketch.js instead of explicitly calling each component made everything much easier. The Register component is just defined once now and is imported by both main.js and web.js.
  • StrengthMeter has been decoupled from the TextBox component and is now rendered with {children}. Commit here.

Just a couple of other things:

  1. What's the ettiqutte for updating this PR? Should I close this and create another or do the new commits just get checked?
  2. Should I be generating the documentation? The examples in examples.md all point to the master branch so I wasn't sure whether to pre-empt a new demo being added.
  3. Running eslint still complains about optional props not having a corresponding defaultProp declaration although this is consistent with the other examples?
  4. Apologies for the lint dump in the final commit, I'd thought it'd been running automatically. Will get that fixed.

Thanks!

Owner

ljharb commented May 2, 2017

Force push to this PR to update it; please don't open a new one :-)

@jongold

jongold approved these changes May 9, 2017 View changes

Finally got to looking at this (sorry for the delay) - looks great!

Last thing - do you mind if I rename it to form validation?

Contributor

lloydwheeler commented May 10, 2017

No problem!

Feel free to rename, by the time I got to the end of building the example I felt basic-form wasn't really that well suited anyway.

🙏

jongold added some commits May 10, 2017

@jongold jongold rename to form-validation df0c2ac
@jongold jongold nwb seems to need explicit extract-text-webpack-plugin 01d09b5

jongold merged commit c46abc0 into airbnb:master May 10, 2017

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