Pular para o conteúdo

Hooks

Every surface in Real Life Stack asks hooks, never the connector. This page lists all 62 hooks the toolkit exports, with the question each answers and what happens when the connector lacks the capability. It is generated from each hook's documentation comment, the same file that feeds Storybook and llms.txt.

The column "without capability" is the important one. Reading hooks answer empty: "no groups", "nobody signed in", "zero comments" are true answers, not errors. Writing hooks fail on the call, not on preparation. Where it says "throws on render", the surface cannot exist without that capability.

  • — the hook needs no capability
  • empty an empty list or count, never an error
  • null null, the caller decides
  • value a neutral value (a default, the raw id)
  • no-op the call does nothing
  • throws on call the surface renders, the action fails
  • throws on render the surface cannot exist without the capability

Read items 7

useSurfaceItems() → Item[]

The items of this surface, filtered as its head shows.

without capability: throws on render, without ModuleSurfaceScopesourcestoryspec
useActivity(limit?) → {data, supported}

What happened in this space recently?

without capability: empty, supported: falsesourcestoryspec
useDraftItem() → Item | null

What is someone typing right now that modules should preview?

without capability: null, without providersourcestoryspec
useModuleFilteredItems(items) → Item[]

Exactly what the toolbar in the module head promises: filter plus search text.

without capability: value, the items unchanged, without FilterProvidersourcestoryspec
useItems(filter?) → {data, isLoading}

Which items match this filter, and is the list still arriving?

without capability: —sourcestoryspec
useItemsWithDraft(filter?) → {data, isLoading}

The same list, with the draft being typed already in it as a card.

without capability: —sourcestoryspec
useItem(id) → {data, isLoading}

Does this one item exist, and is "not found" already decided?

without capability: —sourcestoryspec

Write items 7

useSetDraftItem() → (draft) => void

Publish or discard the running draft.

without capability: no-opsourcestoryspec
useItemEditor(options) → {isOpen, mode, submit, remove, …}

Open the composer and save an input as an item, including its space.

without capability: throws on callsourcestoryspec
useCreateItem() → (input, options?) => Promise<Item>

Create a new item — optionally directly in a given space ({ group }).

without capability: throws on callsourcestoryspec
useUpdateItem() → (id, updates) => Promise<Item>

Change an existing item.

without capability: throws on callsourcestoryspec
useDeleteItem() → (id) => Promise<void>

Delete an item.

without capability: throws on callsourcestoryspec
useUnsavedChanges() → {dirty, setDirty} | null

Are there unsaved inputs that leaving must intercept?

without capability: null, without providersourcestoryspec
useSetUnsavedDirty() → (dirty) => void

Report that something unsaved sits in the form.

without capability: no-opsourcestoryspec

Groups and members 10

useGroupVocabulary(fallbackItems?) → {tags, types}

Which tags and types exist in the space? The one derivation for filter card, chips and tag suggestions.

without capability: emptysourcestoryspec
usePersonalGroupId() → string | null

Where does an item belong that is shared with nobody?

without capability: nullsourcestoryspec
useGroups() → {data, isLoading}

Which spaces do I see?

without capability: emptysourcestoryspec
useCurrentGroup() → Group | null

Which space am I in right now?

without capability: nullsourcestoryspec
useCreateGroup() → (name, data?) => Promise

Create a space.

without capability: throws on callsourcestoryspec
useUpdateGroup() → (id, patch) => Promise

Change a space's name or data.

without capability: throws on callsourcestoryspec
useDeleteGroup() → (id) => Promise

Delete a space.

without capability: throws on callsourcestoryspec
useMembers(groupId) → {data, isLoading}

Who belongs to this space, or with null to all of mine?

without capability: emptysourcestoryspec
useInviteMember() → (groupId, userId) => Promise

Invite someone into a space.

without capability: throws on callsourcestoryspec
useRemoveMember() → (groupId, userId) => Promise

Remove someone from a space.

without capability: throws on callsourcestoryspec

People 8

useOptionalCurrentUser() → {data, isLoading}

Who am I, if anyone at all?

without capability: nullsourcestoryspec
useCurrentUser() → {data, isLoading}

Who am I? For surfaces that make no sense without sign-in.

without capability: throws on rendersourcestoryspec
useContacts() → {contacts, addContact, …}

Whom do I know, who is waiting for confirmation?

without capability: empty, actions no-opsourcestoryspec
useIncomingEvents() → {current, dismiss, …}

Which incoming event is waiting for an answer?

without capability: throws on render, without providersourcestoryspec
useOpenProfile() → (userId) => void

Open a person's profile.

without capability: no-opsourcestoryspec
useResolvedUsers(ids) → Map<string, User>

For which ids do I know a name?

without capability: empty, mapsourcestoryspec
useUserNameResolver() → (userId) => string

A display name for a user id, falling back to the id.

without capability: value, value the id itselfsourcestoryspec
useVerification() → {supported, createChallenge, …}

Two people who meet in real life confirm each other.

without capability: empty, supported: falsesourcestoryspec

Relations 9

useCommentCount(itemId) → number

