1
1
mirror of https://github.com/primer/css.git synced 2024-11-26 02:38:32 +03:00

ActionList followup (#1780)

* collapse state updates

* inset variant

* pseudo, you fine as you are

* tree view pattern draft

* tree view structure

* move treeview to new pr

* Stylelint auto-fixes

* Create fresh-schools-pull.md

Co-authored-by: Actions Auto Build <actions@github.com>
This commit is contained in:
Katie Langerman 2021-12-03 08:50:31 -08:00 committed by GitHub
parent ee27583f59
commit 8e9ba62d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 233 additions and 26 deletions

View File

@ -0,0 +1,5 @@
---
"@primer/css": patch
---
ActionList followup

View File

@ -72,6 +72,18 @@ export default {
table: {
category: 'HTML'
}
},
listPadding: {
options: [0, 1], // iterator
mapping: ['', 'ActionList--full'], // values
control: {
type: 'inline-radio',
labels: ['inset', 'full-bleed']
},
description: 'ActionList includes 8px padding by default, full-bleed removes all padding',
table: {
category: 'CSS'
}
}
}
}
@ -83,10 +95,16 @@ export const ListTemplate = ({
ariaLabel,
ariaLabelledBy,
subGroup,
listboxMultiSelect
listboxMultiSelect,
listPadding
}) => (
<ul
className={clsx('ActionList', showDividers && 'ActionList--divided', subGroup && 'ActionList--subGroup')}
className={clsx(
'ActionList',
showDividers && 'ActionList--divided',
subGroup && 'ActionList--subGroup',
listPadding && `${listPadding}`
)}
role={role}
aria-label={ariaLabel && ariaLabel}
aria-labelledby={ariaLabelledBy && ariaLabelledBy}
@ -102,6 +120,7 @@ Playground.args = {
subGroup: false,
showDividers: false,
listboxMultiSelect: false,
listPadding: '',
ariaLabelledBy: '',
groupId: '',
children: (

View File

@ -51,6 +51,13 @@ export default {
category: 'CSS'
}
},
containsActiveSubItem: {
defaultValue: false,
control: {type: 'boolean'},
table: {
category: 'CSS'
}
},
leadingVisual: {
defaultValue: '',
name: 'leadingVisual',
@ -146,6 +153,13 @@ export default {
category: 'Interactive'
}
},
collapsibleLeading: {
defaultValue: false,
control: {type: 'boolean'},
table: {
category: 'Interactive'
}
},
singleSelect: {
defaultValue: false,
control: {type: 'boolean'},
@ -207,7 +221,9 @@ export const ListItemTemplate = ({
listSingleSelect,
listMultiSelect,
listSemantic,
ariaDisabled
ariaDisabled,
containsActiveSubItem,
collapsibleLeading
}) => {
const [isCollapsed, itemIsCollapsed] = useToggle()
const [isChecked, itemIsChecked] = useToggle()
@ -218,9 +234,10 @@ export const ListItemTemplate = ({
ariaCurrent && 'ActionList-item--navActive',
subItem && `ActionList-item--subItem`,
containsSubItem && `ActionList-item--hasSubItem`,
containsActiveSubItem && `ActionList-item--hasActiveSubItem`,
variant && `${variant}`
)}
onClick={collapsible ? itemIsCollapsed : itemIsChecked}
onClick={collapsible || collapsibleLeading ? itemIsCollapsed : itemIsChecked}
role={
singleSelect
? 'menuitemradio'
@ -235,8 +252,8 @@ export const ListItemTemplate = ({
: undefined
}
id={id}
aria-haspopup={collapsible ? 'true' : undefined}
aria-expanded={collapsible ? (isCollapsed ? 'false' : 'true') : undefined}
aria-haspopup={collapsible || collapsibleLeading ? 'true' : undefined}
aria-expanded={collapsible || collapsibleLeading ? (isCollapsed ? 'false' : 'true') : undefined}
aria-checked={singleSelect || multiSelect ? (isChecked ? 'true' : 'false') : undefined}
aria-selected={listSingleSelect || listMultiSelect ? (isChecked ? 'true' : 'false') : undefined}
aria-disabled={ariaDisabled ? 'true' : undefined}
@ -254,7 +271,12 @@ export const ListItemTemplate = ({
leadingVisual && leadingVisualSize && `${leadingVisualSize}`
)}
>
{(leadingAction || singleSelect || multiSelect || listSingleSelect || listMultiSelect) && (
{(leadingAction ||
singleSelect ||
multiSelect ||
listSingleSelect ||
listMultiSelect ||
collapsibleLeading) && (
<span className="ActionList-item-action ActionList-item-action--leading">
{singleSelect ||
(listSingleSelect && (
@ -290,6 +312,20 @@ export const ListItemTemplate = ({
/>
</svg>
))}
{collapsibleLeading && (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
width="16"
height="16"
className="ActionList-item-collapseIcon"
>
<path
fill-rule="evenodd"
d="M12.78 6.22a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06 0L3.22 7.28a.75.75 0 011.06-1.06L8 9.94l3.72-3.72a.75.75 0 011.06 0z"
></path>
</svg>
)}
{leadingAction}
</span>
)}
@ -346,7 +382,12 @@ export const ListItemTemplate = ({
leadingVisual && leadingVisualSize && `${leadingVisualSize}`
)}
>
{(leadingAction || singleSelect || multiSelect || listSingleSelect || listMultiSelect) && (
{(leadingAction ||
singleSelect ||
multiSelect ||
listSingleSelect ||
listMultiSelect ||
collapsibleLeading) && (
<span className="ActionList-item-action ActionList-item-action--leading">
{(singleSelect || listSingleSelect) && (
<svg
@ -380,6 +421,20 @@ export const ListItemTemplate = ({
/>
</svg>
)}
{collapsibleLeading && (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
width="16"
height="16"
className="ActionList-item-collapseIcon"
>
<path
fill-rule="evenodd"
d="M12.78 6.22a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06 0L3.22 7.28a.75.75 0 011.06-1.06L8 9.94l3.72-3.72a.75.75 0 011.06 0z"
></path>
</svg>
)}
{leadingAction}
</span>
)}

View File

@ -32,6 +32,7 @@ NavWithSubItems.args = {
listSemantic
collapsible
containsSubItem
containsActiveSubItem
text="Nav Item"
children={
<ListTemplate
@ -58,6 +59,51 @@ NavWithSubItems.decorators = [
)
]
export const NavWithNoActiveSubItems = ListTemplate.bind({})
NavWithNoActiveSubItems.storyName = '[Nav] Links + nested collapsible group w/ no active children'
NavWithNoActiveSubItems.args = {
...ListTemplate.args,
...ListItemTemplate.args,
role: undefined,
ariaLabel: 'Main menu description',
showDividers: false,
children: (
<>
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate
listSemantic
collapsible
containsSubItem
text="Nav Item"
children={
<ListTemplate
subGroup
ariaLabel="Sub nav description"
children={
<>
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic />
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic />
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic />
</>
}
/>
}
/>
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
</>
)
}
NavWithNoActiveSubItems.decorators = [
Story => (
<nav>
<Story />
</nav>
)
]
export const NavWithSubItemsLeadingVisual16px = ListTemplate.bind({})
NavWithSubItemsLeadingVisual16px.storyName = '[Nav] Links + nested collapsible group leadingVisual 16px'
NavWithSubItemsLeadingVisual16px.args = {
@ -92,6 +138,7 @@ NavWithSubItemsLeadingVisual16px.args = {
<ListItemTemplate
listSemantic
containsSubItem
containsActiveSubItem
collapsible
text="Nav Item"
href="/"
@ -177,6 +224,7 @@ NavWithSubItemsLeadingVisual20px.args = {
<ListItemTemplate
listSemantic
containsSubItem
containsActiveSubItem
text="Nav Item"
href="/"
leadingVisualSize="ActionList-content--visual20"
@ -261,6 +309,7 @@ NavWithSubItemsLeadingVisual24px.args = {
<ListItemTemplate
listSemantic
containsSubItem
containsActiveSubItem
text="Nav Item"
href="/"
leadingVisualSize="ActionList-content--visual24"
@ -389,6 +438,7 @@ MenuWithSectionDivider.args = {
<DividerTemplate title="Section DividerTemplate (subtle)" id="some-unique-id" />
<ListItemTemplate
containsSubItem
containsActiveSubItem
children={
<ListTemplate
ariaLabelledBy="some-unique-id"
@ -616,6 +666,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
<ListItemTemplate
listSemantic
containsSubItem
containsActiveSubItem
text="Moderation options"
// href="/"
collapsible
@ -626,6 +677,7 @@ NavWithSubItemsLeadingVisual16pxSubSections.args = {
children={
<ListTemplate
containsSubItem
containsActiveSubItem
subGroup
ariaLabel="Sub nav descrioption"
children={
@ -725,3 +777,42 @@ NavWithSubItemsLeadingVisual16pxSubSections.decorators = [
</nav>
)
]
export const ActionListFullBleed = ListTemplate.bind({})
ActionListFullBleed.storyName = '[List] Full bleed Action List inside box'
ActionListFullBleed.args = {
...ListTemplate.args,
...ListItemTemplate.args,
role: undefined,
ariaLabel: 'Main menu description',
showDividers: false,
listPadding: 'ActionList--full',
children: (
<>
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate
listSemantic
collapsible
containsSubItem
text="Nav Item"
children={
<ListTemplate
subGroup
ariaLabel="Sub nav description"
children={
<>
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic ariaCurrent="page" />
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic />
<ListItemTemplate subItem text="Sub Nav Item" href="/" listSemantic />
</>
}
/>
}
/>
<ListItemTemplate text="Nav Item" href="/" listSemantic />
<ListItemTemplate text="Nav Item" href="/" listSemantic />
</>
)
}

View File

@ -5,6 +5,17 @@
box-shadow: 0 0 0 2px var(--color-accent-fg); // this color breaks convention
}
@mixin activeIndicatorLine {
position: absolute;
top: calc(50% - 12px);
left: -$actionList-item-padding-horizontal;
width: $spacer-1;
height: $spacer-4;
content: '';
background: var(--color-accent-fg);
border-radius: $border-radius;
}
// <li>
.ActionList-item {
position: relative;
@ -77,25 +88,26 @@
// active state [aria-current]
&.ActionList-item--navActive:not(.ActionList-item--danger) {
background: var(--color-action-list-item-default-selected-bg);
// stylelint-disable-next-line selector-max-specificity
&::before,
+ .ActionList-item::before {
visibility: hidden;
&.ActionList-item--navActive {
&:not(.ActionList-item--subItem) {
.ActionList-item-label {
font-weight: $font-weight-bold;
}
}
// blue accent line
&::after {
position: absolute;
top: calc(50% - 12px);
left: -$actionList-item-padding-horizontal;
width: $spacer-1;
height: $spacer-4;
content: '';
background: var(--color-accent-fg);
border-radius: $border-radius;
&:not(.ActionList-item--danger) {
background: var(--color-action-list-item-default-selected-bg);
// stylelint-disable-next-line selector-max-specificity
&::before,
+ .ActionList-item::before {
visibility: hidden;
}
// blue accent line
&::after {
@include activeIndicatorLine;
}
}
}
@ -111,7 +123,7 @@
display: block;
}
&.ActionList-item--hasSubItem {
&.ActionList-item--hasActiveSubItem {
// stylelint-disable-next-line selector-max-specificity
> .ActionList-content > .ActionList-item-label {
font-weight: $font-weight-bold;
@ -128,6 +140,26 @@
.ActionList--subGroup {
display: none;
}
// show active indicator on parent collapse if child is active
&.ActionList-item--hasActiveSubItem {
background: var(--color-action-list-item-default-selected-bg);
.ActionList-item-label {
font-weight: $font-weight-bold;
}
// stylelint-disable-next-line selector-max-specificity
&::before,
+ .ActionList-item::before {
visibility: hidden;
}
// blue accent line
&::after {
@include activeIndicatorLine;
}
}
}
// checkbox item [aria-checked]

View File

@ -3,6 +3,11 @@
padding: $spacer-2;
}
// full bleed
.ActionList--full {
padding: 0;
}
// dividers
.ActionList--divided {