diff --git a/.changeset/tall-dancers-exercise.md b/.changeset/tall-dancers-exercise.md new file mode 100644 index 00000000000..edc45b4aba5 --- /dev/null +++ b/.changeset/tall-dancers-exercise.md @@ -0,0 +1,7 @@ +--- +'@primer/react': patch +--- + +- Text input inner action's hover bg should not touch the text input edges +- Increases touch target area of the text input inner action button +- Deprecated `children` and `variant` props on the `TextInputInnerAction` component, but they're **still supported for now**. diff --git a/docs/content/TextInput.mdx b/docs/content/TextInput.mdx index 4ec34745bc8..69ba4872659 100644 --- a/docs/content/TextInput.mdx +++ b/docs/content/TextInput.mdx @@ -111,37 +111,21 @@ render() ### With trailing action ```jsx live - - - Icon action - { - alert('clear input') - }} - icon={XIcon} - aria-label="Clear input" - sx={{color: 'fg.subtle'}} - /> - } - /> - - - Text action - { - alert('clear input') - }} - > - Clear - - } - /> - - + + Icon action + { + alert('clear input') + }} + icon={XIcon} + aria-label="Clear input" + sx={{color: 'fg.subtle'}} + /> + } + /> + ``` ### With error and warning states @@ -315,7 +299,8 @@ render() , 'aria-label' | 'size'> & { + /** @deprecated Text input action buttons should only use icon buttons */ + children?: React.ReactNode /** Text that appears in a tooltip. If an icon is passed, this is also used as the label used by assistive technologies. */ ['aria-label']?: string /** The icon to render inside the button */ icon?: React.FunctionComponent /** + * @deprecated Text input action buttons should only use the 'invisible' button variant * Determine's the styles on a button one of 'default' | 'primary' | 'invisible' | 'danger' */ variant?: ButtonProps['variant'] } & SxProp const invisibleButtonStyleOverrides = { - color: 'fg.default' + color: 'fg.default', + paddingTop: '2px', + paddingRight: '4px', + paddingBottom: '2px', + paddingLeft: '4px', + position: 'relative', + + '@media (pointer: coarse)': { + ':after': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + transform: 'translateY(-50%)', + top: '50%', + minHeight: '44px' + } + } } const ConditionalTooltip: React.FC<{ @@ -44,7 +64,9 @@ const ConditionalTooltip: React.FC<{ const TextInputAction = forwardRef( ({'aria-label': ariaLabel, children, icon, sx: sxProp, variant, ...rest}, forwardedRef) => { const sx = - variant === 'invisible' ? merge(invisibleButtonStyleOverrides, sxProp || {}) : sxProp + variant === 'invisible' + ? merge(invisibleButtonStyleOverrides, sxProp || {}) + : sxProp || {} if ((icon && !ariaLabel) || (!children && !ariaLabel)) { // eslint-disable-next-line no-console @@ -52,7 +74,7 @@ const TextInputAction = forwardRef( } return ( - + {icon && !children ? ( ( type="button" icon={icon} aria-label={ariaLabel} + size="small" sx={sx} {...rest} ref={forwardedRef} diff --git a/src/__tests__/__snapshots__/TextInput.test.tsx.snap b/src/__tests__/__snapshots__/TextInput.test.tsx.snap index f8408bbeaac..587faa121f4 100644 --- a/src/__tests__/__snapshots__/TextInput.test.tsx.snap +++ b/src/__tests__/__snapshots__/TextInput.test.tsx.snap @@ -1155,11 +1155,15 @@ exports[`TextInput renders small 1`] = ` `; exports[`TextInput renders trailingAction icon button 1`] = ` -.c4 { +.c2 { + margin: 4px; +} + +.c5 { display: inline-block; } -.c3 { +.c4 { border-radius: 6px; border: 0; border-color: rgba(27,31,36,0.15); @@ -1179,58 +1183,59 @@ exports[`TextInput renders trailingAction icon button 1`] = ` -webkit-text-decoration: none; text-decoration: none; text-align: center; - padding-top: 6px; - padding-bottom: 6px; - padding-left: 8px; - padding-right: 8px; + padding-top: 2px; + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; font-size: 14px; color: #24292f; background-color: transparent; box-shadow: none; + position: relative; } -.c3:disabled { +.c4:disabled { cursor: default; color: #8c959f; } -.c3:disabled [data-component=ButtonCounter] { +.c4:disabled [data-component=ButtonCounter] { color: inherit; } -.c3:disabled svg { +.c4:disabled svg { opacity: 0.6; } -.c3 [data-component=ButtonCounter] { +.c4 [data-component=ButtonCounter] { font-size: 14px; } -.c3:hover:not([disabled]) { +.c4:hover:not([disabled]) { background-color: #f3f4f6; } -.c3:focus:not([disabled]) { +.c4:focus:not([disabled]) { outline: 2px solid; outline-color: #0969da; outline-offset: -2px; } -.c3:focus:not([disabled]):not(:focus-visible) { +.c4:focus:not([disabled]):not(:focus-visible) { outline: solid 1px transparent; } -.c3:focus-visible:not([disabled]) { +.c4:focus-visible:not([disabled]) { outline: 2px solid; outline-color: #0969da; outline-offset: -2px; } -.c3:active:not([disabled]) { +.c4:active:not([disabled]) { background-color: hsla(220,14%,94%,1); } -.c3[aria-expanded=true] { +.c4[aria-expanded=true] { background-color: hsla(220,14%,94%,1); } @@ -1315,11 +1320,11 @@ exports[`TextInput renders trailingAction icon button 1`] = ` outline: 0; } -.c2 { +.c3 { position: relative; } -.c2::before { +.c3::before { position: absolute; z-index: 1000001; display: none; @@ -1332,7 +1337,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` opacity: 0; } -.c2::after { +.c3::after { position: absolute; z-index: 1000000; display: none; @@ -1358,12 +1363,12 @@ exports[`TextInput renders trailingAction icon button 1`] = ` opacity: 0; } -.c2:hover::before, -.c2:active::before, -.c2:focus::before, -.c2:hover::after, -.c2:active::after, -.c2:focus::after { +.c3:hover::before, +.c3:active::before, +.c3:focus::before, +.c3:hover::after, +.c3:active::after, +.c3:focus::after { display: inline-block; -webkit-text-decoration: none; text-decoration: none; @@ -1379,33 +1384,33 @@ exports[`TextInput renders trailingAction icon button 1`] = ` animation-delay: 0.4s; } -.c2.tooltipped-no-delay:hover::before, -.c2.tooltipped-no-delay:active::before, -.c2.tooltipped-no-delay:focus::before, -.c2.tooltipped-no-delay:hover::after, -.c2.tooltipped-no-delay:active::after, -.c2.tooltipped-no-delay:focus::after { +.c3.tooltipped-no-delay:hover::before, +.c3.tooltipped-no-delay:active::before, +.c3.tooltipped-no-delay:focus::before, +.c3.tooltipped-no-delay:hover::after, +.c3.tooltipped-no-delay:active::after, +.c3.tooltipped-no-delay:focus::after { -webkit-animation-delay: 0s; animation-delay: 0s; } -.c2.tooltipped-multiline:hover::after, -.c2.tooltipped-multiline:active::after, -.c2.tooltipped-multiline:focus::after { +.c3.tooltipped-multiline:hover::after, +.c3.tooltipped-multiline:active::after, +.c3.tooltipped-multiline:focus::after { display: table-cell; } -.c2.tooltipped-s::after, -.c2.tooltipped-se::after, -.c2.tooltipped-sw::after { +.c3.tooltipped-s::after, +.c3.tooltipped-se::after, +.c3.tooltipped-sw::after { top: 100%; right: 50%; margin-top: 6px; } -.c2.tooltipped-s::before, -.c2.tooltipped-se::before, -.c2.tooltipped-sw::before { +.c3.tooltipped-s::before, +.c3.tooltipped-se::before, +.c3.tooltipped-sw::before { top: auto; right: 50%; bottom: -7px; @@ -1413,27 +1418,27 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-bottom-color: #24292f; } -.c2.tooltipped-se::after { +.c3.tooltipped-se::after { right: auto; left: 50%; margin-left: -16px; } -.c2.tooltipped-sw::after { +.c3.tooltipped-sw::after { margin-right: -16px; } -.c2.tooltipped-n::after, -.c2.tooltipped-ne::after, -.c2.tooltipped-nw::after { +.c3.tooltipped-n::after, +.c3.tooltipped-ne::after, +.c3.tooltipped-nw::after { right: 50%; bottom: 100%; margin-bottom: 6px; } -.c2.tooltipped-n::before, -.c2.tooltipped-ne::before, -.c2.tooltipped-nw::before { +.c3.tooltipped-n::before, +.c3.tooltipped-ne::before, +.c3.tooltipped-nw::before { top: -7px; right: 50%; bottom: auto; @@ -1441,24 +1446,24 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-top-color: #24292f; } -.c2.tooltipped-ne::after { +.c3.tooltipped-ne::after { right: auto; left: 50%; margin-left: -16px; } -.c2.tooltipped-nw::after { +.c3.tooltipped-nw::after { margin-right: -16px; } -.c2.tooltipped-s::after, -.c2.tooltipped-n::after { +.c3.tooltipped-s::after, +.c3.tooltipped-n::after { -webkit-transform: translateX(50%); -ms-transform: translateX(50%); transform: translateX(50%); } -.c2.tooltipped-w::after { +.c3.tooltipped-w::after { right: 100%; bottom: 50%; margin-right: 6px; @@ -1467,7 +1472,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` transform: translateY(50%); } -.c2.tooltipped-w::before { +.c3.tooltipped-w::before { top: 50%; bottom: 50%; left: -7px; @@ -1475,7 +1480,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-left-color: #24292f; } -.c2.tooltipped-e::after { +.c3.tooltipped-e::after { bottom: 50%; left: 100%; margin-left: 6px; @@ -1484,7 +1489,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` transform: translateY(50%); } -.c2.tooltipped-e::before { +.c3.tooltipped-e::before { top: 50%; right: -7px; bottom: 50%; @@ -1492,7 +1497,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-right-color: #24292f; } -.c2.tooltipped-multiline::after { +.c3.tooltipped-multiline::after { width: -webkit-max-content; width: -moz-max-content; width: max-content; @@ -1502,8 +1507,8 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-collapse: separate; } -.c2.tooltipped-multiline.tooltipped-s::after, -.c2.tooltipped-multiline.tooltipped-n::after { +.c3.tooltipped-multiline.tooltipped-s::after, +.c3.tooltipped-multiline.tooltipped-n::after { right: auto; left: 50%; -webkit-transform: translateX(-50%); @@ -1511,35 +1516,49 @@ exports[`TextInput renders trailingAction icon button 1`] = ` transform: translateX(-50%); } -.c2.tooltipped-multiline.tooltipped-w::after, -.c2.tooltipped-multiline.tooltipped-e::after { +.c3.tooltipped-multiline.tooltipped-w::after, +.c3.tooltipped-multiline.tooltipped-e::after { right: 100%; } -.c2.tooltipped-align-right-2::after { +.c3.tooltipped-align-right-2::after { right: 0; margin-right: 0; } -.c2.tooltipped-align-right-2::before { +.c3.tooltipped-align-right-2::before { right: 15px; } -.c2.tooltipped-align-left-2::after { +.c3.tooltipped-align-left-2::after { left: 0; margin-left: 0; } -.c2.tooltipped-align-left-2::before { +.c3.tooltipped-align-left-2::before { left: 10px; } @media (forced-colors:active) { - .c3:focus { + .c4:focus { outline: solid 1px transparent; } } +@media (pointer:coarse) { + .c4:after { + content: ""; + position: absolute; + left: 0; + right: 0; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + top: 50%; + min-height: 44px; + } +} + @media (min-width:768px) { .c0 { font-size: 14px; @@ -1562,21 +1581,21 @@ exports[`TextInput renders trailingAction icon button 1`] = ` type="text" />