@keepkit/ui
v0.28.4
Published
Headless, accessible React UI components for KeepKit.
Readme
@keepkit/ui
日本語
Reactアプリケーション向けの標準利用パッケージです。@keepkit/coreを内包し、Provider、保存ボタン、検索・ソート・ページング付きの一覧を少ないコードで構成できます。
pnpm add @keepkit/uiMinimal Starter Recipe
import "@keepkit/ui/theme.css";
import { createBrowserStorageAdapter, createKeepKit } from "@keepkit/ui";
type Meta = { title: string; url: string };
const keep = createKeepKit<Meta>({
storage: createBrowserStorageAdapter({ key: "demo:keeps" }),
});
export function SavedArticle({ article }: { article: Meta & { id: string } }) {
return (
<keep.Provider fallback={<p>Saved items are temporarily unavailable.</p>}>
<keep.Button item={{ id: article.id, targetType: "article", meta: article }} />
<keep.Collection query={{ targetType: "article" }} />
</keep.Provider>
);
}すべてのプリミティブはdata-stateを公開し、処理中はdata-loading="true"、無効時はdata-disabled="true"になります。@keepkit/ui/theme.cssを読み込むと、標準の枠、面色、影、フォーカス表示と装飾アイコンが有効になります。通常の削除・一括削除・stale削除は薄い赤の枠線と文字色、hover時の淡い面色で表示し、強い赤の塗りつぶしは確認が必要なエラー状態に限定します。個別の操作はdata-keep-actionで選択でき、--keep-icon-size、--keep-control-gap、--keep-shadow、--keep-success、--keep-warningで調整できます。CSSを読み込まないheadless利用とKeepButton iconsによる差し替えは維持されます。
import "@keepkit/ui/theme.css";
import { createBrowserStorageAdapter, createKeepKit } from "@keepkit/ui";
type ArticleMeta = { title: string; url: string };
const keep = createKeepKit<ArticleMeta>({
storage: createBrowserStorageAdapter({ key: "articles" }),
locale: "ja-JP",
labels: { save: "保存", remove: "削除" },
});
function SavedArticles() {
return (
<keep.Provider>
<keep.Collection
query={{ targetType: "article" }}
renderItem={(item) => <keep.Button item={{ id: item.id, targetType: item.targetType, meta: item.meta }} />}
/>
</keep.Provider>
);
}keep.Collectionは検索、ソート、ページング、loading / empty / error、ARIA live通知を標準で提供します。検索は既定で300msデバウンスされます。features={{ tagFilter: true, bulkActions: true }}でタグフィルターと一括操作も有効にできます。個別のKeepList、KeepSearchInput、KeepSortSelect、KeepPagination、KeepItemCheckbox、KeepTagEditorなどは高度なレイアウト用に利用できます。KeepBulkActionsはrender propsで操作UIを差し替えられ、isAllSelected / toggleSelectAllで表示中アイテムを一括操作できます。KeepNoteEditorは既定300msのデバウンス保存に対応し、debounceMs={0}でフォーム送信のみへ戻せます。通知領域だけを明示的に置く場合はKeepAnnouncer(KeepAnnouncementsのalias)を使えます。
未分類アイテムを整理するには<keep.Inbox />を使います。Inboxは一括移動・archive・pinと、カードのnote/tag編集を有効にします。KeepCollection features={{ savedViews: true }}は現在のqueryを保存し、保存済みqueryの適用・名前変更・pin・削除を提供します。KeepWorkspace modules={{ inbox: true, savedViews: true }}でも両方をopt-inできます。Saved Viewデータはアイテムとは別のkeepkit:saved-views localStorage keyに保存されます。
再発見にはuseKeepItem(item).recordOpen()でlastOpenedAtを記録し、activityクエリまたはcreateRediscoveryQuery() / useKeepRediscovery()を利用できます。inactiveForMsは未閲覧ならsavedAt、閲覧済みならlastOpenedAtを基準にし、開封記録だけではupdatedAtを変更しません。<KeepRediscovery strategy="forgotten" limit={5} />は低レベルの一覧プリセット、<KeepRediscoveryPanel strategy="forgotten" limit={5} />は表示理由とActivityバッジ付きの標準UIです。カード単位ではtrackOpenを指定したときだけ開封記録を有効にします。
保存確認から対象へ戻すにはrevealRequest={{ requestId, itemId }}を渡し、onRevealResultで結果を受け取れます。検索・タグ・保存先フィルターとページを調整して対象を表示します。
KeepWorkspaceはこれらのプリミティブを一つにまとめ、basic、standard、management、syncのプリセットを提供します。createKeepKit()を利用する場合は同じ実装をkeep.Workspaceから型付きで利用できます。modules、slots、子コンポーネントごとのpropsで部分的に差し替えられます。
KeepCollectionManagerは作成・名前変更・削除・件数表示をまとめたheadless UIです。allowCreate、allowRename、allowDelete、showCountsで機能を個別に切り替えられ、collectionLabels、title、description、emptyで表示を差し替えられます。
標準ブラウザーストレージは空のコレクションと変更後の名前を再読み込み後も復元します。独自のStorageAdapterではgetCollections、setCollection、removeCollectionを実装して永続化できます。
画面領域を明示する場合はsurface="panel"または領域別のsurfaceと、sectionGap="compact" | "comfortable"を指定できます。空のslotは枠を生成せず、未指定時とsurface="plain"では従来のDOM順序を維持します。
const keep = createKeepKit<ArticleMeta>({ storage, locale: "ja" });
<keep.Provider>
<keep.Workspace preset="sync" collectionProps={{ layout: "auto" }} />
</keep.Provider>;一覧の標準カードで必要な機能だけを有効化する場合は、features={{ pin: true, archive: true, tags: false }}を指定できます。pin / archive はカード操作ボタン、tags はカード内のタグ表示を切り替えます。タグフィルターはtagFilter、タグ編集はKeepTagEditorで個別に制御でき、itemCardPropsの明示指定がfeaturesより優先されます。
KeepCollectionは検索語と選択タグをKeepActiveFiltersSummaryのチップとして表示し、個別解除と「すべての条件をクリア」を提供します。activeFiltersでこの領域を差し替えられます。標準のKeepList / KeepCollectionは、全件0件のempty-storageと絞り込み結果0件のempty-filteredを区別し、後者ではonClearFilters付きの解除ボタンを表示します。
toolbarLayout="grouped"とtoolbarVariant="panel"を指定すると、slots.toolbarStart / slots.toolbarEndを含む主操作、検索・ソート、フィルターの各グループをローカライズされたrole="group"として描画します。狭い幅ではグループ内のコントロールを縦に折り返します。
KeepItemCardはhref、onOpen、linkTarget、linkComponentに対応し、保存アイテムから詳細ページへ遷移できます。非公開・期限切れ等のstatusを持つアイテムは自動的にリンクを無効化します。KeepBackupはJSONのエクスポート、merge / replaceインポート、結果件数、容量エラー表示を提供します。
KeepTourBar(alias: KeepNavigator)は進行度、前へ・次へ、一覧へ戻る操作をURLまたはコールバックで提供します。getItemHref、getBackHref、onNavigateでホストのルーティングを注入できます。前後ボタンには隣接アイテム名のプレビューが付き、getItemTitleで表示名を差し替えられます。keyboardShortcutsを指定するとJ/Kまたは]/[で巡回でき、useKeepTourShortcutsではキーと動作を個別に差し替えられます。KeepReorderableListはドラッグ操作と矢印キーによる並び替えを提供し、ドラッグ中の挿入位置を表示します。KeepCollection reorderableではこの導線と標準Undoを差し替えなしで利用できます。
KeepShortcutHintはセマンティックな<kbd>バッジを表示します。KeepTourBar showShortcutHintは前へ/次へのキーを、KeepNoteEditor showShortcutHintはCtrl+Enterを標準ボタン内に表示します。mergeProps / createSlotはasChildでclassName、style、ARIA属性、イベント、子と親のrefを合成し、composeRefsはcallback refとobject refをまとめる共通基盤です。フィルターチップは削除後に隣接チップへ戻り、ArrowLeft / ArrowRightで移動できます。
KeepListやKeepCollectionのカードは検索語を大文字小文字を区別せず<mark class="keep-highlight" data-highlight="true">で表示します。単体のKeepItemCardではhighlightQuery、任意のテキストではKeepHighlightを使えます。KeepItemCard.Mediaは読み込み状態をdata-media-statusで公開し、失敗時はfallbackまたは標準SVGへ切り替わります。
テーマCSSではハイライト用の--keep-highlight-bg / --keep-highlight-fg(ライト/ダーク対応)、タイトル2行・メモプレビュー3行の制限、メディアの固定アスペクト比を適用します。KeepItemStatusBadgeは状態ラベルに加えてチェック・時計・進入禁止・鍵のSVGアイコンを表示し、状態ごとの形状とトーンを組み合わせます。個別の状態スタイルは@keepkit/ui/styles/status.cssからも読み込めます。
外部URLの詳細リンクにはtarget="_blank"とrel="noreferrer"が既定で補完され、利用できないカードにはaria-disabled="true"とdata-item-statusが付与されます。同期競合ダイアログではローカルとリモートの更新日時・メモを並べて確認できます。
カードはcardVariant="outlined" | "elevated" | "filled"で面の表現を選べます。--keep-card-border / --keep-card-shadowと--keep-surface-border / --keep-surface-backgroundはカード、ツールバー、Workspace領域を個別に調整するテーマトークンです。
KeepListは初回ロード中、layoutに合うKeepItemCardSkeletonを既定で6枚表示します。loadingCountで枚数を変更でき、従来のloadingまたはrenderLoadingで完全に差し替えられます。layout="auto"は画面幅ではなく配置コンテナ幅に追従し、サイドバーやモーダルでも1列から複数列へ切り替わります。スケルトンのパルスはprefers-reduced-motionで静止表示になります。
カードグループはRoving Tabindexを採用しており、カードにフォーカスして矢印キー、Home、Endで移動できます。
カードの一部だけを配置し直す場合はCompound APIを利用できます。画像alt、タイトルリンク、タグ一覧のARIAラベル、保存操作の状態は各パーツでも維持されます。
<KeepItemCard item={item} href={`/items/${item.id}`} getImageProps={getImageProps}>
<KeepItemCard.Media fallback="No image" />
<KeepItemCard.Content>
<KeepItemCard.Title />
<KeepItemCard.Tags />
</KeepItemCard.Content>
<KeepItemCard.Actions>
<KeepItemCard.Save />
<KeepItemCard.Pin />
<KeepItemCard.Archive />
<KeepItemCard.Remove />
</KeepItemCard.Actions>
</KeepItemCard>KeepKitProvider / KeepUiProviderのonFeedbackはitem-saved、item-removed、item-restored、sync-completed、sync-failed、stale-prunedを通知します。削除系イベントにはundoと現在ロケールのundoLabelが含まれます。ラベルは既存のlabels: { save: "保存" }形式で内容を上書きし、labelOptions: { collection: { text: "カテゴリ", visible: false } }で内容と表示/非表示を設定できます。非表示の表示ラベルでも、操作に必要なARIA名は維持されます。Sonner互換の関数なら次の1行で接続できます(ライブラリ依存は追加されません)。
const onFeedback = useKeepToastFeedback(toast);
<KeepKitProvider storage={storage} onFeedback={onFeedback}>{children}</KeepKitProvider>;v0.28.4では空のコレクションと変更後の名前が再読み込み後も復元されます。Inbox、Saved Views、利用履歴、Rediscovery、個別解除できるフィルターサマリーも利用できます。
Phase 4の状態UIとしてKeepItemStatusBadge、KeepStaleNotice、KeepPruneStaleButton、KeepSyncStatusBanner、KeepSyncRecoveryDialogを利用できます。import "@keepkit/ui/theme.css"でテーマCSSを有効にできます。
Tailwind/shadcnテーマ
/* globals.css */
@import "tailwindcss";
@import "@keepkit/ui/tailwind.css";import { KeepThemeProvider, KeepCollection } from "@keepkit/ui";
<KeepThemeProvider theme="ocean" mode="system" density="comfortable" radius="medium">
<KeepCollection layout="grid" />
</KeepThemeProvider>;色テーマはdefault、ocean、forest、sunset、lavenderから選べます。既存のcompact、minimal、rounded、high-contrast、darkも引き続き利用できます。themeはmode、density、radiusと独立しており、KeepKitProvider theme="forest" mode="dark"のように組み合わせられます。選択肢をUIへ表示する場合はkeepThemeNamesを利用できます。
Tailwind v4の--color-background、--color-foreground、--color-card、--color-muted、--color-border、--color-primary、--color-destructive、--color-ringをKeepKitのスコープ内へ継承します。KeepKitはホストの--color-*変数を上書きせず、--color-keep-*としてTailwindへ公開します。variables、accentColor、highContrast、reducedMotionによる上書きも維持されます。keepKitThemeは@keepkit/ui/tailwindから、分割CSSは@keepkit/ui/styles/base.css、button.css、collection.css、sync.cssから読み込めます。KeepButton icons={{ save, saved, remove }}とiconOnlyでLucide等へ差し替えられます。
Viewer向け保存カードとカスタムテーマは次のように構成できます。savedAt、タイトル、タグ、詳細リンク、保存解除ボタン、期限切れ表示はKeepItemCardの標準markupに含まれます。
import "@keepkit/ui/theme.css";
import { KeepItemCard, KeepThemeProvider } from "@keepkit/ui";
<KeepThemeProvider
theme="rounded"
variables={{ "--keep-primary": "oklch(0.55 0.2 250)", "--keep-card-gap": "0.75rem" }}
>
<KeepItemCard
item={item}
href={`/guide/${item.id}`}
getImageProps={(entry) => ({ src: entry.meta.image, alt: entry.meta.title })}
/>
</KeepThemeProvider>;状態は色だけに依存せず、ラベルと属性でも利用できます。[data-state="saved"]、[data-state="unsaved"]、[data-loading="true"]、[data-state="error"]、[data-state="empty"]、[data-state="stale"]、[data-status="expired"]、[data-status="removed"]、[data-state="selected"]をホストCSSやTailwindのdata variantから参照できます。既存テーマから移行する場合は、@keepkit/ui/theme.cssを残したまま--keepkit-*参照を--keep-*へ置き換えてください。Pages RouterではcreateNextPagesRouterAdapter(router)をurlAdapterへ注入します。
一覧のqueryは次の形式に統一されています。
const query = {
targetType: "article",
tags: ["read"],
search: { query: "react", mode: "and" as const },
sort: { by: "updatedAt" as const, direction: "desc" as const },
pagination: { page: 1, pageSize: 20 },
};保存操作にはID付きの最小入力を渡します。保存・更新時刻はKeepKitが管理します。
const article = { id: "article-123", targetType: "article", meta: { title, url } };
const item = keep.useItem(article);高度なフレームワーク中立APIは@keepkit/core/core、低レベルのReact APIは@keepkit/core/react、ストレージ実装は@keepkit/core/storageから利用できます。
English
The standard React package for KeepKit. It includes @keepkit/core and provides a single typed provider, save button, and searchable/sortable/paginated collection workflow.
pnpm add @keepkit/uiimport { createBrowserStorageAdapter, createKeepKit } from "@keepkit/ui";
type ArticleMeta = { title: string; url: string };
const keep = createKeepKit<ArticleMeta>({
storage: createBrowserStorageAdapter({ key: "articles" }),
labels: { save: "Save", remove: "Remove" },
});
function SavedArticles() {
return (
<keep.Provider>
<keep.Collection query={{ targetType: "article" }} />
</keep.Provider>
);
}keep.Collection includes search, sorting, pagination, loading/empty/error states, and polite live announcements. Search is debounced by 300ms by default. Enable features={{ tagFilter: true, bulkActions: true }} for tag filtering and bulk operations. Use the individual KeepList, KeepSearchInput, KeepSortSelect, KeepPagination, KeepItemCheckbox, and KeepTagEditor primitives when you need a custom layout. KeepBulkActions supports render props and exposes isAllSelected / toggleSelectAll for visible-item selection. KeepNoteEditor auto-saves dirty notes after 300ms by default; set debounceMs={0} to use form submission only. Mount KeepAnnouncer (KeepAnnouncements alias) when you need the live region explicitly.
Use <keep.Inbox /> to triage unassigned items. It enables batch collection moves, archive/pin actions, and card note/tag editing. KeepCollection features={{ savedViews: true }} saves the current query and supports applying, renaming, pinning, and deleting saved queries. KeepWorkspace modules={{ inbox: true, savedViews: true }} opts into both. Saved Views use the separate keepkit:saved-views localStorage key.
Pass revealRequest={{ requestId, itemId }} to return to an item from a save confirmation; onRevealResult reports the outcome after search, tag, collection, and pagination state is adjusted.
KeepWorkspace composes these primitives into basic, standard, management, and sync presets. createKeepKit() exposes the same implementation as a typed keep.Workspace. Override individual areas through modules, slots, and child-component props.
KeepCollectionManager is a headless collection-management UI for creating, renaming, deleting, and counting collections. Toggle each capability with allowCreate, allowRename, allowDelete, and showCounts; customize collectionLabels, title, description, and empty.
Standard browser storage restores empty collections and renamed labels after reload. Custom StorageAdapter implementations can persist them by implementing getCollections, setCollection, and removeCollection.
Use surface="panel" or a per-region surface map together with sectionGap="compact" | "comfortable" to make workspace boundaries explicit. Empty slots do not create frames, and omitted surface or surface="plain" preserves the existing DOM order.
const keep = createKeepKit<ArticleMeta>({ storage, locale: "en" });
<keep.Provider>
<keep.Workspace preset="sync" collectionProps={{ layout: "auto" }} />
</keep.Provider>;Enable only the standard card features you need with features={{ pin: true, archive: true, tags: false }}. pin and archive toggle card action buttons, while tags controls tag display inside cards. Tag filtering remains independently controlled by tagFilter, tag editing by KeepTagEditor, and explicit itemCardProps values take precedence over features.
KeepCollection renders the current search and tag filters as KeepActiveFiltersSummary chips with individual removal and a “Clear all filters” action. Replace that area with the activeFilters slot. Default KeepList / KeepCollection output distinguishes empty-storage from empty-filtered; the filtered state includes a reset button when onClearFilters is provided.
Set toolbarLayout="grouped" and toolbarVariant="panel" to render host slots.toolbarStart / slots.toolbarEnd, query controls, and filters as localized role="group" regions. The query and filter groups stack their controls at narrow widths.
The opt-in theme adds neutral borders, surfaces, shadows, focus treatment, and decorative action icons without changing accessible names. Regular remove, bulk-delete, and stale-prune actions use a subtle red outline and text with a light hover surface; solid red is reserved for error states that need confirmation. Target individual controls with data-keep-action, or override --keep-icon-size, --keep-control-gap, --keep-shadow, --keep-success, and --keep-warning. Consumers that omit the CSS keep the headless markup, and KeepButton icons continues to take precedence over the built-in icon.
KeepItemCard accepts href, onOpen, linkTarget, and linkComponent for detail-page navigation. Links are disabled for unavailable status values such as private or expired. KeepBackup provides JSON export, merge/replace import, result counts, and quota-error messaging.
KeepTourBar (aliased as KeepNavigator) provides progress, previous/next, and return-to-list actions through URLs or callbacks. Inject host routing with getItemHref, getBackHref, and onNavigate. Adjacent item titles are previewed below the navigation labels; customize them with getItemTitle. Set keyboardShortcuts for J/K or ]/[ tour navigation, or use useKeepTourShortcuts for custom bindings. KeepReorderableList supports drag and keyboard reordering and shows the active insertion position; KeepCollection reorderable includes that path and standard undo without a slot replacement.
KeepTourProvider / useKeepTour manage a session-scoped tour, and KeepFloatingTour renders controls in a body portal so the host layout needs no reserved space. Start with start({ itemIds }), configure position, offset, zIndex, and routing callbacks. Same-tab state resumes from sessionStorage; set tour={{ sessionKey }} on KeepKitProvider to namespace it.
KeepShortcutHint renders semantic <kbd> badges. KeepTourBar showShortcutHint displays the previous/next keys, while KeepNoteEditor showShortcutHint displays Ctrl+Enter in the save button. mergeProps / createSlot compose className, style, ARIA, events, and child/parent refs for asChild slots; composeRefs combines callback and object refs. Filter chips restore focus to an adjacent chip after removal and support ArrowLeft / ArrowRight navigation.
KeepFloatingTour is a fixed portal-rendered tour control that does not consume page layout space. Use KeepTourProvider / useKeepTour to start an ordered session with start({ itemIds }) and configure host routing with getItemHref, getBackHref, or onNavigate.
Cards rendered by KeepList and KeepCollection highlight case-insensitive search matches with <mark class="keep-highlight" data-highlight="true">. Use highlightQuery on a standalone KeepItemCard or KeepHighlight for arbitrary text. KeepItemCard.Media exposes its loading state through data-media-status and replaces failed images with fallback or the built-in SVG placeholder.
The theme defines WCAG-oriented --keep-highlight-bg / --keep-highlight-fg pairs for light and dark modes, clamps titles to two lines and memo previews to three, and reserves a stable media aspect ratio. KeepItemStatusBadge combines visible status text with check, clock, ban, or lock SVG icons; import @keepkit/ui/styles/status.css when using the status styles independently.
External detail URLs receive target="_blank" and rel="noreferrer" defaults. Unavailable cards expose aria-disabled="true" and normalized data-item-status values, and the sync recovery dialog compares local and remote updated dates and notes side by side.
Choose cardVariant="outlined" | "elevated" | "filled" for card surfaces. Override --keep-card-border / --keep-card-shadow and --keep-surface-border / --keep-surface-background independently for cards, toolbars, and workspace regions.
During initial loading, KeepList renders six layout-matched KeepItemCardSkeleton placeholders by default. Change the count with loadingCount, or replace them with the existing loading prop or its renderLoading alias. layout="auto" responds to the available container width rather than viewport width, so embedded sidebars and dialogs collapse to one column. Skeleton pulses become static under prefers-reduced-motion.
Card groups use Roving Tabindex, so a focused card can move to adjacent cards with arrow keys or jump with Home and End.
Use the compound parts to rearrange only the card regions you own while preserving image alt text, linked headings, the labelled tag list, and action state:
<KeepItemCard item={item} href={`/items/${item.id}`} getImageProps={getImageProps}>
<KeepItemCard.Media fallback="No image" />
<KeepItemCard.Content>
<KeepItemCard.Title />
<KeepItemCard.Tags />
</KeepItemCard.Content>
<KeepItemCard.Actions />
</KeepItemCard>onFeedback on KeepKitProvider / KeepUiProvider receives item-saved, item-removed, item-restored, sync-completed, sync-failed, and stale-pruned. Override text with the existing labels: { save: "Save" } form and configure text or visibility with labelOptions: { collection: { text: "Category", visible: false } }; required ARIA names remain available when visible text is hidden. Removal events include an undo function and locale-aware undoLabel. Connect a Sonner-compatible function without adding a package dependency:
const onFeedback = useKeepToastFeedback(toast);
<KeepKitProvider storage={storage} onFeedback={onFeedback}>{children}</KeepKitProvider>;v0.28.4 restores empty collections and renamed labels after reload. Inbox triage, Saved Views, activity tracking, Rediscovery, and removable active-filter summaries are also available. The portal-rendered floating tour UI, Tailwind CSS v4 integration, host-theme isolation, and cascade-layer support remain available.
Phase 4 adds KeepItemStatusBadge, KeepStaleNotice, KeepPruneStaleButton, KeepSyncStatusBanner, and KeepSyncRecoveryDialog for unavailable items, sync failures, conflict resolution, and backup recovery. Import @keepkit/ui/theme.css or @keepkit/ui/tailwind.css for the opt-in theme layer.
Tailwind and shadcn theme
/* globals.css */
@import "tailwindcss";
@import "@keepkit/ui/tailwind.css";import { KeepThemeProvider, KeepCollection } from "@keepkit/ui";
<KeepThemeProvider theme="ocean" mode="system" density="comfortable" radius="medium">
<KeepCollection layout="grid" />
</KeepThemeProvider>;Color themes include default, ocean, forest, sunset, and lavender. Existing compact, minimal, rounded, high-contrast, and dark presets remain available. theme composes independently with mode, density, and radius, so theme="forest" mode="dark" is supported. Use the exported keepThemeNames list when building a selector.
The scoped --keep-* tokens inherit complete Tailwind v4 --color-* values from shadcn/ui when present. KeepKit does not replace the host's generic color aliases; its Tailwind aliases are namespaced as --color-keep-*. The provider supports .dark, system preference, variables, accentColor, highContrast, and reducedMotion. Use keepKitTheme from @keepkit/ui/tailwind, feature CSS from @keepkit/ui/styles/*, and icons={{ save, saved, remove }} / iconOnly on KeepButton for Lucide or shadcn replacements. The existing Next.js Pages Router recipe remains unchanged: inject createNextPagesRouterAdapter(router) into urlAdapter.
For a Viewer card, the default KeepItemCard markup includes the title, tags, saved date, detail link, remove action, thumbnail, and expired-item notice. Override tokens without replacing the markup, or use render props for a complete replacement:
import "@keepkit/ui/theme.css";
import { KeepItemCard, KeepThemeProvider } from "@keepkit/ui";
<KeepThemeProvider
theme="rounded"
variables={{ "--keep-primary": "oklch(0.55 0.2 250)", "--keep-card-gap": "0.75rem" }}
>
<KeepItemCard
item={item}
href={`/guide/${item.id}`}
getImageProps={(entry) => ({ src: entry.meta.image, alt: entry.meta.title })}
/>
</KeepThemeProvider>;Use [data-state="saved"], [data-state="unsaved"], [data-loading="true"], [data-state="error"], [data-state="empty"], [data-state="stale"], [data-status="expired"], [data-status="removed"], and [data-state="selected"] from host CSS or Tailwind data variants. For migration, keep importing @keepkit/ui/theme.css while replacing direct --keepkit-* references with --keep-*. In the Pages Router, inject createNextPagesRouterAdapter(router) into urlAdapter.
Collection queries use one canonical shape: targetType, tags, search, sort, pagination, filter, and savedBetween. Saved item inputs contain only id, meta, targetType, note, and tags; KeepKit owns persistence timestamps.
For rediscovery, use useKeepItem(item).recordOpen() to persist lastOpenedAt, then query activity with opened, lastOpenedBefore, lastOpenedAfter, or inactiveForMs. inactiveForMs uses savedAt for never-opened items and lastOpenedAt for opened items; recording an open does not change updatedAt. createRediscoveryQuery() / useKeepRediscovery() provide standard never-opened, forgotten, and recently-opened views. <KeepRediscovery> remains the low-level list, while <KeepRediscoveryPanel> adds an explanation and Activity badges. KeepItemCard trackOpen opts into tracking without changing existing cards.
Framework-neutral APIs remain available from @keepkit/core/core, low-level React bindings from @keepkit/core/react, and storage adapters from @keepkit/core/storage.
Archive, pin, collections, and quick save editing
The UI package exports KeepArchiveButton, KeepArchiveScopeSelect, KeepPinButton, KeepCollectionSelect, KeepCollectionFilter, KeepSavePopover, KeepQuickEditor, and useKeepQuickEditor. KeepCollection archiveScope="active" | "archived" | "all" provides a localized scope selector and URL synchronization; reorderable provides standard drag/keyboard ordering and undo. Buttons expose aria-pressed, data-archived/data-pinned, and data-keep-action. Collection labels default to IDs and can be overridden with collectionLabels. KeepItemCard showEditButton opens the standard QuickEditor dialog and editSlot customizes its content. Enable features={{ collectionFilter: true }} on KeepCollection to include the collection filter. KeepSavePopover wraps KeepButton, opens after a new save, labels and focuses its dialog, flushes pending edits before closing, and restores focus to the trigger. Its quick editor debounces note, tags, and collection updates by 300ms and exposes saveStatus. Set showSaveButton={false} when visible save status should replace the submit button. KeepItemCard.Save and KeepItemCard.Remove let compound cards place those actions alongside Pin and Archive without replacing the default card API.
アーカイブ・ピン留め・コレクション・保存直後編集
UI パッケージは KeepArchiveButton、KeepArchiveScopeSelect、KeepPinButton、KeepCollectionSelect、KeepCollectionFilter、KeepSavePopover、KeepQuickEditor、useKeepQuickEditor を公開します。KeepCollection archiveScope="active" | "archived" | "all" はローカライズされたスコープ選択とURL同期を、reorderable は標準のドラッグ/キーボード並び替えとUndoを提供します。ボタンは aria-pressed、data-archived / data-pinned、data-keep-action を出力します。KeepItemCard showEditButton は標準QuickEditor dialogを開き、editSlotで内容を差し替えられます。コレクション名は既定で ID を表示し、collectionLabels で置換できます。KeepCollection に features={{ collectionFilter: true }} を指定するとフィルターを統合できます。KeepSavePopover は KeepButton を内部 trigger とし、新規保存後にdialogへフォーカスし、閉じる前に未保存編集をflushしてtriggerへフォーカスを戻します。クイックエディターはメモ・タグ・コレクションを一時状態として扱い、既定300msで保存し、saveStatusで状態を公開します。自動保存だけを表示する場合はshowSaveButton={false}を指定します。compound cardではKeepItemCard.Save / RemoveをPin / Archiveと同じ操作領域に配置できます。
