Skip to content

Commit 58ec871

Browse files
arraypressclaude
andcommitted
Gallery: keyboard-only handle, a drawn cross
The tile already drags from any part of it, so the handle is for the arrow keys alone and is clipped away until it is tabbed to. The remove control is a small translucent dark disc with a drawn cross, red under the pointer, instead of a white square around a font glyph. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Kwx2STJ4EaVaJofEJJ9Zo
1 parent fdef944 commit 58ec871

2 files changed

Lines changed: 67 additions & 48 deletions

File tree

‎assets/css/field-kit.css‎

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -669,26 +669,32 @@ input[type="checkbox"].field-kit__toggle:focus-visible {
669669
display: contents;
670670
}
671671

672-
/* Controls stay out of the way until the tile is hovered or something
673-
inside it takes focus.
674-
*
675-
* :focus-within is what keeps this usable. Dragging cannot be done from a
676-
* keyboard at all, so the move buttons are the only way to reorder without
677-
* a mouse — hiding them on hover alone would make the gallery unorderable
678-
* for anyone tabbing through it, while looking perfectly fine to everyone
679-
* else.
680-
*
681-
* Its size and corners come from the button-link reset further down, which
682-
* is later in the sheet and wins: the 1.5rem circle once declared here was
683-
* never what rendered. */
672+
/* The cross: a small dark disc in the corner that shows when the tile is
673+
hovered or something inside it takes focus, and turns red under the
674+
pointer. Dark over the picture rather than white, because a white disc
675+
vanished on a light photo and sat like a sticker on a dark one; a
676+
translucent dark one reads on both. :focus-within is what keeps it
677+
usable from a keyboard, where there is no hover to reveal it.
678+
Everything about it is here, so nothing later in the sheet resizes it. */
684679
.wp-core-ui .field-kit__gallery-remove {
685680
position: absolute;
686-
top: .2rem;
687-
inset-inline-end: .2rem;
688-
background: rgba(255, 255, 255, .92);
689-
color: #b32d2e;
681+
top: .375rem;
682+
inset-inline-end: .375rem;
683+
z-index: 1;
684+
display: inline-flex;
685+
align-items: center;
686+
justify-content: center;
687+
width: 1.5rem;
688+
height: 1.5rem;
689+
padding: 0;
690+
border: 0;
691+
border-radius: 50%;
692+
background: rgba(29, 35, 39, .7);
693+
color: #fff;
694+
box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
695+
text-decoration: none;
690696
opacity: 0;
691-
transition: opacity .1s ease-in-out;
697+
transition: opacity .12s ease-in-out, background-color .12s ease-in-out;
692698
}
693699

