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

Rework Group and Inputs #2

Merged
merged 44 commits into from Oct 25, 2019
Merged

Rework Group and Inputs #2

merged 44 commits into from Oct 25, 2019

Conversation

xdrdak
Copy link
Contributor

@xdrdak xdrdak commented Sep 13, 2019

Description

The ever famous Group is about to get kicked to the curb!

Group does some weird recursion thing and strange z-index shenannigans which can lead to some really funky behaviour. So, we're gonna be phasing it out in favour of the new grouping components.

On a different note, I've also tweaked the Input components to export their base components and attempted to simplify the API a bit. The old status object prop still works, but will be removed in the next major version.

InputGroup

Introducing the InputGroup component. Use this component to smoosh input components together (like input, select and buttons).

It works by simply cloning its children and forwards the right border props. This has a few interesting quirks, namely you must keep the structure of the components flat. This also means that, as long as the components have the border props, they can get properly smooshed.

// old
<Group noSpacing>
  <Input />
  <Button>Submit</Button>
</Group>

// new
<InputGroup>
  <Input />
  <Button>Submit</Button>
</InputGroup>

⚠️ Please note that it is not possible to smoosh column groups no longer. Only rows is supported at the moment.

Also important to note, InputGroup does not manipulate anything other than border and border-radii. meaning that it will not automatically attempt to set components to have full width or whatever. This also means that trying to nest things in another component (including fragments) will result in the border properties not being applied properly. This is actually intended to reduce zany side-effects.

⚠️ Please note: By going with this approach, any Groups with a Popover component will NOT have the proper styling applied, due to border props not getting forwarded. Instead, you may want to use the Dropdown component instead, which accomplishes the same thing, but has the appropriate border props applied.

You can resize components by either using flex or width props of those input components.

InputGroupAddon

This component functions similarly to the old GroupAddon component. It's essentially a pre-styled Flex.

// old
<Group noSpacing>
  <GroupAddon>addon</GroupAddon>
  <Input />
  <Button>Submit</Button>
</Group>

// new
<InputGroup>
  <InputGroupAddon>addon</InputGroupAddon>
  <Input />
  <Button>Submit</Button>
</InputGroup>

Input, Radio and Checkbox now export their Base Components

Each of these components export a more primitive version of themselves. This is particularly useful if you need to further customize the component, but don't really want the additional cruft that comes with these components.

Asides from some minor additional props (input prefix and suffix is still present), there's not much magic going on, meaning you are free to re-assemble your form inputs should the need presents itself. And to help you do that, we have a few more helper components inbound.

Input no longer uses objects to represent status and status message

You should no longer pass an object with magical keys to output the status and status message of a text input.

// old
<Input status={{ type: 'danger', message: 'some message'}} />

// new
<Input status="danger" statusMessage="some message"

As a fun little upgrade, statusMessage takes a ReactNode, so feel free to customize your error message!

Label and FormHelper

Label is a new component that takes care of the needed styling and positioning of the input's description field. Use it as you would any other regular label!

<Label htmlFor="myinput" description="Some description">My Label</Label>
<Input id="myinput" placeholder="My input placeholder" />

<RadioLabel htmlFor="myinput" description="Some description">
  <Radio id="myinput" placeholder="My input placeholder" />
  My Label
</RadioLabel>

FormHelper is used to display helper text or status messages. Use it in conjunction when you need to display error messages. You'll need to manually set the status of the component, since it's just a dumb pre-styled text component.

<Label htmlFor="myinput" description="Some description">My Label</Label>
// Input still has a status prop
<Input id="myinput" placeholder="My input placeholder" status="error" />
<FormHelper status="error">
  This is an error message
</FormHelper>

RadioLabel and CheckboxLabel

Radio and Checkbox are somewhat odd ducks, in that the positioning of their description is not aligned to the actual input, but rather the label. Meaning the description is shifted slightly right to align with the label.

I've provided a RadioLabel and CheckboxLabel to get around this particular quirk. Both have the same API and styling. It's simply the name has been adjusted to match their relevant context.

// The only added prop is description. Asides from that, it behaves exactly how a regular html label would
<RadioLabel description="My properly aligned description">
  <BaseRadio />
  My Label
<RadioLabel>

How to test?

  • Checkout branch, run yarn dev
  • Open Storybook
  • Or check the deploy preview on Netlify (link available in comments)

Checklist

@netlify
Copy link

netlify bot commented Sep 13, 2019

Deploy preview for lightspeed-flame ready!

Built with commit f8f5159

https://deploy-preview-2--lightspeed-flame.netlify.com

@netlify
Copy link

netlify bot commented Sep 13, 2019

Deploy preview for lightspeed-flame ready!

Built with commit 585f4a5

https://deploy-preview-2--lightspeed-flame.netlify.com

@glambert glambert added breaking change A major version bump will be needed pkg: flame labels Sep 13, 2019
@xdrdak xdrdak marked this pull request as ready for review October 1, 2019 18:41
@xdrdak xdrdak requested a review from a team as a code owner October 1, 2019 18:41
@xdrdak xdrdak added enhancement New feature or request and removed breaking change A major version bump will be needed labels Oct 11, 2019
Copy link
Collaborator

@glambert glambert left a comment

