@keepkit/ui 0.13.0 → 0.14.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 +4 -2
- package/dist/index.d.ts +6 -5
- package/dist/index.js +150 -22
- package/dist/index.js.map +1 -1
- package/dist/styles/base.css +23 -1
- package/dist/styles/collection.css +42 -29
- package/dist/styles/sync.css +39 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -56,8 +56,9 @@ function SavedArticles() {
|
|
|
56
56
|
|
|
57
57
|
`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)を使えます。
|
|
58
58
|
`KeepItemCard`は`href`、`onOpen`、`linkTarget`、`linkComponent`に対応し、保存アイテムから詳細ページへ遷移できます。非公開・期限切れ等の`status`を持つアイテムは自動的にリンクを無効化します。`KeepBackup`はJSONのエクスポート、merge / replaceインポート、結果件数、容量エラー表示を提供します。
|
|
59
|
+
外部URLの詳細リンクには`target="_blank"`と`rel="noreferrer"`が既定で補完され、利用できないカードには`aria-disabled="true"`と`data-item-status`が付与されます。同期競合ダイアログではローカルとリモートの更新日時・メモを並べて確認できます。
|
|
59
60
|
|
|
60
|
-
v0.
|
|
61
|
+
v0.14.0では`KeepCollection urlSync layout="list" | "grid" | "compact"`、`KeepBulkActions selectionScope="page" | "query" | "all"`、`KeepUndo`を利用できます。`createNextPagesRouterAdapter`はNext.js Pages Router用の注入adapterです。`locale`は英語、日本語、韓国語、中国語簡体字・繁体字、タイ語、フランス語、スペイン語、ポルトガル語、イタリア語、ドイツ語、ロシア語、フィリピン語、ベトナム語、インドネシア語、マレー語の16言語に対応し、`labels`で上書きできます。認証付き同期は`createAuthenticatedSyncKit`から利用できます。
|
|
61
62
|
Phase 4の状態UIとして`KeepItemStatusBadge`、`KeepStaleNotice`、`KeepPruneStaleButton`、`KeepSyncStatusBanner`、`KeepSyncRecoveryDialog`を利用できます。`import "@keepkit/ui/theme.css"`でテーマCSSを有効にできます。
|
|
62
63
|
|
|
63
64
|
### Tailwind/shadcnテーマ
|
|
@@ -142,8 +143,9 @@ function SavedArticles() {
|
|
|
142
143
|
|
|
143
144
|
`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.
|
|
144
145
|
`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.
|
|
146
|
+
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.
|
|
145
147
|
|
|
146
|
-
In v0.
|
|
148
|
+
In v0.14.0, use `KeepCollection urlSync` with `layout="list" | "grid" | "compact"`, `KeepBulkActions selectionScope="page" | "query" | "all"`, and `KeepUndo`. `createNextPagesRouterAdapter` is the injected adapter for Next.js Pages Router. `locale` includes complete dictionaries for 16 built-in locales; `labels` overrides individual entries. Authenticated sync is available through `createAuthenticatedSyncKit`.
|
|
147
149
|
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.
|
|
148
150
|
|
|
149
151
|
### Tailwind and shadcn theme
|
package/dist/index.d.ts
CHANGED
|
@@ -211,9 +211,10 @@ type KeepItemCheckboxProps<TMeta = Record<string, unknown>> = Omit<InputHTMLAttr
|
|
|
211
211
|
declare function KeepItemCheckbox<TMeta = Record<string, unknown>>({ item, checked, label, onCheckedChange, "aria-label": ariaLabel, ...props }: KeepItemCheckboxProps<TMeta>): react.JSX.Element;
|
|
212
212
|
|
|
213
213
|
type KeepItemStatusBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
|
|
214
|
-
status?: KeepItemStatus;
|
|
214
|
+
status?: KeepItemStatus | "restricted";
|
|
215
215
|
label?: ReactNode;
|
|
216
216
|
};
|
|
217
|
+
type KeepDisplayStatus = "available" | "expired" | "removed" | "restricted";
|
|
217
218
|
/** Displays the normalized availability state of a saved item. */
|
|
218
219
|
declare function KeepItemStatusBadge({ status, label, className, ...props }: KeepItemStatusBadgeProps): react.JSX.Element;
|
|
219
220
|
|
|
@@ -221,8 +222,8 @@ type KeepLayoutProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
|
221
222
|
layout?: KeepLayoutPreset;
|
|
222
223
|
children?: ReactNode;
|
|
223
224
|
};
|
|
224
|
-
/** A
|
|
225
|
-
declare function KeepLayout({ layout, children,
|
|
225
|
+
/** A style-free layout wrapper with a stable preset attribute for host or theme CSS. */
|
|
226
|
+
declare function KeepLayout({ layout, children, ...props }: KeepLayoutProps): react.JSX.Element;
|
|
226
227
|
|
|
227
228
|
type KeepNoteEditorState<TMeta = Record<string, unknown>> = {
|
|
228
229
|
item: KeepItem<TMeta>;
|
|
@@ -432,7 +433,7 @@ type KeepThemeProviderProps = {
|
|
|
432
433
|
/** Scopes KeepKit tokens and opt-in component styles to one subtree. */
|
|
433
434
|
declare function KeepThemeProvider({ children, theme, mode, density, radius, accentColor, highContrast, reducedMotion, variables, style, className, asChild, ...props }: KeepThemeProviderProps): react.JSX.Element;
|
|
434
435
|
|
|
435
|
-
type KeepUiLabelKey = "save" | "saved" | "remove" | "loading" | "saving" | "syncing" | "error" | "allTags" | "tags" | "filterTags" | "note" | "saveNote" | "noItems" | "loadingItems" | "errorItems" | "search" | "sort" | "newest" | "oldest" | "savedNewest" | "savedOldest" | "updatedNewest" | "updatedOldest" | "previousPage" | "nextPage" | "pagination" | "page" | "selectItems" | "selectedCount" | "deleteSelected" | "tagsToApply" | "applyTags" | "savedMessage" | "removedMessage" | "undo" | "undoAvailable" | "selectionScope" | "currentPage" | "searchResults" | "allItems" | "statusAvailable" | "noteSavedMessage" | "exportData" | "importData" | "importMode" | "merge" | "replace" | "importedCount" | "failedCount" | "storageQuotaError" | "statusExpired" | "statusRemoved" | "statusDeleted" | "statusPrivate" | "statusUnknown" | "retry" | "removeFromList" | "pruneStale" | "retrySync" | "resolveSync" | "keepLocal" | "useServer" | "manualMerge" | "close" | "backupRecovery" | "backupRecoveryDescription" | "syncPending" | "syncSynced" | "syncConflict";
|
|
436
|
+
type KeepUiLabelKey = "save" | "saved" | "remove" | "loading" | "saving" | "syncing" | "error" | "allTags" | "tags" | "filterTags" | "note" | "saveNote" | "noItems" | "loadingItems" | "errorItems" | "search" | "sort" | "newest" | "oldest" | "savedNewest" | "savedOldest" | "updatedNewest" | "updatedOldest" | "previousPage" | "nextPage" | "pagination" | "page" | "selectItems" | "selectedCount" | "deleteSelected" | "tagsToApply" | "applyTags" | "savedMessage" | "removedMessage" | "undo" | "undoAvailable" | "selectionScope" | "currentPage" | "searchResults" | "allItems" | "localVersion" | "remoteVersion" | "updatedAt" | "statusAvailable" | "noteSavedMessage" | "exportData" | "importData" | "importMode" | "merge" | "replace" | "importedCount" | "failedCount" | "storageQuotaError" | "statusExpired" | "statusRemoved" | "statusDeleted" | "statusPrivate" | "statusUnknown" | "retry" | "removeFromList" | "pruneStale" | "retrySync" | "resolveSync" | "keepLocal" | "useServer" | "manualMerge" | "close" | "backupRecovery" | "backupRecoveryDescription" | "syncPending" | "syncSynced" | "syncConflict";
|
|
436
437
|
type KeepUiLabels = Partial<Record<KeepUiLabelKey, string>>;
|
|
437
438
|
type KeepUiLocaleLabels = Record<KeepUiLabelKey, string>;
|
|
438
439
|
|
|
@@ -491,4 +492,4 @@ type KeepKit<TMeta = Record<string, unknown>> = {
|
|
|
491
492
|
/** Create one typed application API for the core and standard UI layer. */
|
|
492
493
|
declare function createKeepKit<TMeta = Record<string, unknown>>(options?: CreateKeepKitOptions<TMeta>): KeepKit<TMeta>;
|
|
493
494
|
|
|
494
|
-
export { type CreateKeepKitOptions, KeepAnnouncements, type KeepAnnouncementsProps, KeepAnnouncer, KeepBackup, type KeepBackupProps, KeepBulkActions, type KeepBulkActionsProps, type KeepBulkActionsState, KeepButton, type KeepButtonIcon, type KeepButtonIconProps, type KeepButtonIcons, type KeepButtonLabels, type KeepButtonProps, KeepCollection, type KeepCollectionFeature, type KeepCollectionProps, KeepEmptyState, type KeepEmptyStateProps, type KeepImageProps, KeepItemCard, type KeepItemCardLinkProps, type KeepItemCardProps, type KeepItemCardState, KeepItemCheckbox, type KeepItemCheckboxProps, KeepItemStatusBadge, type KeepItemStatusBadgeProps, type KeepKit, KeepKitProvider, type KeepKitProviderProps, KeepLayout, type KeepLayoutPreset, type KeepLayoutProps, KeepList, type KeepListProps, type KeepListState, KeepNoteEditor, type KeepNoteEditorProps, type KeepNoteEditorState, type KeepPagesRouterLike, KeepPagination, type KeepPaginationProps, type KeepPaginationState, KeepPruneStaleButton, type KeepPruneStaleButtonProps, KeepSearchInput, type KeepSearchInputProps, type KeepSelectionScope, 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 KeepUiLabelContext, type KeepUiLabelKey, type KeepUiLabels, type KeepUiLocale, type KeepUiLocaleLabels, KeepUiProvider, type KeepUiProviderProps, KeepUndo, type KeepUndoProps, type KeepUrlAdapter, type RenderProp, createKeepKit, createNextPagesRouterAdapter, getKeepLocaleLabels, isAllSelected, toggleSelectAll, useKeepUiLabels, useKeepUrlSync };
|
|
495
|
+
export { type CreateKeepKitOptions, KeepAnnouncements, type KeepAnnouncementsProps, KeepAnnouncer, KeepBackup, type KeepBackupProps, KeepBulkActions, type KeepBulkActionsProps, type KeepBulkActionsState, KeepButton, type KeepButtonIcon, type KeepButtonIconProps, type KeepButtonIcons, type KeepButtonLabels, type KeepButtonProps, KeepCollection, type KeepCollectionFeature, type KeepCollectionProps, type KeepDisplayStatus, KeepEmptyState, type KeepEmptyStateProps, type KeepImageProps, KeepItemCard, type KeepItemCardLinkProps, type KeepItemCardProps, type KeepItemCardState, KeepItemCheckbox, type KeepItemCheckboxProps, KeepItemStatusBadge, type KeepItemStatusBadgeProps, type KeepKit, KeepKitProvider, type KeepKitProviderProps, KeepLayout, type KeepLayoutPreset, type KeepLayoutProps, KeepList, type KeepListProps, type KeepListState, KeepNoteEditor, type KeepNoteEditorProps, type KeepNoteEditorState, type KeepPagesRouterLike, KeepPagination, type KeepPaginationProps, type KeepPaginationState, KeepPruneStaleButton, type KeepPruneStaleButtonProps, KeepSearchInput, type KeepSearchInputProps, type KeepSelectionScope, 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 KeepUiLabelContext, type KeepUiLabelKey, type KeepUiLabels, type KeepUiLocale, type KeepUiLocaleLabels, KeepUiProvider, type KeepUiProviderProps, KeepUndo, type KeepUndoProps, type KeepUrlAdapter, type RenderProp, createKeepKit, createNextPagesRouterAdapter, getKeepLocaleLabels, isAllSelected, toggleSelectAll, useKeepUiLabels, useKeepUrlSync };
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,9 @@ var DE_LABELS = {
|
|
|
55
55
|
currentPage: "Aktuelle Seite",
|
|
56
56
|
searchResults: "Aktuelle Suchergebnisse",
|
|
57
57
|
allItems: "Alle gespeicherten Elemente",
|
|
58
|
+
localVersion: "Lokal",
|
|
59
|
+
remoteVersion: "Server",
|
|
60
|
+
updatedAt: "Aktualisiert",
|
|
58
61
|
statusAvailable: "Verf\xFCgbar",
|
|
59
62
|
noteSavedMessage: "Notiz gespeichert.",
|
|
60
63
|
exportData: "JSON exportieren",
|
|
@@ -128,6 +131,9 @@ var EN_LABELS = {
|
|
|
128
131
|
currentPage: "Current page",
|
|
129
132
|
searchResults: "Current search results",
|
|
130
133
|
allItems: "All saved items",
|
|
134
|
+
localVersion: "Local",
|
|
135
|
+
remoteVersion: "Remote",
|
|
136
|
+
updatedAt: "Updated",
|
|
131
137
|
statusAvailable: "Available",
|
|
132
138
|
noteSavedMessage: "Note saved.",
|
|
133
139
|
exportData: "Export JSON",
|
|
@@ -201,6 +207,9 @@ var ES_LABELS = {
|
|
|
201
207
|
currentPage: "P\xE1gina actual",
|
|
202
208
|
searchResults: "Resultados de b\xFAsqueda actuales",
|
|
203
209
|
allItems: "Todos los elementos guardados",
|
|
210
|
+
localVersion: "Local",
|
|
211
|
+
remoteVersion: "Servidor",
|
|
212
|
+
updatedAt: "Actualizado",
|
|
204
213
|
statusAvailable: "Disponible",
|
|
205
214
|
noteSavedMessage: "Nota guardada.",
|
|
206
215
|
exportData: "Exportar JSON",
|
|
@@ -274,6 +283,9 @@ var FIL_LABELS = {
|
|
|
274
283
|
currentPage: "Kasalukuyang pahina",
|
|
275
284
|
searchResults: "Kasalukuyang resulta ng paghahanap",
|
|
276
285
|
allItems: "Lahat ng naka-save na item",
|
|
286
|
+
localVersion: "Lokal",
|
|
287
|
+
remoteVersion: "Remote",
|
|
288
|
+
updatedAt: "Na-update",
|
|
277
289
|
statusAvailable: "Available",
|
|
278
290
|
noteSavedMessage: "Na-save ang tala.",
|
|
279
291
|
exportData: "I-export ang JSON",
|
|
@@ -347,6 +359,9 @@ var FR_LABELS = {
|
|
|
347
359
|
currentPage: "Page actuelle",
|
|
348
360
|
searchResults: "R\xE9sultats de recherche actuels",
|
|
349
361
|
allItems: "Tous les \xE9l\xE9ments enregistr\xE9s",
|
|
362
|
+
localVersion: "Local",
|
|
363
|
+
remoteVersion: "Distant",
|
|
364
|
+
updatedAt: "Mis \xE0 jour",
|
|
350
365
|
statusAvailable: "Disponible",
|
|
351
366
|
noteSavedMessage: "Note enregistr\xE9e.",
|
|
352
367
|
exportData: "Exporter JSON",
|
|
@@ -420,6 +435,9 @@ var ID_LABELS = {
|
|
|
420
435
|
currentPage: "Halaman saat ini",
|
|
421
436
|
searchResults: "Hasil pencarian saat ini",
|
|
422
437
|
allItems: "Semua item tersimpan",
|
|
438
|
+
localVersion: "Lokal",
|
|
439
|
+
remoteVersion: "Server",
|
|
440
|
+
updatedAt: "Diperbarui",
|
|
423
441
|
statusAvailable: "Tersedia",
|
|
424
442
|
noteSavedMessage: "Catatan tersimpan.",
|
|
425
443
|
exportData: "Ekspor JSON",
|
|
@@ -493,6 +511,9 @@ var IT_LABELS = {
|
|
|
493
511
|
currentPage: "Pagina corrente",
|
|
494
512
|
searchResults: "Risultati di ricerca correnti",
|
|
495
513
|
allItems: "Tutti gli elementi salvati",
|
|
514
|
+
localVersion: "Locale",
|
|
515
|
+
remoteVersion: "Server",
|
|
516
|
+
updatedAt: "Aggiornato",
|
|
496
517
|
statusAvailable: "Disponibile",
|
|
497
518
|
noteSavedMessage: "Nota salvata.",
|
|
498
519
|
exportData: "Esporta JSON",
|
|
@@ -566,6 +587,9 @@ var JA_LABELS = {
|
|
|
566
587
|
currentPage: "\u8868\u793A\u4E2D\u306E\u30DA\u30FC\u30B8",
|
|
567
588
|
searchResults: "\u73FE\u5728\u306E\u691C\u7D22\u7D50\u679C\u5168\u4F53",
|
|
568
589
|
allItems: "\u3059\u3079\u3066\u306E\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0",
|
|
590
|
+
localVersion: "\u30ED\u30FC\u30AB\u30EB",
|
|
591
|
+
remoteVersion: "\u30EA\u30E2\u30FC\u30C8",
|
|
592
|
+
updatedAt: "\u66F4\u65B0\u65E5\u6642",
|
|
569
593
|
statusAvailable: "\u5229\u7528\u53EF\u80FD",
|
|
570
594
|
noteSavedMessage: "\u30E1\u30E2\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
|
|
571
595
|
exportData: "JSON\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8",
|
|
@@ -639,6 +663,9 @@ var KO_LABELS = {
|
|
|
639
663
|
currentPage: "\uD604\uC7AC \uD398\uC774\uC9C0",
|
|
640
664
|
searchResults: "\uD604\uC7AC \uAC80\uC0C9 \uACB0\uACFC \uC804\uCCB4",
|
|
641
665
|
allItems: "\uBAA8\uB4E0 \uC800\uC7A5 \uD56D\uBAA9",
|
|
666
|
+
localVersion: "\uB85C\uCEEC",
|
|
667
|
+
remoteVersion: "\uC6D0\uACA9",
|
|
668
|
+
updatedAt: "\uC5C5\uB370\uC774\uD2B8 \uC2DC\uAC04",
|
|
642
669
|
statusAvailable: "\uC0AC\uC6A9 \uAC00\uB2A5",
|
|
643
670
|
noteSavedMessage: "\uBA54\uBAA8\uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.",
|
|
644
671
|
exportData: "JSON \uB0B4\uBCF4\uB0B4\uAE30",
|
|
@@ -712,6 +739,9 @@ var MS_LABELS = {
|
|
|
712
739
|
currentPage: "Halaman semasa",
|
|
713
740
|
searchResults: "Hasil carian semasa",
|
|
714
741
|
allItems: "Semua item yang disimpan",
|
|
742
|
+
localVersion: "Tempatan",
|
|
743
|
+
remoteVersion: "Pelayan",
|
|
744
|
+
updatedAt: "Dikemas kini",
|
|
715
745
|
statusAvailable: "Tersedia",
|
|
716
746
|
noteSavedMessage: "Nota disimpan.",
|
|
717
747
|
exportData: "Eksport JSON",
|
|
@@ -785,6 +815,9 @@ var PT_BR_LABELS = {
|
|
|
785
815
|
currentPage: "P\xE1gina atual",
|
|
786
816
|
searchResults: "Resultados da pesquisa atual",
|
|
787
817
|
allItems: "Todos os itens salvos",
|
|
818
|
+
localVersion: "Local",
|
|
819
|
+
remoteVersion: "Servidor",
|
|
820
|
+
updatedAt: "Atualizado",
|
|
788
821
|
statusAvailable: "Dispon\xEDvel",
|
|
789
822
|
noteSavedMessage: "Nota salva.",
|
|
790
823
|
exportData: "Exportar JSON",
|
|
@@ -858,6 +891,9 @@ var RU_LABELS = {
|
|
|
858
891
|
currentPage: "\u0422\u0435\u043A\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
|
|
859
892
|
searchResults: "\u0422\u0435\u043A\u0443\u0449\u0438\u0435 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E\u0438\u0441\u043A\u0430",
|
|
860
893
|
allItems: "\u0412\u0441\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B",
|
|
894
|
+
localVersion: "\u041B\u043E\u043A\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F",
|
|
895
|
+
remoteVersion: "\u0421\u0435\u0440\u0432\u0435\u0440\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F",
|
|
896
|
+
updatedAt: "\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u043E",
|
|
861
897
|
statusAvailable: "\u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D",
|
|
862
898
|
noteSavedMessage: "\u0417\u0430\u043C\u0435\u0442\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0430.",
|
|
863
899
|
exportData: "\u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C JSON",
|
|
@@ -931,6 +967,9 @@ var TH_LABELS = {
|
|
|
931
967
|
currentPage: "\u0E2B\u0E19\u0E49\u0E32\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
|
|
932
968
|
searchResults: "\u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
|
|
933
969
|
allItems: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
|
|
970
|
+
localVersion: "\u0E43\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07",
|
|
971
|
+
remoteVersion: "\u0E23\u0E30\u0E22\u0E30\u0E44\u0E01\u0E25",
|
|
972
|
+
updatedAt: "\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E40\u0E21\u0E37\u0E48\u0E2D",
|
|
934
973
|
statusAvailable: "\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19",
|
|
935
974
|
noteSavedMessage: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D\u0E41\u0E25\u0E49\u0E27",
|
|
936
975
|
exportData: "\u0E2A\u0E48\u0E07\u0E2D\u0E2D\u0E01 JSON",
|
|
@@ -1004,6 +1043,9 @@ var VI_LABELS = {
|
|
|
1004
1043
|
currentPage: "Trang hi\u1EC7n t\u1EA1i",
|
|
1005
1044
|
searchResults: "K\u1EBFt qu\u1EA3 t\xECm ki\u1EBFm hi\u1EC7n t\u1EA1i",
|
|
1006
1045
|
allItems: "T\u1EA5t c\u1EA3 m\u1EE5c \u0111\xE3 l\u01B0u",
|
|
1046
|
+
localVersion: "C\u1EE5c b\u1ED9",
|
|
1047
|
+
remoteVersion: "M\xE1y ch\u1EE7",
|
|
1048
|
+
updatedAt: "\u0110\xE3 c\u1EADp nh\u1EADt",
|
|
1007
1049
|
statusAvailable: "Kh\u1EA3 d\u1EE5ng",
|
|
1008
1050
|
noteSavedMessage: "\u0110\xE3 l\u01B0u ghi ch\xFA.",
|
|
1009
1051
|
exportData: "Xu\u1EA5t JSON",
|
|
@@ -1077,6 +1119,9 @@ var ZH_HANS_LABELS = {
|
|
|
1077
1119
|
currentPage: "\u5F53\u524D\u9875",
|
|
1078
1120
|
searchResults: "\u5F53\u524D\u5168\u90E8\u641C\u7D22\u7ED3\u679C",
|
|
1079
1121
|
allItems: "\u5168\u90E8\u5DF2\u4FDD\u5B58\u9879\u76EE",
|
|
1122
|
+
localVersion: "\u672C\u5730",
|
|
1123
|
+
remoteVersion: "\u8FDC\u7A0B",
|
|
1124
|
+
updatedAt: "\u66F4\u65B0\u65F6\u95F4",
|
|
1080
1125
|
statusAvailable: "\u53EF\u7528",
|
|
1081
1126
|
noteSavedMessage: "\u5907\u6CE8\u5DF2\u4FDD\u5B58\u3002",
|
|
1082
1127
|
exportData: "\u5BFC\u51FAJSON",
|
|
@@ -1150,6 +1195,9 @@ var ZH_HANT_LABELS = {
|
|
|
1150
1195
|
currentPage: "\u76EE\u524D\u9801\u9762",
|
|
1151
1196
|
searchResults: "\u76EE\u524D\u5168\u90E8\u641C\u5C0B\u7D50\u679C",
|
|
1152
1197
|
allItems: "\u6240\u6709\u5DF2\u5132\u5B58\u9805\u76EE",
|
|
1198
|
+
localVersion: "\u672C\u6A5F",
|
|
1199
|
+
remoteVersion: "\u9060\u7AEF",
|
|
1200
|
+
updatedAt: "\u66F4\u65B0\u6642\u9593",
|
|
1153
1201
|
statusAvailable: "\u53EF\u7528",
|
|
1154
1202
|
noteSavedMessage: "\u5099\u8A3B\u5DF2\u5132\u5B58\u3002",
|
|
1155
1203
|
exportData: "\u532F\u51FAJSON",
|
|
@@ -1661,9 +1709,19 @@ import { useState as useState3 } from "react";
|
|
|
1661
1709
|
// src/KeepItemStatusBadge.tsx
|
|
1662
1710
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1663
1711
|
function KeepItemStatusBadge({ status = "available", label, className, ...props }) {
|
|
1664
|
-
const resolvedStatus = status
|
|
1665
|
-
const statusLabel = useUiLabel(getStatusLabelKey(
|
|
1666
|
-
return /* @__PURE__ */ jsx7(
|
|
1712
|
+
const resolvedStatus = getDisplayStatus(status);
|
|
1713
|
+
const statusLabel = useUiLabel(getStatusLabelKey(status));
|
|
1714
|
+
return /* @__PURE__ */ jsx7(
|
|
1715
|
+
"span",
|
|
1716
|
+
{
|
|
1717
|
+
...props,
|
|
1718
|
+
className,
|
|
1719
|
+
"data-keepkit": "status-badge",
|
|
1720
|
+
"data-status": status,
|
|
1721
|
+
"data-item-status": resolvedStatus,
|
|
1722
|
+
children: label ?? statusLabel
|
|
1723
|
+
}
|
|
1724
|
+
);
|
|
1667
1725
|
}
|
|
1668
1726
|
function getStatusLabelKey(status) {
|
|
1669
1727
|
switch (status) {
|
|
@@ -1676,10 +1734,19 @@ function getStatusLabelKey(status) {
|
|
|
1676
1734
|
case "deleted":
|
|
1677
1735
|
return "statusDeleted";
|
|
1678
1736
|
case "private":
|
|
1737
|
+
return "statusPrivate";
|
|
1679
1738
|
case "unknown":
|
|
1680
|
-
return
|
|
1739
|
+
return "statusUnknown";
|
|
1740
|
+
case "restricted":
|
|
1741
|
+
return "statusPrivate";
|
|
1681
1742
|
}
|
|
1682
1743
|
}
|
|
1744
|
+
function getDisplayStatus(status) {
|
|
1745
|
+
if (status === "available") return "available";
|
|
1746
|
+
if (status === "expired") return "expired";
|
|
1747
|
+
if (status === "removed") return "removed";
|
|
1748
|
+
return "restricted";
|
|
1749
|
+
}
|
|
1683
1750
|
|
|
1684
1751
|
// src/KeepStaleNotice.tsx
|
|
1685
1752
|
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
@@ -1810,6 +1877,10 @@ function KeepItemCard({
|
|
|
1810
1877
|
const imageProps = getImageProps?.(item, resolvedTitle);
|
|
1811
1878
|
const href = typeof hrefOption === "function" ? hrefOption(item) : hrefOption;
|
|
1812
1879
|
const isAvailable = item.status === void 0 || item.status === "available";
|
|
1880
|
+
const displayStatus = getDisplayStatus2(item.status);
|
|
1881
|
+
const isExternalLink = href ? isExternalHref(href) : false;
|
|
1882
|
+
const resolvedLinkTarget = linkTargetAttribute ?? (isExternalLink ? "_blank" : void 0);
|
|
1883
|
+
const resolvedLinkRel = linkRel ?? (isExternalLink ? "noreferrer" : void 0);
|
|
1813
1884
|
const statusLabelKey = item.status && item.status !== "available" ? getStatusLabelKey2(item.status) : "statusUnknown";
|
|
1814
1885
|
const unavailableLabel = useUiLabel(statusLabelKey);
|
|
1815
1886
|
const tagsLabel = useUiLabel("tags");
|
|
@@ -1818,8 +1889,8 @@ function KeepItemCard({
|
|
|
1818
1889
|
if (!href || !isAvailable) return content;
|
|
1819
1890
|
const linkProps = {
|
|
1820
1891
|
href,
|
|
1821
|
-
target:
|
|
1822
|
-
rel:
|
|
1892
|
+
target: resolvedLinkTarget,
|
|
1893
|
+
rel: resolvedLinkRel,
|
|
1823
1894
|
onClick: (event) => onOpen?.(item, event),
|
|
1824
1895
|
children: content
|
|
1825
1896
|
};
|
|
@@ -1835,7 +1906,7 @@ function KeepItemCard({
|
|
|
1835
1906
|
}
|
|
1836
1907
|
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1837
1908
|
imageProps ? renderImage?.({ ...imageProps, alt: imageAlt ?? imageProps.alt }, item) ?? (ImageComponent ? /* @__PURE__ */ jsx9(ImageComponent, { ...imageProps, alt: imageAlt ?? imageProps.alt }) : /* @__PURE__ */ jsx9("img", { ...imageProps, alt: imageAlt ?? imageProps.alt })) : null,
|
|
1838
|
-
/* @__PURE__ */ jsx9("h3", { children: linkTarget === "title" ? renderLink(resolvedTitle) : resolvedTitle }),
|
|
1909
|
+
/* @__PURE__ */ jsx9("h3", { children: linkTarget === "title" ? isAvailable ? renderLink(resolvedTitle) : href ? /* @__PURE__ */ jsx9("span", { "aria-disabled": "true", "data-link-disabled": "true", children: resolvedTitle }) : resolvedTitle : resolvedTitle }),
|
|
1839
1910
|
showSavedAt ? /* @__PURE__ */ jsxs5("div", { "data-card-meta": true, children: [
|
|
1840
1911
|
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1841
1912
|
savedAtLabel,
|
|
@@ -1857,7 +1928,7 @@ function KeepItemCard({
|
|
|
1857
1928
|
) : null,
|
|
1858
1929
|
!statusLabel ? /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => void handleRemove(), disabled: itemState.isMutating, children: removeLabel ?? removeActionLabel }) : null
|
|
1859
1930
|
] });
|
|
1860
|
-
const linkedBody = linkTarget === "card" ? renderLink(body) : body;
|
|
1931
|
+
const linkedBody = linkTarget === "card" && isAvailable ? renderLink(body) : body;
|
|
1861
1932
|
return renderRoot(
|
|
1862
1933
|
asChild,
|
|
1863
1934
|
isValidElement2(children) ? children : void 0,
|
|
@@ -1866,8 +1937,10 @@ function KeepItemCard({
|
|
|
1866
1937
|
className,
|
|
1867
1938
|
"data-keepkit": "card",
|
|
1868
1939
|
"aria-busy": itemState.isMutating || rootProps["aria-busy"],
|
|
1940
|
+
"aria-disabled": rootProps["aria-disabled"] ?? (!isAvailable ? "true" : void 0),
|
|
1869
1941
|
"data-state": itemState.error ? "error" : itemState.isSaved ? "saved" : "unsaved",
|
|
1870
1942
|
"data-status": item.status ?? "available",
|
|
1943
|
+
"data-item-status": displayStatus,
|
|
1871
1944
|
"data-loading": itemState.isMutating ? "true" : void 0
|
|
1872
1945
|
},
|
|
1873
1946
|
linkedBody,
|
|
@@ -1888,6 +1961,15 @@ function getStatusLabelKey2(status) {
|
|
|
1888
1961
|
return "statusUnknown";
|
|
1889
1962
|
}
|
|
1890
1963
|
}
|
|
1964
|
+
function getDisplayStatus2(status) {
|
|
1965
|
+
if (status === void 0 || status === "available") return "available";
|
|
1966
|
+
if (status === "expired") return "expired";
|
|
1967
|
+
if (status === "removed") return "removed";
|
|
1968
|
+
return "restricted";
|
|
1969
|
+
}
|
|
1970
|
+
function isExternalHref(href) {
|
|
1971
|
+
return /^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(href);
|
|
1972
|
+
}
|
|
1891
1973
|
function formatSavedAt(timestamp) {
|
|
1892
1974
|
return new Date(timestamp).toISOString().slice(0, 10);
|
|
1893
1975
|
}
|
|
@@ -1936,6 +2018,7 @@ function KeepListContent({
|
|
|
1936
2018
|
...rootProps,
|
|
1937
2019
|
className,
|
|
1938
2020
|
"data-keepkit": "list",
|
|
2021
|
+
"data-layout": layout,
|
|
1939
2022
|
"aria-busy": state.isLoading || rootProps["aria-busy"],
|
|
1940
2023
|
"data-state": getListState(state),
|
|
1941
2024
|
"data-loading": state.isLoading ? "true" : void 0
|
|
@@ -1956,16 +2039,9 @@ function getListBody(state, options) {
|
|
|
1956
2039
|
if (state.isHydrated && state.items.length === 0) return resolveContent(options.empty, state);
|
|
1957
2040
|
if (typeof options.children === "function") return options.children(state);
|
|
1958
2041
|
if (options.children !== void 0 && !isValidElement3(options.children)) return options.children;
|
|
1959
|
-
return /* @__PURE__ */ jsx10(
|
|
1960
|
-
"
|
|
1961
|
-
|
|
1962
|
-
"data-layout": options.layout,
|
|
1963
|
-
style: options.layout === "grid" ? { display: "grid", gap: "1rem", gridTemplateColumns: "repeat(auto-fit, minmax(16rem, 1fr))" } : options.layout === "compact" ? { display: "grid", gap: "0.5rem", gridTemplateColumns: "repeat(auto-fit, minmax(12rem, 1fr))" } : { display: "flex", flexDirection: "column", gap: "1rem" },
|
|
1964
|
-
children: state.items.map(
|
|
1965
|
-
(item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
|
|
1966
|
-
)
|
|
1967
|
-
}
|
|
1968
|
-
);
|
|
2042
|
+
return /* @__PURE__ */ jsx10("ul", { "data-layout": options.layout, children: state.items.map(
|
|
2043
|
+
(item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
|
|
2044
|
+
) });
|
|
1969
2045
|
}
|
|
1970
2046
|
|
|
1971
2047
|
// src/KeepTagFilter.tsx
|
|
@@ -2315,6 +2391,7 @@ function KeepCollectionContent({
|
|
|
2315
2391
|
...rootProps,
|
|
2316
2392
|
className,
|
|
2317
2393
|
"data-keepkit": "collection",
|
|
2394
|
+
"data-layout": layout,
|
|
2318
2395
|
"aria-busy": list.isLoading || list.isMutating || rootProps["aria-busy"],
|
|
2319
2396
|
"data-state": getCollectionState(list),
|
|
2320
2397
|
"data-loading": list.isLoading || list.isMutating ? "true" : void 0,
|
|
@@ -2387,9 +2464,8 @@ function getCollectionState(list) {
|
|
|
2387
2464
|
|
|
2388
2465
|
// src/KeepLayout.tsx
|
|
2389
2466
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2390
|
-
function KeepLayout({ layout = "list", children,
|
|
2391
|
-
|
|
2392
|
-
return /* @__PURE__ */ jsx14("div", { ...props, style: { ...layoutStyle, ...style }, "data-keepkit": "layout", "data-layout": layout, children });
|
|
2467
|
+
function KeepLayout({ layout = "list", children, ...props }) {
|
|
2468
|
+
return /* @__PURE__ */ jsx14("div", { ...props, "data-keepkit": "layout", "data-layout": layout, children });
|
|
2393
2469
|
}
|
|
2394
2470
|
|
|
2395
2471
|
// src/KeepNoteEditor.tsx
|
|
@@ -2541,6 +2617,10 @@ function KeepSyncRecoveryDialog({
|
|
|
2541
2617
|
const keepLocalLabel = useUiLabel("keepLocal");
|
|
2542
2618
|
const useServerLabel = useUiLabel("useServer");
|
|
2543
2619
|
const manualMergeLabel = useUiLabel("manualMerge");
|
|
2620
|
+
const localVersionLabel = useUiLabel("localVersion");
|
|
2621
|
+
const remoteVersionLabel = useUiLabel("remoteVersion");
|
|
2622
|
+
const updatedAtLabel = useUiLabel("updatedAt");
|
|
2623
|
+
const noteLabel = useUiLabel("note");
|
|
2544
2624
|
const backupRecoveryLabel = useUiLabel("backupRecovery");
|
|
2545
2625
|
const backupRecoveryDescription = useUiLabel("backupRecoveryDescription");
|
|
2546
2626
|
const errorLabel = useUiLabel("error");
|
|
@@ -2579,6 +2659,8 @@ function KeepSyncRecoveryDialog({
|
|
|
2579
2659
|
role: "dialog",
|
|
2580
2660
|
"aria-modal": "true",
|
|
2581
2661
|
"aria-labelledby": "keepkit-sync-recovery-title",
|
|
2662
|
+
"aria-describedby": error ? "keepkit-sync-recovery-error" : void 0,
|
|
2663
|
+
"aria-busy": busyId !== void 0,
|
|
2582
2664
|
"data-keepkit": "sync-recovery",
|
|
2583
2665
|
"data-state": conflictList.length > 0 ? "conflict" : "error",
|
|
2584
2666
|
"data-loading": busyId !== void 0 ? "true" : void 0,
|
|
@@ -2592,6 +2674,28 @@ function KeepSyncRecoveryDialog({
|
|
|
2592
2674
|
/* @__PURE__ */ jsx16("p", { children: conflictLabel }),
|
|
2593
2675
|
conflictList.map((conflict) => /* @__PURE__ */ jsxs10("article", { "data-conflict-id": conflict.id, children: [
|
|
2594
2676
|
/* @__PURE__ */ jsx16("h3", { children: getMetaTitle(conflict.operation.item?.meta) ?? conflict.id }),
|
|
2677
|
+
/* @__PURE__ */ jsxs10("div", { "data-conflict-preview": true, children: [
|
|
2678
|
+
/* @__PURE__ */ jsx16(
|
|
2679
|
+
ConflictPreview,
|
|
2680
|
+
{
|
|
2681
|
+
item: conflict.operation.item,
|
|
2682
|
+
heading: localVersionLabel,
|
|
2683
|
+
updatedAtLabel,
|
|
2684
|
+
noteLabel,
|
|
2685
|
+
side: "local"
|
|
2686
|
+
}
|
|
2687
|
+
),
|
|
2688
|
+
/* @__PURE__ */ jsx16(
|
|
2689
|
+
ConflictPreview,
|
|
2690
|
+
{
|
|
2691
|
+
item: conflict.remote,
|
|
2692
|
+
heading: remoteVersionLabel,
|
|
2693
|
+
updatedAtLabel,
|
|
2694
|
+
noteLabel,
|
|
2695
|
+
side: "remote"
|
|
2696
|
+
}
|
|
2697
|
+
)
|
|
2698
|
+
] }),
|
|
2595
2699
|
/* @__PURE__ */ jsxs10("div", { children: [
|
|
2596
2700
|
/* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void resolve(conflict, "local"), disabled: busyId !== void 0, children: keepLocalLabel }),
|
|
2597
2701
|
/* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void resolve(conflict, "remote"), disabled: busyId !== void 0, children: useServerLabel }),
|
|
@@ -2612,11 +2716,35 @@ function KeepSyncRecoveryDialog({
|
|
|
2612
2716
|
/* @__PURE__ */ jsx16("p", { children: backupRecoveryDescription }),
|
|
2613
2717
|
backup ?? (showBackupControls ? /* @__PURE__ */ jsx16(KeepBackup, {}) : null)
|
|
2614
2718
|
] }) : null,
|
|
2615
|
-
error ? /* @__PURE__ */ jsx16("p", { role: "alert", children: error instanceof Error ? error.message : errorLabel }) : null
|
|
2719
|
+
error ? /* @__PURE__ */ jsx16("p", { id: "keepkit-sync-recovery-error", role: "alert", "aria-live": "assertive", children: error instanceof Error ? error.message : errorLabel }) : null
|
|
2616
2720
|
]
|
|
2617
2721
|
}
|
|
2618
2722
|
);
|
|
2619
2723
|
}
|
|
2724
|
+
function ConflictPreview({
|
|
2725
|
+
item,
|
|
2726
|
+
heading,
|
|
2727
|
+
updatedAtLabel,
|
|
2728
|
+
noteLabel,
|
|
2729
|
+
side
|
|
2730
|
+
}) {
|
|
2731
|
+
return /* @__PURE__ */ jsxs10("article", { "data-conflict-version": side, "aria-label": heading, children: [
|
|
2732
|
+
/* @__PURE__ */ jsx16("h4", { children: heading }),
|
|
2733
|
+
/* @__PURE__ */ jsxs10("dl", { children: [
|
|
2734
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
2735
|
+
/* @__PURE__ */ jsx16("dt", { children: updatedAtLabel }),
|
|
2736
|
+
/* @__PURE__ */ jsx16("dd", { children: item ? /* @__PURE__ */ jsx16("time", { dateTime: new Date(item.updatedAt).toISOString(), children: formatConflictDate(item.updatedAt) }) : "\u2014" })
|
|
2737
|
+
] }),
|
|
2738
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
2739
|
+
/* @__PURE__ */ jsx16("dt", { children: noteLabel }),
|
|
2740
|
+
/* @__PURE__ */ jsx16("dd", { children: item?.note || "\u2014" })
|
|
2741
|
+
] })
|
|
2742
|
+
] })
|
|
2743
|
+
] });
|
|
2744
|
+
}
|
|
2745
|
+
function formatConflictDate(timestamp) {
|
|
2746
|
+
return new Date(timestamp).toISOString().slice(0, 10);
|
|
2747
|
+
}
|
|
2620
2748
|
|
|
2621
2749
|
// src/KeepSyncStatusBanner.tsx
|
|
2622
2750
|
import { useKeepContext as useKeepContext4 } from "@keepkit/core/react";
|