694700
.field-kit__gallery-item:hover .field-kit__gallery-remove,
@@ -699,30 +705,30 @@ input[type="checkbox"].field-kit__toggle:focus-visible {
699705

700706
.wp-core-ui .field-kit__gallery-remove:hover,
701707
.wp-core-ui .field-kit__gallery-remove:focus {
702-
background: #b32d2e;
708+
background: #d63638;
703709
color: #fff;
710+
text-decoration: none;
704711
}
705712

706-
/* The cross is a small white disc in the corner, which is what a cross
707-
for removing a picture looks like everywhere else in the admin. */
708-
.wp-core-ui .field-kit__gallery-remove {
709-
width: 1.5rem;
710-
height: 1.5rem;
711-
border-radius: 50%;
712-
box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
713+
.wp-core-ui .field-kit__gallery-remove:focus-visible {
714+
outline: 2px solid #fff;
715+
outline-offset: 1px;
716+
box-shadow: 0 0 0 4px rgba(29, 35, 39, .5);
717+
}
718+
719+
.field-kit__gallery-remove svg {
720+
display: block;
713721
}
714722

715723
/* Nothing may be revealed by hover alone where hovering is not possible. */
716724
@media (hover: none) {
717-
.wp-core-ui .field-kit__gallery-remove,
718-
.field-kit__gallery-item .field-kit__gallery-handle {
725+
.wp-core-ui .field-kit__gallery-remove {
719726
opacity: 1;
720727
}
721728
}
722729

723730
@media (prefers-reduced-motion: reduce) {
724-
.wp-core-ui .field-kit__gallery-remove,
725-
.field-kit__gallery-item .field-kit__gallery-handle {
731+
.wp-core-ui .field-kit__gallery-remove {
726732
transition: none;
727733
}
728734
}
@@ -1836,7 +1842,6 @@ li.field-kit__repeater-row {
18361842
/* Core defines .wp-core-ui .button-link at specificity 0,2,0 and underlines
18371843
it, so a bare class here loses and every chevron carries a line under it.
18381844
Matching the prefix is what makes these win. */
1839-
.wp-core-ui .field-kit__gallery-remove,
18401845
.wp-core-ui .field-kit__repeater-remove,
18411846
.wp-core-ui .field-kit__sortable-move {
18421847
display: inline-flex;
@@ -1875,7 +1880,6 @@ li.field-kit__repeater-row {
18751880
/* The dashicon is the button's whole content, so it should not carry the
18761881
line-height of surrounding text. */
18771882
.field-kit__sortable-move .dashicons,
1878-
.field-kit__gallery-remove .dashicons,
18791883
.field-kit__repeater-remove .dashicons {
18801884
width: 1rem;
18811885
height: 1rem;
@@ -3587,32 +3591,43 @@ li.field-kit__repeater-row--collapsible.is-closed .field-kit__repeater-toggle .t
35873591
color: #646970;
35883592
}
35893593

3590-
/* On a tile the handle sits over the image; in a row it sits beside the name.
3591-
Either way it is the thing you grab, so the item itself stops claiming to
3592-
be. */
3594+
/* A tile is dragged by any part of it, so the handle is for the keyboard
3595+
alone: the button that takes the arrow keys. Nobody with a pointer needs
3596+
to see it, so it is clipped away the way core hides screen-reader text
3597+
and comes back only when it is tabbed to -- over the picture on a tile,
3598+
beside the name in a row. */
35933599
.field-kit__gallery-item .field-kit__gallery-handle {
35943600
position: absolute;
3595-
top: .25rem;
3596-
inset-inline-start: .25rem;
3601+
top: .375rem;
3602+
inset-inline-start: .375rem;
35973603
z-index: 1;
3604+
width: 1px;
3605+
height: 1px;
3606+
margin: -1px;
3607+
padding: 0;
3608+
overflow: hidden;
3609+
clip: rect( 1px, 1px, 1px, 1px );
3610+
clip-path: inset( 50% );
3611+
border: 0;
35983612
border-radius: 2px;
3599-
background: rgba( 255, 255, 255, .85 );
3600-
opacity: 0;
3601-
transition: opacity .1s ease-in-out;
3613+
background: rgba( 255, 255, 255, .92 );
3614+
box-shadow: 0 1px 2px rgba( 0, 0, 0, .25 );
36023615
}
36033616

3604-
/* A tile is dragged by any part of it, so the handle is for the keyboard:
3605-
it appears with the cross, on hover or when something in the tile has
3606-
focus, and stays out of the picture the rest of the time. */
3607-
.field-kit__gallery-item:hover .field-kit__gallery-handle,
3608-
.field-kit__gallery-item:focus-within .field-kit__gallery-handle,
36093617
.field-kit__gallery-item .field-kit__gallery-handle:focus-visible {
3610-
opacity: 1;
3618+
width: auto;
3619+
height: auto;
3620+
margin: 0;
3621+
overflow: visible;
3622+
clip: auto;
3623+
clip-path: none;
36113624
}
36123625

36133626
.field-kit__gallery-item--file .field-kit__gallery-handle {
3614-
position: static;
3615-
background: none;
3627+
position: absolute;
3628+
inset-inline-start: .25rem;
3629+
top: 50%;
3630+
transform: translateY( -50% );
36163631
}
36173632

36183633
.field-kit__gallery-items:has( .field-kit__gallery-item--file ) {

‎src/Types/GalleryType.php‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,12 @@ private function remove_button( string $name ): string {
366366
/* translators: %s: item name */
367367
$button->set( 'aria-label', sprintf( __( 'Remove %s', 'arraypress' ), $name ) );
368368

369+
// A drawn cross rather than the dashicon: the font glyph is cut for
370+
// 20px and blurs at the size a corner control is, and the stroke is
371+
// the same weight at any size.
369372
return sprintf(
370-
'<button%s><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button>',
373+
'<button%s><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true" focusable="false">' .
374+
'<path d="M2.5 2.5l7 7M9.5 2.5l-7 7" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" /></svg></button>',
371375
$button->render()
372376
);
373377
}

0 commit comments

Comments
 (0)