Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/css-layers-overlay-consumers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

AnchoredOverlay, Autocomplete, Banner, Blankslate, Breadcrumbs, Dialog, ActionMenu, ActionBar, SelectPanel2: Add CSS layer support for component styles
178 changes: 90 additions & 88 deletions packages/react/src/ActionBar/ActionBar.module.css
Original file line number Diff line number Diff line change
@@ -1,110 +1,112 @@
.List {
position: relative;
display: flex;
min-width: 0;

/* wonder why this is here */
/* stylelint-disable-next-line primer/spacing */
margin-bottom: -1px;
list-style: none;
align-items: flex-start;
gap: var(--actionbar-gap, var(--stack-gap-condensed));
overflow: hidden;
/* Explicit height is required to clip wrapped items */
height: var(--actionbar-height, var(--control-small-size));

/* Scroll-based animations have no effect unless the container is scrollable (has overflow, even with overflow:hidden)
so we can use them to detect overflow. It would be cleaner to use scroll-state container queries for this, but
browser support for scroll-driven animations is slightly better. */
animation: detect-overflow linear;
animation-timeline: scroll(self block);

/* After initial render, JS is used to control visibility which provides progressive enhancement for unsupported browsers */
&[data-has-overflow='true'] {
--morebutton-display: flex;
}
@layer primer.components.ActionBar {
.List {
position: relative;
display: flex;
min-width: 0;

&:where([data-size='small']) {
--actionbar-height: var(--control-small-size);
}
/* wonder why this is here */
/* stylelint-disable-next-line primer/spacing */
margin-bottom: -1px;
list-style: none;
align-items: flex-start;
gap: var(--actionbar-gap, var(--stack-gap-condensed));
overflow: hidden;
/* Explicit height is required to clip wrapped items */
height: var(--actionbar-height, var(--control-small-size));

/* Scroll-based animations have no effect unless the container is scrollable (has overflow, even with overflow:hidden)
so we can use them to detect overflow. It would be cleaner to use scroll-state container queries for this, but
browser support for scroll-driven animations is slightly better. */
animation: detect-overflow linear;
animation-timeline: scroll(self block);

/* After initial render, JS is used to control visibility which provides progressive enhancement for unsupported browsers */
&[data-has-overflow='true'] {
--morebutton-display: flex;
}

&:where([data-size='medium']) {
--actionbar-height: var(--control-medium-size);
}
&:where([data-size='small']) {
--actionbar-height: var(--control-small-size);
}

&:where([data-size='large']) {
--actionbar-height: var(--control-large-size);
}
&:where([data-size='medium']) {
--actionbar-height: var(--control-medium-size);
}

&:where([data-size='large']) {
--actionbar-height: var(--control-large-size);
}

/* Gap scale (mirrors Stack) */
&:where([data-gap='none']) {
--actionbar-gap: 0;
/* Gap scale (mirrors Stack) */
&:where([data-gap='none']) {
--actionbar-gap: 0;

.Divider {
padding: 0 var(--base-size-8);
.Divider {
padding: 0 var(--base-size-8);
}
}
}

&:where([data-gap='condensed']) {
--actionbar-gap: var(--stack-gap-condensed);
}
&:where([data-gap='condensed']) {
--actionbar-gap: var(--stack-gap-condensed);
}

& [data-overflowing] {
/* Hide overflowing items. Even though they are clipped by `overflow: hidden`, setting `visibility: hidden` ensures
they can't accidentally be shown and also hides them from screen readers / keyboard nav. `!important` prevents
consumers from unintentionally overriding this and breaking accessibility. */
visibility: hidden !important;
& [data-overflowing] {
/* Hide overflowing items. Even though they are clipped by `overflow: hidden`, setting `visibility: hidden` ensures
they can't accidentally be shown and also hides them from screen readers / keyboard nav. `!important` prevents
consumers from unintentionally overriding this and breaking accessibility. */
visibility: hidden !important;
}
}
}

@keyframes detect-overflow {
0%,
100% {
--morebutton-display: flex;
@keyframes detect-overflow {
0%,
100% {
--morebutton-display: flex;
}
}
}

.Nav {
display: flex;
padding-inline: var(--base-size-16);
justify-content: flex-end;
align-items: center;
.Nav {
display: flex;
padding-inline: var(--base-size-16);
justify-content: flex-end;
align-items: center;

&:where([data-flush='true']) {
padding-inline: 0;
&:where([data-flush='true']) {
padding-inline: 0;
}
}
}

.Divider {
&::before {
display: block;
width: var(--borderWidth-thin);
height: var(--base-size-20);
content: '';
/* stylelint-disable-next-line primer/colors */
background: var(--borderColor-muted);
/* stylelint-disable-next-line primer/spacing */
margin-top: calc((var(--actionbar-height) - var(--base-size-20)) / 2);
.Divider {
&::before {
display: block;
width: var(--borderWidth-thin);
height: var(--base-size-20);
content: '';
/* stylelint-disable-next-line primer/colors */
background: var(--borderColor-muted);
/* stylelint-disable-next-line primer/spacing */
margin-top: calc((var(--actionbar-height) - var(--base-size-20)) / 2);
}
}
}

.Group {
display: flex;
gap: inherit;
}
.Group {
display: flex;
gap: inherit;
}

.OverflowContainer {
display: flex;
flex-wrap: wrap;
gap: inherit;
justify-content: flex-end;
overflow: hidden;
.OverflowContainer {
display: flex;
flex-wrap: wrap;
gap: inherit;
justify-content: flex-end;
overflow: hidden;

.OverflowSpacer {
height: var(--actionbar-height);
.OverflowSpacer {
height: var(--actionbar-height);
}
}
}

.MoreButton {
display: var(--morebutton-display, none);
.MoreButton {
display: var(--morebutton-display, none);
}
}
96 changes: 49 additions & 47 deletions packages/react/src/ActionMenu/ActionMenu.module.css
Original file line number Diff line number Diff line change
@@ -1,70 +1,72 @@
.ActionMenuContainer {
/* add default max height */
max-height: 100vh;
@layer primer.components.ActionMenu {
.ActionMenuContainer {
/* add default max height */
max-height: 100vh;

&:where([data-variant='fullscreen']) {
padding-top: var(--base-size-36);
}
&:where([data-variant='fullscreen']) {
padding-top: var(--base-size-36);
}

/* Overflow variants */
&:where([data-overflow-auto]) {
overflow: auto;
}
/* Overflow variants */
&:where([data-overflow-auto]) {
overflow: auto;
}

&:where([data-overflow-hidden]) {
overflow: hidden;
}
&:where([data-overflow-hidden]) {
overflow: hidden;
}

&:where([data-overflow-scroll]) {
overflow: scroll;
}
&:where([data-overflow-scroll]) {
overflow: scroll;
}

&:where([data-overflow-visible]) {
overflow: visible;
}
&:where([data-overflow-visible]) {
overflow: visible;
}

/* Max-height size tokens (mirror Overlay sizes) */
&:where([data-max-height-xsmall]) {
max-height: min(192px, 100vh);
/* Max-height size tokens (mirror Overlay sizes) */
&:where([data-max-height-xsmall]) {
max-height: min(192px, 100vh);

@supports (height: 100dvh) {
max-height: min(192px, 100dvh);
@supports (height: 100dvh) {
max-height: min(192px, 100dvh);
}
}
}

&:where([data-max-height-small]) {
max-height: min(256px, 100vh);
&:where([data-max-height-small]) {
max-height: min(256px, 100vh);

@supports (height: 100dvh) {
max-height: min(256px, 100dvh);
@supports (height: 100dvh) {
max-height: min(256px, 100dvh);
}
}
}

&:where([data-max-height-medium]) {
max-height: min(320px, 100vh);
&:where([data-max-height-medium]) {
max-height: min(320px, 100vh);

@supports (height: 100dvh) {
max-height: min(320px, 100dvh);
@supports (height: 100dvh) {
max-height: min(320px, 100dvh);
}
}
}

&:where([data-max-height-large]) {
max-height: min(432px, 100vh);
&:where([data-max-height-large]) {
max-height: min(432px, 100vh);

@supports (height: 100dvh) {
max-height: min(432px, 100dvh);
@supports (height: 100dvh) {
max-height: min(432px, 100dvh);
}
}
}

&:where([data-max-height-xlarge]) {
max-height: min(600px, 100vh);
&:where([data-max-height-xlarge]) {
max-height: min(600px, 100vh);

@supports (height: 100dvh) {
max-height: min(600px, 100dvh);
@supports (height: 100dvh) {
max-height: min(600px, 100dvh);
}
}
}

&:where([data-max-height-fit-content]) {
max-height: fit-content;
&:where([data-max-height-fit-content]) {
max-height: fit-content;
}
}
}
Loading
Loading