wayBetter for X

This commit is contained in:
CRTkafa 2026-10-01 06:01:13 +07:00
commit df5dff619e
720 changed files with 147465 additions and 0 deletions

View file

@ -0,0 +1,73 @@
// The parts of X a Profile+ feature reads, shaped like X's own markup (the same nesting and test
// ids as scripts/visual-bugs/x-fixture.mjs; class names left out): a profile header, a post in a
// timeline, an opened post, a quoted post, a hover card and a profile's ··· menu. Invented
// accounts only. Not a live X test.
import { h, t, type El } from './miniDom.ts';
export type Account = { name: string; handle: string; bio?: string; joined?: string };
const words = (value: string) => h('div', { dir: 'ltr' }, h('span', null, value));
const nameText = (name: string) => h('div', { dir: 'ltr' }, h('span', null, h('span', null, name)));
/** `<div data-testid="primaryColumn">` with a profile header: name row, handle row, bio, "Joined …", the ··· button. */
export function profile({ name, handle, bio = 'Invented bio.', joined = 'Joined June 2015' }: Account): El {
return t('primaryColumn',
h('div', null,
h('button', { 'data-testid': 'userActions', 'aria-label': 'More' }),
h('div', null,
t('UserName', h('div', null, h('div', null,
h('div', { class: 'name-row' }, nameText(name)),
h('div', { class: 'handle-row' }, h('div', null, words(`@${handle}`)), t('userFollowIndicator', h('span', null, 'Follows you'))),
))),
bio ? t('UserDescription', h('span', null, bio)) : null,
t('UserProfileHeader_Items', joined ? h('span', { 'data-testid': 'UserJoinDate' }, h('span', null, joined)) : null),
),
),
);
}
/** A post's name block in a timeline: the name and the "@handle · time" in one row. */
export function userName({ name, handle }: Account): El {
return t('User-Name',
h('div', { class: 'name-row' }, h('div', null, h('a', { href: `/${handle}`, role: 'link' }, h('div', null, nameText(name))))),
h('div', { class: 'handle-row' }, h('div', null,
h('div', null, h('a', { href: `/${handle}`, role: 'link', tabindex: '-1' }, words(`@${handle}`))),
h('div', { dir: 'ltr', 'aria-hidden': 'true' }, h('span', null, '·')),
h('div', null, h('a', { href: `/${handle}/status/1` }, h('time', { datetime: '2026-09-28T10:00:00.000Z' }, '2h'))),
)),
);
}
export function post(account: Account, body = 'Invented post.', quoted?: Account): El {
return t('cellInnerDiv', h('article', { 'data-testid': 'tweet', role: 'article' },
userName(account),
t('tweetText', h('span', null, body)),
quoted ? h('div', { role: 'link', tabindex: '0' },
// A quoted post names its author without links.
t('User-Name', h('div', { class: 'name-row' }, nameText(quoted.name)), h('div', { class: 'handle-row' }, h('div', null, h('div', null, words(`@${quoted.handle}`))))),
) : null,
));
}
/** X's hover card as it is in `#layers`: avatar, name link, handle link, bio, counts. */
export function hoverCard({ name, handle, bio = 'Invented bio.' }: Account): El {
return t('hoverCardParent', t('HoverCard',
t(`UserAvatar-Container-${handle}`),
h('div', null,
h('div', { class: 'name-row' }, h('a', { href: `/${handle}`, role: 'link' }, h('div', null, nameText(name)))),
h('div', { class: 'handle-row' }, h('a', { href: `/${handle}`, role: 'link', tabindex: '-1' }, words(`@${handle}`))),
),
bio ? t('UserDescription', h('span', null, bio)) : null,
h('div', null, h('a', { href: `/${handle}/following` }, h('span', null, '30'), h('span', null, ' Following'))),
));
}
/** The menu X opens for a profile's ··· button. */
export function profileMenu(handle: string): El[] {
return [
t('mask'),
h('div', { role: 'menu' }, h('div', { role: 'menuitem', 'data-testid': 'block', tabindex: '0' },
h('svg', null, h('path', { d: 'M0 0' }), h('path', { d: 'M1 1' })), h('div', null, h('span', null, `Block @${handle}`)))),
];
}