Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2d8165d
refactor(button): style with pseudo-private custom properties
dancormier Jul 25, 2022
3a21409
Merge branch 'develop' into dcormier/btn-css-refactor
dancormier Jul 25, 2022
ac9a78d
refactor(btn): increase badge opacity
dancormier Jul 27, 2022
6d871c2
Merge branch 'develop' into dcormier/btn-css-refactor
dancormier Sep 27, 2022
50c8608
Merge branch 'develop' into dcormier/btn-css-refactor
dancormier Nov 3, 2022
d58b22b
Merge branch 'develop' into dcormier/btn-css-refactor
dancormier Nov 4, 2022
62d59fc
refactor(button-group): add radio layout (#1135)
dancormier Nov 4, 2022
d00b522
Merge branch 'dcormier/btn-css-refactor' of https://github.com/StackE…
dancormier Nov 4, 2022
8f6e4d5
Conform btn styles to standard
dancormier Nov 4, 2022
1a3be55
Prefix component custom properties
dancormier Nov 4, 2022
3276510
Fix --radio selector
dancormier Nov 8, 2022
76e7f17
match styles to template (mostly)
dancormier Nov 8, 2022
3abf5ef
Ensure unset docs buttons have base class
dancormier Nov 8, 2022
acef3c4
Move contextual styles within variants
dancormier Nov 9, 2022
ae587ec
Remove unneeded todo
dancormier Nov 9, 2022
0183a3e
Improve radio-based button styling
dancormier Nov 9, 2022
44458a1
fix muted filled interactive background colors
dancormier Nov 9, 2022
4e14d2b
Match PPCP format
dancormier Nov 9, 2022
6f35c09
Ensure btn groups have correct hover styling
dancormier Nov 9, 2022
73790a3
Adjust button group styling
dancormier Nov 9, 2022
de2e267
drop trailing whitespace
b-kelly Nov 10, 2022
4bf095c
Remove commented code
dancormier Nov 10, 2022
e946105
Fix radio button group focus
dancormier Nov 10, 2022
857d311
typo fixes
b-kelly Nov 11, 2022
e519ab4
Fix primary variant dark mode interaction bg colors
dancormier Nov 11, 2022
77c425c
Compensate for form wrappers within button group buttons
dancormier Nov 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/_data/button-groups.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"description": "Base button group style."
},
{
"class": ".s-btn-group--container",
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this is a breaking change. How should we handle this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I originally intended this to be a non-breaking change, but a deprecation. In 77c425c, I've targeted the form element and once again made this a deprecation. Basically with the PR as it is now, the changes should be backwards compatible.

image

Note
Image for demo purposes only. Don't worry. I didn't change the docs to this permanently.

Should we reintroduce .s-btn-group--container? I know targeting a HTML tag feels a little icky but it doesn't feel totally wrong here. That said, I'm fine with targeting that class and punting on any of this and FWIW it's pretty low stakes since I only found it used in one place in Core.


PS: .s-btn-group--container previously just set any nested button border radius to 0. That means if the button was at the start or end of the button group, it would get squared off. I've addressed this in 77c425c.

"applies": "form",
"description": "When required to wrap one of our buttons within a button group in a form, apply this class to the form to maintain the intended visuals."
"class": ".s-btn-group--radio",
"applies": ".s-btn-group",
"description": "Applies styling to button groups built using radio and label elements."
}
]
}
4 changes: 2 additions & 2 deletions docs/_includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@

<ol class="s-topbar--content ml0 sm:fl1 overflow-hidden">
<li class="d-none sm:d-inline-flex ml-auto">
<button class="s-topbar--item s-btn__unset c-pointer p8 ml-auto js-search-btn">
<button class="s-topbar--item s-btn s-btn__unset c-pointer p8 ml-auto js-search-btn">
{% icon "Search", "js-search-icon" %}
{% icon "Clear", "d-none js-search-close-icon" %}
</button>
</li>
<li>
<button type="button" class="s-topbar--item s-btn__unset c-pointer stacks-theme-button"
<button type="button" class="s-topbar--item s-btn s-btn__unset c-pointer stacks-theme-button"
aria-controls="theming-popover"
data-controller="s-popover"
data-action="s-popover#toggle"
Expand Down
2 changes: 1 addition & 1 deletion docs/_includes/layouts/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
{% icon "Search", "s-input-icon s-input-icon__search" %}
</div>

<button class="s-btn__unset c-pointer flex--item stacks-theme-button stacks-theme-button__home"
<button class="s-btn s-btn__unset c-pointer flex--item stacks-theme-button stacks-theme-button__home"
aria-controls="theming-popover"
data-controller="s-popover"
data-action="s-popover#toggle"
Expand Down
67 changes: 55 additions & 12 deletions docs/product/components/button-groups.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,25 @@
<div class="s-btn-group">
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Newest</button>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Frequent</button>
<form class="s-btn-group--container">
<form>
<button class="s-btn s-btn__muted s-btn__outlined is-selected" role="button" aria-current="true">Votes</button>
</form>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Active</button>
<form class="s-btn-group--container">
<form>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Unanswered</button>
</form>
</div>
{% endhighlight %}
<div class="stacks-preview--example">
<div class="s-btn-group js-btn-group">
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item" role="button">Newest</button>
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item" role="button">Frequent</button>
<form class="s-btn-group--container">
<button class="s-btn s-btn__muted s-btn__outlined is-selected js-btn-group-item" role="button" aria-current="true">Votes</button>
<div class="s-btn-group">
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Newest</button>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Frequent</button>
<form>
<button class="s-btn s-btn__muted s-btn__outlined is-selected" role="button" aria-current="true">Votes</button>
</form>
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item" role="button">Active</button>
<form class="s-btn-group--container">
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item" role="button">Unanswered</button>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Active</button>
<form>
<button class="s-btn s-btn__muted s-btn__outlined" role="button">Unanswered</button>
</form>
</div>
</div>
Expand Down Expand Up @@ -123,13 +123,13 @@
<span class="s-btn--number">197</span>
</span>
</button>
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item" role="button">
<button class="s-btn s-btn__muted s-btn__outlined js-btn-group-item s-btn__dropdown" role="button">
Inactive
<span class="s-btn--badge">
<span class="s-btn--number">37</span>
</span>
</button>
<button class="s-btn s-btn__muted s-btn__outlined is-selected js-btn-group-item" role="button">
<button class="s-btn s-btn__muted s-btn__outlined is-selected js-btn-group-item" role="button" aria-current="true">
All
<span class="s-btn--badge">
<span class="s-btn--number">234</span>
Expand All @@ -140,6 +140,49 @@
</div>
</section>

<section class="stacks-section">
{% header "h2", "Radio" %}
<p class="stacks-copy">
Button groups can be implemented using radio elements with the modifier class <code class="stacks-code">.s-btn-group--radio</code>. This modifier class assumes all buttons are styled <code class="stacks-code">label</code> elements.
</p>
<div class="stacks-preview">
{% highlight html %}
<div class="s-btn-group">
<div class="s-btn-group s-btn-group--radio">
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-1" />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-1">
Active
</label>
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-2" />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-2">
Inactive
</label>
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-3" checked />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-3">
All
</label>
</div>
</div>
{% endhighlight %}
<div class="stacks-preview--example">
<div class="s-btn-group s-btn-group--radio">
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-1" />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-1">
Active
</label>
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-2" />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-2">
Inactive
</label>
<input class="s-btn--radio" type="radio" name="example-btn-group" id="example-btn-group-3" checked />
<label class="s-btn s-btn__muted s-btn__outlined" for="example-btn-group-3">
All
</label>
</div>
</div>
</div>
</section>

<script>
document.querySelectorAll('.js-btn-group-item').forEach(buttonGroup => {
buttonGroup.addEventListener('click', e => {
Expand Down
12 changes: 6 additions & 6 deletions docs/product/components/buttons.html
Original file line number Diff line number Diff line change
Expand Up @@ -369,18 +369,18 @@
</div>
</td>
<td class="va-middle ta-center px4">
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %} {{ btn.class }}" type="button">
Active <span class="s-btn--badge"><span class="s-btn--number">198</span></span>
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %}" type="button">
Active <span class="{{ btn.class }}"><span class="s-btn--number">198</span></span>
</button>
</td>
<td class="va-middle ta-center px4">
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %} {{ btn.class }} is-selected" type="button" aria-pressed="true">
Active <span class="s-btn--badge"><span class="s-btn--number">198</span></span>
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %} is-selected" type="button" aria-pressed="true">
Active <span class="{{ btn.class }}"><span class="s-btn--number">198</span></span>
</button>
</td>
<td class="va-middle ta-center px4">
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %} {{ btn.class }}" type="button" disabled>
Active <span class="s-btn--badge"><span class="s-btn--number">198</span></span>
<button class="ws-nowrap s-btn {{ class.class }} {% if class.class2 %}{{ class.class2 }}{% endif %}" type="button" disabled>
Active <span class="{{ btn.class }}"><span class="s-btn--number">198</span></span>
</button>
</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion lib/css/atomic/colors.less
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// visit https://stackoverflow.design/
//
// ============================================================================
// UTLITY OVERRIDES
// UTILITY OVERRIDES
// Instead of re-adding colors to unique class names, use these atomic classes
// for text and background colors
// ============================================================================
Expand Down
128 changes: 59 additions & 69 deletions lib/css/components/button-groups.less
Original file line number Diff line number Diff line change
@@ -1,90 +1,80 @@
.s-btn-group {
display: flex;
flex-wrap: wrap;
margin-bottom: 1px; // Compensate for buttons having a margin bottom of -1px to account for row wrapping

.s-btn {
margin-bottom: -1px; // When wrapping we need to account for the border
white-space: nowrap; // When the buttons wrap, they get super tall and mess up the whole layout
// CONTEXTUAL STYLES
#stacks-internals #screen-sm({
.s-btn {
&.s-btn__dropdown {
padding-right: 1.2em;

// If it isn't the last button, we should slide the button over to account for border thickness
&:not(:last-child) {
margin-right: -1px;
}
&:after {
right: 0.4em;
}
}

// We don't want border-radii on interior buttons
&:not(:first-child):not(:last-child) {
border-radius: 0;
padding-left: 0.4em;
padding-right: 0.4em;
}
}, @force-selector: true);

// Kill the right border radius on the first button
&:first-child:not(:only-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
// VARIANTS
&:not(&--radio) .s-btn:not(:first-child):not(:last-child),
&&--radio .s-btn:not(:first-of-type):not(:last-of-type) {
border-radius: 0;
}

// Kill the left border radius on the last button
&:last-child:not(:only-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&:not(&--radio) .s-btn:first-child:not(:only-child),
&&--radio .s-btn:first-of-type:not(:last-of-type) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

// When the button is active or selected, it should pop above its siblings
&.is-selected {
z-index: var(--zi-selected);
}
&:not(&--radio) .s-btn:last-child:not(:only-child),
&&--radio .s-btn:last-of-type:not(:first-of-type) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

.highcontrast-mode({
&.is-selected {
background-color: var(--black-400);
color: var(--white);
&:not(&--radio) .s-btn:not(:last-child),
&&--radio .s-btn:not(:last-of-type) {
margin-right: calc(var(--su-static1) * -1);
}

.s-btn--number {
color: var(--black);
}
// CHILD ELEMENTS
form {
&:not(:first-child):not(:last-child) {
.s-btn {
border-radius: 0;
}
});

&:active {
z-index: var(--zi-active);
}

#stacks-internals #screen-sm({
padding-left: 0.4em;
padding-right: 0.4em;
}, @force-selector: true);
}

#stacks-internals #screen-sm({
.s-btn.s-btn__dropdown {
padding-right: 1.2em;

&:after {
right: 0.4em;
&:last-child:not(:only-child) {
.s-btn:not(:last-child) {
border-radius: 0;
}
}
&:first-child:not(:only-child) {
.s-btn:not(:first-child) {
border-radius: 0;
}
}
}, @force-selector: true);

.s-btn-group--container {
display: flex;
margin-right: calc(var(--su-static1) * -1); // -1px
}

.s-btn {
margin-right: -1px; // We should slide buttons over to account for border thickness
.s-btn {
&:active {
z-index: var(--zi-active);
}

&:not(:first-child):not(:last-child) .s-btn {
border-radius: 0;
&.is-selected,
&--radio:checked + .s-btn {
z-index: var(--zi-selected); // When the button is active or selected, it should pop above its siblings
}

&:first-child .s-btn {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
margin-left: 0;
}

&:last-child .s-btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
margin-bottom: calc(var(--su-static1) * -1); // When wrapping we need to account for the border
white-space: nowrap; // When the buttons wrap, they get super tall and mess up the whole layout
}

// STATIC COMPONENT STYLES
display: flex;
flex-wrap: wrap;
margin-bottom: var(--su-static1); // Compensate for buttons having a margin bottom of -1px to account for row wrapping
}
Loading