Choose a reason for hiding this comment

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

Grouping Select does not remove border-radius on top and bottom left:

image

For InputGroup the input container still has the border-radius set on it, so it shows with the box-shadow:

image

@alexislightspeed
Copy link
Contributor

alexislightspeed commented Oct 17, 2019

LegacyGroup does this nice thing where the last element you've clicked shows focus on all 4 borders. This Group doesn't seem to have the same behaviour.
Screen Shot 2019-10-17 at 3 29 19 PM
Screen Shot 2019-10-17 at 3 35 00 PM

@alexislightspeed
Copy link
Contributor

FormField is missing a README

@alexislightspeed
Copy link
Contributor

alexislightspeed commented Oct 17, 2019

InputGroupAddon has the same color as bodyBg. This makes it harder to tell the layers of UI apart. Maybe consider changing that to gray-100 instead of gray-50 ?

@glambert could we have a bg and color prop on InputGroupAddon to allow the manipulation of those colors?

@glambert
Copy link
Collaborator

glambert commented Oct 18, 2019

InputGroupAddon has the same color as bodyBg. This makes it harder to tell the layers of UI apart. Maybe consider changing that to gray-100 instead of gray-50 ?

@glambert could we have a bg and color prop on InputGroupAddon to allow the manipulation of those colors?

Related to bodyBg, those inputs will always be in a Card tho, correct?

Yes, it would be for edge-cases but we can enable it. We should write a note in the README on that as well 👍

@glambert
Copy link
Collaborator

LegacyGroup does this nice thing where the last element you've clicked shows focus on all 4 borders. This Group doesn't seem to have the same behaviour.
Screen Shot 2019-10-17 at 3 29 19 PM
Screen Shot 2019-10-17 at 3 35 00 PM

@alexislightspeed so if we start putting back those z-index "hacks" this always come back to haunt us when people are using those groups and put things inside, such as a DatePicker for example. You'll see that when an input is the first item on the left, the 4 borders will be highlighted correctly on focus. Do we have use-cases where an input is not the first element in a group?

@alexislightspeed
Copy link
Contributor

Yes, there are loads of usecases
image
(for one)
Is it so bad to swap z-indices within InputGroups ?

@glambert
Copy link
Collaborator

glambert commented Oct 24, 2019

Yes, there are loads of usecases
image
(for one)
Is it so bad to swap z-indices within InputGroups ?

It creates lots of issues when you start putting Dropdown-type content because InputGroup needs to be relatively positioned to fiddle around z-indices.

The gains of that tiny visual change is minimal compared of the downstream issues we can get by messing with z-index, I'd keep it as is for now and if anything, this can be done on consumer-side which we can provide examples for.

Copy link
Contributor

@kvicrey-ls kvicrey-ls left a comment

Choose a reason for hiding this comment

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

A few minor comments, otherwise very impressed by the quality of the PR.
I did my best to review carefully the component changes, a bit less on the stories.

I'm going to try the changes on local, but at least for now you can answer my questions.

Great job!! 👍

@@ -12,8 +12,8 @@ type RenderTest = {
indeterminate?: boolean;
id?: string;
value?: string;
label?: string | Function;
description?: string | Function;
label?: any;
Copy link
Contributor

Choose a reason for hiding this comment

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

string | Function | React.Element?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a test file so I don't think its worth 😉

borderBottomRightRadius?: string | number;
}

const borderRadii = system({
Copy link
Contributor

Choose a reason for hiding this comment

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

Surprised this is not already part of styled-system?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is, but it's part of the border API which also has a lot more we don't want to enable. Probably why this was created, to limit props you can change to only those needed. To be re-confirmed by @xdrdak.

import { Input } from '@lightspeed/flame/Input';

const MyComponent = () => (
<Label htmlFor="myinput" description="Some description">My Label</Label>
Copy link
Contributor

Choose a reason for hiding this comment

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

It misses <> </> to wrap this series of components.

| Prop | Type | Default | Description |
| --------------- | ---------------------------- | --------- | -------------------------------------------------------------- |
| `description` | `string` or `child function` | undefined | Description's text |
| `html property` | `string` | undefined | Any extra properties passed will be added to the `<label>` tag |
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I understand html property

Copy link
Collaborator

Choose a reason for hiding this comment

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

Any valid HTML properties such as id, for, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, I would add an example then, because it's not very clear.

`;

const InputGroup: React.FC = ({ children, ...restProps }) => {
const nextChildren = React.Children.map(children, (child: any, index) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

any => React.Element?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Usually there is a good reason @xdrdak uses any for those. I'd keep it as is and fix in a later PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe sometimes it's only a text, in such case I'm not sure it's a React.Element. But we should remove any any in the future.

Co-Authored-By: Kevin Vicrey <45831907+kvicrey-ls@users.noreply.github.com>
Copy link
Contributor

@kvicrey-ls kvicrey-ls left a comment

Choose a reason for hiding this comment

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

Let's merge the MPR! 💯 💯

@glambert glambert merged commit 8655589 into master Oct 25, 2019
@glambert glambert deleted the rework-group-and-inputs branch October 25, 2019 19:50
@glambert glambert mentioned this pull request Oct 25, 2019
@glambert glambert mentioned this pull request Nov 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants