Skip to content

WIP: Button/Link API exploration #1874

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

Closed
wants to merge 18 commits into from
Closed

WIP: Button/Link API exploration #1874

wants to merge 18 commits into from

Conversation

langermank
Copy link
Contributor

@langermank langermank commented Jan 13, 2022

Design and API exploration for buttony and linky components: Button, IconButton, Link, LinkStyledAsButton, ButtonGroup, ReactionButton

Working notes and prop tables can be found in this readme

Figma draft

Progress tracking

  • Gather insights from existing issues and discussions
  • Create base component templates for stress testing/markup + draft CSS
  • Discuss initial draft with Pattern Working Group
  • Edit naming conventions and design based on Pattern Working Group feedback
  • Meet with group again to discuss nitty-gritty things (mainly naming and style)
  • Request detailed markup and CSS review
  • Begin documenting breaking changes between old Button and this new refactor

@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2022

⚠️ No Changeset found

Latest commit: 2b1c7c8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

| -- | -- |
| Button | standard `button` with variants, size, visual slots |
| IconButton | `button` with icon only (square) and required `aria-label` |
| ButtonStyledAsLink | `button` that visually looks like a link |
Copy link

Choose a reason for hiding this comment

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

Agree this seems like a requirement. See primer/react#1733 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

coming from Primer Patterns Working group recording, +1 for not having ButtonStyledAsLink at all and using Invisible Button variant for that.

see also: @ashygee's proposal of the feature I mentioned in the above PR: https://github.com/github/primer/discussions/477#discussioncomment-1915419


| prop | type | options | default | notes |
| -- | -- | -- | -- | -- |
| `variant` | one-of string | `primary` `secondary` `danger` `outline`? | `secondary` | |
Copy link

Choose a reason for hiding this comment

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

invisible is missing here?

Copy link
Contributor

Choose a reason for hiding this comment

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

If I'm interpreting this correctly, invisible would become ButtonStyledAsLink and maintain the hover background? I wonder what that means for IconButton which is often styled as invisible (PVC's IconButton is invisible) IconButtonStyledAsLink is a mouthful 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, @pouretrebelle's interpretation is correct! Thanks for pointing out that use case.. I'll make note of this for the pattern working group to discuss. I think Ash had an idea for a solution to this based on the Button audit.

@pksjce
Copy link

pksjce commented Jan 14, 2022

To gain full context, is this a refactor of existing design or is there scope to make any design changes?

A few I can think that came up during the react implementation

How much of this do you think can get addressed in this iteration?

| `trailingVisual` | children (slot) | octicon | null | |
| `trailingAction` | children (slot) | octicon | null | slot for caret to maintain leading/trailing visuals if they exist |
| `fullWidth` | boolean | `true/false` | `false` | |
| `visualPosition` | one-of string | `fixed` `some-other-word` | `fixed` | lock icon to the text label or to the button container |
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% on what this means, is it about (to use a flex analogy) center vs space-between for full-width buttons that have leading/trailing visuals? I like the solution Sid posted here for spacing visuals and actions with text, do we need more design flexibility than that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, and I'm struggling to name this prop. I plan to ask the pattern working group how much granularity we need for positioning visuals in a button. The way I see it, we either allow each visual to have a prop (align to the button bounds, or align to the text) OR we are prescriptive and just have one prop where all visuals act the same way. The way I handled it looks similar to Sid but I'm not sure we have any left-aligned text in buttons 🤔

Copy link
Contributor

@pouretrebelle pouretrebelle Jan 18, 2022

Choose a reason for hiding this comment

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

I don't know if we already have any left-aligned buttons but here's an example that Sid was ideating on - imo if we don't already need that flexibility we should avoid introducing it and be prescriptive as you say, although I do think having actions locked to the container and visuals locked to the text looks more intuitive.

| `trailingVisual` | children (slot) | octicon | null | |
| `trailingAction` | children (slot) | octicon | null | slot for caret to maintain leading/trailing visuals if they exist |
| `fullWidth` | boolean | `true/false` | `false` | |
| `visualPosition` | one-of string | `fixed` `some-other-word` | `fixed` | lock icon to the text label or to the button container |
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need an option for alignment with text? I'd imagine that you'd sometimes want ButtonStyledAsLink to be inline and other times want it to line up with other buttons 🥴

