Feat: Prepare frontend future model

This commit is contained in:
MangoPig
2026-06-18 16:58:31 +01:00
parent fcf96590bb
commit 25c6934801
13 changed files with 342 additions and 146 deletions

View File

@@ -27,9 +27,11 @@ export const NotificationsMenu = (props: NotificationsMenuProps): JSX.Element =>
role="menu"
aria-label="Notifications"
ref={props.menuRef}
data-ui="notifications-menu"
data-variant={variant}
>
<div class={styles.header}>
<div class={styles.headerCopy}>
<div class={styles.header} data-slot="notifications-header">
<div class={styles.headerCopy} data-slot="notifications-header-copy">
<strong class={styles.title}>Notifications</strong>
<span class={styles.subtitle}>
{unreadNotificationCount > 0
@@ -45,7 +47,7 @@ export const NotificationsMenu = (props: NotificationsMenuProps): JSX.Element =>
</Show>
</div>
<div class={styles.listWrap}>
<div class={styles.listWrap} data-slot="notifications-body">
<Show when={!hasNotifications}>
<div class={styles.stateCard}>
<span class={styles.stateIcon} aria-hidden="true">
@@ -67,12 +69,12 @@ export const NotificationsMenu = (props: NotificationsMenuProps): JSX.Element =>
</Show>
<Show when={unreadItems.length > 0}>
<section class={styles.section} aria-label="Unread notifications">
<section class={styles.section} aria-label="Unread notifications" data-slot="notifications-section" data-section-id="unread">
<span class={styles.sectionLabel}>Unread</span>
<div class={styles.list}>
<div class={styles.list} data-slot="notifications-list" data-section-id="unread">
<For each={unreadItems}>
{(item): JSX.Element => (
<button type="button" role="menuitem" classList={{ [styles.item]: true, [styles.itemUnread]: true }} onClick={props.onSelect}>
<button type="button" role="menuitem" classList={{ [styles.item]: true, [styles.itemUnread]: true }} data-slot="notification-item" data-state="unread" onClick={props.onSelect}>
<span class={styles.itemMarker} aria-hidden="true" />
<div class={styles.itemBody}>
<span class={styles.itemTitle}>{item.title}</span>
@@ -87,12 +89,12 @@ export const NotificationsMenu = (props: NotificationsMenuProps): JSX.Element =>
</Show>
<Show when={earlierItems.length > 0}>
<section class={styles.section} aria-label="Earlier notifications">
<section class={styles.section} aria-label="Earlier notifications" data-slot="notifications-section" data-section-id="earlier">
<span class={styles.sectionLabel}>Earlier</span>
<div class={styles.list}>
<div class={styles.list} data-slot="notifications-list" data-section-id="earlier">
<For each={earlierItems}>
{(item): JSX.Element => (
<button type="button" role="menuitem" class={styles.item} onClick={props.onSelect}>
<button type="button" role="menuitem" class={styles.item} data-slot="notification-item" data-state="read" onClick={props.onSelect}>
<span class={styles.itemMarkerMuted} aria-hidden="true" />
<div class={styles.itemBody}>
<span class={styles.itemTitle}>{item.title}</span>
@@ -107,7 +109,7 @@ export const NotificationsMenu = (props: NotificationsMenuProps): JSX.Element =>
</Show>
</div>
<div class={styles.footer}>
<div class={styles.footer} data-slot="notifications-footer">
<button type="button" role="menuitem" class={styles.footerAction} onClick={props.onSelect}>
<Settings size={16} strokeWidth={2} />
<span>Notification settings</span>

View File

@@ -23,8 +23,10 @@ export const ProfileMenu = (props: ProfileMenuProps): JSX.Element => {
role="menu"
aria-label="Profile menu"
ref={props.menuRef}
data-ui="profile-menu"
data-variant={variant}
>
<div class={styles.summary}>
<div class={styles.summary} data-slot="profile-summary">
<div class={styles.avatar} aria-hidden="true">
<span class={styles.avatarRing} />
<span class={styles.avatarCore}>
@@ -40,10 +42,10 @@ export const ProfileMenu = (props: ProfileMenuProps): JSX.Element => {
</div>
</div>
<div class={styles.sections}>
<div class={styles.sections} data-slot="profile-sections">
<For each={profileMenuSections}>
{(section): JSX.Element => (
<div class={styles.section}>
<div class={styles.section} data-slot="profile-section" data-section-id={section.id}>
<For each={section.items}>
{(item): JSX.Element => {
const Icon = item.icon;
@@ -52,11 +54,14 @@ export const ProfileMenu = (props: ProfileMenuProps): JSX.Element => {
<button
type="button"
role="menuitem"
classList={{
[styles.item]: true,
[styles.itemDanger]: item.tone === "danger",
}}
onClick={props.onSelect}
classList={{
[styles.item]: true,
[styles.itemDanger]: item.tone === "danger",
}}
data-slot="profile-action"
data-action-id={item.id}
data-tone={item.tone ?? "default"}
onClick={props.onSelect}
>
<span class={styles.itemIcon} aria-hidden="true">
<Icon size={16} strokeWidth={2} />

View File

@@ -21,20 +21,20 @@ type TopBarProps = {
export const TopBar = (props: TopBarProps): JSX.Element => {
return (
<header class={styles.topBar}>
<div class={styles.identity}>
<header class={styles.topBar} data-ui="top-bar">
<div class={styles.identity} data-slot="top-bar-identity">
<span class={styles.eyebrow}>Moku Work</span>
<DepartmentSelector />
</div>
<div class={styles.controls}>
<div class={styles.actions}>
<div class={styles.controls} data-slot="top-bar-controls">
<div class={styles.actions} data-slot="top-bar-actions">
<For each={topBarActions}>
{(item): JSX.Element => {
const Icon = item.icon;
return (
<button class={styles.actionButton} type="button" aria-label={item.label} title={item.label}>
<button class={styles.actionButton} type="button" aria-label={item.label} title={item.label} data-slot="top-bar-action" data-action-id={item.id}>
<Icon size={18} strokeWidth={2} />
</button>
);