-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
UI: Create new form elements in the new Core UI (Input, TextArea, Select) #23469
Conversation
@CodiumAI-Agent /review |
PR Analysis
PR Feedback
How to use
|
import React, { forwardRef } from 'react'; | ||
import { styled } from '@storybook/theming'; | ||
|
||
interface InputProps { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding PropTypes for better type checking and to make the code more self-documenting. [medium]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
euh ... no.
export default meta; | ||
type Story = StoryObj<typeof Input>; | ||
|
||
export const Base: Story = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding more diverse storybook examples to cover different use cases and edge cases. [medium]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting one. I could do that.
New dependencies detected. Learn more about Socket for GitHub ↗︎
|
export const Base: Story = { | ||
args: {}, | ||
render: (_, { args }) => ( | ||
<div style={{ width: 400 }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's put this in a decorator, though I'm not a fan of arbitrary wrappers for widths.
I guess we don't want to use viewports here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's really just to test it inside a container. By default it is width 100%
export const Select = { | ||
Root: SelectPrimitive.Root, | ||
Group: SelectPrimitive.Group, | ||
Value: SelectPrimitive.Value, | ||
Trigger: SelectTrigger, | ||
Content: SelectContent, | ||
Label: SelectLabel, | ||
Item: SelectItem, | ||
Separator: SelectSeparator, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For complex combination-components like these JSdoc
comments with mini examples would be great.
That way when users import these, all they have to do to get a example snippet, is hover over this import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a wrapper on top of Radix with styles added to it. I can improve the docs to specify that I guess to make sure they go to Radix to understand all the use cases. We will not try to recreate their docs.
interface SelectItemProps { | ||
children: React.ReactNode; | ||
value: string; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lie, it's actually much much more.
ComponentProps<typeof StyledItem>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. I can replace it with that type.
return <StyledTextarea ref={ref} {...props} />; | ||
}); | ||
|
||
Textarea.displayName = 'Textarea'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed? Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's a forwardRef with an arrow function inside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is needed to make sure React devtools function correctly. This triggers an error otherwise.
|
||
SelectItem.displayName = 'SelectItem'; | ||
|
||
const StyledItem = styled(RadixSelect.Item)(({ theme }) => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not actually using the theme in this component?
}, | ||
})); | ||
|
||
const StyledItemIndicator = styled(RadixSelect.ItemIndicator)(({ theme }) => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not actually using the theme in this component?
overflow: 'hidden', | ||
backgroundColor: theme.input.background, | ||
borderRadius: '6px', | ||
border: theme.base === 'dark' ? `1px solid ${theme.input.border}` : 'none', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting choice to have no border at all in dark-mode. Can you elaborate?
Would a 1px solid transparent
not be better? Less layout shifts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't have any layout shift since it will close the panel when you click anywhere else but you're right just to be safe we can add 1px solid transparent
import React, { forwardRef } from 'react'; | ||
import { styled } from '@storybook/theming'; | ||
|
||
interface InputProps { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lie, it's actually more!
ComponentProps<typeof StyledInput>
export const Input = forwardRef<HTMLInputElement, InputProps>(({ ...props }, ref) => { | ||
return <StyledInput ref={ref} {...props} />; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ ...props }
does not make any sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
What I did
As part of the work of moving components to Core UI, I'm creating 3 new components:
Input
TextArea
Select
These components are now primitives and not sub components of the
Form
component. For context, we are depreciating theForm
component in favour of better primitives. In term of design, nothing is changing except for the fact that by default all of these component will be 100% in width.How to test
Checklist
MIGRATION.MD
Maintainers
ci:normal
,ci:merged
orci:daily
GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli/src/sandbox-templates.ts
["cleanup", "BREAKING CHANGE", "feature request", "bug", "documentation", "maintenance", "dependencies", "other"]