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

Support state #66

Open
markdalgleish opened this issue Apr 26, 2019 · 4 comments

Comments

@markdalgleish
Copy link
Member

commented Apr 26, 2019

It'd be great if users could make their designs stateful.

My thinking is that we could do this in a code-oriented way by allowing usage of React hooks like this:

const [ firstName, setFirstName ] = useState('');
const [ lastName, setLastName ] = useState('');

<TextField label="First name" value={name} onChange=(event => setFirstName(event.target.value)} />
<TextField label="Last name" value={name} onChange=(event => setLastName(event.target.value)} />

For this to work, we'd need to treat the last n number of JSX elements as an implicitly returned fragment, i.e. behind the scenes we'd turn it into a component that looks like this:

() => {
  const [ firstName, setFirstName ] = useState('');
  const [ lastName, setLastName ] = useState('');

  return (
    <React.Fragment>
      <TextField label="First name" value={name} onChange=(event => setFirstName(event.target.value)} />
      <TextField label="Last name" value={name} onChange=(event => setName(event.target.value)} />
    </React.Fragment>
  );
};
@kvendrik

This comment has been minimized.

Copy link

commented Apr 26, 2019

As an alternative to consider last week we did some thinking on if we would be able to let people set hooks within the JSX somehow using say a custom component. Not sure if this should be something that is directly implemented into Playroom itself but thought the idea was interesting. I do wonder though if and how limiting this would be.

<PlayroomState defaultState={false}>
  {(toggled, setToggled) => {
    <Button onClick={() => setToggled(true)}>Open</Button>
    <Modal
      open={toggled}
      onClose={() => setToggled(false)}
    >
      Modal content
    </Modal>
  }}
</PlayroomState>

Or to make it even easier we have also thought about creating helpers that have default state values to allow non-devs to understand and rapidly prototype using state even quicker:

<ToggleState>
  {(isToggled, toggle) => {
    <Button onClick={toggle}>Open</Button>
    <Modal
      open={isToggled}
      onClose={toggle}
    >
      Modal content
    </Modal>
  }}
</ToggleState>

As we plan on trying to use Playroom as a way for our designers to prototype setting state using the least amount of JS complexity would be the ideal scenario for us. This doesn't have to be something that is necessarily directly integrated into Playroom though. I can for example imagine that within Playroom we just want some way of setting state and then devs can create their own wrappers around that depending on their target audience.

@danrosenthal

This comment has been minimized.

Copy link

commented Apr 26, 2019

Here's a quick-n-dirty pull request that creates some wrapped functions and uses context magic to enable no-config state that gets us pretty close to what I consider to be the ideal prototyping API from a designer's perspective.

Shopify/polaris-react#1372

I see an approach like this as following the 80/20 rule. Any components that require state, or any components that require lots of config, would follow this approach. That gets you to about 80% of your rapid prototyping needs. Having hooks available gets you the other 20% of the way there.

I see this as the ideal compromise for designer prototyping productivity.

The API this gives us for building a stateful Popover with Polaris then is really simple in Playroom:

<Play.ToggleState>
  <Play.Popover
    sectioned
    activator={<Play.ToggleButton>Toggle</Play.ToggleButton>}
  >
    <p>Some popover content</p>
  </Play.Popover>
</Play.ToggleState>
@markdalgleish

This comment has been minimized.

Copy link
Member Author

commented Apr 28, 2019

That's interesting. Anything component-based is inherently supported by Playroom already. I see the potential here for people to create component-oriented state management libraries designed for prototyping. If you come up with something along these lines, I might see if I can find a way to talk about it in the readme.

@hipstersmoothie

This comment has been minimized.

Copy link

commented Apr 30, 2019

You can already kind of do this in your components file:

import { Checkbox as CheckboxComponent } from './Choice';
export const Checkbox = props => {
  const [checked, set] = React.useState(props.checked);

  return (
    <CheckboxComponent
      {...props}
      checked={checked}
      onChange={() => set(!checked)}
    />
  );
};

Having a way to do this without creating the wrapper though would be interesting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants
You can’t perform that action at this time.