feat(card): add gallery layout and media overlay slot to swc-card - #6536
Conversation
|
| @@ -10,11 +10,9 @@ | |||
| * governing permissions and limitations under the License. | |||
| */ | |||
There was a problem hiding this comment.
See the PR description for the explanation on this temp fix until #6522 merges
|
|
||
| :host { | ||
| display: inline-block; | ||
| display: inline-flex; |
There was a problem hiding this comment.
Correctly collapse space around the avatar
📚 Branch Preview Links🔍 Gen1 Visual Regression Test ResultsWhen a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
Deployed to Azure Blob Storage: If the changes are expected, update the |
cdransf
left a comment
There was a problem hiding this comment.
This looks awesome! Just a tiny test question ✨
| grid-template-rows: repeat(2, auto); | ||
| } | ||
|
|
||
| ::slotted([slot="media"]) { |
There was a problem hiding this comment.
Should this be shared in card-template? User card could also this
There was a problem hiding this comment.
user card and product card's preview area default aspect-ratio is very short so I was hesitant to have this be shared quite yet
| --_swc-card-collection-columns: repeat(3, 1fr); | ||
| } | ||
|
|
||
| .swc-Card-media { |
There was a problem hiding this comment.
When selectable state swc-Card-media has a visible focus outline. Does it need this?
There was a problem hiding this comment.
Yes, that is expected per the Figma and it receives the outline since tabindex="0" is also added to the card to make it a tab stop.
Description
Adds the gallery layout to
swc-card— the last of the threeswc-cardlayouts (regular/collection/gallery) called out in the card family plan — plus a newmediaoverlay slot that lets consumers layer additional content (ex. badge, avatar) over the preview/collection region.title/description/actions/footer/default-slot content, regardless of whetherprevieworcollectionis populated — the image/asset becomes the card's only content and fills the available space. Implemented via a--_swc-card-media-layout: gallerycustom property (set by a:host(:not(:has(...)))selector) read through@container style(--_swc-card-media-layout: gallery), with a companion--_swc-card-media-containsproperty gating the preview-only aspect-ratio override so it doesn't apply whencollectionslots are also filled and visible.mediaslot: opt-in per component via a newrenderMediacallback onrenderCardTemplate()(mirroring the existingrenderCollection/renderGlyphpattern), wired up inswc-card'sCard.ts. The slotted content sharesgrid-area: mediawith.swc-CardBase-mediain the sharedcard-template.css, so it visually overlays the preview/collection region via normal DOM stacking order — noz-indexneeded. This resolves the card family plan's previously-open Q2 (gallery badge/avatar decoration) with a purpose-built slot instead of the originally-sketchedactions-slot reuse.TEMP:
ObserveSlotTextmixin fix (2nd-gen/packages/core/mixins/observe-slot-text.ts)Building the gallery trigger condition requires
CardBaseto correctly detect default-slot content, which surfaced two real, previously-uncaught bugs in this shared mixin (also used byButtonBaseforhasLabelandBadge.tsfor its no-label class):MutationControllerconfig only watchedcharacterData, notchildList— adding/removing an entire slotted node went undetected.@queryAssignedNodes-decorated field didn't resolve against the mixin's computed (Symbol-keyed) private field, always returningundefined— silently no-oping the entire reactive re-check path for every consumer of this mixin, not just Card.Both are fixed here (config now includes
childList: true; the decorated field is replaced with a plain method that queriesrenderRootdirectly). Regression tests added for bothCard(DefaultSlotClassUpdatesDynamicallyTest) andButton(LabelSlotUpdatesDynamicallyTest), since no existing test exercised the dynamic add/remove path before now.Motivation and context
Gallery was deliberately deferred to its own follow-up ticket so it didn't block the collection-slot work (SWC-2362) landing separately — see the card family plan's Scope and Component checklist. The
mediaslot wasn't originally scoped as its own deliverable, but fell out naturally while implementing gallery: the plan's Q2 ("gallery badge/avatar viaactions-slot reuse") needed resolving, and a dedicated overlay slot proved simpler and more flexible than the originally-sketchedactions-slot reuse.Related issue(s)
Screenshots (if appropriate)
See the
Gallerystory in Storybook: preview-only, collection-only, and a badge/avatarmedia-overlay variant)Manual review test cases
Gallery layout renders correctly with only
previewpopulatedGallery layout renders correctly with both
previewandcollectionpopulatedmediaoverlay slot positions independently of the underlying imageObserveSlotTextdynamic add/remove fix doesn't regressButton/BadgeDevice review
Accessibility testing checklist
Keyboard (required — document steps below)
selectablegallery-layout card (combine with theSelectablestory's args).swc-CardBase-mediain gallery mode) to render correctly around the image, with no change to tab order versus non-gallery cardsScreen reader (required — document steps below)
media-slottedswc-badge/swc-avatarmediaslot itself; a gallery card with no title/description is expected to have no accessible name from Card (consumer-owned viaaria-labelif needed, out of scope for this PR)