feat(a11y/ui): profile-bio auto-collapse, mobile bottom-sheet with drag-to-dismiss (#315/#314)#325
Merged
Chucks1093 merged 1 commit intoMay 28, 2026
Conversation
…with drag-to-dismiss Closes accesslayerorg#315, accesslayerorg#314. - accesslayerorg#315 CreatorBio: gains collapsible + collapsedMaxLines + collapseThresholdChars props. When enabled on the profile variant and the bio is long enough (default >200 chars), the paragraph renders clamped with a focusable Show more / Show less toggle that carries aria-expanded + aria-controls so screen readers know the bio's collapsed state. Short bios are unaffected (no toggle, no clamp). The card variant ignores collapsible since it already clamps via maxLines. Wired into CreatorProfileHeader where the profile bio actually renders. - accesslayerorg#314 BottomSheet: new mobile-first primitive built on Radix Dialog for the focus trap / role / Escape handling. Adds drag-to-dismiss via native pointer events: * The visual handle (BottomSheetHandle) registers itself with the sheet's content surface so a gesture that starts on the handle is always treated as 'grabbing the sheet'. * Otherwise the gesture is captured only when no inner scroller is engaged (walks up from the target, bails if any ancestor has scrollTop>0) — so a downward swipe on scrollable content scrolls instead of dismissing. * Dragging past dismissThresholdPx (default 96) dismisses by dispatching Escape so Radix's onOpenChange(false) pipeline runs. * Short / upward drags snap back via a brief transform reset. * The default close button always works as an alternative; pass enableDrag=false to make it the only path. Tests (12 new, all passing): - src/components/common/__tests__/CreatorBio.test.tsx (6 new cases): no toggle for short bio, no engagement on card variant, clamps + Show more wiring, toggles to Show less + removes clamp, custom collapseThresholdChars, custom collapsedMaxLines. - src/components/ui/bottom-sheet.test.tsx (6 cases): render + handle + close button, close-button dismissal, drag past threshold dismisses, short drag does not, upward drag clamps + never dismisses, enableDrag=false leaves close button as only path. Repo verification: - pnpm test 129/130 (1 pre-existing CreatorInitialsAvatar failure, same one disclosed in accesslayerorg#310 / accesslayerorg#311 / accesslayerorg#324). - pnpm lint clean - pnpm build clean Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@DeJune06 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR closes #315 and #314 — two related profile/mobile UX issues in the creator marketplace.
closes #315
closes #314
What's in this PR
#315 — Auto-collapse + expand toggle for the creator profile bio
CreatorBiogains three opt-in props:collapsible: boolean— turns the feature on. Only meaningful for theprofilevariant; thecardvariant ignores it (the card already clamps viamaxLines).collapsedMaxLines: number(default4) — line count in the collapsed state.collapseThresholdChars: number(default200) — character-count threshold above which the toggle appears. Short bios are unaffected (no toggle, no clamp).<button>("Show more" / "Show less") that carriesaria-expandedandaria-controls={bio paragraph id}so screen readers communicate the collapsed/expanded state and link the toggle to the content it controls.CreatorProfileHeaderwhere the profile bio is actually rendered.#314 — Drag-to-dismiss bottom sheet primitive
src/components/ui/bottom-sheet.tsxexportingBottomSheet,BottomSheetContent,BottomSheetHandle,BottomSheetClose,BottomSheetTitle,BottomSheetDescription.@radix-ui/react-dialogto inherit the focus trap,role="dialog", Escape handling, and Portal/overlay layering the rest of the app already relies on.dismissThresholdPx(default96px) dismisses the sheet by dispatching Escape, so Radix'sonOpenChange(false)pipeline runs and the rest of the app's cleanup behaves identically to keyboard dismissal.<BottomSheetHandle />) registers itself with the content surface so a gesture starting on the handle is always captured.scrollTop > 0, the gesture is left to that scroller (no accidental "trying to scroll up = dismiss the sheet" misfire).enableDrag={false}disables the gesture entirely, leaving the close button as the only dismissal path.hideCloseButton={false}) always works — that's the primary accessible dismissal affordance for keyboard / screen-reader users.Tests
12 new vitest cases, all passing:
src/components/common/__tests__/CreatorBio.test.tsx(6 added in the#315describe block): no toggle for short bio, no engagement on the card variant, clamp + toggle wiring (aria-expanded/aria-controls), toggle to "Show less" + clamp removal on expand, customcollapseThresholdChars, customcollapsedMaxLines.src/components/ui/bottom-sheet.test.tsx(6 cases): render (handle + close button + title), close-button dismissal, drag past threshold dismisses, short drag does not, upward drag clamps and never dismisses,enableDrag={false}leaves close button as only path.Disclosures
src/components/common/__tests__/CreatorInitialsAvatar.test.tsxfails onmain— same pre-existing failure disclosed in PRs feat(a11y/ui): main landmark, price-refresh state, no-script fallback, handle norm (#306/#305/#299/#298) #310 (kalveen), feat(a11y/ui): profile header skeleton, accessible metric tooltips, bio clamp, onboarding placeholders (#291/#290/#282/#273) #311 (precious), and feat(a11y/ux): high-contrast overlay tokens, stale-data warning, staggered card entry (#313/#301/#300) #324 (mawuli). The test queriesgetByLabelText('Alex Rivers initials avatar'), but the component renders the initials witharia-hidden="true"(no matchingaria-label). Not touched here.BottomSheetyet. The repo's existing mobile dismissal flows go through RadixDialogdirectly; the issue's wording ("identify the bottom sheet panel components used on mobile") doesn't match any existing component. Rather than re-skin an unrelatedTradeDialoginto a bottom sheet, this PR ships the primitive + tests so a follow-up can adopt it as the platform pattern. The tests exercise the gesture surface end-to-end, so the primitive is verified independently of any consumer.