Copy link
Contributor Author

@langermank langermank Jan 18, 2022

Choose a reason for hiding this comment

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

Ahh see that's where I also get 🥴

I feel like ButtonStyledAsLink means you want to hide the fact that this is actually a button.. so its inline, blue text, not centered text.. but retains height for accessibility?

Which makes me think we still need a subtle Button variant. When you want a Button that's.. subtle 🙃

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess there are two use cases for buttons styled as links:

  1. Secondary CTAs in forms or modals, e.g.
    Modal with dismiss link-style button
  2. Downplaying visual weight, where they should always be accompanied by an icon/action, and are in line with text e.g.
    Assignees gear icon with dropdown action
    Add assignees button with dropdown action

And some ideas for how to accommodate both of those cases:

  1. The first one is some subtle/invisible Button variant and the second is a ButtonStyledAsLink (so BSAL always requires a trailing icon/action)
    It feels a bit weird that you could achieve a similar visual style for button elements using different combinations of components/props, I feel like that's how we got into this mess?
  2. They're both ButtonStyledAsLink but we have a display prop to toggle between block/inline
    Then it's a bit ambiguous when icon/action are required, only when they're not locked up with other buttons?
  3. They're both ButtonStyledAsLink and are inline, but we use a button group component for vertical alignment of locked-up buttons

FWIW I think they can be in line with text but have padding and negative margin so they still have accessible tap targets, but maybe that's a different conversation.

Also curious how <summary> comes in to this discussion, if at all 🥴

Far too many thoughts for one comment, I'm sorry 🙃

| ReactionButton | `button` snowflake with specific styles/interaction design |
| ButtonGroup | wrapper to handle grouping buttons |
| Link | `a` with variants, optional trailing visuals |
| LinkStyledAsButton | `a` with button variants, required trailing visuals |
Copy link
Contributor

Choose a reason for hiding this comment

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

When would we not want this to be a chevron (or potentially link-external)? I think that should be a feature of LinkStyledAsButton rather than a required option.

@langermank
Copy link
Contributor Author

To gain full context, is this a refactor of existing design or is there scope to make any design changes?

There's scope to make design changes, but mostly around consistency in spacing, sizing and alignment. Potentially changing some variants.

How much of this do you think can get addressed in this iteration?

We are covering everything in that list 😸 The outline styles is actually separate, but should be released soon #1744

@mperrotti
Copy link
Contributor

Just a heads up - the latest Storybook deployment throws an error for the Buttons explorations:

ariaLabel is not defined

// button child elements

// align svg
.Button-visual {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

pointer-events: none;

@vdepizzol vdepizzol mentioned this pull request Mar 3, 2022
1 task
Co-authored-by: Vinicius Depizzol <vdepizzol@gmail.com>
@github-actions
Copy link
Contributor

Hi! This pull request has been marked as stale because it has been open with no activity for 60 days. You can comment on the pull request or remove the stale label to keep it open. If you do nothing, this pull request will be closed in 7 days.

@github-actions github-actions bot added the Stale Automatically marked as stale. label May 22, 2022
@langermank langermank removed the Stale Automatically marked as stale. label May 26, 2022
@langermank langermank temporarily deployed to github-pages July 14, 2022 02:09 Inactive
@github-actions github-actions bot temporarily deployed to Storybook Preview July 14, 2022 02:10 Inactive
@langermank langermank temporarily deployed to github-pages July 14, 2022 02:38 Inactive
@github-actions github-actions bot temporarily deployed to Storybook Preview July 14, 2022 02:38 Inactive
@langermank langermank temporarily deployed to github-pages August 19, 2022 22:44 Inactive
@github-actions github-actions bot temporarily deployed to Storybook Preview August 19, 2022 22:45 Inactive
@github-actions github-actions bot temporarily deployed to Storybook Preview August 23, 2022 20:26 Inactive
@langermank
Copy link
Contributor Author

Closing in favor of the PVC implementation ✨

@langermank langermank closed this Oct 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants