-
Notifications
You must be signed in to change notification settings - Fork 470
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
feat(@clayui/link): add ability to style link like a button #3303
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 8514628:
|
Hey @bryceosterhaus, wouldn't adding support for a I wonder why you went with this approach, putting both in ClayButton, adding a dependency to ClayButton that is only necessary when it's used as a link. While discussing this yesterday with @jbalsas I envisioned just adding the I'm interested in your thinking while going about doing it this way @bryceosterhaus. |
This does feel weirdly unsemantic to me as well.
It does hint to this being something else, though... The key is, what is the developer expectation? What's more important, the implementation or the design? Does the user know she needs a link I'm torn here and don't have a clear answer 🤔 |
In my opinion I think the functionality should be what drives the decision when in the process of using the component. For example:
This is keeping in mind that in any circumstance, at least in a modern stack, the user can just style their buttons and links however they want. |
That seems like a bit of a problem. I would expect React to warn about us doing that in development mode (maybe it doesn't though 🤷 ). So, independently of the design question we might want to replace the On the design question, I don't know if it is useful, but my intuition seems to match up with what @kresimir-coko said. I would intuitively expect |
That's exactly what this one does, actually.
I meant that since |
I see I didn't make myself clear. I was saying that I'd expect React to warn in development because of the if (href) {
return <a ...>;
} else {
return <button ...>;
} |
I was also a little uneasy about putting 'btn-block': block,
'btn-monospaced': monospaced,
'btn-outline-borderless': borderless,
'btn-sm': small,
[`btn-${displayType}`]: displayType && !outline && !borderless,
[`btn-outline-${displayType}`]: displayType && (outline || borderless), I'm imaging that once we add the ability to make a link look like a button, we also need to add all the button variants. Maybe duplication of this isn't bad though. Any idea how common this pattern is of making links look like buttons? The design of it seems off, but maybe I just can't think of clear examples. If its not common or if it's an anti-pattern in design, maybe we just recommend adding the appropriate classes. |
That's a good argument... this is a common enough pattern that should be easy to get right and not overcomplicated exposing internal CSS classes... but again, maybe copy-pasting that logic isn't the worse that can happen... 🤔 |
</ClayButton> | ||
|
||
<ClayButton href="#foo" ref={anchorRef}> | ||
{'Looks like a button, but is an achor'} |
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.
should change achor to anchor?
@jbalsas from that picture you linked, only one of those really looks like a button to me, "New Entry". For the rest of those, are we expecting people to use button styles for those? I would think those would just be links around an icon or text. I think both APIs seem odd to me when I look at it though... <ClayButton href="/goes/somewhere">Click me</ClayButton>
<ClayLink button href="/goes/somewhere" displayType="primary">Click me</ClayLink> ClayLink would likely have to duplicate the same props as button as well, not just the class name logic. If I had to choose one, I think I would lean to using href in ClayButton. But that could also be that my brain reads the button/link jsx more as "what is this component displaying" vs "what is this component doing". tldr; |
Well... that's because they're |
@jbalsas whats your preference for where this logic lies? I don't feel strongly enough to really push for one side. If I had to choose, I would go with Button w/ href, but I am open to Link w/ button props if people feel strongly about that. |
I honestly have no idea what's the right call... If you're asking for preference, I'd prefer to put this in
I think this is kinda the right train of thought... links are links and buttons are buttons for reasons and backed by years of research. While we want to allow deviating from that path... we don't necessarily need to make it super easy (just convenient enough). So, adding some friction here in terms of a developer having to translate from "visual" to "implementation" should be okayish... That's my thinking, but I can be persuaded |
@jbalsas makes sense to me. I like the idea of adding some friction to it, which I think having button props on a Link makes sense. We might even limit the props to only a few and require classes for more nuanced versions of button. I'll update this PR today |
just updated |
note, I had to change the tsconfig target to allow for optional chaining syntax. This is probably the target we should have had this entire tiem |
😱 |
LGTM! |
packages/clay-link/src/index.tsx
Outdated
|
||
classes = { | ||
btn: !!button, | ||
'btn-block': button?.block, |
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 a shame you need the ?.
here, because I would have thought that TS would have been able to narrow the type; eg.
- At top, we know
button
isboolean
,{}
orundefined
. - After
if
, we know it istrue
or{}
. - After
button =
reassignment, we know it is{}
It seems that if you assign it to a variable then it can narrow it for sure (eg. playground):
function x(
button?:
| boolean
| {
block?: boolean,
monospaced?: boolean,
small?: boolean,
}
) {
if (button) {
/*
* Type of `narrowed` inferred here is:
*
* {
* block?: boolean | undefined;
* monospaced?: boolean | undefined;
* small?: boolean | undefined;
* }
*/
const narrowed = button === true ? {} : button;
}
}
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.
@wincent yeah I think I initially tried to use the optional chaining and was still getting errors, so then I added the assignment and it was fine. But you are right, the chaining was redundant and not needed, I just removed it in the latest commit.
fixes #3301
Here is a POC of adding ClayLink to Button so that we can render both links as buttons and buttons as links.
Any concerns with this?