@bgord/ui 0.4.0 → 0.5.1
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/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/use-client-filter.d.ts +20 -0
- package/dist/hooks/use-exit-action.d.ts +1 -1
- package/dist/hooks/use-focus-shortcut.d.ts +8 -0
- package/dist/hooks/use-language-selector.d.ts +4 -0
- package/dist/hooks/use-meta-enter-submit.d.ts +3 -0
- package/dist/hooks/use-shortcuts.d.ts +8 -0
- package/dist/index.js +202 -76
- package/dist/services/etag.d.ts +6 -0
- package/dist/services/exec.d.ts +3 -0
- package/dist/services/get-safe-window.d.ts +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/weak-etag.d.ts +6 -0
- package/package.json +9 -6
- package/readme.md +52 -0
- package/README.md +0 -15
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
export * from "./use-client-filter";
|
|
1
2
|
export * from "./use-exit-action";
|
|
2
3
|
export * from "./use-field";
|
|
4
|
+
export * from "./use-focus-shortcut";
|
|
3
5
|
export * from "./use-hover";
|
|
6
|
+
export * from "./use-language-selector";
|
|
7
|
+
export * from "./use-meta-enter-submit";
|
|
8
|
+
export * from "./use-shortcuts";
|
|
4
9
|
export * from "./use-toggle";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FieldValueAllowedTypes } from "../services/field";
|
|
2
|
+
import { useFieldConfigType, useFieldReturnType, useFieldStrategyEnum } from "./use-field";
|
|
3
|
+
export type useClientFilterQueryType = string | undefined;
|
|
4
|
+
type useClientFilterConfigType<T extends FieldValueAllowedTypes> = Omit<useFieldConfigType<T>, "strategy"> & {
|
|
5
|
+
enum: {
|
|
6
|
+
[key: string]: useClientFilterQueryType;
|
|
7
|
+
};
|
|
8
|
+
filterFn?: (value: T) => boolean;
|
|
9
|
+
};
|
|
10
|
+
export type useClientFilterReturnType<T extends FieldValueAllowedTypes> = useFieldReturnType<T> & {
|
|
11
|
+
filterFn: NonNullable<useClientFilterConfigType<T>["filterFn"]>;
|
|
12
|
+
options: {
|
|
13
|
+
name: string;
|
|
14
|
+
value: useClientFilterConfigType<T>["enum"][0];
|
|
15
|
+
}[];
|
|
16
|
+
} & {
|
|
17
|
+
strategy: useFieldStrategyEnum.local;
|
|
18
|
+
};
|
|
19
|
+
export declare function useClientFilter<T extends FieldValueAllowedTypes>(config: useClientFilterConfigType<T>): useClientFilterReturnType<T>;
|
|
20
|
+
export {};
|
|
@@ -8,7 +8,7 @@ type UseExitActionReturnType = {
|
|
|
8
8
|
visible: boolean;
|
|
9
9
|
trigger: (event: React.MouseEvent) => void;
|
|
10
10
|
attach: {
|
|
11
|
-
"data-
|
|
11
|
+
"data-animation": UseExitActionAnimationType;
|
|
12
12
|
onAnimationEnd: (event: React.AnimationEvent) => void;
|
|
13
13
|
} | undefined;
|
|
14
14
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface UseKeyboardShortcutsConfigType {
|
|
2
|
+
[keybinding: string]: (event: KeyboardEvent) => void;
|
|
3
|
+
}
|
|
4
|
+
type UseKeyboardShortcutsOptionsType = {
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function useKeyboardShortcuts(config: UseKeyboardShortcutsConfigType, options?: UseKeyboardShortcutsOptionsType): void;
|
|
8
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -6,27 +6,8 @@ function Button() {
|
|
|
6
6
|
children: "Click"
|
|
7
7
|
}, undefined, false, undefined, this);
|
|
8
8
|
}
|
|
9
|
-
// src/hooks/use-
|
|
10
|
-
import
|
|
11
|
-
function useExitAction(options) {
|
|
12
|
-
const [phase, setPhase] = React.useState("idle" /* idle */);
|
|
13
|
-
const trigger = (event) => {
|
|
14
|
-
event.preventDefault();
|
|
15
|
-
if (phase === "idle")
|
|
16
|
-
setPhase("exiting" /* exiting */);
|
|
17
|
-
};
|
|
18
|
-
const onAnimationEnd = (event) => {
|
|
19
|
-
if (event.animationName !== options.animation)
|
|
20
|
-
return;
|
|
21
|
-
options.actionFn();
|
|
22
|
-
setPhase("gone" /* gone */);
|
|
23
|
-
};
|
|
24
|
-
const attach = phase === "exiting" ? { "data-exit": options.animation, onAnimationEnd } : undefined;
|
|
25
|
-
return { visible: phase !== "gone", attach, trigger };
|
|
26
|
-
}
|
|
27
|
-
// src/hooks/use-field.ts
|
|
28
|
-
import { useEffect, useState } from "react";
|
|
29
|
-
import { useSearchParams } from "react-router";
|
|
9
|
+
// src/hooks/use-client-filter.ts
|
|
10
|
+
import { useCallback, useMemo } from "react";
|
|
30
11
|
|
|
31
12
|
// src/services/field.ts
|
|
32
13
|
class Field {
|
|
@@ -53,6 +34,8 @@ class Field {
|
|
|
53
34
|
}
|
|
54
35
|
|
|
55
36
|
// src/hooks/use-field.ts
|
|
37
|
+
import { useEffect, useState } from "react";
|
|
38
|
+
import { useSearchParams } from "react-router";
|
|
56
39
|
var useFieldStrategyEnum;
|
|
57
40
|
((useFieldStrategyEnum2) => {
|
|
58
41
|
useFieldStrategyEnum2["params"] = "params";
|
|
@@ -104,8 +87,75 @@ class LocalFields {
|
|
|
104
87
|
return () => fields.forEach((field) => field.clear());
|
|
105
88
|
}
|
|
106
89
|
}
|
|
90
|
+
|
|
91
|
+
// src/hooks/use-client-filter.ts
|
|
92
|
+
function useClientFilter(config) {
|
|
93
|
+
const query = useField({
|
|
94
|
+
...config,
|
|
95
|
+
strategy: "local" /* local */
|
|
96
|
+
});
|
|
97
|
+
const defaultFilterFn = useCallback((given) => {
|
|
98
|
+
if (query.empty)
|
|
99
|
+
return true;
|
|
100
|
+
return Field.compare(given, query.currentValue);
|
|
101
|
+
}, [query.empty, query.currentValue]);
|
|
102
|
+
const filterFn = useMemo(() => config.filterFn ?? defaultFilterFn, [config.filterFn, defaultFilterFn]);
|
|
103
|
+
const options = useMemo(() => Object.entries(config.enum).map(([name, value]) => ({ name, value })), [config.enum]);
|
|
104
|
+
return useMemo(() => ({
|
|
105
|
+
...query,
|
|
106
|
+
filterFn,
|
|
107
|
+
options,
|
|
108
|
+
strategy: "local" /* local */
|
|
109
|
+
}), [query, filterFn, options]);
|
|
110
|
+
}
|
|
111
|
+
// src/hooks/use-exit-action.ts
|
|
112
|
+
import React from "react";
|
|
113
|
+
function useExitAction(options) {
|
|
114
|
+
const [phase, setPhase] = React.useState("idle" /* idle */);
|
|
115
|
+
const trigger = (event) => {
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
if (phase === "idle")
|
|
118
|
+
setPhase("exiting" /* exiting */);
|
|
119
|
+
};
|
|
120
|
+
const onAnimationEnd = (event) => {
|
|
121
|
+
if (event.animationName !== options.animation)
|
|
122
|
+
return;
|
|
123
|
+
options.actionFn();
|
|
124
|
+
setPhase("gone" /* gone */);
|
|
125
|
+
};
|
|
126
|
+
const attach = phase === "exiting" ? { "data-animation": options.animation, onAnimationEnd } : undefined;
|
|
127
|
+
return { visible: phase !== "gone", attach, trigger };
|
|
128
|
+
}
|
|
129
|
+
// src/hooks/use-focus-shortcut.ts
|
|
130
|
+
import { useCallback as useCallback2, useMemo as useMemo3, useRef } from "react";
|
|
131
|
+
|
|
132
|
+
// src/hooks/use-shortcuts.ts
|
|
133
|
+
import { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
134
|
+
import { tinykeys } from "tinykeys";
|
|
135
|
+
function useKeyboardShortcuts(config, options) {
|
|
136
|
+
const enabled = options?.enabled ?? true;
|
|
137
|
+
const memoizedConfig = useMemo2(() => config, [JSON.stringify(Object.keys(config))]);
|
|
138
|
+
useEffect2(() => {
|
|
139
|
+
if (!enabled)
|
|
140
|
+
return;
|
|
141
|
+
const unsubscribe = tinykeys(window, memoizedConfig);
|
|
142
|
+
return () => unsubscribe();
|
|
143
|
+
}, [memoizedConfig, enabled]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/hooks/use-focus-shortcut.ts
|
|
147
|
+
function useFocusKeyboardShortcut(shortcut) {
|
|
148
|
+
const ref = useRef(null);
|
|
149
|
+
const handleFocus = useCallback2(() => {
|
|
150
|
+
if (ref.current) {
|
|
151
|
+
ref.current.focus();
|
|
152
|
+
}
|
|
153
|
+
}, []);
|
|
154
|
+
useKeyboardShortcuts({ [shortcut]: handleFocus });
|
|
155
|
+
return useMemo3(() => ({ ref }), []);
|
|
156
|
+
}
|
|
107
157
|
// src/hooks/use-hover.ts
|
|
108
|
-
import { useCallback, useRef } from "react";
|
|
158
|
+
import { useCallback as useCallback3, useRef as useRef2 } from "react";
|
|
109
159
|
|
|
110
160
|
// src/hooks/use-toggle.ts
|
|
111
161
|
import { useState as useState2 } from "react";
|
|
@@ -143,10 +193,10 @@ function useHover({
|
|
|
143
193
|
enabled = true
|
|
144
194
|
} = {}) {
|
|
145
195
|
const { on: isOn, enable, disable } = useToggle({ name: "is-hovering" });
|
|
146
|
-
const nodeRef =
|
|
196
|
+
const nodeRef = useRef2(null);
|
|
147
197
|
const enterEvent = typeof window !== "undefined" && "PointerEvent" in window ? "pointerenter" : "mouseenter";
|
|
148
198
|
const leaveEvent = typeof window !== "undefined" && "PointerEvent" in window ? "pointerleave" : "mouseleave";
|
|
149
|
-
const ref =
|
|
199
|
+
const ref = useCallback3((node) => {
|
|
150
200
|
const prev = nodeRef.current;
|
|
151
201
|
if (prev) {
|
|
152
202
|
prev.removeEventListener(enterEvent, enable);
|
|
@@ -163,6 +213,102 @@ function useHover({
|
|
|
163
213
|
isHovering: isOn && enabled
|
|
164
214
|
};
|
|
165
215
|
}
|
|
216
|
+
// src/hooks/use-language-selector.tsx
|
|
217
|
+
import Cookies from "js-cookie";
|
|
218
|
+
import { useCallback as useCallback5, useEffect as useEffect3 } from "react";
|
|
219
|
+
import { useRevalidator } from "react-router";
|
|
220
|
+
|
|
221
|
+
// src/services/translations.tsx
|
|
222
|
+
import { createContext, use, useCallback as useCallback4 } from "react";
|
|
223
|
+
|
|
224
|
+
// src/services/pluralize.ts
|
|
225
|
+
import { polishPlurals } from "polish-plurals";
|
|
226
|
+
function pluralize(options) {
|
|
227
|
+
if (options.language === "en" /* en */) {
|
|
228
|
+
const plural = options.plural ?? `${options.singular}s`;
|
|
229
|
+
if (options.value === 1)
|
|
230
|
+
return options.singular;
|
|
231
|
+
return plural;
|
|
232
|
+
}
|
|
233
|
+
if (options.language === "pl" /* pl */) {
|
|
234
|
+
const value = options.value ?? 1;
|
|
235
|
+
if (value === 1)
|
|
236
|
+
return options.singular;
|
|
237
|
+
return polishPlurals(options.singular, String(options.plural), String(options.genitive), value);
|
|
238
|
+
}
|
|
239
|
+
console.warn(`[@bgord/frontend] missing pluralization function for language: ${options.language}.`);
|
|
240
|
+
return options.singular;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/services/translations.tsx
|
|
244
|
+
var TranslationsContext = createContext({
|
|
245
|
+
translations: {},
|
|
246
|
+
language: "en"
|
|
247
|
+
});
|
|
248
|
+
function useTranslations() {
|
|
249
|
+
const value = use(TranslationsContext);
|
|
250
|
+
if (value === undefined) {
|
|
251
|
+
throw new Error("useTranslations must be used within the TranslationsContext");
|
|
252
|
+
}
|
|
253
|
+
const translate = useCallback4((key, variables) => {
|
|
254
|
+
const translation = value.translations[key];
|
|
255
|
+
if (!translation) {
|
|
256
|
+
console.warn(`[@bgord/ui] missing translation for key: ${key}`);
|
|
257
|
+
return key;
|
|
258
|
+
}
|
|
259
|
+
if (!variables)
|
|
260
|
+
return translation;
|
|
261
|
+
return Object.entries(variables).reduce((result, [placeholder, value2]) => {
|
|
262
|
+
const regex = new RegExp(`{{${placeholder}}}`, "g");
|
|
263
|
+
return result.replace(regex, String(value2));
|
|
264
|
+
}, translation);
|
|
265
|
+
}, [value.translations]);
|
|
266
|
+
return translate;
|
|
267
|
+
}
|
|
268
|
+
function useLanguage() {
|
|
269
|
+
const value = use(TranslationsContext);
|
|
270
|
+
if (value === undefined) {
|
|
271
|
+
throw new Error("useLanguage must be used within the TranslationsContext");
|
|
272
|
+
}
|
|
273
|
+
return value.language;
|
|
274
|
+
}
|
|
275
|
+
function usePluralize() {
|
|
276
|
+
const language = useLanguage();
|
|
277
|
+
return (options) => pluralize({ ...options, language });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/hooks/use-language-selector.tsx
|
|
281
|
+
function useLanguageSelector(supportedLanguages) {
|
|
282
|
+
const language = useLanguage();
|
|
283
|
+
const revalidator = useRevalidator();
|
|
284
|
+
const field = useClientFilter({
|
|
285
|
+
enum: supportedLanguages,
|
|
286
|
+
defaultValue: language,
|
|
287
|
+
name: "language"
|
|
288
|
+
});
|
|
289
|
+
const handleLanguageChange = useCallback5(() => {
|
|
290
|
+
const current = new Field(field.currentValue);
|
|
291
|
+
if (!current.isEmpty() && field.changed) {
|
|
292
|
+
Cookies.set("language", String(current.get()));
|
|
293
|
+
revalidator.revalidate();
|
|
294
|
+
}
|
|
295
|
+
}, [field.currentValue, field.changed]);
|
|
296
|
+
useEffect3(() => {
|
|
297
|
+
handleLanguageChange();
|
|
298
|
+
}, [handleLanguageChange]);
|
|
299
|
+
return field;
|
|
300
|
+
}
|
|
301
|
+
// src/hooks/use-meta-enter-submit.tsx
|
|
302
|
+
import { useCallback as useCallback6, useMemo as useMemo4 } from "react";
|
|
303
|
+
function useMetaEnterSubmit() {
|
|
304
|
+
const handleMetaEnterSubmit = useCallback6((event) => {
|
|
305
|
+
if (event.key !== "Enter" || !event.metaKey)
|
|
306
|
+
return;
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
event.currentTarget.form?.requestSubmit();
|
|
309
|
+
}, []);
|
|
310
|
+
return useMemo4(() => ({ onKeyDown: handleMetaEnterSubmit }), [handleMetaEnterSubmit]);
|
|
311
|
+
}
|
|
166
312
|
// src/services/colorful.ts
|
|
167
313
|
function Colorful(color) {
|
|
168
314
|
const value = `var(--${color})`;
|
|
@@ -176,6 +322,20 @@ function Colorful(color) {
|
|
|
176
322
|
};
|
|
177
323
|
return { ...options, style };
|
|
178
324
|
}
|
|
325
|
+
// src/services/etag.ts
|
|
326
|
+
class ETag {
|
|
327
|
+
static fromRevision(revision) {
|
|
328
|
+
return { "if-match": String(revision) };
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// src/services/exec.ts
|
|
332
|
+
function exec(list) {
|
|
333
|
+
return function() {
|
|
334
|
+
for (const item of list) {
|
|
335
|
+
item();
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
179
339
|
// src/services/fields.ts
|
|
180
340
|
class Fields {
|
|
181
341
|
static allUnchanged(fields) {
|
|
@@ -217,23 +377,11 @@ class Form {
|
|
|
217
377
|
return { required };
|
|
218
378
|
}
|
|
219
379
|
}
|
|
220
|
-
// src/services/
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (options.value === 1)
|
|
226
|
-
return options.singular;
|
|
227
|
-
return plural;
|
|
228
|
-
}
|
|
229
|
-
if (options.language === "pl" /* pl */) {
|
|
230
|
-
const value = options.value ?? 1;
|
|
231
|
-
if (value === 1)
|
|
232
|
-
return options.singular;
|
|
233
|
-
return polishPlurals(options.singular, String(options.plural), String(options.genitive), value);
|
|
234
|
-
}
|
|
235
|
-
console.warn(`[@bgord/frontend] missing pluralization function for language: ${options.language}.`);
|
|
236
|
-
return options.singular;
|
|
380
|
+
// src/services/get-safe-window.ts
|
|
381
|
+
function getSafeWindow() {
|
|
382
|
+
if (typeof window === "undefined")
|
|
383
|
+
return;
|
|
384
|
+
return window;
|
|
237
385
|
}
|
|
238
386
|
// src/services/rhythm.ts
|
|
239
387
|
var DEFAULT_BASE_PX = 12;
|
|
@@ -266,60 +414,38 @@ function Rhythm(base = DEFAULT_BASE_PX) {
|
|
|
266
414
|
function px(number) {
|
|
267
415
|
return `${number}px`;
|
|
268
416
|
}
|
|
269
|
-
// src/services/
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
language: "en"
|
|
274
|
-
});
|
|
275
|
-
function useTranslations() {
|
|
276
|
-
const value = use(TranslationsContext);
|
|
277
|
-
if (value === undefined) {
|
|
278
|
-
throw new Error("useTranslations must be used within the TranslationsContext");
|
|
417
|
+
// src/services/weak-etag.ts
|
|
418
|
+
class WeakETag {
|
|
419
|
+
static fromRevision(revision) {
|
|
420
|
+
return { "if-match": `W/${revision}` };
|
|
279
421
|
}
|
|
280
|
-
const translate = useCallback2((key, variables) => {
|
|
281
|
-
const translation = value.translations[key];
|
|
282
|
-
if (!translation) {
|
|
283
|
-
console.warn(`[@bgord/ui] missing translation for key: ${key}`);
|
|
284
|
-
return key;
|
|
285
|
-
}
|
|
286
|
-
if (!variables)
|
|
287
|
-
return translation;
|
|
288
|
-
return Object.entries(variables).reduce((result, [placeholder, value2]) => {
|
|
289
|
-
const regex = new RegExp(`{{${placeholder}}}`, "g");
|
|
290
|
-
return result.replace(regex, String(value2));
|
|
291
|
-
}, translation);
|
|
292
|
-
}, [value.translations]);
|
|
293
|
-
return translate;
|
|
294
|
-
}
|
|
295
|
-
function useLanguage() {
|
|
296
|
-
const value = use(TranslationsContext);
|
|
297
|
-
if (value === undefined) {
|
|
298
|
-
throw new Error("useLanguage must be used within the TranslationsContext");
|
|
299
|
-
}
|
|
300
|
-
return value.language;
|
|
301
|
-
}
|
|
302
|
-
function usePluralize() {
|
|
303
|
-
const language = useLanguage();
|
|
304
|
-
return (options) => pluralize({ ...options, language });
|
|
305
422
|
}
|
|
306
423
|
export {
|
|
307
424
|
useTranslations,
|
|
308
425
|
useToggle,
|
|
309
426
|
usePluralize,
|
|
427
|
+
useMetaEnterSubmit,
|
|
428
|
+
useLanguageSelector,
|
|
310
429
|
useLanguage,
|
|
430
|
+
useKeyboardShortcuts,
|
|
311
431
|
useHover,
|
|
432
|
+
useFocusKeyboardShortcut,
|
|
312
433
|
useFieldStrategyEnum,
|
|
313
434
|
useField,
|
|
314
435
|
useExitAction,
|
|
436
|
+
useClientFilter,
|
|
315
437
|
pluralize,
|
|
438
|
+
getSafeWindow,
|
|
316
439
|
extractUseToggle,
|
|
440
|
+
exec,
|
|
441
|
+
WeakETag,
|
|
317
442
|
TranslationsContext,
|
|
318
443
|
Rhythm,
|
|
319
444
|
LocalFields,
|
|
320
445
|
Form,
|
|
321
446
|
Fields,
|
|
322
447
|
Field,
|
|
448
|
+
ETag,
|
|
323
449
|
Colorful,
|
|
324
450
|
Button
|
|
325
451
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getSafeWindow(): (Window & typeof globalThis) | undefined;
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export * from "./colorful";
|
|
2
|
+
export * from "./etag";
|
|
3
|
+
export * from "./exec";
|
|
2
4
|
export * from "./field";
|
|
3
5
|
export * from "./fields";
|
|
4
6
|
export * from "./form";
|
|
7
|
+
export * from "./get-safe-window";
|
|
5
8
|
export * from "./pluralize";
|
|
6
9
|
export * from "./rhythm";
|
|
7
10
|
export * from "./translations";
|
|
11
|
+
export * from "./weak-etag";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -25,24 +25,27 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@biomejs/biome": "2.0.6",
|
|
29
|
+
"@commitlint/cli": "19.8.1",
|
|
30
|
+
"@commitlint/config-conventional": "19.8.1",
|
|
28
31
|
"@happy-dom/global-registrator": "18.0.1",
|
|
29
32
|
"@testing-library/dom": "10.4.0",
|
|
30
33
|
"@testing-library/jest-dom": "6.6.3",
|
|
31
34
|
"@testing-library/react": "16.3.0",
|
|
32
35
|
"@testing-library/user-event": "14.6.1",
|
|
33
36
|
"@types/bun": "1.2.18",
|
|
37
|
+
"@types/js-cookie": "^3.0.6",
|
|
34
38
|
"@types/react": "19.1.8",
|
|
35
39
|
"@types/react-dom": "19.1.6",
|
|
36
|
-
"
|
|
37
|
-
"@commitlint/cli": "19.8.1",
|
|
38
|
-
"@commitlint/config-conventional": "19.8.1",
|
|
39
|
-
"cspell": "9.1.3",
|
|
40
|
+
"cspell": "9.1.5",
|
|
40
41
|
"knip": "5.61.3",
|
|
41
42
|
"lefthook": "1.12.2",
|
|
42
43
|
"only-allow": "1.2.1",
|
|
43
44
|
"shellcheck": "3.1.0"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
|
-
"
|
|
47
|
+
"js-cookie": "3.0.5",
|
|
48
|
+
"polish-plurals": "1.1.0",
|
|
49
|
+
"tinykeys": "3.0.0"
|
|
47
50
|
}
|
|
48
51
|
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# bgord-ui
|
|
2
|
+
|
|
3
|
+
## Configuration:
|
|
4
|
+
|
|
5
|
+
Clone the repository
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
git clone git@github.com:bgord/journal.git --recurse-submodules
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install packages
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
bun i
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run the tests
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
./bgord-scripts/test-run.sh
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Files:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
src/
|
|
27
|
+
├── components
|
|
28
|
+
│ ├── button.tsx
|
|
29
|
+
├── hooks
|
|
30
|
+
│ ├── use-client-filter.ts
|
|
31
|
+
│ ├── use-exit-action.ts
|
|
32
|
+
│ ├── use-field.ts
|
|
33
|
+
│ ├── use-focus-shortcut.ts
|
|
34
|
+
│ ├── use-hover.ts
|
|
35
|
+
│ ├── use-language-selector.tsx
|
|
36
|
+
│ ├── use-meta-enter-submit.tsx
|
|
37
|
+
│ ├── use-shortcuts.ts
|
|
38
|
+
│ └── use-toggle.ts
|
|
39
|
+
└── services
|
|
40
|
+
├── colorful.ts
|
|
41
|
+
├── etag.ts
|
|
42
|
+
├── exec.ts
|
|
43
|
+
├── field.ts
|
|
44
|
+
├── fields.ts
|
|
45
|
+
├── form.ts
|
|
46
|
+
├── get-safe-window.ts
|
|
47
|
+
├── pluralize.ts
|
|
48
|
+
├── rhythm.ts
|
|
49
|
+
├── translations.tsx
|
|
50
|
+
└── weak-etag.ts
|
|
51
|
+
```
|
|
52
|
+
|
package/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# bgord-ui
|
|
2
|
-
|
|
3
|
-
To install dependencies:
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
bun install
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
To run:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
bun run index.ts
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
This project was created using `bun init` in bun v1.2.17. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|