Is there a conversation on this card?

without capability: value, 0sourcestoryspec
useComments(itemId) → {data, isLoading, canComment, createComment, …}

What was said, by whom, and may I reply?

without capability: empty, writing no-opsourcestoryspec
useReplies(itemId, commentId) → {data, isLoading}

Which replies does this comment have?

without capability: emptysourcestoryspec
useReactions(itemId) → {data, isLoading, react, canReact}

How was reacted, and can I set my reaction?

without capability: empty, react no-opsourcestoryspec
useReactionUsers(itemId, emojiFilter?) → {data, isLoading}

Who reacted with which emoji?

without capability: emptysourcestoryspec
useRelationRecords(filter?) → {data, supported}

Which signed relation records match?

without capability: empty, supported: falsesourcestoryspec
useVerifiedRelationRecords(records) → RelationRecord[]

Which of those are cryptographically covered?

without capability: empty, also while checkingsourcestoryspec
useVotes(statementId) → {data, isLoading, vote, canVote}

How does the resonance stand, and how do I vote?

without capability: empty, without signature verification no vote countssourcestoryspec
useVoteUsers(statementId, enabled?) → {data, isLoading}

Who voted how?

without capability: emptysourcestoryspec

Permissions and capabilities 3

useOptionalConnector() → DataInterface | null

The same for surfaces that render without data access too.

without capability: nullsourcestoryspec
useConnector() → DataInterface

Which data access applies here?

without capability: throws on render, without providersourcestoryspec
useItemPermissions(item) → {canEdit, canDelete}

May I show the ⋮ menu here?

without capability: value, both falsesourcestoryspec

Host and focus 8

useSharedFilter() → {value, searchText, setSearchText, clear}

The app-wide filter that survives the module switch.

without capability: throws on rendersourcestoryspec
useCreate() → {isComposing, startCreate, patchCreate}

Start creating — with suggestion and prefill, never with restriction.

without capability: throws on rendersourcestoryspec
useOptionalCreate() → CreateHostValue | null

The create host, or null where a surface may stand without one (story, test).

without capability: value, nullsourcestoryspec
useModuleHost() → {entry, currentSpace, members, groups, items, setCreateAnchor, …}

The space context and the items the module host produced for this surface.

without capability: throws on rendersourcestoryspec
useModulePanel() → {current, open, close}

Open a panel beside the module. There is only one.

without capability: throws on rendersourcestoryspec
useItemFocus() → {itemId, isEditing, composeType, focusItem, editItem, startCompose, …}

Which item is open, is it being edited, is something being created? The focus contract — in the app the URL (UrlFocusProvider from /router), otherwise memory.

without capability: throws on rendersourcestoryspec
useOptionalItemFocus() → ItemFocus | null

The focus, or null where a surface may stand without one.

without capability: value, nullsourcestoryspec
useModuleFilter(key, initial) → [value, setValue]

A module's own filter value that survives the module switch.

without capability: value, local statesourcespec

Environment 8

useColorScheme() → "light" | "dark"

Is it light or dark right now?

without capability: —sourcestoryspec
useInitialSync() → {active, loadedGroups, expectedGroups}

Is the first fill still running, may "nothing there" be said?

without capability: value, permanently active: falsesourcestoryspec
useIsMobile() → boolean

Narrower than 768px?

without capability: —sourcestoryspec
useIsCompact() → boolean

Below 1024px, where the panel becomes a drawer?

without capability: —sourcestoryspec
useNotifications() → {notifications, badgeCount, …}

What is new for me, and how much is unread?

without capability: emptysourcestoryspec
useMarkNotificationsSeen(notifications) → —

Advance the seen boundary once per opening.

without capability: no-opsourcestoryspec
useRelayStatus() → {state, isConnected, pendingCount}

Is this device attached to the relay, is anything unsent waiting?

without capability: throws on rendersourcestoryspec
useI18n() → I18n — {language, locale, t, tDynamic, formatDate, formatTime, formatFullDateTime, formatRelativeTime, setLanguage}

In which language and regional locale does this surface speak — and how?

without capability: —, works without a provider; the toolkit owns its language statesourcestoryspec

Item properties 2

useItemPresentation(activeGroupId?) → (item) => {group, color, isPrivate}

How does this item present itself: which group it comes from, in which colour, and whether it is private?

without capability: value, no group, palette colour, falsesourcestoryspec
useItemTags(item) → string[]

Which tags does this item carry?

without capability: —sourcestoryspec

Pairs easily confused

  • useCurrentUser and useOptionalCurrentUser differ in what happens on a connector without the authentication capability: the first throws on render, the second yields null. While nobody is signed in, both answer data: null. The same pattern with useConnector/useOptionalConnector, useItemFocus/useOptionalItemFocus, useCreate/useOptionalCreate.
  • useReactions already carries in data[].userIds what useReactionUsers fetches again.
  • useCommentCount is the cheap half of useComments.
  • useItems and useItemsWithDraft are the same list, the latter with the running draft.
  • useIsMobile and useIsCompact are the same mechanism with a different threshold: 768px for navigation, 1024px for the panel shape.