From 7f21a1611537a146062eced675207c9ab140b70c Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Wed, 14 Feb 2024 15:43:46 -0500 Subject: [PATCH 01/73] Add fixes for ActionList --- packages/react/src/ActionList/Item.tsx | 36 +- packages/react/src/NavList/NavList.tsx | 61 ++- .../__snapshots__/NavList.test.tsx.snap | 510 +++++++++--------- .../_AutocompleteSuggestions.tsx | 2 +- 4 files changed, 329 insertions(+), 280 deletions(-) diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index 2dd3f0d7ed0..6ee51cdeee1 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -133,6 +133,12 @@ export const Item = React.forwardRef( }, } + const listItemStyles = { + display: 'flex', + // show between 2 items + ':not(:first-of-type)': {'--divider-color': theme?.colors.actionListItem.inlineDivider}, + } + const styles = { position: 'relative', display: 'flex', @@ -246,8 +252,22 @@ export const Item = React.forwardRef( const inlineDescriptionId = `${itemId}--inline-description` const blockDescriptionId = `${itemId}--block-description` const inactiveWarningId = inactive && !showInactiveIndicator ? `${itemId}--warning-message` : undefined + const validAriaRole = listRole === 'listbox' || listRole === 'menu' + + const ButtonItemWrapper = React.forwardRef(({as: Component = 'button', children, ...props}, forwardedRef) => { + return ( + (styles, sxProp)} + ref={forwardedRef} + {...props} + > + {children} + + ) + }) as PolymorphicForwardRefComponent - const ItemWrapper = _PrivateItemWrapper || React.Fragment + const ItemWrapper = _PrivateItemWrapper || (validAriaRole ? React.Fragment : ButtonItemWrapper) // only apply aria-selected and aria-checked to selectable items const selectableRoles = ['menuitemradio', 'menuitemcheckbox', 'option'] @@ -268,9 +288,13 @@ export const Item = React.forwardRef( id: itemId, } - const containerProps = _PrivateItemWrapper ? {role: itemRole ? 'none' : undefined} : menuItemProps + const containerProps = _PrivateItemWrapper + ? {role: itemRole ? 'none' : undefined, ...props} + : (validAriaRole && {...menuItemProps, ...props}) || {} - const wrapperProps = _PrivateItemWrapper ? menuItemProps : {} + const wrapperProps = _PrivateItemWrapper + ? menuItemProps + : !validAriaRole && {...menuItemProps, styles: merge(styles, sxProp), ...props} return ( ( > (styles, sxProp)} + sx={merge( + validAriaRole || _PrivateItemWrapper ? styles : listItemStyles, + validAriaRole || _PrivateItemWrapper ? sxProp : {}, + )} data-variant={variant === 'danger' ? variant : undefined} {...containerProps} - {...props} > diff --git a/packages/react/src/NavList/NavList.tsx b/packages/react/src/NavList/NavList.tsx index d3524872a41..5916dfd59c3 100644 --- a/packages/react/src/NavList/NavList.tsx +++ b/packages/react/src/NavList/NavList.tsx @@ -117,7 +117,7 @@ function ItemWithSubNav({children, subNav, depth, defaultOpen, sx: sxProp = defa const buttonId = useId() const subNavId = useId() const [isOpen, setIsOpen] = React.useState((defaultOpen || null) ?? false) - const subNavRef = React.useRef(null) + const subNavRef = React.useRef(null) const [containsCurrentItem, setContainsCurrentItem] = React.useState(false) useIsomorphicLayoutEffect(() => { @@ -135,36 +135,35 @@ function ItemWithSubNav({children, subNav, depth, defaultOpen, sx: sxProp = defa return ( - - setIsOpen(open => !open)} - sx={merge( - { - ...getSubnavStyles(depth), - fontWeight: containsCurrentItem ? 'bold' : null, // Parent item is bold if any of it's sub-items are current - }, - sxProp, - )} - > - {children} - {/* What happens if the user provides a TrailingVisual? */} - - - - - -
{subNav}
+ setIsOpen(open => !open)} + sx={merge( + { + ...getSubnavStyles(depth), + fontWeight: containsCurrentItem ? 'bold' : null, // Parent item is bold if any of it's sub-items are current + }, + sxProp, + )} + > + {children} + {/* What happens if the user provides a TrailingVisual? */} + + + + + + + {subNav}
) diff --git a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap index 1d86fc61fcb..5ae1f95f0ae 100644 --- a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap +++ b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap @@ -833,8 +833,13 @@ exports[`NavList renders with groups 1`] = ` `; exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav contains the current item and is open 1`] = ` -.c2 { - list-style: none; +[data-component="ActionList.Divider"] + .c3 { + --divider-color: transparent !important; +} + +.c15:hover:not([aria-disabled]):not([data-inactive]) + .c3, +.c15[data-focus-visible-added] + li { + --divider-color: transparent; } .c5 { @@ -881,50 +886,25 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav font-weight: initial; } -[data-variant="danger"]:hover .c1, +[data-variant="danger"]:hover .c3, [data-variant="danger"]:active .c8 { color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } .c10 { - padding: 0; - margin: 0; - display: block; -} - -.c9 { - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} - -.c0 { - margin: 0; - padding-inline-start: 0; - padding-top: 8px; - padding-bottom: 8px; -} - -[data-component="ActionList.Divider"] + .c3 { - --divider-color: transparent !important; -} - -.c14:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c14[data-focus-visible-added] + li { - --divider-color: transparent; + list-style: none; } -.c11 { +.c4 { position: relative; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; - padding-left: 0; - padding-right: 0; - font-size: 14px; - padding-top: 0; - padding-bottom: 0; + padding-left: 8px; + padding-right: 8px; + padding-top: 6px; + padding-bottom: 6px; line-height: 20px; min-height: 5px; margin-left: 8px; @@ -945,26 +925,25 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav margin-top: unset; margin-bottom: unset; font-weight: 600; - background-color: var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(208,215,222,0.24))); } -.c11[aria-disabled], -.c11[data-inactive] { +.c4[aria-disabled], +.c4[data-inactive] { cursor: not-allowed; } -.c11[aria-disabled] [data-component="ActionList.Checkbox"], -.c11[data-inactive] [data-component="ActionList.Checkbox"] { +.c4[aria-disabled] [data-component="ActionList.Checkbox"], +.c4[data-inactive] [data-component="ActionList.Checkbox"] { cursor: not-allowed; background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); border-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); } -.c11 [data-component="ActionList.Item--DividerContainer"] { +.c4 [data-component="ActionList.Item--DividerContainer"] { position: relative; } -.c11 [data-component="ActionList.Item--DividerContainer"]::before { +.c4 [data-component="ActionList.Item--DividerContainer"]::before { content: " "; display: block; position: absolute; @@ -975,7 +954,7 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav border-color: var(--divider-color,transparent); } -.c11:not(:first-of-type) { +.c4:not(:first-of-type) { --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); } @@ -983,38 +962,58 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav --divider-color: transparent !important; } -.c11:hover:not([aria-disabled]):not([data-inactive]), -.c11:focus:not([aria-disabled]):not([data-inactive]), -.c11[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { +.c4:hover:not([aria-disabled]):not([data-inactive]), +.c4:focus:not([aria-disabled]):not([data-inactive]), +.c4[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { --divider-color: transparent; } -.c11:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c11[data-focus-visible-added] + li { +.c4:hover:not([aria-disabled]):not([data-inactive]) + .c3, +.c4[data-focus-visible-added] + li { --divider-color: transparent; } -.c11::after { - position: absolute; - top: calc(50% - 12px); - left: -8px; - width: 4px; - height: 24px; - content: ""; - background-color: var(--fgColor-accent,var(--color-accent-fg,#0969da)); - border-radius: 6px; +.c11 { + padding: 0; + margin: 0; + display: block; } -.c4 { +.c9 { + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} + +.c0 { + margin: 0; + padding-inline-start: 0; + padding-top: 8px; + padding-bottom: 8px; +} + +.c2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.c2:not(:first-of-type) { + --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); +} + +.c12 { position: relative; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; - padding-left: 8px; - padding-right: 8px; - padding-top: 6px; - padding-bottom: 6px; + padding-left: 0; + padding-right: 0; + font-size: 14px; + padding-top: 0; + padding-bottom: 0; line-height: 20px; min-height: 5px; margin-left: 8px; @@ -1035,25 +1034,26 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav margin-top: unset; margin-bottom: unset; font-weight: 600; + background-color: var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(208,215,222,0.24))); } -.c4[aria-disabled], -.c4[data-inactive] { +.c12[aria-disabled], +.c12[data-inactive] { cursor: not-allowed; } -.c4[aria-disabled] [data-component="ActionList.Checkbox"], -.c4[data-inactive] [data-component="ActionList.Checkbox"] { +.c12[aria-disabled] [data-component="ActionList.Checkbox"], +.c12[data-inactive] [data-component="ActionList.Checkbox"] { cursor: not-allowed; background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); border-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); } -.c4 [data-component="ActionList.Item--DividerContainer"] { +.c12 [data-component="ActionList.Item--DividerContainer"] { position: relative; } -.c4 [data-component="ActionList.Item--DividerContainer"]::before { +.c12 [data-component="ActionList.Item--DividerContainer"]::before { content: " "; display: block; position: absolute; @@ -1064,26 +1064,37 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav border-color: var(--divider-color,transparent); } -.c4:not(:first-of-type) { +.c12:not(:first-of-type) { --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); } -[data-component="ActionList.Divider"] + .c3 { +[data-component="ActionList.Divider"] + .c1 { --divider-color: transparent !important; } -.c4:hover:not([aria-disabled]):not([data-inactive]), -.c4:focus:not([aria-disabled]):not([data-inactive]), -.c4[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { +.c12:hover:not([aria-disabled]):not([data-inactive]), +.c12:focus:not([aria-disabled]):not([data-inactive]), +.c12[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { --divider-color: transparent; } -.c4:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c4[data-focus-visible-added] + li { +.c12:hover:not([aria-disabled]):not([data-inactive]) + .c1, +.c12[data-focus-visible-added] + li { --divider-color: transparent; } -.c13 { +.c12::after { + position: absolute; + top: calc(50% - 12px); + left: -8px; + width: 4px; + height: 24px; + content: ""; + background-color: var(--fgColor-accent,var(--color-accent-fg,#0969da)); + border-radius: 6px; +} + +.c14 { color: var(--fgColor-accent,var(--color-accent-fg,#0969da)); -webkit-text-decoration: none; text-decoration: none; @@ -1105,17 +1116,17 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav font-weight: 400; } -[data-a11y-link-underlines='true'] .c12[data-inline='true'] { +[data-a11y-link-underlines='true'] .c13[data-inline='true'] { -webkit-text-decoration: underline; text-decoration: underline; } -.c13:hover { +.c14:hover { -webkit-text-decoration: underline; text-decoration: underline; } -.c13:is(button) { +.c14:is(button) { display: inline-block; padding: 0; font-size: inherit; @@ -1132,7 +1143,7 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav appearance: none; } -.c13:hover { +.c14:hover { color: inherit; -webkit-text-decoration: none; text-decoration: none; @@ -1147,55 +1158,55 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav } @media (hover:hover) and (pointer:fine) { - .c11:hover:not([aria-disabled]):not([data-inactive]) { + .c4:hover:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(208,215,222,0.32))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); box-shadow: inset 0 0 0 max(1px,0.0625rem) var(--control-transparent-borderColor-active,var(--color-action-list-item-default-active-border,transparent)); } - .c11:focus-visible, - .c11 > a:focus-visible, - .c11:focus.focus-visible { + .c4:focus-visible, + .c4 > a:focus-visible, + .c4:focus.focus-visible { outline: none; border: 2 solid; box-shadow: 0 0 0 2px var(--bgColor-accent-emphasis,var(--color-accent-emphasis,#0969da)); } - .c11:active:not([aria-disabled]):not([data-inactive]) { + .c4:active:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(208,215,222,0.48))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } } @media (forced-colors:active) { - .c11:focus { + .c4:focus { outline: solid 1px transparent !important; } } @media (hover:hover) and (pointer:fine) { - .c4:hover:not([aria-disabled]):not([data-inactive]) { + .c12:hover:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(208,215,222,0.32))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); box-shadow: inset 0 0 0 max(1px,0.0625rem) var(--control-transparent-borderColor-active,var(--color-action-list-item-default-active-border,transparent)); } - .c4:focus-visible, - .c4 > a:focus-visible, - .c4:focus.focus-visible { + .c12:focus-visible, + .c12 > a:focus-visible, + .c12:focus.focus-visible { outline: none; border: 2 solid; box-shadow: 0 0 0 2px var(--bgColor-accent-emphasis,var(--color-accent-emphasis,#0969da)); } - .c4:active:not([aria-disabled]):not([data-inactive]) { + .c12:active:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(208,215,222,0.48))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } } @media (forced-colors:active) { - .c4:focus { + .c12:focus { outline: solid 1px transparent !important; } } @@ -1208,7 +1219,6 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav class="c0" >
  • -
    -
    + Sub Item + + + +
  • + @@ -1293,8 +1305,13 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav `; exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains the current item and is closed 1`] = ` -.c2 { - list-style: none; +[data-component="ActionList.Divider"] + .c3 { + --divider-color: transparent !important; +} + +.c15:hover:not([aria-disabled]):not([data-inactive]) + .c3, +.c15[data-focus-visible-added] + li { + --divider-color: transparent; } .c5 { @@ -1341,50 +1358,40 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t font-weight: initial; } -[data-variant="danger"]:hover .c1, +[data-variant="danger"]:hover .c3, [data-variant="danger"]:active .c8 { color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } .c10 { - padding: 0; - margin: 0; - display: none; -} - -.c9 { - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); + list-style: none; } -.c0 { +.c11 { + padding: 0; margin: 0; - padding-inline-start: 0; - padding-top: 8px; - padding-bottom: 8px; + display: none; } [data-component="ActionList.Divider"] + .c3 { --divider-color: transparent !important; } -.c14:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c14[data-focus-visible-added] + li { +.c16:hover:not([aria-disabled]):not([data-inactive]) + .c3, +.c16[data-focus-visible-added] + li { --divider-color: transparent; } -.c11 { +.c4 { position: relative; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; - padding-left: 0; - padding-right: 0; - font-size: 14px; - padding-top: 0; - padding-bottom: 0; + padding-left: 8px; + padding-right: 8px; + padding-top: 6px; + padding-bottom: 6px; line-height: 20px; min-height: 5px; margin-left: 8px; @@ -1408,23 +1415,23 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t background-color: var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(208,215,222,0.24))); } -.c11[aria-disabled], -.c11[data-inactive] { +.c4[aria-disabled], +.c4[data-inactive] { cursor: not-allowed; } -.c11[aria-disabled] [data-component="ActionList.Checkbox"], -.c11[data-inactive] [data-component="ActionList.Checkbox"] { +.c4[aria-disabled] [data-component="ActionList.Checkbox"], +.c4[data-inactive] [data-component="ActionList.Checkbox"] { cursor: not-allowed; background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); border-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); } -.c11 [data-component="ActionList.Item--DividerContainer"] { +.c4 [data-component="ActionList.Item--DividerContainer"] { position: relative; } -.c11 [data-component="ActionList.Item--DividerContainer"]::before { +.c4 [data-component="ActionList.Item--DividerContainer"]::before { content: " "; display: block; position: absolute; @@ -1435,7 +1442,7 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t border-color: var(--divider-color,transparent); } -.c11:not(:first-of-type) { +.c4:not(:first-of-type) { --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); } @@ -1443,18 +1450,18 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t --divider-color: transparent !important; } -.c11:hover:not([aria-disabled]):not([data-inactive]), -.c11:focus:not([aria-disabled]):not([data-inactive]), -.c11[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { +.c4:hover:not([aria-disabled]):not([data-inactive]), +.c4:focus:not([aria-disabled]):not([data-inactive]), +.c4[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { --divider-color: transparent; } -.c11:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c11[data-focus-visible-added] + li { +.c4:hover:not([aria-disabled]):not([data-inactive]) + .c3, +.c4[data-focus-visible-added] + li { --divider-color: transparent; } -.c11::after { +.c4::after { position: absolute; top: calc(50% - 12px); left: -8px; @@ -1465,25 +1472,41 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t border-radius: 6px; } -[data-component="ActionList.Divider"] + .c3 { - --divider-color: transparent !important; +.c9 { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); } -.c15:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c15[data-focus-visible-added] + li { - --divider-color: transparent; +.c0 { + margin: 0; + padding-inline-start: 0; + padding-top: 8px; + padding-bottom: 8px; } -.c4 { +.c2 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.c2:not(:first-of-type) { + --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); +} + +.c12 { position: relative; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; - padding-left: 8px; - padding-right: 8px; - padding-top: 6px; - padding-bottom: 6px; + padding-left: 0; + padding-right: 0; + font-size: 14px; + padding-top: 0; + padding-bottom: 0; line-height: 20px; min-height: 5px; margin-left: 8px; @@ -1507,23 +1530,23 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t background-color: var(--control-transparent-bgColor-selected,var(--color-action-list-item-default-selected-bg,rgba(208,215,222,0.24))); } -.c4[aria-disabled], -.c4[data-inactive] { +.c12[aria-disabled], +.c12[data-inactive] { cursor: not-allowed; } -.c4[aria-disabled] [data-component="ActionList.Checkbox"], -.c4[data-inactive] [data-component="ActionList.Checkbox"] { +.c12[aria-disabled] [data-component="ActionList.Checkbox"], +.c12[data-inactive] [data-component="ActionList.Checkbox"] { cursor: not-allowed; background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); border-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); } -.c4 [data-component="ActionList.Item--DividerContainer"] { +.c12 [data-component="ActionList.Item--DividerContainer"] { position: relative; } -.c4 [data-component="ActionList.Item--DividerContainer"]::before { +.c12 [data-component="ActionList.Item--DividerContainer"]::before { content: " "; display: block; position: absolute; @@ -1534,26 +1557,26 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t border-color: var(--divider-color,transparent); } -.c4:not(:first-of-type) { +.c12:not(:first-of-type) { --divider-color: var(--borderColor-muted,var(--color-action-list-item-inline-divider,rgba(208,215,222,0.48))); } -[data-component="ActionList.Divider"] + .c3 { +[data-component="ActionList.Divider"] + .c1 { --divider-color: transparent !important; } -.c4:hover:not([aria-disabled]):not([data-inactive]), -.c4:focus:not([aria-disabled]):not([data-inactive]), -.c4[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { +.c12:hover:not([aria-disabled]):not([data-inactive]), +.c12:focus:not([aria-disabled]):not([data-inactive]), +.c12[data-focus-visible-added]:not([aria-disabled]):not([data-inactive]) { --divider-color: transparent; } -.c4:hover:not([aria-disabled]):not([data-inactive]) + .c3, -.c4[data-focus-visible-added] + li { +.c12:hover:not([aria-disabled]):not([data-inactive]) + .c1, +.c12[data-focus-visible-added] + li { --divider-color: transparent; } -.c4::after { +.c12::after { position: absolute; top: calc(50% - 12px); left: -8px; @@ -1564,7 +1587,7 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t border-radius: 6px; } -.c13 { +.c14 { color: var(--fgColor-accent,var(--color-accent-fg,#0969da)); -webkit-text-decoration: none; text-decoration: none; @@ -1586,17 +1609,17 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t font-weight: 400; } -[data-a11y-link-underlines='true'] .c12[data-inline='true'] { +[data-a11y-link-underlines='true'] .c13[data-inline='true'] { -webkit-text-decoration: underline; text-decoration: underline; } -.c13:hover { +.c14:hover { -webkit-text-decoration: underline; text-decoration: underline; } -.c13:is(button) { +.c14:is(button) { display: inline-block; padding: 0; font-size: inherit; @@ -1613,7 +1636,7 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t appearance: none; } -.c13:hover { +.c14:hover { color: inherit; -webkit-text-decoration: none; text-decoration: none; @@ -1628,63 +1651,63 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t } @media (hover:hover) and (pointer:fine) { - .c11:hover:not([aria-disabled]):not([data-inactive]) { + +} + +@media (forced-colors:active) { + +} + +@media (hover:hover) and (pointer:fine) { + .c4:hover:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(208,215,222,0.32))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); box-shadow: inset 0 0 0 max(1px,0.0625rem) var(--control-transparent-borderColor-active,var(--color-action-list-item-default-active-border,transparent)); } - .c11:focus-visible, - .c11 > a:focus-visible, - .c11:focus.focus-visible { + .c4:focus-visible, + .c4 > a:focus-visible, + .c4:focus.focus-visible { outline: none; border: 2 solid; box-shadow: 0 0 0 2px var(--bgColor-accent-emphasis,var(--color-accent-emphasis,#0969da)); } - .c11:active:not([aria-disabled]):not([data-inactive]) { + .c4:active:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(208,215,222,0.48))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } } @media (forced-colors:active) { - .c11:focus { + .c4:focus { outline: solid 1px transparent !important; } } @media (hover:hover) and (pointer:fine) { - -} - -@media (forced-colors:active) { - -} - -@media (hover:hover) and (pointer:fine) { - .c4:hover:not([aria-disabled]):not([data-inactive]) { + .c12:hover:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-hover,var(--color-action-list-item-default-hover-bg,rgba(208,215,222,0.32))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); box-shadow: inset 0 0 0 max(1px,0.0625rem) var(--control-transparent-borderColor-active,var(--color-action-list-item-default-active-border,transparent)); } - .c4:focus-visible, - .c4 > a:focus-visible, - .c4:focus.focus-visible { + .c12:focus-visible, + .c12 > a:focus-visible, + .c12:focus.focus-visible { outline: none; border: 2 solid; box-shadow: 0 0 0 2px var(--bgColor-accent-emphasis,var(--color-accent-emphasis,#0969da)); } - .c4:active:not([aria-disabled]):not([data-inactive]) { + .c12:active:not([aria-disabled]):not([data-inactive]) { background-color: var(--control-transparent-bgColor-active,var(--color-action-list-item-default-active-bg,rgba(208,215,222,0.48))); color: var(--fgColor-default,var(--color-fg-default,#1F2328)); } } @media (forced-colors:active) { - .c4:focus { + .c12:focus { outline: solid 1px transparent !important; } } @@ -1697,7 +1720,6 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t class="c0" >
  • -
    -
    + Sub Item + + + +
  • + diff --git a/packages/react/src/drafts/InlineAutocomplete/_AutocompleteSuggestions.tsx b/packages/react/src/drafts/InlineAutocomplete/_AutocompleteSuggestions.tsx index 3d9bdfa51c6..757827e906a 100644 --- a/packages/react/src/drafts/InlineAutocomplete/_AutocompleteSuggestions.tsx +++ b/packages/react/src/drafts/InlineAutocomplete/_AutocompleteSuggestions.tsx @@ -131,7 +131,7 @@ const AutocompleteSuggestions = ({ left={triggerCharCoords.left} ref={overlayRef} > - + {suggestions === 'loading' ? ( ) : ( From fa708b1dc0a766db419a36966d449880ee9c519b Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Thu, 15 Feb 2024 10:26:39 -0500 Subject: [PATCH 02/73] More type fixes --- packages/react/src/ActionList/Item.tsx | 18 +++++++++--------- packages/react/src/ActionList/shared.ts | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index 6ee51cdeee1..fd01bed476b 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -45,7 +45,7 @@ const InactiveIndicator: React.FC<{ ) -export const Item = React.forwardRef( +export const Item = React.forwardRef( ( { variant = 'default', @@ -82,7 +82,7 @@ export const Item = React.forwardRef( const onSelect = React.useCallback( ( - event: React.MouseEvent | React.KeyboardEvent, + event: React.MouseEvent | React.KeyboardEvent, // eslint-disable-next-line @typescript-eslint/ban-types afterSelect?: Function, ) => { @@ -224,7 +224,7 @@ export const Item = React.forwardRef( } const clickHandler = React.useCallback( - (event: React.MouseEvent) => { + (event: React.MouseEvent) => { if (disabled || inactive) return onSelect(event, afterSelect) }, @@ -232,7 +232,7 @@ export const Item = React.forwardRef( ) const keyPressHandler = React.useCallback( - (event: React.KeyboardEvent) => { + (event: React.KeyboardEvent) => { if (disabled || inactive) return if ([' ', 'Enter'].includes(event.key)) { if (event.key === ' ') { @@ -265,7 +265,7 @@ export const Item = React.forwardRef( {children} ) - }) as PolymorphicForwardRefComponent + }) as PolymorphicForwardRefComponent<'button', ActionListItemProps> const ItemWrapper = _PrivateItemWrapper || (validAriaRole ? React.Fragment : ButtonItemWrapper) @@ -290,7 +290,8 @@ export const Item = React.forwardRef( const containerProps = _PrivateItemWrapper ? {role: itemRole ? 'none' : undefined, ...props} - : (validAriaRole && {...menuItemProps, ...props}) || {} + : // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + (validAriaRole && {...menuItemProps, ...props}) || {} const wrapperProps = _PrivateItemWrapper ? menuItemProps @@ -301,7 +302,6 @@ export const Item = React.forwardRef( value={{variant, disabled, inactive: Boolean(inactiveText), inlineDescriptionId, blockDescriptionId}} > ( validAriaRole || _PrivateItemWrapper ? styles : listItemStyles, validAriaRole || _PrivateItemWrapper ? sxProp : {}, @@ -309,7 +309,7 @@ export const Item = React.forwardRef( data-variant={variant === 'danger' ? variant : undefined} {...containerProps} > - + { // If we're showing an inactive indicator and a leading visual has been passed, @@ -391,7 +391,7 @@ export const Item = React.forwardRef(
    ) }, -) as PolymorphicForwardRefComponent<'li', ActionListItemProps> +) as PolymorphicForwardRefComponent<'button', ActionListItemProps> Item.displayName = 'ActionList.Item' diff --git a/packages/react/src/ActionList/shared.ts b/packages/react/src/ActionList/shared.ts index 635eb08ed8b..d2f18e44f8f 100644 --- a/packages/react/src/ActionList/shared.ts +++ b/packages/react/src/ActionList/shared.ts @@ -11,7 +11,7 @@ export type ActionListItemProps = { * Callback that will trigger both on click selection and keyboard selection. * This is not called for disabled or inactive items. */ - onSelect?: (event: React.MouseEvent | React.KeyboardEvent) => void + onSelect?: (event: React.MouseEvent | React.KeyboardEvent) => void /** * Is the `Item` is currently selected? */ @@ -51,8 +51,8 @@ export type ActionListItemProps = { } & SxProp type MenuItemProps = { - onClick?: (event: React.MouseEvent) => void - onKeyPress?: (event: React.KeyboardEvent) => void + onClick?: (event: React.MouseEvent) => void + onKeyPress?: (event: React.KeyboardEvent) => void 'aria-disabled'?: boolean tabIndex?: number 'aria-labelledby'?: string From e087f87af384c5fcb9c0cf9d70d150c76c57d8cb Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Thu, 15 Feb 2024 11:40:07 -0500 Subject: [PATCH 03/73] temp type fixes --- packages/react/src/ActionList/Item.tsx | 8 ++++---- packages/react/src/ActionList/shared.ts | 4 ++-- .../react/src/ActionMenu/ActionMenu.examples.stories.tsx | 2 +- packages/react/src/SegmentedControl/SegmentedControl.tsx | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index fd01bed476b..1c08e73ab98 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -82,11 +82,11 @@ export const Item = React.forwardRef( const onSelect = React.useCallback( ( - event: React.MouseEvent | React.KeyboardEvent, + event: React.MouseEvent | React.KeyboardEvent, // eslint-disable-next-line @typescript-eslint/ban-types afterSelect?: Function, ) => { - if (typeof onSelectUser === 'function') onSelectUser(event) + if (typeof onSelectUser === 'function') onSelectUser(event as React.MouseEvent) if (event.defaultPrevented) return if (typeof afterSelect === 'function') afterSelect(event) }, @@ -224,7 +224,7 @@ export const Item = React.forwardRef( } const clickHandler = React.useCallback( - (event: React.MouseEvent) => { + (event: React.MouseEvent) => { if (disabled || inactive) return onSelect(event, afterSelect) }, @@ -232,7 +232,7 @@ export const Item = React.forwardRef( ) const keyPressHandler = React.useCallback( - (event: React.KeyboardEvent) => { + (event: React.KeyboardEvent) => { if (disabled || inactive) return if ([' ', 'Enter'].includes(event.key)) { if (event.key === ' ') { diff --git a/packages/react/src/ActionList/shared.ts b/packages/react/src/ActionList/shared.ts index d2f18e44f8f..1e607e40ce2 100644 --- a/packages/react/src/ActionList/shared.ts +++ b/packages/react/src/ActionList/shared.ts @@ -51,8 +51,8 @@ export type ActionListItemProps = { } & SxProp type MenuItemProps = { - onClick?: (event: React.MouseEvent) => void - onKeyPress?: (event: React.KeyboardEvent) => void + onClick?: (event: React.MouseEvent) => void + onKeyPress?: (event: React.KeyboardEvent) => void 'aria-disabled'?: boolean tabIndex?: number 'aria-labelledby'?: string diff --git a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx index fa750b7dd41..88dd89579d5 100644 --- a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx @@ -346,7 +346,7 @@ export const MultipleSections = () => { export const DelayedMenuClose = () => { const [open, setOpen] = React.useState(false) const [copyLinkSuccess, setCopyLinkSuccess] = React.useState(false) - const onSelect = (event: React.MouseEvent | React.KeyboardEvent) => { + const onSelect = (event: React.MouseEvent | React.KeyboardEvent) => { event.preventDefault() setCopyLinkSuccess(true) diff --git a/packages/react/src/SegmentedControl/SegmentedControl.tsx b/packages/react/src/SegmentedControl/SegmentedControl.tsx index 0b047524c5c..d810ec9d48f 100644 --- a/packages/react/src/SegmentedControl/SegmentedControl.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControl.tsx @@ -125,10 +125,10 @@ const Root: React.FC> = ({ | React.KeyboardEvent) => { + onSelect={(event: React.MouseEvent | React.KeyboardEvent) => { isUncontrolled && setSelectedIndexInternalState(index) onChange && onChange(index) - child.props.onClick && child.props.onClick(event as React.MouseEvent) + child.props.onClick && child.props.onClick(event as React.MouseEvent) }} > {ChildIcon && } {getChildText(child)} From 76e26066f43982c63be2b885b5f6b3616bd373dc Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Thu, 15 Feb 2024 12:05:11 -0500 Subject: [PATCH 04/73] Add condition for inactive items --- packages/react/src/ActionList/Item.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index 1c08e73ab98..63298feb37c 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -252,7 +252,7 @@ export const Item = React.forwardRef( const inlineDescriptionId = `${itemId}--inline-description` const blockDescriptionId = `${itemId}--block-description` const inactiveWarningId = inactive && !showInactiveIndicator ? `${itemId}--warning-message` : undefined - const validAriaRole = listRole === 'listbox' || listRole === 'menu' + const validRole = listRole === 'listbox' || listRole === 'menu' || inactive const ButtonItemWrapper = React.forwardRef(({as: Component = 'button', children, ...props}, forwardedRef) => { return ( @@ -267,7 +267,7 @@ export const Item = React.forwardRef( ) }) as PolymorphicForwardRefComponent<'button', ActionListItemProps> - const ItemWrapper = _PrivateItemWrapper || (validAriaRole ? React.Fragment : ButtonItemWrapper) + const ItemWrapper = _PrivateItemWrapper || (validRole ? React.Fragment : ButtonItemWrapper) // only apply aria-selected and aria-checked to selectable items const selectableRoles = ['menuitemradio', 'menuitemcheckbox', 'option'] @@ -291,11 +291,11 @@ export const Item = React.forwardRef( const containerProps = _PrivateItemWrapper ? {role: itemRole ? 'none' : undefined, ...props} : // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - (validAriaRole && {...menuItemProps, ...props}) || {} + (validRole && {...menuItemProps, ...props}) || {} const wrapperProps = _PrivateItemWrapper ? menuItemProps - : !validAriaRole && {...menuItemProps, styles: merge(styles, sxProp), ...props} + : !validRole && {...menuItemProps, styles: merge(styles, sxProp), ...props} return ( ( > ( - validAriaRole || _PrivateItemWrapper ? styles : listItemStyles, - validAriaRole || _PrivateItemWrapper ? sxProp : {}, + validRole || _PrivateItemWrapper ? styles : listItemStyles, + validRole || _PrivateItemWrapper ? sxProp : {}, )} data-variant={variant === 'danger' ? variant : undefined} {...containerProps} From eab6fd9aa347527532a0b70783539b2f59a3315c Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Fri, 16 Feb 2024 10:41:55 -0500 Subject: [PATCH 05/73] add yet another condition --- packages/react/src/ActionList/Item.tsx | 2 +- packages/react/src/NavList/NavList.tsx | 63 +- .../__snapshots__/NavList.test.tsx.snap | 571 +++++++++--------- 3 files changed, 314 insertions(+), 322 deletions(-) diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index 63298feb37c..45f4a01e1f4 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -252,7 +252,7 @@ export const Item = React.forwardRef( const inlineDescriptionId = `${itemId}--inline-description` const blockDescriptionId = `${itemId}--block-description` const inactiveWarningId = inactive && !showInactiveIndicator ? `${itemId}--warning-message` : undefined - const validRole = listRole === 'listbox' || listRole === 'menu' || inactive + const validRole = listRole === 'listbox' || listRole === 'menu' || listRole === 'list' || inactive const ButtonItemWrapper = React.forwardRef(({as: Component = 'button', children, ...props}, forwardedRef) => { return ( diff --git a/packages/react/src/NavList/NavList.tsx b/packages/react/src/NavList/NavList.tsx index 5916dfd59c3..78f53bbcab9 100644 --- a/packages/react/src/NavList/NavList.tsx +++ b/packages/react/src/NavList/NavList.tsx @@ -36,7 +36,7 @@ const NavBox = styled.nav(sx) const Root = React.forwardRef(({children, ...props}, ref) => { return ( - {children} + {children} ) }) @@ -117,7 +117,7 @@ function ItemWithSubNav({children, subNav, depth, defaultOpen, sx: sxProp = defa const buttonId = useId() const subNavId = useId() const [isOpen, setIsOpen] = React.useState((defaultOpen || null) ?? false) - const subNavRef = React.useRef(null) + const subNavRef = React.useRef(null) const [containsCurrentItem, setContainsCurrentItem] = React.useState(false) useIsomorphicLayoutEffect(() => { @@ -135,35 +135,36 @@ function ItemWithSubNav({children, subNav, depth, defaultOpen, sx: sxProp = defa return ( - setIsOpen(open => !open)} - sx={merge( - { - ...getSubnavStyles(depth), - fontWeight: containsCurrentItem ? 'bold' : null, // Parent item is bold if any of it's sub-items are current - }, - sxProp, - )} - > - {children} - {/* What happens if the user provides a TrailingVisual? */} - - - - - - - {subNav} + + setIsOpen(open => !open)} + sx={merge( + { + ...getSubnavStyles(depth), + fontWeight: containsCurrentItem ? 'bold' : null, // Parent item is bold if any of it's sub-items are current + }, + sxProp, + )} + > + {children} + {/* What happens if the user provides a TrailingVisual? */} + + + + + +
    {subNav}
    ) diff --git a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap index 5ae1f95f0ae..c145f27a3b7 100644 --- a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap +++ b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap @@ -313,6 +313,7 @@ exports[`NavList renders a simple list 1`] = ` >