@keepkit/ui 0.23.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,6 +57,16 @@ function SavedArticles() {
57
57
  ```
58
58
 
59
59
  `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)を使えます。
60
+ `KeepWorkspace`はこれらのプリミティブを一つにまとめ、`basic`、`standard`、`management`、`sync`のプリセットを提供します。`createKeepKit()`を利用する場合は同じ実装を`keep.Workspace`から型付きで利用できます。`modules`、`slots`、子コンポーネントごとのpropsで部分的に差し替えられます。
61
+
62
+ ```tsx
63
+ const keep = createKeepKit<ArticleMeta>({ storage, locale: "ja" });
64
+
65
+ <keep.Provider>
66
+ <keep.Workspace preset="sync" collectionProps={{ layout: "auto" }} />
67
+ </keep.Provider>;
68
+ ```
69
+ 一覧の標準カードで必要な機能だけを有効化する場合は、`features={{ pin: true, archive: true, tags: false }}`を指定できます。`pin` / `archive` はカード操作ボタン、`tags` はカード内のタグ表示を切り替えます。タグフィルターは`tagFilter`、タグ編集は`KeepTagEditor`で個別に制御でき、`itemCardProps`の明示指定が`features`より優先されます。
60
70
  `KeepCollection`は検索語と選択タグを`KeepActiveFiltersSummary`のチップとして表示し、個別解除と「すべての条件をクリア」を提供します。`activeFilters`でこの領域を差し替えられます。標準の`KeepList` / `KeepCollection`は、全件0件の`empty-storage`と絞り込み結果0件の`empty-filtered`を区別し、後者では`onClearFilters`付きの解除ボタンを表示します。
61
71
  `KeepItemCard`は`href`、`onOpen`、`linkTarget`、`linkComponent`に対応し、保存アイテムから詳細ページへ遷移できます。非公開・期限切れ等の`status`を持つアイテムは自動的にリンクを無効化します。`KeepBackup`はJSONのエクスポート、merge / replaceインポート、結果件数、容量エラー表示を提供します。
