ActivityFeed
عرض شاملimport { ActivityFeed, ActivityFeedFile, ActivityFeedFooter, ActivityFeedHeader, ActivityFeedItemType, ActivityFeedKey } from '@nili/ui';هذه صفحة العرض الشامل الخاصة بالمكتبة، معروضة حيّة. غيّر اللغة أو السمة من الأعلى وسَتتبعك.
أنواع العناصر
أربعة أنواع من الصفوف: نص عادي، وصفّ بإجراءات، وصفّ يحمل ملفًا، وصفّ يقتبس رسالة. ويحدّد النوع أي فتحة تُرسم، والفتحات خصائص لا أبناء كي لا يُركّب الصف بشكل خاطئ.
import { ActivityFeedItem, Avatar, Button } from "@nili/ui"
export function Example() {
return (
<>
<ActivityFeedItem
type="basic"
avatar={<Avatar size="sm" name="Ada Lovelace" tone="blue" />}
title="Ada Lovelace commented"
timestamp="8 min ago"
subject="Design system"
description="This looks good to me — shipping it."
/>
<ActivityFeedItem
type="button"
avatar={<Avatar size="sm" name="Grace Hopper" tone="purple" />}
title="Grace Hopper wants to join"
timestamp="1 h ago"
actions={
<>
<Button size="xs">Accept</Button>
<Button size="xs" appearance="stroke">Decline</Button>
</>
}
/>
<ActivityFeedItem
type="file"
title="Katherine shared a file"
file={{ name: "annual-report.pdf", size: "4mb", href: "#" }}
/>
<ActivityFeedItem
type="message"
title="Radia replied"
message="Can we move the review to Thursday?"
/>
</>
)
}الصفوف غير المقروءة والقابلة للاختيار
يحوّل onSelect العنوان إلى زر حقيقي يمتد على البطاقة — فيصير الصف قابلًا للنقر بينما تبقى الإجراءات والقائمة بداخله أزرارًا منفصلة قابلة للتركيز. أما صفّ يحمل onClick على الغلاف فيبتلعها كلها.
import { ActivityFeedItem } from "@nili/ui"
export function Example() {
return (
<>
<ActivityFeedItem
unread
onSelect={() => open(notification)}
title="Ada Lovelace mentioned you"
timestamp="8 min ago"
badge={<Badge size="small" color="blue" appearance="lighter">New</Badge>}
/>
<ActivityFeedItem
onSelect={() => open(notification)}
title="Already read"
timestamp="2 days ago"
/>
</>
)
}اللوحة كاملة
الترويسة وصفّ الألسنة والتذييل كلها فتحات في ActivityFeed. والألسنة أزرار عادية لا نسخة من Tabs — فهي ترشّح قائمة واحدة في مكانها بدل تبديل اللوحات، وتسميتها tablist كذبة على قارئ الشاشة.
الإشعارات
import {
ActivityFeed, ActivityFeedItem, ActivityFeedTab,
ActivityFeedTabSeparator, ActivityFeedFooter, LinkButton,
} from "@nili/ui"
export function Example() {
const [tab, setTab] = useState("all")
return (
<ActivityFeed
label="Notifications"
title="Notifications"
headerAction={<LinkButton color="primary" size="sm">Mark all as read</LinkButton>}
tabs={
<>
<ActivityFeedTab selected={tab === "all"} onClick={() => setTab("all")}>
All
</ActivityFeedTab>
<ActivityFeedTab
selected={tab === "unread"}
onClick={() => setTab("unread")}
count={3}
>
Unread
</ActivityFeedTab>
<ActivityFeedTabSeparator />
<ActivityFeedTab selected={tab === "mentions"} onClick={() => setTab("mentions")}>
Mentions
</ActivityFeedTab>
</>
}
footer={
<ActivityFeedFooter
hint={<><ActivityFeedKey>↑</ActivityFeedKey><ActivityFeedKey>↓</ActivityFeedKey> to navigate</>}
action={<LinkButton href="#" size="sm">See all activity</LinkButton>}
/>
}
>
…
</ActivityFeed>
)
}ActivityFeed
extends Omit< ComponentPropsWithoutRef<'section'>, 'title' >
باقي الخصائص
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| title | ReactNode | — | Figma Header title, e.g. "Notifications". |
| headerAction | ReactNode | — | End of the header, e.g. `<LinkButton color="primary">Mark all as read</LinkButton>`. |
| tabs | ReactNode | — | `<ActivityFeedTab>` children (and `<ActivityFeedTabSeparator>`). |
| tabsAction | ReactNode | — | End of the tab row, e.g. a filter `<CompactButton appearance="ghost">`. |
| footer | ReactNode | — | Figma Footer content — see `<ActivityFeedFooter>`. |
| label | string | — |
ActivityFeedChip
داخليمحاور التنويع — من تعريف cva للمكوّن
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| kind | file | message | file |
ActivityFeedCount
داخليActivityFeedFooter
ActivityFeedHeader
ActivityFeedItem
extends Omit< ComponentPropsWithoutRef<'li'>, 'title' | 'children' >
محاور التنويع — من تعريف cva للمكوّن
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| unread | boolean | false |
باقي الخصائص
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| type | basic | button | file | message | basic | Figma Type: Basic · Button · File · Message. |
| avatar | ReactNode | — | Usually a 40px `<Avatar size="sm">`. |
| title* | ReactNode | — | |
| timestamp | ReactNode | — | Pre-formatted time, e.g. "8 min ago". First part of the meta line. |
| subject | ReactNode | — | Figma "Insert subject here." — second part of the meta line. |
| subjectIcon | ReactNode | — | 16px glyph before `subject` (an app or workspace logo). |
| badge | ReactNode | — | Sits beside the title, e.g. a status or a count. |
| description | ReactNode | — | Body text — Figma Type Basic. |
| actions | ReactNode | — | Figma Type Button: the actions row, usually two `size="xs"` Buttons. |
| file | ActivityFeedFile | — | Figma Type File: the attachment chip. |
| message | ReactNode | — | Figma Type Message: the boxed message text. |
| menu | ReactNode | — | The "more" control Figma reveals on hover — pass a ghost icon Button or a Dropdown trigger. Shown on hover and keyboard focus, and always on touch screens. |
| onSelect | () => void | — | Makes the whole card selectable. The title becomes a real button that stretches over the card, so actions and the menu inside stay separate, valid, focusable buttons. |
ActivityFeedKey
ActivityFeedTab
extends ComponentPropsWithoutRef<'button'>
محاور التنويع — من تعريف cva للمكوّن
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| selected | boolean | false |
باقي الخصائص
| الخاصيّة | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
| children | ReactNode | — | |
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| aria-label | string | — | |
| count | ReactNode | — | Figma's red count after the label. |
| badge | ReactNode | — | Any other node after the label — e.g. a `<Badge>`. |