mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
fix(mobile): the trip rail's More wears the dock's ring while its sheet is open
This commit is contained in:
@@ -97,6 +97,11 @@ export function MRailSpacer() {
|
||||
interface MRailButtonProps {
|
||||
label: string;
|
||||
active: boolean;
|
||||
/**
|
||||
* Opens a sheet rather than a section (More): while that sheet is open the button wears
|
||||
* the ring the phone dock's More wears, so the rail says where the sheet came from.
|
||||
*/
|
||||
expanded?: boolean;
|
||||
onClick: () => void;
|
||||
/** The icon, drawn at 20px. */
|
||||
children: ReactNode;
|
||||
@@ -108,19 +113,24 @@ interface MRailButtonProps {
|
||||
* and never shrunk: it wraps into a second, balanced line where its language
|
||||
* needs one, and only a word longer than the rail is hyphenated.
|
||||
*/
|
||||
export function MRailButton({ label, active, onClick, children }: MRailButtonProps) {
|
||||
export function MRailButton({ label, active, expanded, onClick, children }: MRailButtonProps) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
title={label}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
aria-expanded={expanded}
|
||||
className="group flex w-full flex-none flex-col items-center gap-[3px] rounded-[18px] py-[5px] outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--m-act)]"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={`flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-150 ${
|
||||
active ? 'bg-m-act text-m-actfg' : 'text-m-muted group-hover:bg-[color:var(--m-ic)] group-hover:text-m-ink'
|
||||
active
|
||||
? 'bg-m-act text-m-actfg'
|
||||
: expanded
|
||||
? 'bg-[color:var(--m-ic)] text-m-ink ring-[1.5px] ring-inset ring-[color:var(--m-act)]'
|
||||
: 'text-m-muted group-hover:bg-[color:var(--m-ic)] group-hover:text-m-ink'
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -16,6 +16,8 @@ interface MTripRailProps {
|
||||
onSelect: (id: string) => void;
|
||||
/** Opens the More sheet: trip settings, export, the assistant. */
|
||||
onMore: () => void;
|
||||
/** Whether the More sheet is open, which the More button shows with a ring. */
|
||||
moreOpen?: boolean;
|
||||
labelOf: (id: string) => string;
|
||||
}
|
||||
|
||||
@@ -27,7 +29,7 @@ const DOCK_ICONS = new Map(DOCK_PRIORITY.map((tab) => [tab.id, tab.icon]));
|
||||
* collaboration and plugin pages sit in it too, each with its name, and More
|
||||
* keeps only the trip's actions.
|
||||
*/
|
||||
export default function MTripRail({ tabs, active, onSelect, onMore, labelOf }: MTripRailProps) {
|
||||
export default function MTripRail({ tabs, active, onSelect, onMore, moreOpen = false, labelOf }: MTripRailProps) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<MRail label={t('mobileTrip.sections')}>
|
||||
@@ -41,7 +43,7 @@ export default function MTripRail({ tabs, active, onSelect, onMore, labelOf }: M
|
||||
);
|
||||
})}
|
||||
<MRailSpacer />
|
||||
<MRailButton label={t('mobileTrip.more')} active={false} onClick={onMore}>
|
||||
<MRailButton label={t('mobileTrip.more')} active={false} expanded={moreOpen} onClick={onMore}>
|
||||
<MoreHorizontal size={20} strokeWidth={2.2} />
|
||||
</MRailButton>
|
||||
</MRail>
|
||||
|
||||
@@ -901,6 +901,7 @@ export default function MTripShell({
|
||||
active={trTab}
|
||||
onSelect={setTrTab}
|
||||
onMore={() => openSheet('mehr')}
|
||||
moreOpen={sheet?.id === 'mehr'}
|
||||
labelOf={tabLabel}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -190,6 +190,24 @@ describe('MTripRail', () => {
|
||||
fireEvent.click(within(nav).getByRole('button', { name: 'More' }));
|
||||
expect(onMore).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('FE-MOB-RAIL-014: More wears a ring while its sheet is open, and says it is expanded', () => {
|
||||
const props = {
|
||||
tabs,
|
||||
active: 'plan',
|
||||
onSelect: vi.fn(),
|
||||
onMore: vi.fn(),
|
||||
labelOf: (id: string) => tabs.find((x) => x.id === id)?.label ?? id,
|
||||
};
|
||||
const { rerender } = render(<MTripRail {...props} />);
|
||||
const more = () => screen.getByRole('button', { name: 'More' });
|
||||
expect(more()).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(more().firstElementChild?.className).not.toContain('ring-');
|
||||
rerender(<MTripRail {...props} moreOpen />);
|
||||
expect(more()).toHaveAttribute('aria-expanded', 'true');
|
||||
expect(more().firstElementChild?.className).toContain('ring-[color:var(--m-act)]');
|
||||
expect(more()).not.toHaveAttribute('aria-current');
|
||||
});
|
||||
});
|
||||
|
||||
describe('MobileShell on a wide window', () => {
|
||||
|
||||
Reference in New Issue
Block a user