62
72
  `KeepTourBar`(alias: `KeepNavigator`)は進行度、前へ・次へ、一覧へ戻る操作をURLまたはコールバックで提供します。前後ボタンには隣接アイテム名のプレビューが付き、`getItemTitle`で表示名を差し替えられます。`keyboardShortcuts`を指定するとJ/Kまたは]/[で巡回でき、`useKeepTourShortcuts`ではキーと動作を個別に差し替えられます。`KeepReorderableList`はドラッグ操作と矢印キーによる並び替えを提供し、ドラッグ中の挿入位置を表示します。
@@ -93,7 +103,7 @@ const onFeedback = useKeepToastFeedback(toast);
93
103
  <KeepKitProvider storage={storage} onFeedback={onFeedback}>{children}</KeepKitProvider>;
94
104
  ```
95
105
 
96
- v0.23.1ではTailwind CSS v4との統合、ホストテーマ変数との衝突回避、CSS cascade layer対応を追加しました。保存直後の`KeepSavePopover`自動編集、`KeepQuickEditorState.saveStatus`、`KeepItemCard.Save` / `KeepItemCard.Remove`、管理モード向け`KeepBulkActions`、通知からのコレクション再訪導線も引き続き利用できます。
106
+ v0.24.0では`KeepWorkspace`と型付きの`keep.Workspace`を追加しました。Tailwind CSS v4との統合、ホストテーマ変数との衝突回避、CSS cascade layer対応も引き続き利用できます。保存直後の`KeepSavePopover`自動編集、`KeepQuickEditorState.saveStatus`、`KeepItemCard.Save` / `KeepItemCard.Remove`、管理モード向け`KeepBulkActions`、通知からのコレクション再訪導線も引き続き利用できます。
97
107
  Phase 4の状態UIとして`KeepItemStatusBadge`、`KeepStaleNotice`、`KeepPruneStaleButton`、`KeepSyncStatusBanner`、`KeepSyncRecoveryDialog`を利用できます。`import "@keepkit/ui/theme.css"`でテーマCSSを有効にできます。
98
108
 
99
109
  ### Tailwind/shadcnテーマ
@@ -184,6 +194,16 @@ function SavedArticles() {
184
194
  ```
185
195
 
186
196
  `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.
197
+ `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.
198
+
199
+ ```tsx
200
+ const keep = createKeepKit<ArticleMeta>({ storage, locale: "en" });
201
+
202
+ <keep.Provider>
203
+ <keep.Workspace preset="sync" collectionProps={{ layout: "auto" }} />
204
+ </keep.Provider>;
205
+ ```
206
+ 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`.
187
207
  `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.
188
208
 
189
209
  The opt-in theme adds neutral borders, surfaces, shadows, focus treatment, and decorative action icons without changing accessible names. 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.
@@ -217,7 +237,7 @@ const onFeedback = useKeepToastFeedback(toast);
217
237
  <KeepKitProvider storage={storage} onFeedback={onFeedback}>{children}</KeepKitProvider>;
218
238
  ```
219
239
 
220
- In v0.23.1, Tailwind CSS v4 integration, host-theme isolation, and cascade-layer support are included. `KeepSavePopover` post-save editing, `KeepQuickEditorState.saveStatus`, `KeepItemCard.Save` / `KeepItemCard.Remove`, management-mode `KeepBulkActions`, and notification-driven return to the collection remain available.
240
+ v0.24.0 adds `KeepWorkspace` and the typed `keep.Workspace`. Tailwind CSS v4 integration, host-theme isolation, and cascade-layer support remain available. `KeepSavePopover` post-save editing, `KeepQuickEditorState.saveStatus`, `KeepItemCard.Save` / `KeepItemCard.Remove`, management-mode `KeepBulkActions`, and notification-driven return to the collection remain available.
221
241
  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.
222
242
 
223
243
  ### Tailwind and shadcn theme
package/dist/index.d.ts CHANGED
@@ -273,6 +273,8 @@ type KeepItemCardProps<TMeta = Record<string, unknown>> = Omit<HTMLAttributes<HT
273
273
  onRemoved?: (item: KeepItem<TMeta>) => void;
274
274
  onRetry?: (item: KeepItem<TMeta>) => void | Promise<void>;
275
275
  showSaveButton?: boolean;
276
+ showPinButton?: boolean;
277
+ showArchiveButton?: boolean;
276
278
  saveButtonLabels?: KeepButtonLabels;
277
279
  asChild?: boolean;
278
280
  href?: string | ((item: KeepItem<TMeta>) => string | undefined);
@@ -297,7 +299,7 @@ type KeepItemCardSkeletonProps = Omit<HTMLAttributes<HTMLElement>, "children"> &
297
299
  layout?: KeepLayoutPreset;
298
300
  };
299
301
  /** A low-dependency item presentation primitive with composable card parts. */
300
- declare function KeepItemCardRoot<TMeta = Record<string, unknown>>({ item, title, getTitle, getImageProps, imageComponent: ImageComponent, renderImage, renderTags, showTags, showSavedAt, collectionLabels, imageAlt, render, children, removeLabel, onRemoveError, onRemoved, onRetry, showSaveButton, saveButtonLabels, asChild, href: hrefOption, onOpen, linkTarget, linkComponent: LinkComponent, linkTargetAttribute, linkRel, highlightQuery, className, ...rootProps }: KeepItemCardProps<TMeta>): react.JSX.Element;
302
+ declare function KeepItemCardRoot<TMeta = Record<string, unknown>>({ item, title, getTitle, getImageProps, imageComponent: ImageComponent, renderImage, renderTags, showTags, showSavedAt, collectionLabels, imageAlt, render, children, removeLabel, onRemoveError, onRemoved, onRetry, showSaveButton, showPinButton, showArchiveButton, saveButtonLabels, asChild, href: hrefOption, onOpen, linkTarget, linkComponent: LinkComponent, linkTargetAttribute, linkRel, highlightQuery, className, ...rootProps }: KeepItemCardProps<TMeta>): react.JSX.Element;
301
303
  declare function KeepItemCardMedia({ children, fallback, ...props }: KeepItemCardMediaProps): react.JSX.Element;
302
304
  declare function KeepItemCardContent({ children, ...props }: KeepItemCardContentProps): react.JSX.Element;
303
305
  declare function KeepItemCardTitle({ as, children, ...props }: KeepItemCardTitleProps): react.DetailedReactHTMLElement<{
@@ -641,7 +643,7 @@ type KeepListProps<TMeta = Record<string, unknown>> = Omit<HTMLAttributes<HTMLEl
641
643
  /** A list primitive with built-in loading, empty, error, and removal states. */
642
644
  declare function KeepList<TMeta = Record<string, unknown>>(props: KeepListProps<TMeta>): react.JSX.Element;
643
645
 
644
- type KeepCollectionFeature = "search" | "sort" | "pagination" | "tagFilter" | "collectionFilter" | "bulkActions";
646
+ type KeepCollectionFeature = "search" | "sort" | "pagination" | "tagFilter" | "collectionFilter" | "bulkActions" | "tags" | "pin" | "archive";
645
647
  type KeepLayoutPreset = "list" | "grid" | "compact" | "auto";
646
648
  type KeepCollectionProps<TMeta = Record<string, unknown>> = Omit<HTMLAttributes<HTMLElement>, "children"> & {
647
649
  query?: KeepListQuery<TMeta>;
@@ -1039,6 +1041,39 @@ type KeepSyncStatusBannerProps = Omit<HTMLAttributes<HTMLElement>, "children"> &
1039
1041
  /** Announces synchronization failures and exposes retry or conflict-recovery entry points. */
1040
1042
  declare function KeepSyncStatusBanner({ onRetry, onResolveConflicts, children, className, ...props }: KeepSyncStatusBannerProps): react.JSX.Element | null;
1041
1043
 
1044
+ type KeepWorkspacePreset = "basic" | "standard" | "management" | "sync";
1045
+ type KeepWorkspaceModule = "syncStatus" | "undo" | "recovery" | "backup" | "stalePrune";
1046
+ type KeepWorkspaceState = {
1047
+ preset: KeepWorkspacePreset;
1048
+ modules: Readonly<Record<KeepWorkspaceModule, boolean>>;
1049
+ recoveryOpen: boolean;
1050
+ setRecoveryOpen: (open: boolean) => void;
1051
+ };
1052
+ type KeepWorkspaceContent = ReactNode | RenderProp<KeepWorkspaceState>;
1053
+ type KeepWorkspaceSlots = {
1054
+ before?: KeepWorkspaceContent;
1055
+ syncStatus?: KeepWorkspaceContent;
1056
+ collection?: KeepWorkspaceContent;
1057
+ actions?: KeepWorkspaceContent;
1058
+ undo?: KeepWorkspaceContent;
1059
+ recovery?: KeepWorkspaceContent;
1060
+ after?: KeepWorkspaceContent;
1061
+ };
1062
+ type KeepWorkspaceProps<TMeta = Record<string, unknown>> = Omit<HTMLAttributes<HTMLElement>, "children"> & {
1063
+ preset?: KeepWorkspacePreset;
1064
+ modules?: Partial<Record<KeepWorkspaceModule, boolean>>;
1065
+ collectionProps?: KeepCollectionProps<TMeta>;
1066
+ syncStatusProps?: KeepSyncStatusBannerProps;
1067
+ recoveryProps?: KeepSyncRecoveryDialogProps<TMeta>;
1068
+ backupProps?: KeepBackupProps<TMeta>;
1069
+ undoProps?: KeepUndoProps;
1070
+ stalePruneProps?: KeepPruneStaleButtonProps;
1071
+ slots?: KeepWorkspaceSlots;
1072
+ children?: KeepWorkspaceContent;
1073
+ };
1074
+ /** Composes the standard collection, management, and sync primitives into one customizable workspace. */
1075
+ declare function KeepWorkspace<TMeta = Record<string, unknown>>({ preset, modules, collectionProps, syncStatusProps, recoveryProps, backupProps, undoProps, stalePruneProps, slots, children, className, ...props }: KeepWorkspaceProps<TMeta>): react.JSX.Element;
1076
+
1042
1077
  declare const keepThemeNames: readonly ["default", "ocean", "forest", "sunset", "lavender", "compact", "minimal", "rounded", "high-contrast", "dark"];
1043
1078
  type KeepThemeName = (typeof keepThemeNames)[number];
1044
1079
  type KeepThemeMode = "light" | "dark" | "system";
@@ -1096,6 +1131,7 @@ type KeepKit<TMeta = Record<string, unknown>> = {
1096
1131
  Button: ComponentType<KeepButtonProps<TMeta>>;
1097
1132
  Backup: ComponentType<KeepBackupProps<TMeta>>;
1098
1133
  Collection: ComponentType<KeepCollectionProps<TMeta>>;
1134
+ Workspace: ComponentType<KeepWorkspaceProps<TMeta>>;
1099
1135
  useContext: () => ReturnType<typeof useKeepContext<TMeta>>;
1100
1136
  useItem: (item?: KeepItemInput<TMeta>) => ReturnType<typeof useKeepItem<TMeta>>;
1101
1137
  useList: (query?: KeepListQuery<TMeta>) => ReturnType<typeof useKeepList<TMeta>>;
@@ -1105,4 +1141,4 @@ type KeepKit<TMeta = Record<string, unknown>> = {
1105
1141
  /** Create one typed application API for the core and standard UI layer. */
1106
1142
  declare function createKeepKit<TMeta = Record<string, unknown>>(options?: CreateKeepKitOptions<TMeta>): KeepKit<TMeta>;
1107
1143
 
1108
- export { type CreateKeepKitOptions, KeepActiveFiltersSummary, type KeepActiveFiltersSummaryProps, type KeepActiveFiltersSummaryState, KeepAnnouncements, type KeepAnnouncementsProps, KeepAnnouncer, KeepArchiveButton, type KeepArchiveButtonProps, type KeepArchiveButtonState, KeepBackup, type KeepBackupProps, KeepBulkActions, type KeepBulkActionsProps, type KeepBulkActionsState, KeepButton, type KeepButtonIcon, type KeepButtonIconProps, type KeepButtonIcons, type KeepButtonLabels, type KeepButtonProps, KeepCollection, type KeepCollectionControlProps, type KeepCollectionFeature, KeepCollectionFilter, type KeepCollectionOption, type KeepCollectionProps, KeepCollectionSelect, type KeepDisplayStatus, KeepEmptyState, type KeepEmptyStateProps, type KeepEmptyStateVariant, KeepHighlight, type KeepHighlightProps, type KeepImageProps, KeepItemCard, type KeepItemCardActionSlotProps, type KeepItemCardActionsProps, type KeepItemCardBadgeProps, type KeepItemCardContentProps, type KeepItemCardLinkProps, type KeepItemCardMediaProps, type KeepItemCardProps, type KeepItemCardRemoveProps, type KeepItemCardSaveProps, KeepItemCardSkeleton, type KeepItemCardSkeletonProps, type KeepItemCardState, type KeepItemCardTagsProps, type KeepItemCardTitleProps, KeepItemCheckbox, type KeepItemCheckboxProps, KeepItemStatusBadge, type KeepItemStatusBadgeProps, type KeepKit, KeepKitProvider, type KeepKitProviderProps, KeepLayout, type KeepLayoutPreset, type KeepLayoutProps, KeepList, type KeepListProps, type KeepListState, KeepNavigator, KeepNoteEditor, type KeepNoteEditorProps, type KeepNoteEditorState, type KeepPagesRouterLike, KeepPagination, type KeepPaginationProps, type KeepPaginationState, KeepPinButton, type KeepPinButtonProps, type KeepPinButtonState, KeepPruneStaleButton, type KeepPruneStaleButtonProps, KeepQuickEditor, type KeepQuickEditorProps, type KeepQuickEditorState, type KeepReorderableItemState, KeepReorderableList, type KeepReorderableListProps, KeepSavePopover, type KeepSavePopoverProps, KeepSearchInput, type KeepSearchInputProps, type KeepSelectionScope, KeepShortcutHint, type KeepShortcutHintProps, KeepSortSelect, type KeepSortSelectProps, type KeepSortValue, KeepStaleNotice, type KeepStaleNoticeProps, KeepStatus, type KeepStatusLabels, type KeepStatusProps, type KeepStatusState, type KeepStatusValue, KeepSyncRecoveryDialog, type KeepSyncRecoveryDialogProps, KeepSyncStatusBanner, type KeepSyncStatusBannerProps, KeepTagEditor, type KeepTagEditorProps, type KeepTagEditorState, KeepTagFilter, type KeepTagFilterProps, type KeepTagFilterState, type KeepThemeDensity, type KeepThemeMode, type KeepThemeName, KeepThemeProvider, type KeepThemeProviderProps, type KeepThemeRadius, type KeepThemeVariables, type KeepToastFeedbackOptions, type KeepToastHandler, KeepTourBar, type KeepTourBarProps, type KeepTourShortcutsOptions, type KeepUiFeedbackEvent, type KeepUiLabelContext, type KeepUiLabelKey, type KeepUiLabels, type KeepUiLocale, type KeepUiLocaleLabels, KeepUiProvider, type KeepUiProviderProps, KeepUndo, type KeepUndoProps, type KeepUrlAdapter, type RenderProp, chainedFunction, composeRefs, createKeepKit, createNextPagesRouterAdapter, createSlot, getKeepLocaleLabels, highlightText, isAllSelected, keepThemeNames, mergeProps, toggleSelectAll, useKeepQuickEditor, useKeepToastFeedback, useKeepTourShortcuts, useKeepUiLabels, useKeepUrlSync };
1144
+ export { type CreateKeepKitOptions, KeepActiveFiltersSummary, type KeepActiveFiltersSummaryProps, type KeepActiveFiltersSummaryState, KeepAnnouncements, type KeepAnnouncementsProps, KeepAnnouncer, KeepArchiveButton, type KeepArchiveButtonProps, type KeepArchiveButtonState, KeepBackup, type KeepBackupProps, KeepBulkActions, type KeepBulkActionsProps, type KeepBulkActionsState, KeepButton, type KeepButtonIcon, type KeepButtonIconProps, type KeepButtonIcons, type KeepButtonLabels, type KeepButtonProps, KeepCollection, type KeepCollectionControlProps, type KeepCollectionFeature, KeepCollectionFilter, type KeepCollectionOption, type KeepCollectionProps, KeepCollectionSelect, type KeepDisplayStatus, KeepEmptyState, type KeepEmptyStateProps, type KeepEmptyStateVariant, KeepHighlight, type KeepHighlightProps, type KeepImageProps, KeepItemCard, type KeepItemCardActionSlotProps, type KeepItemCardActionsProps, type KeepItemCardBadgeProps, type KeepItemCardContentProps, type KeepItemCardLinkProps, type KeepItemCardMediaProps, type KeepItemCardProps, type KeepItemCardRemoveProps, type KeepItemCardSaveProps, KeepItemCardSkeleton, type KeepItemCardSkeletonProps, type KeepItemCardState, type KeepItemCardTagsProps, type KeepItemCardTitleProps, KeepItemCheckbox, type KeepItemCheckboxProps, KeepItemStatusBadge, type KeepItemStatusBadgeProps, type KeepKit, KeepKitProvider, type KeepKitProviderProps, KeepLayout, type KeepLayoutPreset, type KeepLayoutProps, KeepList, type KeepListProps, type KeepListState, KeepNavigator, KeepNoteEditor, type KeepNoteEditorProps, type KeepNoteEditorState, type KeepPagesRouterLike, KeepPagination, type KeepPaginationProps, type KeepPaginationState, KeepPinButton, type KeepPinButtonProps, type KeepPinButtonState, KeepPruneStaleButton, type KeepPruneStaleButtonProps, KeepQuickEditor, type KeepQuickEditorProps, type KeepQuickEditorState, type KeepReorderableItemState, KeepReorderableList, type KeepReorderableListProps, KeepSavePopover, type KeepSavePopoverProps, KeepSearchInput, type KeepSearchInputProps, type KeepSelectionScope, KeepShortcutHint, type KeepShortcutHintProps, KeepSortSelect, type KeepSortSelectProps, type KeepSortValue, KeepStaleNotice, type KeepStaleNoticeProps, KeepStatus, type KeepStatusLabels, type KeepStatusProps, type KeepStatusState, type KeepStatusValue, KeepSyncRecoveryDialog, type KeepSyncRecoveryDialogProps, KeepSyncStatusBanner, type KeepSyncStatusBannerProps, KeepTagEditor, type KeepTagEditorProps, type KeepTagEditorState, KeepTagFilter, type KeepTagFilterProps, type KeepTagFilterState, type KeepThemeDensity, type KeepThemeMode, type KeepThemeName, KeepThemeProvider, type KeepThemeProviderProps, type KeepThemeRadius, type KeepThemeVariables, type KeepToastFeedbackOptions, type KeepToastHandler, KeepTourBar, type KeepTourBarProps, type KeepTourShortcutsOptions, type KeepUiFeedbackEvent, type KeepUiLabelContext, type KeepUiLabelKey, type KeepUiLabels, type KeepUiLocale, type KeepUiLocaleLabels, KeepUiProvider, type KeepUiProviderProps, KeepUndo, type KeepUndoProps, type KeepUrlAdapter, KeepWorkspace, type KeepWorkspaceModule, type KeepWorkspacePreset, type KeepWorkspaceProps, type KeepWorkspaceSlots, type KeepWorkspaceState, type RenderProp, chainedFunction, composeRefs, createKeepKit, createNextPagesRouterAdapter, createSlot, getKeepLocaleLabels, highlightText, isAllSelected, keepThemeNames, mergeProps, toggleSelectAll, useKeepQuickEditor, useKeepToastFeedback, useKeepTourShortcuts, useKeepUiLabels, useKeepUrlSync };
package/dist/index.js CHANGED
@@ -3521,6 +3521,9 @@ function useKeepCollection({
3521
3521
  tagFilter: false,
3522
3522
  collectionFilter: false,
3523
3523
  bulkActions: false,
3524
+ tags: true,
3525
+ pin: false,
3526
+ archive: false,
3524
3527
  ...features
3525
3528
  };
3526
3529
  const [searchValue, setSearchValue] = useState9(query.search?.query ?? "");
@@ -3994,6 +3997,8 @@ function KeepItemCardRoot({
3994
3997
  onRemoved,
3995
3998
  onRetry,
3996
3999
  showSaveButton = true,
4000
+ showPinButton = false,
4001
+ showArchiveButton = false,
3997
4002
  saveButtonLabels,
3998
4003
  asChild = false,
3999
4004
  href: hrefOption,
@@ -4072,6 +4077,8 @@ function KeepItemCardRoot({
4072
4077
  const error = view.itemState.error ? /* @__PURE__ */ jsx16("p", { role: "alert", children: getErrorMessage3(view.itemState.error, view.labels.error) }) : null;
4073
4078
  const actions = view.statusLabel ? /* @__PURE__ */ jsx16(KeepStaleNotice, { item, onRetry, onRemoved }) : /* @__PURE__ */ jsxs14(Fragment8, { children: [
4074
4079
  showSaveButton ? /* @__PURE__ */ jsx16(KeepItemCardSave, {}) : null,
4080
+ showPinButton ? /* @__PURE__ */ jsx16(KeepItemCardPin, {}) : null,
4081
+ showArchiveButton ? /* @__PURE__ */ jsx16(KeepItemCardArchive, {}) : null,
4075
4082
  /* @__PURE__ */ jsx16(KeepItemCardRemove, {})
4076
4083
  ] });
4077
4084
  const compoundValue = {
@@ -4494,6 +4501,12 @@ function KeepCollectionContent({
4494
4501
  ...rootProps
4495
4502
  }) {
4496
4503
  const view = useKeepCollection({ query, pageSize, urlSync, urlAdapter, features });
4504
+ const resolvedItemCardProps = {
4505
+ ...itemCardProps,
4506
+ showTags: itemCardProps?.showTags ?? view.enabled.tags,
4507
+ showPinButton: itemCardProps?.showPinButton ?? view.enabled.pin,
4508
+ showArchiveButton: itemCardProps?.showArchiveButton ?? view.enabled.archive
4509
+ };
4497
4510
  return /* @__PURE__ */ jsxs17(
4498
4511
  "section",
4499
4512
  {
@@ -4533,7 +4546,7 @@ function KeepCollectionContent({
4533
4546
  {
4534
4547
  query: view.resolvedQuery,
4535
4548
  renderItem,
4536
- itemCardProps,
4549
+ itemCardProps: resolvedItemCardProps,
4537
4550
  layout,
4538
4551
  loading,
4539
4552
  renderLoading,
@@ -5532,9 +5545,128 @@ function KeepSyncStatusBanner({
5532
5545
  );
5533
5546
  }
5534
5547
 
5548
+ // src/features/workspace/hooks/useKeepWorkspace.ts
5549
+ import { useCallback as useCallback9, useState as useState17 } from "react";
5550
+ var PRESET_MODULES = {
5551
+ basic: { syncStatus: false, undo: false, recovery: false, backup: false, stalePrune: false },
5552
+ standard: { syncStatus: false, undo: true, recovery: false, backup: false, stalePrune: false },
5553
+ management: { syncStatus: false, undo: true, recovery: false, backup: true, stalePrune: true },
5554
+ sync: { syncStatus: true, undo: true, recovery: true, backup: false, stalePrune: false }
5555
+ };
5556
+ var PRESET_COLLECTION_FEATURES = {
5557
+ basic: { search: false, sort: false, pagination: false },
5558
+ standard: {},
5559
+ management: { tagFilter: true, collectionFilter: true, bulkActions: true, pin: true, archive: true },
5560
+ sync: {}
5561
+ };
5562
+ function useKeepWorkspace({
5563
+ preset,
5564
+ modules,
5565
+ recoveryOpen,
5566
+ onRecoveryOpenChange,
5567
+ onResolveConflicts
5568
+ }) {
5569
+ const [internalRecoveryOpen, setInternalRecoveryOpen] = useState17(false);
5570
+ const resolvedModules = { ...PRESET_MODULES[preset], ...modules };
5571
+ const setRecoveryOpen = useCallback9(
5572
+ (open) => {
5573
+ if (recoveryOpen === void 0) setInternalRecoveryOpen(open);
5574
+ onRecoveryOpenChange?.(open);
5575
+ },
5576
+ [onRecoveryOpenChange, recoveryOpen]
5577
+ );
5578
+ const openRecovery = useCallback9(() => {
5579
+ onResolveConflicts?.();
5580
+ setRecoveryOpen(true);
5581
+ }, [onResolveConflicts, setRecoveryOpen]);
5582
+ return {
5583
+ preset,
5584
+ modules: resolvedModules,
5585
+ collectionFeatures: PRESET_COLLECTION_FEATURES[preset],
5586
+ recoveryOpen: recoveryOpen ?? internalRecoveryOpen,
5587
+ setRecoveryOpen,
5588
+ openRecovery
5589
+ };
5590
+ }
5591
+
5592
+ // src/features/workspace/KeepWorkspace.tsx
5593
+ import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
5594
+ function KeepWorkspace({
5595
+ preset = "standard",
5596
+ modules,
5597
+ collectionProps,
5598
+ syncStatusProps,
5599
+ recoveryProps,
5600
+ backupProps,
5601
+ undoProps,
5602
+ stalePruneProps,
5603
+ slots,
5604
+ children,
5605
+ className,
5606
+ ...props
5607
+ }) {
5608
+ const view = useKeepWorkspace({
5609
+ preset,
5610
+ modules,
5611
+ recoveryOpen: recoveryProps?.open,
5612
+ onRecoveryOpenChange: recoveryProps?.onOpenChange,
5613
+ onResolveConflicts: syncStatusProps?.onResolveConflicts
5614
+ });
5615
+ const state = {
5616
+ preset: view.preset,
5617
+ modules: view.modules,
5618
+ recoveryOpen: view.recoveryOpen,
5619
+ setRecoveryOpen: view.setRecoveryOpen
5620
+ };
5621
+ const resolvedCollectionProps = {
5622
+ ...collectionProps,
5623
+ features: { ...view.collectionFeatures, ...collectionProps?.features }
5624
+ };
5625
+ return /* @__PURE__ */ jsxs24("section", { ...props, className, "data-keepkit": "workspace", "data-preset": preset, children: [
5626
+ resolveOptionalSlot(slots?.before, state),
5627
+ view.modules.syncStatus ? resolveSlot(
5628
+ slots?.syncStatus,
5629
+ /* @__PURE__ */ jsx29(KeepSyncStatusBanner, { ...syncStatusProps, onResolveConflicts: view.openRecovery }),
5630
+ state
5631
+ ) : null,
5632
+ resolveSlot(slots?.collection, /* @__PURE__ */ jsx29(KeepCollection, { ...resolvedCollectionProps }), state),
5633
+ view.modules.backup || view.modules.stalePrune ? resolveSlot(
5634
+ slots?.actions,
5635
+ /* @__PURE__ */ jsxs24("div", { "data-keepkit": "workspace-actions", children: [
5636
+ view.modules.stalePrune ? /* @__PURE__ */ jsx29(KeepPruneStaleButton, { ...stalePruneProps }) : null,
5637
+ view.modules.backup ? /* @__PURE__ */ jsx29(KeepBackup, { ...backupProps }) : null
5638
+ ] }),
5639
+ state
5640
+ ) : null,
5641
+ view.modules.undo ? resolveSlot(slots?.undo, /* @__PURE__ */ jsx29(KeepUndo, { ...undoProps }), state) : null,
5642
+ view.modules.recovery ? resolveSlot(
5643
+ slots?.recovery,
5644
+ /* @__PURE__ */ jsx29(
5645
+ KeepSyncRecoveryDialog,
5646
+ {
5647
+ ...recoveryProps,
5648
+ open: view.recoveryOpen,
5649
+ onOpenChange: view.setRecoveryOpen
5650
+ }
5651
+ ),
5652
+ state
5653
+ ) : null,
5654
+ resolveOptionalSlot(children, state),
5655
+ resolveOptionalSlot(slots?.after, state)
5656
+ ] });
5657
+ }
5658
+ function resolveSlot(slot, fallback, state) {
5659
+ if (slot === void 0) return fallback;
5660
+ return resolveContent(slot, state);
5661
+ }
5662
+ function resolveOptionalSlot(slot, state) {
5663
+ if (slot === void 0) return null;
5664
+ return resolveContent(slot, state);
5665
+ }
5666
+
5535
5667
  // src/foundation/theme.tsx
5536
5668
  import { isValidElement as isValidElement9 } from "react";
5537
- import { jsx as jsx29 } from "react/jsx-runtime";
5669
+ import { jsx as jsx30 } from "react/jsx-runtime";
5538
5670
  var keepThemeNames = [
5539
5671
  "default",
5540
5672
  "ocean",
@@ -5593,7 +5725,7 @@ function KeepThemeProvider({
5593
5725
  throw new Error("KeepThemeProvider with asChild requires a single React element child.");
5594
5726
  return createSlot(children, rootProps);
5595
5727
  }
5596
- return /* @__PURE__ */ jsx29("div", { ...rootProps, children });
5728
+ return /* @__PURE__ */ jsx30("div", { ...rootProps, children });
5597
5729
  }
5598
5730
 
5599
5731
  // src/index.tsx
@@ -5617,7 +5749,7 @@ import {
5617
5749
  LocalStorageSyncQueueAdapter,
5618
5750
  SyncStorageAdapter
5619
5751
  } from "@keepkit/core/storage";
5620
- import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
5752
+ import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
5621
5753
  function KeepKitProvider({
5622
5754
  labels,
5623
5755
  locale,
@@ -5637,7 +5769,7 @@ function KeepKitProvider({
5637
5769
  children,
5638
5770
  ...providerProps
5639
5771
  }) {
5640
- return /* @__PURE__ */ jsx30(KeepUiProvider, { labels, locale, labelResolver, onFeedback, children: /* @__PURE__ */ jsx30(
5772
+ return /* @__PURE__ */ jsx31(KeepUiProvider, { labels, locale, labelResolver, onFeedback, children: /* @__PURE__ */ jsx31(
5641
5773
  KeepThemeProvider,
5642
5774
  {
5643
5775
  theme,
@@ -5651,10 +5783,10 @@ function KeepKitProvider({
5651
5783
  className: themeClassName,
5652
5784
  style: themeStyle,
5653
5785
  asChild: themeAsChild,
5654
- children: /* @__PURE__ */ jsxs24(CoreKeepProvider, { ...providerProps, children: [
5655
- /* @__PURE__ */ jsx30(KeepSyncFeedbackObserver, {}),
5786
+ children: /* @__PURE__ */ jsxs25(CoreKeepProvider, { ...providerProps, children: [
5787
+ /* @__PURE__ */ jsx31(KeepSyncFeedbackObserver, {}),
5656
5788
  children,
5657
- /* @__PURE__ */ jsx30(KeepAnnouncements, {})
5789
+ /* @__PURE__ */ jsx31(KeepAnnouncements, {})
5658
5790
  ] })
5659
5791
  }
5660
5792
  ) });
@@ -5681,7 +5813,7 @@ function createKeepKit(options = {}) {
5681
5813
  } = options;
5682
5814
  const coreKit = createCoreKeepKit(coreOptions);
5683
5815
  return {
5684
- Provider: (props) => /* @__PURE__ */ jsx30(
5816
+ Provider: (props) => /* @__PURE__ */ jsx31(
5685
5817
  KeepKitProvider,
5686
5818
  {
5687
5819
  ...coreOptions,
@@ -5702,9 +5834,9 @@ function createKeepKit(options = {}) {
5702
5834
  ...props
5703
5835
  }
5704
5836
  ),
5705
- Button: (props) => /* @__PURE__ */ jsx30(KeepButton, { ...props }),
5706
- Backup: (props) => /* @__PURE__ */ jsx30(KeepBackup, { ...props }),
5707
- Collection: (props) => /* @__PURE__ */ jsx30(
5837
+ Button: (props) => /* @__PURE__ */ jsx31(KeepButton, { ...props }),
5838
+ Backup: (props) => /* @__PURE__ */ jsx31(KeepBackup, { ...props }),
5839
+ Collection: (props) => /* @__PURE__ */ jsx31(
5708
5840
  KeepCollection,
5709
5841
  {
5710
5842
  ...props,
@@ -5715,6 +5847,20 @@ function createKeepKit(options = {}) {
5715
5847
  }
5716
5848
  }
5717
5849
  ),
5850
+ Workspace: (props) => /* @__PURE__ */ jsx31(
5851
+ KeepWorkspace,
5852
+ {
5853
+ ...props,
5854
+ collectionProps: {
5855
+ ...props.collectionProps,
5856
+ itemCardProps: {
5857
+ ...getTitle ? { getTitle } : {},
5858
+ ...getImageProps ? { getImageProps } : {},
5859
+ ...props.collectionProps?.itemCardProps
5860
+ }
5861
+ }
5862
+ }
5863
+ ),
5718
5864
  useContext: () => coreKit.useContext(),
5719
5865
  useItem: (item) => coreKit.useItem(item),
5720
5866
  useList: (query) => coreKit.useList(query),
@@ -5768,6 +5914,7 @@ export {
5768
5914
  KeepTourBar,
5769
5915
  KeepUiProvider,
5770
5916
  KeepUndo,
5917
+ KeepWorkspace,
5771
5918
  LocalStorageAdapter,
5772
5919
  LocalStorageSyncQueueAdapter,
5773
5920
  SyncStorageAdapter,