@keepkit/ui 0.3.0 → 0.5.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 +54 -26
- package/dist/index.d.ts +131 -14
- package/dist/index.js +532 -51
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -3,41 +3,143 @@
|
|
|
3
3
|
// src/index.tsx
|
|
4
4
|
import {
|
|
5
5
|
KeepButton as CoreKeepButton,
|
|
6
|
+
KeepProvider as CoreKeepProvider,
|
|
7
|
+
createKeepKit as createCoreKeepKit,
|
|
6
8
|
useKeepContext,
|
|
7
9
|
useKeepItem,
|
|
8
10
|
useKeepList
|
|
9
11
|
} from "@keepkit/core/react";
|
|
10
12
|
import {
|
|
11
13
|
cloneElement,
|
|
14
|
+
createContext,
|
|
12
15
|
isValidElement,
|
|
13
16
|
useCallback,
|
|
17
|
+
useContext,
|
|
14
18
|
useEffect,
|
|
15
19
|
useMemo,
|
|
20
|
+
useRef,
|
|
16
21
|
useState
|
|
17
22
|
} from "react";
|
|
18
|
-
import { KeepProvider, useKeepContext as useKeepContext2, useKeepItem as useKeepItem2, useKeepList as useKeepList2 } from "@keepkit/core/react";
|
|
23
|
+
import { KeepProvider, useKeepContext as useKeepContext2, useKeepItem as useKeepItem2, useKeepList as useKeepList2, useKeepShortcut } from "@keepkit/core/react";
|
|
24
|
+
import {
|
|
25
|
+
createBrowserStorageAdapter,
|
|
26
|
+
createStorageAdapter,
|
|
27
|
+
FallbackStorageAdapter,
|
|
28
|
+
IndexedDBAdapter,
|
|
29
|
+
IndexedDBSyncQueueAdapter,
|
|
30
|
+
LocalStorageAdapter,
|
|
31
|
+
LocalStorageSyncQueueAdapter,
|
|
32
|
+
SyncStorageAdapter
|
|
33
|
+
} from "@keepkit/core/storage";
|
|
19
34
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
35
|
+
var DEFAULT_LABELS = {
|
|
36
|
+
save: "Save",
|
|
37
|
+
saved: "Saved",
|
|
38
|
+
remove: "Remove",
|
|
39
|
+
loading: "Loading\u2026",
|
|
40
|
+
saving: "Saving\u2026",
|
|
41
|
+
syncing: "Syncing\u2026",
|
|
42
|
+
error: "Something went wrong.",
|
|
43
|
+
allTags: "All",
|
|
44
|
+
filterTags: "Filter saved items by tag",
|
|
45
|
+
note: "Note",
|
|
46
|
+
saveNote: "Save note",
|
|
47
|
+
noItems: "No saved items.",
|
|
48
|
+
loadingItems: "Loading saved items\u2026",
|
|
49
|
+
errorItems: "Could not load saved items.",
|
|
50
|
+
search: "Search saved items",
|
|
51
|
+
sort: "Sort saved items",
|
|
52
|
+
newest: "Newest first",
|
|
53
|
+
oldest: "Oldest first",
|
|
54
|
+
previousPage: "Previous page",
|
|
55
|
+
nextPage: "Next page",
|
|
56
|
+
pagination: "Pagination",
|
|
57
|
+
page: "Page",
|
|
58
|
+
selectItems: "Select saved items",
|
|
59
|
+
selectedCount: "selected",
|
|
60
|
+
deleteSelected: "Delete selected",
|
|
61
|
+
tagsToApply: "Tags to apply",
|
|
62
|
+
applyTags: "Apply tags",
|
|
63
|
+
savedMessage: "Item saved.",
|
|
64
|
+
removedMessage: "Item removed.",
|
|
65
|
+
noteSavedMessage: "Note saved."
|
|
66
|
+
};
|
|
67
|
+
var KeepUiLabelsContext = createContext({ labels: DEFAULT_LABELS });
|
|
68
|
+
function KeepUiProvider({ labels, locale, labelResolver, children }) {
|
|
69
|
+
const value = useMemo(() => {
|
|
70
|
+
const resolved = { ...DEFAULT_LABELS, ...labels };
|
|
71
|
+
return { locale, labels: resolved, labelResolver };
|
|
72
|
+
}, [labelResolver, labels, locale]);
|
|
73
|
+
return /* @__PURE__ */ jsx(KeepUiLabelsContext.Provider, { value, children });
|
|
74
|
+
}
|
|
75
|
+
function KeepKitProvider({
|
|
76
|
+
labels,
|
|
77
|
+
locale,
|
|
78
|
+
labelResolver,
|
|
79
|
+
children,
|
|
80
|
+
...providerProps
|
|
81
|
+
}) {
|
|
82
|
+
return /* @__PURE__ */ jsx(KeepUiProvider, { labels, locale, labelResolver, children: /* @__PURE__ */ jsx(CoreKeepProvider, { ...providerProps, children }) });
|
|
83
|
+
}
|
|
84
|
+
function useKeepUiLabels() {
|
|
85
|
+
return useContext(KeepUiLabelsContext);
|
|
86
|
+
}
|
|
87
|
+
function useUiLabel(key, override) {
|
|
88
|
+
const context = useKeepUiLabels();
|
|
89
|
+
return override ?? context.labelResolver?.(key, { locale: context.locale }) ?? context.labels[key];
|
|
90
|
+
}
|
|
91
|
+
function createKeepKit(options = {}) {
|
|
92
|
+
const { labels, locale, labelResolver, getTitle, getImageProps, ...coreOptions } = options;
|
|
93
|
+
const coreKit = createCoreKeepKit(coreOptions);
|
|
94
|
+
return {
|
|
95
|
+
Provider: (props) => /* @__PURE__ */ jsx(
|
|
96
|
+
KeepKitProvider,
|
|
97
|
+
{
|
|
98
|
+
...coreOptions,
|
|
99
|
+
labels,
|
|
100
|
+
locale,
|
|
101
|
+
labelResolver,
|
|
102
|
+
...props
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
Button: (props) => /* @__PURE__ */ jsx(KeepButton, { ...props }),
|
|
106
|
+
Collection: (props) => /* @__PURE__ */ jsx(
|
|
107
|
+
KeepCollection,
|
|
108
|
+
{
|
|
109
|
+
...props,
|
|
110
|
+
itemCardProps: {
|
|
111
|
+
...getTitle ? { getTitle } : {},
|
|
112
|
+
...getImageProps ? { getImageProps } : {},
|
|
113
|
+
...props.itemCardProps
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
),
|
|
117
|
+
useContext: () => coreKit.useContext(),
|
|
118
|
+
useItem: (item) => coreKit.useItem(item),
|
|
119
|
+
useList: (query) => coreKit.useList(query),
|
|
120
|
+
useShortcut: (shortcutOptions) => coreKit.useShortcut(shortcutOptions)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
20
123
|
function KeepButton({ labels, ...props }) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
124
|
+
const saveLabel = useUiLabel("save", typeof labels?.unsaved === "string" ? labels.unsaved : void 0);
|
|
125
|
+
const savedLabel = useUiLabel("saved", typeof labels?.saved === "string" ? labels.saved : void 0);
|
|
126
|
+
const loadingLabel = useUiLabel("loading", typeof labels?.loading === "string" ? labels.loading : void 0);
|
|
127
|
+
const errorLabel = useUiLabel("error", typeof labels?.error === "string" ? labels.error : void 0);
|
|
128
|
+
const buttonState = useKeepItem(props.item);
|
|
27
129
|
const customStateLabel = labels?.loading !== void 0 || labels?.error !== void 0;
|
|
28
130
|
const getStateContent = (state) => {
|
|
29
|
-
if (state.error
|
|
30
|
-
if (state.isMutating
|
|
131
|
+
if (state.error) return labels?.error ?? errorLabel;
|
|
132
|
+
if (state.isMutating) return labels?.loading ?? loadingLabel;
|
|
31
133
|
if (typeof props.children === "function") return props.children(state);
|
|
32
134
|
if (props.children !== void 0) return props.children;
|
|
33
|
-
return state.isSaved ? labels?.saved ??
|
|
135
|
+
return state.isSaved ? labels?.saved ?? savedLabel : labels?.unsaved ?? saveLabel;
|
|
34
136
|
};
|
|
35
137
|
if (props.asChild === true) {
|
|
36
138
|
const sharedProps2 = {
|
|
37
139
|
...props,
|
|
38
140
|
"aria-busy": props["aria-busy"] ?? (buttonState.isLoading || buttonState.isMutating),
|
|
39
|
-
savedLabel: labels?.saved ?? props.savedLabel,
|
|
40
|
-
unsavedLabel: labels?.unsaved ?? props.unsavedLabel,
|
|
141
|
+
savedLabel: labels?.saved ?? props.savedLabel ?? savedLabel,
|
|
142
|
+
unsavedLabel: labels?.unsaved ?? props.unsavedLabel ?? saveLabel,
|
|
41
143
|
savedAriaLabel: labels?.savedAriaLabel ?? props.savedAriaLabel,
|
|
42
144
|
unsavedAriaLabel: labels?.unsavedAriaLabel ?? props.unsavedAriaLabel
|
|
43
145
|
};
|
|
@@ -51,8 +153,8 @@ function KeepButton({ labels, ...props }) {
|
|
|
51
153
|
const sharedProps = {
|
|
52
154
|
...props,
|
|
53
155
|
"aria-busy": props["aria-busy"] ?? (buttonState.isLoading || buttonState.isMutating),
|
|
54
|
-
savedLabel: labels?.saved ?? props.savedLabel,
|
|
55
|
-
unsavedLabel: labels?.unsaved ?? props.unsavedLabel,
|
|
156
|
+
savedLabel: labels?.saved ?? props.savedLabel ?? savedLabel,
|
|
157
|
+
unsavedLabel: labels?.unsaved ?? props.unsavedLabel ?? saveLabel,
|
|
56
158
|
savedAriaLabel: labels?.savedAriaLabel ?? props.savedAriaLabel,
|
|
57
159
|
unsavedAriaLabel: labels?.unsavedAriaLabel ?? props.unsavedAriaLabel
|
|
58
160
|
};
|
|
@@ -63,11 +165,14 @@ function KeepButton({ labels, ...props }) {
|
|
|
63
165
|
function KeepItemCard({
|
|
64
166
|
item,
|
|
65
167
|
title,
|
|
66
|
-
|
|
168
|
+
getTitle,
|
|
169
|
+
getImageProps,
|
|
170
|
+
imageComponent: ImageComponent,
|
|
171
|
+
renderImage,
|
|
67
172
|
imageAlt,
|
|
68
173
|
render,
|
|
69
174
|
children,
|
|
70
|
-
removeLabel
|
|
175
|
+
removeLabel,
|
|
71
176
|
onRemoveError,
|
|
72
177
|
onRemoved,
|
|
73
178
|
showSaveButton = true,
|
|
@@ -76,7 +181,9 @@ function KeepItemCard({
|
|
|
76
181
|
className,
|
|
77
182
|
...rootProps
|
|
78
183
|
}) {
|
|
79
|
-
const
|
|
184
|
+
const saveActionLabel = useUiLabel("save");
|
|
185
|
+
const removeActionLabel = useUiLabel("remove");
|
|
186
|
+
const itemState = useKeepItem(item);
|
|
80
187
|
const contentChildren = asChild && isValidElement(children) ? void 0 : children;
|
|
81
188
|
const state = {
|
|
82
189
|
item,
|
|
@@ -85,8 +192,8 @@ function KeepItemCard({
|
|
|
85
192
|
error: itemState.error,
|
|
86
193
|
remove: itemState.remove
|
|
87
194
|
};
|
|
88
|
-
const resolvedTitle = typeof title === "function" ? title(item) : title ?? getMetaTitle(item.meta) ?? item.id;
|
|
89
|
-
const
|
|
195
|
+
const resolvedTitle = typeof title === "function" ? title(item) : title ?? getTitle?.(item) ?? getMetaTitle(item.meta) ?? item.id;
|
|
196
|
+
const imageProps = getImageProps?.(item, resolvedTitle);
|
|
90
197
|
async function handleRemove() {
|
|
91
198
|
try {
|
|
92
199
|
await itemState.remove();
|
|
@@ -96,17 +203,17 @@ function KeepItemCard({
|
|
|
96
203
|
}
|
|
97
204
|
}
|
|
98
205
|
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
99
|
-
|
|
206
|
+
imageProps ? renderImage?.({ ...imageProps, alt: imageAlt ?? imageProps.alt }, item) ?? (ImageComponent ? /* @__PURE__ */ jsx(ImageComponent, { ...imageProps, alt: imageAlt ?? imageProps.alt }) : /* @__PURE__ */ jsx("img", { ...imageProps, alt: imageAlt ?? imageProps.alt })) : null,
|
|
100
207
|
/* @__PURE__ */ jsx("h3", { children: resolvedTitle }),
|
|
101
208
|
showSaveButton ? /* @__PURE__ */ jsx(
|
|
102
209
|
KeepButton,
|
|
103
210
|
{
|
|
104
211
|
item: toKeepButtonItem(item),
|
|
105
212
|
labels: saveButtonLabels,
|
|
106
|
-
getAriaLabel: (buttonState) => `${buttonState.isSaved ?
|
|
213
|
+
getAriaLabel: (buttonState) => `${buttonState.isSaved ? removeActionLabel : saveActionLabel} ${String(resolvedTitle)}`
|
|
107
214
|
}
|
|
108
215
|
) : null,
|
|
109
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void handleRemove(), disabled: itemState.isMutating, children: removeLabel })
|
|
216
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void handleRemove(), disabled: itemState.isMutating, children: removeLabel ?? removeActionLabel })
|
|
110
217
|
] });
|
|
111
218
|
return renderRoot(
|
|
112
219
|
asChild,
|
|
@@ -117,19 +224,29 @@ function KeepItemCard({
|
|
|
117
224
|
);
|
|
118
225
|
}
|
|
119
226
|
function KeepList({
|
|
120
|
-
|
|
227
|
+
query,
|
|
121
228
|
children,
|
|
122
229
|
renderItem,
|
|
123
|
-
loading
|
|
124
|
-
empty
|
|
125
|
-
error: errorContent
|
|
230
|
+
loading,
|
|
231
|
+
empty,
|
|
232
|
+
error: errorContent,
|
|
126
233
|
itemCardProps,
|
|
127
234
|
asChild = false,
|
|
128
235
|
className,
|
|
129
236
|
...rootProps
|
|
130
237
|
}) {
|
|
131
|
-
const
|
|
132
|
-
const
|
|
238
|
+
const defaultLoading = useUiLabel("loadingItems");
|
|
239
|
+
const defaultEmpty = useUiLabel("noItems");
|
|
240
|
+
const defaultError = useUiLabel("errorItems");
|
|
241
|
+
const state = useKeepList(query);
|
|
242
|
+
const body = getListBody(state, {
|
|
243
|
+
children,
|
|
244
|
+
renderItem,
|
|
245
|
+
loading: loading ?? defaultLoading,
|
|
246
|
+
empty: empty ?? defaultEmpty,
|
|
247
|
+
error: errorContent ?? defaultError,
|
|
248
|
+
itemCardProps
|
|
249
|
+
});
|
|
133
250
|
const root = asChild && isValidElement(children) ? children : void 0;
|
|
134
251
|
return renderRoot(
|
|
135
252
|
asChild,
|
|
@@ -150,14 +267,93 @@ function getListBody(state, options) {
|
|
|
150
267
|
);
|
|
151
268
|
return /* @__PURE__ */ jsx("ul", { children: items });
|
|
152
269
|
}
|
|
270
|
+
function KeepCollection({
|
|
271
|
+
query = {},
|
|
272
|
+
pageSize = 20,
|
|
273
|
+
features,
|
|
274
|
+
renderItem,
|
|
275
|
+
itemCardProps,
|
|
276
|
+
loading,
|
|
277
|
+
empty,
|
|
278
|
+
error,
|
|
279
|
+
className,
|
|
280
|
+
...rootProps
|
|
281
|
+
}) {
|
|
282
|
+
const enabled = {
|
|
283
|
+
search: true,
|
|
284
|
+
sort: true,
|
|
285
|
+
pagination: true,
|
|
286
|
+
tagFilter: false,
|
|
287
|
+
bulkActions: false,
|
|
288
|
+
...features
|
|
289
|
+
};
|
|
290
|
+
const [searchValue, setSearchValue] = useState(query.search?.query ?? "");
|
|
291
|
+
const [sort, setSort] = useState(query.sort ?? { by: "updatedAt", direction: "desc" });
|
|
292
|
+
const [tag, setTag] = useState(query.tags?.[0]);
|
|
293
|
+
const [page, setPage] = useState(query.pagination?.page ?? 1);
|
|
294
|
+
const resolvedPageSize = query.pagination?.pageSize ?? pageSize;
|
|
295
|
+
const resolvedQuery = useMemo(
|
|
296
|
+
() => ({
|
|
297
|
+
...query,
|
|
298
|
+
search: enabled.search ? { ...query.search, query: searchValue } : query.search,
|
|
299
|
+
sort: enabled.sort ? sort : query.sort,
|
|
300
|
+
tags: tag ? [.../* @__PURE__ */ new Set([...query.tags ?? [], tag])] : query.tags,
|
|
301
|
+
pagination: enabled.pagination ? { ...query.pagination, page, pageSize: resolvedPageSize } : query.pagination
|
|
302
|
+
}),
|
|
303
|
+
[enabled.pagination, enabled.search, enabled.sort, page, query, resolvedPageSize, searchValue, sort, tag]
|
|
304
|
+
);
|
|
305
|
+
const list = useKeepList(resolvedQuery);
|
|
306
|
+
useEffect(() => {
|
|
307
|
+
if (searchValue !== void 0 || sort.by !== void 0 || sort.direction !== void 0 || tag !== void 0) {
|
|
308
|
+
setPage(1);
|
|
309
|
+
}
|
|
310
|
+
}, [searchValue, sort.by, sort.direction, tag]);
|
|
311
|
+
return /* @__PURE__ */ jsxs(
|
|
312
|
+
"section",
|
|
313
|
+
{
|
|
314
|
+
...rootProps,
|
|
315
|
+
className,
|
|
316
|
+
"aria-busy": list.isLoading || list.isMutating || rootProps["aria-busy"],
|
|
317
|
+
children: [
|
|
318
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
319
|
+
enabled.search ? /* @__PURE__ */ jsx(KeepSearchInput, { value: searchValue, onValueChange: setSearchValue }) : null,
|
|
320
|
+
enabled.sort ? /* @__PURE__ */ jsx(KeepSortSelect, { value: sortToValue(sort), onValueChange: (_value, nextSort) => setSort(nextSort) }) : null,
|
|
321
|
+
enabled.tagFilter ? /* @__PURE__ */ jsx(KeepTagFilter, { query, value: tag, onValueChange: setTag }) : null
|
|
322
|
+
] }),
|
|
323
|
+
/* @__PURE__ */ jsx(
|
|
324
|
+
KeepList,
|
|
325
|
+
{
|
|
326
|
+
query: resolvedQuery,
|
|
327
|
+
renderItem,
|
|
328
|
+
itemCardProps,
|
|
329
|
+
loading,
|
|
330
|
+
empty,
|
|
331
|
+
error
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
enabled.pagination ? /* @__PURE__ */ jsx(
|
|
335
|
+
KeepPagination,
|
|
336
|
+
{
|
|
337
|
+
totalCount: list.totalCount,
|
|
338
|
+
pageSize: resolvedPageSize,
|
|
339
|
+
page: list.page,
|
|
340
|
+
onPageChange: (_nextPage, nextPageOffset) => setPage(Math.floor(nextPageOffset / resolvedPageSize) + 1)
|
|
341
|
+
}
|
|
342
|
+
) : null,
|
|
343
|
+
enabled.bulkActions ? /* @__PURE__ */ jsx(KeepBulkActions, { query: resolvedQuery }) : null,
|
|
344
|
+
/* @__PURE__ */ jsx(KeepAnnouncements, {})
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
}
|
|
153
349
|
function KeepTagFilter({
|
|
154
|
-
|
|
350
|
+
query,
|
|
155
351
|
value: controlledValue,
|
|
156
352
|
defaultValue,
|
|
157
353
|
onChange,
|
|
158
354
|
onValueChange,
|
|
159
|
-
allLabel
|
|
160
|
-
ariaLabel
|
|
355
|
+
allLabel,
|
|
356
|
+
ariaLabel,
|
|
161
357
|
renderTag,
|
|
162
358
|
render,
|
|
163
359
|
children,
|
|
@@ -165,10 +361,14 @@ function KeepTagFilter({
|
|
|
165
361
|
className,
|
|
166
362
|
...rootProps
|
|
167
363
|
}) {
|
|
168
|
-
const
|
|
364
|
+
const uiAllLabel = useUiLabel("allTags");
|
|
365
|
+
const uiAriaLabel = useUiLabel("filterTags");
|
|
366
|
+
const defaultAllLabel = allLabel ?? uiAllLabel;
|
|
367
|
+
const defaultAriaLabel = ariaLabel ?? uiAriaLabel;
|
|
169
368
|
const contentChildren = asChild && isValidElement(children) ? void 0 : children;
|
|
170
369
|
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
171
370
|
const value = controlledValue ?? uncontrolledValue;
|
|
371
|
+
const list = useKeepList({ ...query, tags: value ? [...query?.tags ?? [], value] : query?.tags });
|
|
172
372
|
const select = useCallback(
|
|
173
373
|
(tag) => {
|
|
174
374
|
if (controlledValue === void 0) setUncontrolledValue(tag);
|
|
@@ -182,8 +382,8 @@ function KeepTagFilter({
|
|
|
182
382
|
[list.tagCounts, list.tags, select, value]
|
|
183
383
|
);
|
|
184
384
|
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs("fieldset", { children: [
|
|
185
|
-
/* @__PURE__ */ jsx("legend", { children:
|
|
186
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": value === void 0, onClick: () => select(), children:
|
|
385
|
+
/* @__PURE__ */ jsx("legend", { children: defaultAriaLabel }),
|
|
386
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": value === void 0, onClick: () => select(), children: defaultAllLabel }),
|
|
187
387
|
list.tags.map((tag) => /* @__PURE__ */ jsxs("button", { type: "button", "aria-pressed": value === tag, onClick: () => select(tag), children: [
|
|
188
388
|
renderTag ? renderTag(tag, list.tagCounts[tag] ?? 0, value === tag) : tag,
|
|
189
389
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
@@ -203,8 +403,8 @@ function KeepTagFilter({
|
|
|
203
403
|
}
|
|
204
404
|
function KeepNoteEditor({
|
|
205
405
|
item,
|
|
206
|
-
label
|
|
207
|
-
saveLabel
|
|
406
|
+
label,
|
|
407
|
+
saveLabel,
|
|
208
408
|
placeholder,
|
|
209
409
|
onSaved,
|
|
210
410
|
onSaveError,
|
|
@@ -214,7 +414,9 @@ function KeepNoteEditor({
|
|
|
214
414
|
className,
|
|
215
415
|
...formProps
|
|
216
416
|
}) {
|
|
217
|
-
const
|
|
417
|
+
const defaultLabel = useUiLabel("note");
|
|
418
|
+
const defaultSaveLabel = useUiLabel("saveNote");
|
|
419
|
+
const itemState = useKeepItem(item);
|
|
218
420
|
const contentChildren = asChild && isValidElement(children) ? void 0 : children;
|
|
219
421
|
const [note, setNote] = useState(item.note ?? "");
|
|
220
422
|
useEffect(() => setNote(itemState.item?.note ?? item.note ?? ""), [item.note, itemState.item?.note]);
|
|
@@ -239,7 +441,7 @@ function KeepNoteEditor({
|
|
|
239
441
|
};
|
|
240
442
|
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
241
443
|
/* @__PURE__ */ jsxs("label", { children: [
|
|
242
|
-
label,
|
|
444
|
+
label ?? defaultLabel,
|
|
243
445
|
/* @__PURE__ */ jsx(
|
|
244
446
|
"textarea",
|
|
245
447
|
{
|
|
@@ -250,22 +452,256 @@ function KeepNoteEditor({
|
|
|
250
452
|
}
|
|
251
453
|
)
|
|
252
454
|
] }),
|
|
253
|
-
/* @__PURE__ */ jsx("button", { type: "submit", disabled: itemState.isMutating, "aria-busy": itemState.isMutating, children: saveLabel })
|
|
455
|
+
/* @__PURE__ */ jsx("button", { type: "submit", disabled: itemState.isMutating, "aria-busy": itemState.isMutating, children: saveLabel ?? defaultSaveLabel })
|
|
254
456
|
] });
|
|
255
457
|
const handleSubmit = (event) => {
|
|
256
458
|
event.preventDefault();
|
|
257
459
|
void save().catch(() => void 0);
|
|
258
460
|
};
|
|
461
|
+
if (!asChild) {
|
|
462
|
+
return /* @__PURE__ */ jsx(
|
|
463
|
+
"form",
|
|
464
|
+
{
|
|
465
|
+
...formProps,
|
|
466
|
+
className,
|
|
467
|
+
onSubmit: handleSubmit,
|
|
468
|
+
"aria-busy": itemState.isMutating || formProps["aria-busy"],
|
|
469
|
+
children: body
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
}
|
|
259
473
|
return renderRoot(
|
|
260
|
-
|
|
474
|
+
true,
|
|
261
475
|
isValidElement(children) ? children : void 0,
|
|
262
476
|
{ ...formProps, className, onSubmit: handleSubmit, "aria-busy": itemState.isMutating || formProps["aria-busy"] },
|
|
263
477
|
body,
|
|
264
478
|
"KeepNoteEditor"
|
|
265
479
|
);
|
|
266
480
|
}
|
|
481
|
+
function KeepSearchInput({
|
|
482
|
+
value: controlledValue,
|
|
483
|
+
defaultValue = "",
|
|
484
|
+
onValueChange,
|
|
485
|
+
"aria-label": ariaLabel,
|
|
486
|
+
placeholder,
|
|
487
|
+
...props
|
|
488
|
+
}) {
|
|
489
|
+
const label = useUiLabel("search");
|
|
490
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
491
|
+
const value = controlledValue ?? uncontrolledValue;
|
|
492
|
+
return /* @__PURE__ */ jsx(
|
|
493
|
+
"input",
|
|
494
|
+
{
|
|
495
|
+
...props,
|
|
496
|
+
type: "search",
|
|
497
|
+
value,
|
|
498
|
+
"aria-label": ariaLabel ?? label,
|
|
499
|
+
placeholder: placeholder ?? label,
|
|
500
|
+
onChange: (event) => {
|
|
501
|
+
const nextValue = event.currentTarget.value;
|
|
502
|
+
if (controlledValue === void 0) setUncontrolledValue(nextValue);
|
|
503
|
+
onValueChange?.(nextValue);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
function KeepSortSelect({
|
|
509
|
+
value: controlledValue,
|
|
510
|
+
defaultValue = "updatedAt:desc",
|
|
511
|
+
onValueChange,
|
|
512
|
+
"aria-label": ariaLabel,
|
|
513
|
+
children,
|
|
514
|
+
...props
|
|
515
|
+
}) {
|
|
516
|
+
const label = useUiLabel("sort");
|
|
517
|
+
const newestLabel = useUiLabel("newest");
|
|
518
|
+
const savedLabel = useUiLabel("saved");
|
|
519
|
+
const oldestLabel = useUiLabel("oldest");
|
|
520
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
521
|
+
const value = controlledValue ?? uncontrolledValue;
|
|
522
|
+
const options = children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
523
|
+
/* @__PURE__ */ jsx("option", { value: "updatedAt:desc", children: newestLabel }),
|
|
524
|
+
/* @__PURE__ */ jsx("option", { value: "savedAt:desc", children: savedLabel }),
|
|
525
|
+
/* @__PURE__ */ jsx("option", { value: "updatedAt:asc", children: oldestLabel }),
|
|
526
|
+
/* @__PURE__ */ jsx("option", { value: "savedAt:asc", children: oldestLabel })
|
|
527
|
+
] });
|
|
528
|
+
return /* @__PURE__ */ jsx(
|
|
529
|
+
"select",
|
|
530
|
+
{
|
|
531
|
+
...props,
|
|
532
|
+
value,
|
|
533
|
+
"aria-label": ariaLabel ?? label,
|
|
534
|
+
onChange: (event) => {
|
|
535
|
+
const nextValue = event.currentTarget.value;
|
|
536
|
+
if (controlledValue === void 0) setUncontrolledValue(nextValue);
|
|
537
|
+
const [by, direction] = nextValue.split(":");
|
|
538
|
+
onValueChange?.(nextValue, { by, direction });
|
|
539
|
+
},
|
|
540
|
+
children: options
|
|
541
|
+
}
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
function KeepPagination({
|
|
545
|
+
totalCount,
|
|
546
|
+
pageSize,
|
|
547
|
+
page = 1,
|
|
548
|
+
onPageChange,
|
|
549
|
+
render,
|
|
550
|
+
...props
|
|
551
|
+
}) {
|
|
552
|
+
const previousPageLabel = useUiLabel("previousPage");
|
|
553
|
+
const nextPageLabel = useUiLabel("nextPage");
|
|
554
|
+
const pageLabel = useUiLabel("page");
|
|
555
|
+
const paginationLabel = useUiLabel("pagination");
|
|
556
|
+
const pageCount = Math.max(1, Math.ceil(totalCount / Math.max(1, pageSize)));
|
|
557
|
+
const currentPage = Math.min(Math.max(1, page), pageCount);
|
|
558
|
+
const goToPage = (nextPage) => {
|
|
559
|
+
const next = Math.min(Math.max(1, nextPage), pageCount);
|
|
560
|
+
onPageChange?.(next, (next - 1) * pageSize);
|
|
561
|
+
};
|
|
562
|
+
if (render) return /* @__PURE__ */ jsx("nav", { ...props, children: render({ page: currentPage, pageCount, goToPage }) });
|
|
563
|
+
return /* @__PURE__ */ jsxs("nav", { ...props, "aria-label": props["aria-label"] ?? paginationLabel, children: [
|
|
564
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => goToPage(currentPage - 1), disabled: currentPage <= 1, children: previousPageLabel }),
|
|
565
|
+
/* @__PURE__ */ jsxs("span", { "aria-current": "page", children: [
|
|
566
|
+
pageLabel,
|
|
567
|
+
" ",
|
|
568
|
+
currentPage,
|
|
569
|
+
" / ",
|
|
570
|
+
pageCount
|
|
571
|
+
] }),
|
|
572
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => goToPage(currentPage + 1), disabled: currentPage >= pageCount, children: nextPageLabel })
|
|
573
|
+
] });
|
|
574
|
+
}
|
|
575
|
+
function KeepTagEditor({
|
|
576
|
+
item,
|
|
577
|
+
availableTags = [],
|
|
578
|
+
onSaved,
|
|
579
|
+
onSaveError,
|
|
580
|
+
render,
|
|
581
|
+
...props
|
|
582
|
+
}) {
|
|
583
|
+
const tagsLabel = useUiLabel("tagsToApply");
|
|
584
|
+
const removeLabel = useUiLabel("remove");
|
|
585
|
+
const applyTagsLabel = useUiLabel("applyTags");
|
|
586
|
+
const itemState = useKeepItem(item);
|
|
587
|
+
const [tags, setTags] = useState(item.tags ?? []);
|
|
588
|
+
const [input, setInput] = useState("");
|
|
589
|
+
useEffect(() => setTags(itemState.item?.tags ?? item.tags ?? []), [item.tags, itemState.item?.tags]);
|
|
590
|
+
const save = useCallback(async () => {
|
|
591
|
+
const nextTags = normalizeUiTags(tags);
|
|
592
|
+
try {
|
|
593
|
+
await itemState.updateTags(nextTags);
|
|
594
|
+
setTags(nextTags);
|
|
595
|
+
onSaved?.(nextTags);
|
|
596
|
+
} catch (error) {
|
|
597
|
+
onSaveError?.(error);
|
|
598
|
+
throw error;
|
|
599
|
+
}
|
|
600
|
+
}, [itemState, onSaveError, onSaved, tags]);
|
|
601
|
+
const addTag = (tag) => {
|
|
602
|
+
const next = normalizeUiTags([...tags, tag]);
|
|
603
|
+
setTags(next);
|
|
604
|
+
setInput("");
|
|
605
|
+
};
|
|
606
|
+
const body = render ? render({ tags, setTags, save, isSaving: itemState.isMutating }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
607
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
608
|
+
tagsLabel,
|
|
609
|
+
/* @__PURE__ */ jsx(
|
|
610
|
+
"input",
|
|
611
|
+
{
|
|
612
|
+
value: input,
|
|
613
|
+
list: availableTags.length > 0 ? `keep-tags-${item.id}` : void 0,
|
|
614
|
+
onChange: (event) => setInput(event.currentTarget.value),
|
|
615
|
+
onKeyDown: (event) => {
|
|
616
|
+
if (event.key === "Enter") {
|
|
617
|
+
event.preventDefault();
|
|
618
|
+
if (input.trim()) addTag(input);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
)
|
|
623
|
+
] }),
|
|
624
|
+
availableTags.length > 0 ? /* @__PURE__ */ jsx("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx("option", { value: tag }, tag)) }) : null,
|
|
625
|
+
/* @__PURE__ */ jsx("ul", { "aria-label": tagsLabel, children: tags.map((tag) => /* @__PURE__ */ jsxs("li", { children: [
|
|
626
|
+
tag,
|
|
627
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setTags(tags.filter((current) => current !== tag)), children: removeLabel })
|
|
628
|
+
] }, tag)) }),
|
|
629
|
+
/* @__PURE__ */ jsx("button", { type: "submit", disabled: itemState.isMutating, "aria-busy": itemState.isMutating, children: applyTagsLabel })
|
|
630
|
+
] });
|
|
631
|
+
return /* @__PURE__ */ jsx(
|
|
632
|
+
"form",
|
|
633
|
+
{
|
|
634
|
+
...props,
|
|
635
|
+
onSubmit: (event) => {
|
|
636
|
+
event.preventDefault();
|
|
637
|
+
void save().catch(() => void 0);
|
|
638
|
+
},
|
|
639
|
+
"aria-busy": itemState.isMutating || props["aria-busy"],
|
|
640
|
+
children: body
|
|
641
|
+
}
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
function KeepBulkActions({
|
|
645
|
+
query,
|
|
646
|
+
selectedIds: controlledSelectedIds,
|
|
647
|
+
defaultSelectedIds = [],
|
|
648
|
+
onSelectedIdsChange,
|
|
649
|
+
renderItem,
|
|
650
|
+
onCompleted,
|
|
651
|
+
...props
|
|
652
|
+
}) {
|
|
653
|
+
const selectItemsLabel = useUiLabel("selectItems");
|
|
654
|
+
const selectedCountLabel = useUiLabel("selectedCount");
|
|
655
|
+
const deleteSelectedLabel = useUiLabel("deleteSelected");
|
|
656
|
+
const tagsLabel = useUiLabel("tagsToApply");
|
|
657
|
+
const applyTagsLabel = useUiLabel("applyTags");
|
|
658
|
+
const list = useKeepList(query);
|
|
659
|
+
const [uncontrolledSelectedIds, setUncontrolledSelectedIds] = useState(defaultSelectedIds);
|
|
660
|
+
const selectedIds = controlledSelectedIds ?? uncontrolledSelectedIds;
|
|
661
|
+
const selected = new Set(selectedIds);
|
|
662
|
+
const [tagsInput, setTagsInput] = useState("");
|
|
663
|
+
const setSelectedIds = (ids) => {
|
|
664
|
+
if (controlledSelectedIds === void 0) setUncontrolledSelectedIds(ids);
|
|
665
|
+
onSelectedIdsChange?.(ids);
|
|
666
|
+
};
|
|
667
|
+
const toggle = (id) => setSelectedIds(selected.has(id) ? selectedIds.filter((current) => current !== id) : [...selectedIds, id]);
|
|
668
|
+
const allSelected = list.items.length > 0 && list.items.every((item) => selected.has(item.id));
|
|
669
|
+
const toggleAll = () => setSelectedIds(allSelected ? [] : list.items.map((item) => item.id));
|
|
670
|
+
const remove = async () => {
|
|
671
|
+
await list.removeBatch(selectedIds);
|
|
672
|
+
onCompleted?.("remove", selectedIds);
|
|
673
|
+
setSelectedIds([]);
|
|
674
|
+
};
|
|
675
|
+
const updateTags = async () => {
|
|
676
|
+
const tags = normalizeUiTags(tagsInput.split(","));
|
|
677
|
+
await list.updateTagsBatch(selectedIds, tags);
|
|
678
|
+
onCompleted?.("tags", selectedIds);
|
|
679
|
+
setSelectedIds([]);
|
|
680
|
+
};
|
|
681
|
+
return /* @__PURE__ */ jsxs("section", { ...props, "aria-busy": list.isMutating || props["aria-busy"], children: [
|
|
682
|
+
/* @__PURE__ */ jsxs("fieldset", { children: [
|
|
683
|
+
/* @__PURE__ */ jsx("legend", { children: selectItemsLabel }),
|
|
684
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
685
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: allSelected, onChange: toggleAll }),
|
|
686
|
+
selectedIds.length,
|
|
687
|
+
" ",
|
|
688
|
+
selectedCountLabel
|
|
689
|
+
] }),
|
|
690
|
+
list.items.map((item) => /* @__PURE__ */ jsxs("label", { children: [
|
|
691
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: selected.has(item.id), onChange: () => toggle(item.id) }),
|
|
692
|
+
renderItem ? renderItem(item, selected.has(item.id)) : getMetaTitle(item.meta) ?? item.id
|
|
693
|
+
] }, item.id))
|
|
694
|
+
] }),
|
|
695
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void remove(), disabled: selectedIds.length === 0 || list.isMutating, children: deleteSelectedLabel }),
|
|
696
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
697
|
+
tagsLabel,
|
|
698
|
+
/* @__PURE__ */ jsx("input", { value: tagsInput, onChange: (event) => setTagsInput(event.currentTarget.value) })
|
|
699
|
+
] }),
|
|
700
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void updateTags(), disabled: selectedIds.length === 0 || list.isMutating, children: applyTagsLabel })
|
|
701
|
+
] });
|
|
702
|
+
}
|
|
267
703
|
function KeepEmptyState({
|
|
268
|
-
title
|
|
704
|
+
title,
|
|
269
705
|
description,
|
|
270
706
|
action,
|
|
271
707
|
children,
|
|
@@ -273,9 +709,10 @@ function KeepEmptyState({
|
|
|
273
709
|
className,
|
|
274
710
|
...rootProps
|
|
275
711
|
}) {
|
|
712
|
+
const defaultTitle = useUiLabel("noItems").replace(/\.$/, "");
|
|
276
713
|
const contentChildren = asChild && isValidElement(children) ? void 0 : children;
|
|
277
714
|
const body = contentChildren ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
278
|
-
/* @__PURE__ */ jsx("h2", { children: title }),
|
|
715
|
+
/* @__PURE__ */ jsx("h2", { children: title ?? defaultTitle }),
|
|
279
716
|
description ? /* @__PURE__ */ jsx("p", { children: description }) : null,
|
|
280
717
|
action
|
|
281
718
|
] });
|
|
@@ -293,13 +730,14 @@ function KeepStatus({
|
|
|
293
730
|
const context = useKeepContext();
|
|
294
731
|
const contentChildren = asChild && isValidElement(children) ? void 0 : children;
|
|
295
732
|
const resolvedStatus = status ?? getDerivedStatus(context);
|
|
733
|
+
const defaultLabel = useUiLabel(getStatusLabelKey(resolvedStatus));
|
|
296
734
|
const state = {
|
|
297
735
|
status: resolvedStatus,
|
|
298
736
|
error: context.error,
|
|
299
737
|
pendingCount: context.syncState.pendingCount,
|
|
300
738
|
items: context.items
|
|
301
739
|
};
|
|
302
|
-
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? labels?.[resolvedStatus] ??
|
|
740
|
+
const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? labels?.[resolvedStatus] ?? defaultLabel;
|
|
303
741
|
const role = rootProps.role ?? (resolvedStatus === "error" ? "alert" : "status");
|
|
304
742
|
return renderRoot(
|
|
305
743
|
asChild,
|
|
@@ -309,6 +747,23 @@ function KeepStatus({
|
|
|
309
747
|
"KeepStatus"
|
|
310
748
|
);
|
|
311
749
|
}
|
|
750
|
+
function KeepAnnouncements({ messages, ...props }) {
|
|
751
|
+
const context = useKeepContext();
|
|
752
|
+
const savedMessage = useUiLabel("savedMessage", messages?.save);
|
|
753
|
+
const removedMessage = useUiLabel("removedMessage", messages?.remove);
|
|
754
|
+
const noteSavedMessage = useUiLabel("noteSavedMessage", messages?.note);
|
|
755
|
+
const [message, setMessage] = useState("");
|
|
756
|
+
const lastChangeRef = useRef(void 0);
|
|
757
|
+
useEffect(() => {
|
|
758
|
+
const change = context.lastChange;
|
|
759
|
+
if (!change || change === lastChangeRef.current) return;
|
|
760
|
+
lastChangeRef.current = change;
|
|
761
|
+
if (change.action === "save") setMessage(savedMessage);
|
|
762
|
+
else if (change.action === "remove" || change.action === "removeBatch") setMessage(removedMessage);
|
|
763
|
+
else if (change.action === "updateNote") setMessage(noteSavedMessage);
|
|
764
|
+
}, [context.lastChange, noteSavedMessage, removedMessage, savedMessage]);
|
|
765
|
+
return /* @__PURE__ */ jsx("div", { ...props, role: props.role ?? "status", "aria-live": props["aria-live"] ?? "polite", "aria-atomic": "true", children: message });
|
|
766
|
+
}
|
|
312
767
|
function getDerivedStatus(context) {
|
|
313
768
|
if (context.error) return "error";
|
|
314
769
|
if (context.syncState.status === "pending" || context.syncState.status === "syncing") return "syncing";
|
|
@@ -317,13 +772,13 @@ function getDerivedStatus(context) {
|
|
|
317
772
|
if (context.isHydrated && context.items.length === 0) return "empty";
|
|
318
773
|
return "idle";
|
|
319
774
|
}
|
|
320
|
-
function
|
|
321
|
-
if (status === "empty") return "
|
|
322
|
-
if (status === "loading") return "
|
|
323
|
-
if (status === "
|
|
324
|
-
if (status === "
|
|
325
|
-
if (status === "
|
|
326
|
-
return "";
|
|
775
|
+
function getStatusLabelKey(status) {
|
|
776
|
+
if (status === "empty") return "noItems";
|
|
777
|
+
if (status === "loading") return "loadingItems";
|
|
778
|
+
if (status === "error") return "error";
|
|
779
|
+
if (status === "saving") return "saving";
|
|
780
|
+
if (status === "syncing") return "syncing";
|
|
781
|
+
return "saved";
|
|
327
782
|
}
|
|
328
783
|
function resolveContent(content, state) {
|
|
329
784
|
return typeof content === "function" ? content(state) : content;
|
|
@@ -342,6 +797,12 @@ function getMetaTitle(meta) {
|
|
|
342
797
|
const title = meta.title;
|
|
343
798
|
return typeof title === "string" && title.trim() ? title.trim() : void 0;
|
|
344
799
|
}
|
|
800
|
+
function normalizeUiTags(tags) {
|
|
801
|
+
return [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
|
|
802
|
+
}
|
|
803
|
+
function sortToValue(sort) {
|
|
804
|
+
return `${sort?.by ?? "updatedAt"}:${sort?.direction ?? "desc"}`;
|
|
805
|
+
}
|
|
345
806
|
function renderRoot(asChild, child, props, body, componentName) {
|
|
346
807
|
if (asChild) {
|
|
347
808
|
if (!isValidElement(child)) throw new Error(`${componentName} with asChild requires a single React element child.`);
|
|
@@ -350,16 +811,36 @@ function renderRoot(asChild, child, props, body, componentName) {
|
|
|
350
811
|
return /* @__PURE__ */ jsx("div", { ...props, children: body });
|
|
351
812
|
}
|
|
352
813
|
export {
|
|
814
|
+
FallbackStorageAdapter,
|
|
815
|
+
IndexedDBAdapter,
|
|
816
|
+
IndexedDBSyncQueueAdapter,
|
|
817
|
+
KeepAnnouncements,
|
|
818
|
+
KeepBulkActions,
|
|
353
819
|
KeepButton,
|
|
820
|
+
KeepCollection,
|
|
354
821
|
KeepEmptyState,
|
|
355
822
|
KeepItemCard,
|
|
823
|
+
KeepKitProvider,
|
|
356
824
|
KeepList,
|
|
357
825
|
KeepNoteEditor,
|
|
826
|
+
KeepPagination,
|
|
358
827
|
KeepProvider,
|
|
828
|
+
KeepSearchInput,
|
|
829
|
+
KeepSortSelect,
|
|
359
830
|
KeepStatus,
|
|
831
|
+
KeepTagEditor,
|
|
360
832
|
KeepTagFilter,
|
|
833
|
+
KeepUiProvider,
|
|
834
|
+
LocalStorageAdapter,
|
|
835
|
+
LocalStorageSyncQueueAdapter,
|
|
836
|
+
SyncStorageAdapter,
|
|
837
|
+
createBrowserStorageAdapter,
|
|
838
|
+
createKeepKit,
|
|
839
|
+
createStorageAdapter,
|
|
361
840
|
useKeepContext2 as useKeepContext,
|
|
362
841
|
useKeepItem2 as useKeepItem,
|
|
363
|
-
useKeepList2 as useKeepList
|
|
842
|
+
useKeepList2 as useKeepList,
|
|
843
|
+
useKeepShortcut,
|
|
844
|
+
useKeepUiLabels
|
|
364
845
|
};
|
|
365
846
|
//# sourceMappingURL=index.js.map
|