@tekki-forge/runtime-admin 0.1.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 +5 -0
- package/dist/account.d.ts +1 -0
- package/dist/account.js +105 -0
- package/dist/account.js.map +1 -0
- package/dist/activity.d.ts +65 -0
- package/dist/activity.js +299 -0
- package/dist/activity.js.map +1 -0
- package/dist/admin-access.d.ts +4 -0
- package/dist/admin-access.js +177 -0
- package/dist/admin-access.js.map +1 -0
- package/dist/admin.d.ts +5 -0
- package/dist/admin.js +129 -0
- package/dist/admin.js.map +1 -0
- package/dist/auth-pages.d.ts +13 -0
- package/dist/auth-pages.js +207 -0
- package/dist/auth-pages.js.map +1 -0
- package/dist/brand-art.d.ts +24 -0
- package/dist/brand-art.js +33 -0
- package/dist/brand-art.js.map +1 -0
- package/dist/brand.d.ts +11 -0
- package/dist/brand.js +16 -0
- package/dist/brand.js.map +1 -0
- package/dist/charts.d.ts +23 -0
- package/dist/charts.js +259 -0
- package/dist/charts.js.map +1 -0
- package/dist/command-palette.d.ts +9 -0
- package/dist/command-palette.js +115 -0
- package/dist/command-palette.js.map +1 -0
- package/dist/context.d.ts +242 -0
- package/dist/context.js +107 -0
- package/dist/context.js.map +1 -0
- package/dist/dashboard.d.ts +66 -0
- package/dist/dashboard.js +144 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/fields.d.ts +71 -0
- package/dist/fields.js +326 -0
- package/dist/fields.js.map +1 -0
- package/dist/i18n/catalog.d.ts +7 -0
- package/dist/i18n/catalog.js +23 -0
- package/dist/i18n/catalog.js.map +1 -0
- package/dist/i18n/locale.d.ts +15 -0
- package/dist/i18n/locale.js +69 -0
- package/dist/i18n/locale.js.map +1 -0
- package/dist/i18n/messages/de.d.ts +3 -0
- package/dist/i18n/messages/de.js +627 -0
- package/dist/i18n/messages/de.js.map +1 -0
- package/dist/i18n/messages/en.d.ts +3 -0
- package/dist/i18n/messages/en.js +627 -0
- package/dist/i18n/messages/en.js.map +1 -0
- package/dist/i18n/messages/es.d.ts +3 -0
- package/dist/i18n/messages/es.js +627 -0
- package/dist/i18n/messages/es.js.map +1 -0
- package/dist/i18n/messages/fr.d.ts +3 -0
- package/dist/i18n/messages/fr.js +627 -0
- package/dist/i18n/messages/fr.js.map +1 -0
- package/dist/i18n/messages/pt.d.ts +3 -0
- package/dist/i18n/messages/pt.js +627 -0
- package/dist/i18n/messages/pt.js.map +1 -0
- package/dist/i18n/validation.d.ts +3 -0
- package/dist/i18n/validation.js +36 -0
- package/dist/i18n/validation.js.map +1 -0
- package/dist/illustrations.d.ts +6 -0
- package/dist/illustrations.js +16 -0
- package/dist/illustrations.js.map +1 -0
- package/dist/import-dialog.d.ts +11 -0
- package/dist/import-dialog.js +152 -0
- package/dist/import-dialog.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/inline-edit.d.ts +18 -0
- package/dist/inline-edit.js +115 -0
- package/dist/inline-edit.js.map +1 -0
- package/dist/landing.d.ts +79 -0
- package/dist/landing.js +122 -0
- package/dist/landing.js.map +1 -0
- package/dist/locale-switcher.d.ts +4 -0
- package/dist/locale-switcher.js +15 -0
- package/dist/locale-switcher.js.map +1 -0
- package/dist/map.d.ts +26 -0
- package/dist/map.js +232 -0
- package/dist/map.js.map +1 -0
- package/dist/notifications.d.ts +12 -0
- package/dist/notifications.js +75 -0
- package/dist/notifications.js.map +1 -0
- package/dist/record-mutation.d.ts +19 -0
- package/dist/record-mutation.js +39 -0
- package/dist/record-mutation.js.map +1 -0
- package/dist/resource-detail.d.ts +4 -0
- package/dist/resource-detail.js +96 -0
- package/dist/resource-detail.js.map +1 -0
- package/dist/resource-form.d.ts +11 -0
- package/dist/resource-form.js +92 -0
- package/dist/resource-form.js.map +1 -0
- package/dist/resource-list.d.ts +10 -0
- package/dist/resource-list.js +154 -0
- package/dist/resource-list.js.map +1 -0
- package/dist/saved-views.d.ts +16 -0
- package/dist/saved-views.js +64 -0
- package/dist/saved-views.js.map +1 -0
- package/dist/schema-editor-diagram.d.ts +14 -0
- package/dist/schema-editor-diagram.js +54 -0
- package/dist/schema-editor-diagram.js.map +1 -0
- package/dist/schema-editor.d.ts +98 -0
- package/dist/schema-editor.js +571 -0
- package/dist/schema-editor.js.map +1 -0
- package/dist/shell.d.ts +10 -0
- package/dist/shell.js +228 -0
- package/dist/shell.js.map +1 -0
- package/dist/skeleton.d.ts +25 -0
- package/dist/skeleton.js +34 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/theme-catalog.d.ts +71 -0
- package/dist/theme-catalog.js +55 -0
- package/dist/theme-catalog.js.map +1 -0
- package/dist/theme-head.d.ts +8 -0
- package/dist/theme-head.js +11 -0
- package/dist/theme-head.js.map +1 -0
- package/dist/theme-preview.d.ts +2 -0
- package/dist/theme-preview.js +23 -0
- package/dist/theme-preview.js.map +1 -0
- package/dist/theme-switcher.d.ts +20 -0
- package/dist/theme-switcher.js +159 -0
- package/dist/theme-switcher.js.map +1 -0
- package/dist/theme.d.ts +24 -0
- package/dist/theme.js +30 -0
- package/dist/theme.js.map +1 -0
- package/dist/toast.d.ts +21 -0
- package/dist/toast.js +51 -0
- package/dist/toast.js.map +1 -0
- package/dist/ui.d.ts +86 -0
- package/dist/ui.js +106 -0
- package/dist/ui.js.map +1 -0
- package/dist/views.d.ts +23 -0
- package/dist/views.js +238 -0
- package/dist/views.js.map +1 -0
- package/package.json +58 -0
- package/styles.css +778 -0
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { FieldIR, FormFieldMeta } from "@tekki-forge/compiler";
|
|
2
|
+
type Value = unknown;
|
|
3
|
+
/** Convert an API record value into the representation a form control edits. */
|
|
4
|
+
export interface FileValue {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
size: number;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
url: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function toFormValue(field: FormFieldMeta, value: Value): Value;
|
|
12
|
+
/** Convert form state back into an API payload value. */
|
|
13
|
+
export declare function toPayloadValue(field: FormFieldMeta, value: Value): Value;
|
|
14
|
+
export declare function FieldInput({ field, value, onChange, error, entity }: {
|
|
15
|
+
field: FormFieldMeta;
|
|
16
|
+
value: Value;
|
|
17
|
+
onChange: (v: Value) => void;
|
|
18
|
+
error?: string;
|
|
19
|
+
entity?: string;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
/** Async, searchable picker backed by the `<resource>/lookup` endpoint. */
|
|
22
|
+
export declare function RelationSelect({ id, lookupPath, value, onChange, invalid, placeholder, emptyLabel, compact, }: {
|
|
23
|
+
id?: string;
|
|
24
|
+
lookupPath: string;
|
|
25
|
+
value: string | null;
|
|
26
|
+
onChange: (v: string | null) => void;
|
|
27
|
+
invalid?: boolean;
|
|
28
|
+
placeholder?: string;
|
|
29
|
+
emptyLabel?: string;
|
|
30
|
+
compact?: boolean;
|
|
31
|
+
}): import("react").JSX.Element;
|
|
32
|
+
/** Multi-select for many-to-many relations: removable chips plus an async search list. */
|
|
33
|
+
export declare function RelationMultiSelect({ id, lookupPath, value, onChange, invalid }: {
|
|
34
|
+
id?: string;
|
|
35
|
+
lookupPath: string;
|
|
36
|
+
value: string[];
|
|
37
|
+
onChange: (v: string[]) => void;
|
|
38
|
+
invalid?: boolean;
|
|
39
|
+
}): import("react").JSX.Element;
|
|
40
|
+
export declare function formatBytes(n: number): string;
|
|
41
|
+
/** Upload widget for file and image fields: drag & drop, progress, preview, remove/replace. */
|
|
42
|
+
export declare function FileInput({ id, entity, field, value, onChange, invalid }: {
|
|
43
|
+
id?: string;
|
|
44
|
+
entity: string;
|
|
45
|
+
field: FormFieldMeta;
|
|
46
|
+
value: FileValue | null;
|
|
47
|
+
onChange: (v: FileValue | null) => void;
|
|
48
|
+
invalid?: boolean;
|
|
49
|
+
}): import("react").JSX.Element;
|
|
50
|
+
/** Latitude/longitude inputs with a "use my location" shortcut. */
|
|
51
|
+
export declare function LocationInput({ id, value, onChange, invalid }: {
|
|
52
|
+
id?: string;
|
|
53
|
+
value: {
|
|
54
|
+
lat: string;
|
|
55
|
+
lng: string;
|
|
56
|
+
};
|
|
57
|
+
onChange: (v: {
|
|
58
|
+
lat: string;
|
|
59
|
+
lng: string;
|
|
60
|
+
}) => void;
|
|
61
|
+
invalid?: boolean;
|
|
62
|
+
}): import("react").JSX.Element;
|
|
63
|
+
/** Locale-aware text for scalar values (dates and numbers follow the UI language). */
|
|
64
|
+
export declare function displayText(field: FieldIR | undefined, value: unknown, locale: string): string;
|
|
65
|
+
/** Read-only rendering of a field value in tables and detail views. */
|
|
66
|
+
export declare function FieldValue({ field, value, cell }: {
|
|
67
|
+
field?: FieldIR;
|
|
68
|
+
value: unknown;
|
|
69
|
+
cell?: string;
|
|
70
|
+
}): import("react").JSX.Element;
|
|
71
|
+
export {};
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { formatValue } from "@tekki-forge/runtime-schema";
|
|
4
|
+
import { useQuery } from "@tanstack/react-query";
|
|
5
|
+
import { Check, ChevronsUpDown, File as FileIcon, MapPin, UploadCloud, X } from "lucide-react";
|
|
6
|
+
import { useEffect, useRef, useState } from "react";
|
|
7
|
+
import { useForge, useLocale, useT } from "./context.js";
|
|
8
|
+
import { Badge, FieldShell, Input, Select, Textarea, cn, inputClass } from "./ui.js";
|
|
9
|
+
export function toFormValue(field, value) {
|
|
10
|
+
if (field.file)
|
|
11
|
+
return value && typeof value === "object" ? value : null;
|
|
12
|
+
if (field.component === "relation-multi")
|
|
13
|
+
return Array.isArray(value) ? value : [];
|
|
14
|
+
if (field.component === "location") {
|
|
15
|
+
const v = value;
|
|
16
|
+
return { lat: v ? String(v.lat) : "", lng: v ? String(v.lng) : "" };
|
|
17
|
+
}
|
|
18
|
+
if (value === null || value === undefined)
|
|
19
|
+
return field.component === "switch" ? false : "";
|
|
20
|
+
if (field.component === "datetime") {
|
|
21
|
+
const d = new Date(String(value));
|
|
22
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
23
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
24
|
+
}
|
|
25
|
+
if (field.component === "json")
|
|
26
|
+
return JSON.stringify(value, null, 2);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
/** Convert form state back into an API payload value. */
|
|
30
|
+
export function toPayloadValue(field, value) {
|
|
31
|
+
if (field.file)
|
|
32
|
+
return value && typeof value === "object" ? value.id : null;
|
|
33
|
+
if (field.component === "switch")
|
|
34
|
+
return !!value;
|
|
35
|
+
if (field.component === "relation-multi")
|
|
36
|
+
return Array.isArray(value) ? value : [];
|
|
37
|
+
if (field.component === "location") {
|
|
38
|
+
const v = (value ?? {});
|
|
39
|
+
if (!v.lat?.trim() && !v.lng?.trim())
|
|
40
|
+
return null;
|
|
41
|
+
return { lat: Number(v.lat), lng: Number(v.lng) };
|
|
42
|
+
}
|
|
43
|
+
if (value === "" || value === undefined)
|
|
44
|
+
return null;
|
|
45
|
+
if (field.component === "datetime")
|
|
46
|
+
return new Date(String(value)).toISOString();
|
|
47
|
+
if (field.component === "json") {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(String(value));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
export function FieldInput({ field, value, onChange, error, entity }) {
|
|
58
|
+
const t = useT();
|
|
59
|
+
const id = `field-${field.name}`;
|
|
60
|
+
const common = { id, name: field.apiName, "aria-invalid": error ? true : undefined, placeholder: field.placeholder };
|
|
61
|
+
const str = value === null || value === undefined ? "" : String(value);
|
|
62
|
+
let control;
|
|
63
|
+
switch (field.component) {
|
|
64
|
+
case "textarea":
|
|
65
|
+
case "markdown":
|
|
66
|
+
control = _jsx(Textarea, { ...common, value: str, onChange: (e) => onChange(e.target.value), rows: field.component === "markdown" ? 8 : 4 });
|
|
67
|
+
break;
|
|
68
|
+
case "json":
|
|
69
|
+
control = _jsx(Textarea, { ...common, className: "font-mono text-xs", value: str, onChange: (e) => onChange(e.target.value), rows: 6 });
|
|
70
|
+
break;
|
|
71
|
+
case "switch":
|
|
72
|
+
control = (_jsx("button", { id: id, type: "button", role: "switch", "aria-checked": !!value, onClick: () => onChange(!value), className: "forge-switch relative inline-flex h-6 w-11 items-center", children: _jsx("span", { className: cn("forge-switch-thumb inline-block size-5 transition-transform", value ? "translate-x-5" : "translate-x-0.5") }) }));
|
|
73
|
+
break;
|
|
74
|
+
case "select":
|
|
75
|
+
control = (_jsxs(Select, { ...common, value: str, onChange: (e) => onChange(e.target.value), children: [!field.required && _jsx("option", { value: "", children: "\u2014" }), field.required && !str && _jsx("option", { value: "", children: t("common.select") }), field.options?.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value)))] }));
|
|
76
|
+
break;
|
|
77
|
+
case "relation-select":
|
|
78
|
+
control = _jsx(RelationSelect, { id: id, lookupPath: field.relation.lookupPath, value: str || null, onChange: (v) => onChange(v ?? ""), invalid: !!error });
|
|
79
|
+
break;
|
|
80
|
+
case "relation-multi":
|
|
81
|
+
control = _jsx(RelationMultiSelect, { id: id, lookupPath: field.relation.lookupPath, value: value ?? [], onChange: onChange, invalid: !!error });
|
|
82
|
+
break;
|
|
83
|
+
case "file":
|
|
84
|
+
case "image":
|
|
85
|
+
control = _jsx(FileInput, { id: id, entity: entity ?? "", field: field, value: value, onChange: onChange, invalid: !!error });
|
|
86
|
+
break;
|
|
87
|
+
case "location":
|
|
88
|
+
control = _jsx(LocationInput, { id: id, value: value, onChange: onChange, invalid: !!error });
|
|
89
|
+
break;
|
|
90
|
+
case "money":
|
|
91
|
+
case "percentage":
|
|
92
|
+
case "number":
|
|
93
|
+
control = (_jsxs("div", { className: "relative", children: [_jsx(Input, { ...common, type: "number", inputMode: "decimal", step: "any", min: field.validation.min, max: field.validation.max, value: str, onChange: (e) => onChange(e.target.value), className: field.component !== "number" ? "pr-14" : undefined }), field.component !== "number" && (_jsx("span", { className: "pointer-events-none absolute inset-y-0 right-3 flex items-center text-xs text-ink-subtle", children: field.component === "money" ? field.currency : "%" }))] }));
|
|
94
|
+
break;
|
|
95
|
+
case "color":
|
|
96
|
+
control = (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "color", "aria-label": t("fields.colorPicker", { label: field.label }), value: str || "#000000", onChange: (e) => onChange(e.target.value), className: "forge-input h-9 w-12 p-0.5" }), _jsx(Input, { ...common, value: str, onChange: (e) => onChange(e.target.value), className: "font-mono" })] }));
|
|
97
|
+
break;
|
|
98
|
+
case "date":
|
|
99
|
+
control = _jsx(Input, { ...common, type: "date", value: str.slice(0, 10), onChange: (e) => onChange(e.target.value) });
|
|
100
|
+
break;
|
|
101
|
+
case "datetime":
|
|
102
|
+
control = _jsx(Input, { ...common, type: "datetime-local", value: str, onChange: (e) => onChange(e.target.value) });
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
control = (_jsx(Input, { ...common, type: field.component === "email" ? "email" : field.component === "url" ? "url" : field.component === "tel" ? "tel" : "text", maxLength: field.validation.maxLength, value: str, onChange: (e) => onChange(e.target.value) }));
|
|
106
|
+
}
|
|
107
|
+
return (_jsx(FieldShell, { label: field.label, htmlFor: id, required: field.required, error: error, hint: field.description, children: control }));
|
|
108
|
+
}
|
|
109
|
+
/** Async, searchable picker backed by the `<resource>/lookup` endpoint. */
|
|
110
|
+
export function RelationSelect({ id, lookupPath, value, onChange, invalid, placeholder, emptyLabel, compact, }) {
|
|
111
|
+
const { api, t } = useForge();
|
|
112
|
+
const [open, setOpen] = useState(false);
|
|
113
|
+
const [search, setSearch] = useState("");
|
|
114
|
+
const [debounced, setDebounced] = useState("");
|
|
115
|
+
const ref = useRef(null);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const t = setTimeout(() => setDebounced(search), 200);
|
|
118
|
+
return () => clearTimeout(t);
|
|
119
|
+
}, [search]);
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
const close = (e) => ref.current && !ref.current.contains(e.target) && setOpen(false);
|
|
122
|
+
document.addEventListener("mousedown", close);
|
|
123
|
+
return () => document.removeEventListener("mousedown", close);
|
|
124
|
+
}, []);
|
|
125
|
+
const selected = useQuery({
|
|
126
|
+
queryKey: ["lookup", lookupPath, "ids", value],
|
|
127
|
+
queryFn: () => api(`/${lookupPath}`, { query: { ids: value } }),
|
|
128
|
+
enabled: !!value,
|
|
129
|
+
});
|
|
130
|
+
const options = useQuery({
|
|
131
|
+
queryKey: ["lookup", lookupPath, "search", debounced],
|
|
132
|
+
queryFn: () => api(`/${lookupPath}`, { query: { search: debounced } }),
|
|
133
|
+
enabled: open,
|
|
134
|
+
});
|
|
135
|
+
const selectedLabel = selected.data?.data[0]?.label;
|
|
136
|
+
return (_jsxs("div", { ref: ref, className: "relative", children: [_jsxs("button", { id: id, type: "button", "aria-haspopup": "listbox", "aria-expanded": open, "aria-invalid": invalid || undefined, onClick: () => setOpen((o) => !o), className: cn(inputClass, "flex items-center justify-between text-left", compact && "h-8 py-0 text-xs"), children: [_jsx("span", { className: cn("truncate", !value && (compact ? "text-ink" : "text-ink-subtle")), children: value ? (selectedLabel ?? t("common.loading")) : (emptyLabel ?? t("common.select")) }), _jsxs("span", { className: "flex items-center gap-1", children: [value && (_jsx("span", { role: "button", tabIndex: 0, "aria-label": t("common.clear"), onClick: (e) => {
|
|
137
|
+
e.stopPropagation();
|
|
138
|
+
onChange(null);
|
|
139
|
+
}, className: "p-0.5 text-ink-subtle hover:text-ink", children: _jsx(X, { className: "size-3.5" }) })), _jsx(ChevronsUpDown, { className: "size-4 text-ink-subtle" })] })] }), open && (_jsxs("div", { className: "forge-popover absolute z-20 mt-1 w-full", children: [_jsx("div", { className: "border-b border-line p-2", children: _jsx(Input, { autoFocus: true, placeholder: placeholder ?? t("common.searchEllipsis"), value: search, onChange: (e) => setSearch(e.target.value), className: "h-8" }) }), _jsxs("ul", { role: "listbox", className: "max-h-60 overflow-auto py-1 text-sm", children: [options.isLoading && _jsx("li", { className: "px-3 py-2 text-ink-subtle", children: t("common.loading") }), options.data?.data.length === 0 && _jsx("li", { className: "px-3 py-2 text-ink-subtle", children: t("fields.noMatches") }), options.data?.data.map((o) => (_jsx("li", { role: "option", "aria-selected": o.id === value, children: _jsxs("button", { type: "button", className: "flex w-full items-center justify-between px-3 py-1.5 text-left text-ink hover:bg-hover", onClick: () => {
|
|
140
|
+
onChange(o.id);
|
|
141
|
+
setOpen(false);
|
|
142
|
+
setSearch("");
|
|
143
|
+
}, children: [_jsx("span", { className: "truncate", children: o.label }), o.id === value && _jsx(Check, { className: "size-4 text-link" })] }) }, o.id)))] })] }))] }));
|
|
144
|
+
}
|
|
145
|
+
/** Multi-select for many-to-many relations: removable chips plus an async search list. */
|
|
146
|
+
export function RelationMultiSelect({ id, lookupPath, value, onChange, invalid }) {
|
|
147
|
+
const { api, t } = useForge();
|
|
148
|
+
const [open, setOpen] = useState(false);
|
|
149
|
+
const [search, setSearch] = useState("");
|
|
150
|
+
const [debounced, setDebounced] = useState("");
|
|
151
|
+
const ref = useRef(null);
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
const t = setTimeout(() => setDebounced(search), 200);
|
|
154
|
+
return () => clearTimeout(t);
|
|
155
|
+
}, [search]);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
const close = (e) => ref.current && !ref.current.contains(e.target) && setOpen(false);
|
|
158
|
+
document.addEventListener("mousedown", close);
|
|
159
|
+
return () => document.removeEventListener("mousedown", close);
|
|
160
|
+
}, []);
|
|
161
|
+
const selected = useQuery({
|
|
162
|
+
queryKey: ["lookup", lookupPath, "ids", [...value].sort().join(",")],
|
|
163
|
+
queryFn: () => api(`/${lookupPath}`, { query: { ids: value.join(",") } }),
|
|
164
|
+
enabled: value.length > 0,
|
|
165
|
+
});
|
|
166
|
+
const options = useQuery({
|
|
167
|
+
queryKey: ["lookup", lookupPath, "search", debounced],
|
|
168
|
+
queryFn: () => api(`/${lookupPath}`, { query: { search: debounced } }),
|
|
169
|
+
enabled: open,
|
|
170
|
+
});
|
|
171
|
+
const labels = new Map(selected.data?.data.map((o) => [o.id, o.label]));
|
|
172
|
+
const toggle = (optionId) => onChange(value.includes(optionId) ? value.filter((v) => v !== optionId) : [...value, optionId]);
|
|
173
|
+
return (_jsxs("div", { ref: ref, className: "relative", children: [_jsxs("div", { id: id, role: "combobox", "aria-expanded": open, "aria-invalid": invalid || undefined, tabIndex: 0, onClick: () => setOpen(true), onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && setOpen(true), className: cn(inputClass, "flex min-h-9 flex-wrap items-center gap-1.5 py-1.5"), children: [value.length === 0 && _jsx("span", { className: "text-ink-subtle", children: t("common.select") }), value.map((v) => (_jsxs("span", { className: "forge-badge inline-flex items-center gap-1 px-2 py-0.5 text-xs", children: [labels.get(v) ?? "…", _jsx("button", { type: "button", "aria-label": t("fields.removeItem", { item: labels.get(v) ?? v }), onClick: (e) => (e.stopPropagation(), toggle(v)), className: "opacity-60 hover:opacity-100", children: _jsx(X, { className: "size-3" }) })] }, v)))] }), open && (_jsxs("div", { className: "forge-popover absolute z-20 mt-1 w-full", children: [_jsx("div", { className: "border-b border-line p-2", children: _jsx(Input, { autoFocus: true, placeholder: t("common.searchEllipsis"), value: search, onChange: (e) => setSearch(e.target.value), className: "h-8" }) }), _jsxs("ul", { role: "listbox", "aria-multiselectable": "true", className: "max-h-60 overflow-auto py-1 text-sm", children: [options.isLoading && _jsx("li", { className: "px-3 py-2 text-ink-subtle", children: t("common.loading") }), options.data?.data.length === 0 && _jsx("li", { className: "px-3 py-2 text-ink-subtle", children: t("fields.noMatches") }), options.data?.data.map((o) => (_jsx("li", { role: "option", "aria-selected": value.includes(o.id), children: _jsxs("button", { type: "button", className: "flex w-full items-center justify-between px-3 py-1.5 text-left text-ink hover:bg-hover", onClick: () => toggle(o.id), children: [_jsx("span", { className: "truncate", children: o.label }), value.includes(o.id) && _jsx(Check, { className: "size-4 text-primary" })] }) }, o.id)))] })] }))] }));
|
|
174
|
+
}
|
|
175
|
+
export function formatBytes(n) {
|
|
176
|
+
if (n >= 1024 ** 2)
|
|
177
|
+
return `${(n / 1024 ** 2).toFixed(1).replace(/\.0$/, "")} MB`;
|
|
178
|
+
if (n >= 1024)
|
|
179
|
+
return `${Math.round(n / 1024)} KB`;
|
|
180
|
+
return `${n} B`;
|
|
181
|
+
}
|
|
182
|
+
function acceptAttr(accept) {
|
|
183
|
+
return accept.length ? accept.join(",") : undefined;
|
|
184
|
+
}
|
|
185
|
+
function matchesAccept(accept, file) {
|
|
186
|
+
if (!accept.length)
|
|
187
|
+
return true;
|
|
188
|
+
const ext = /\.[a-z0-9]+$/i.exec(file.name)?.[0]?.toLowerCase();
|
|
189
|
+
return accept.some((a) => (a.startsWith(".") ? ext === a : a.endsWith("/*") ? file.type.startsWith(a.slice(0, -1)) : file.type === a));
|
|
190
|
+
}
|
|
191
|
+
/** Upload widget for file and image fields: drag & drop, progress, preview, remove/replace. */
|
|
192
|
+
export function FileInput({ id, entity, field, value, onChange, invalid }) {
|
|
193
|
+
const { app, t } = useForge();
|
|
194
|
+
const spec = field.file;
|
|
195
|
+
const [progress, setProgress] = useState(null);
|
|
196
|
+
const [error, setError] = useState(null);
|
|
197
|
+
const [dragging, setDragging] = useState(false);
|
|
198
|
+
const inputRef = useRef(null);
|
|
199
|
+
const upload = (file) => {
|
|
200
|
+
setError(null);
|
|
201
|
+
if (file.size > spec.maxSize)
|
|
202
|
+
return setError(t("fields.file.tooLarge", { size: formatBytes(spec.maxSize) }));
|
|
203
|
+
if (!matchesAccept(spec.accept, file))
|
|
204
|
+
return setError(t("fields.file.wrongType", { types: spec.accept.join(", ") }));
|
|
205
|
+
const form = new FormData();
|
|
206
|
+
form.append("entity", entity);
|
|
207
|
+
form.append("field", field.name);
|
|
208
|
+
form.append("file", file);
|
|
209
|
+
const xhr = new XMLHttpRequest();
|
|
210
|
+
xhr.open("POST", `${app.api.prefix}/files`);
|
|
211
|
+
xhr.withCredentials = true;
|
|
212
|
+
xhr.upload.onprogress = (e) => e.lengthComputable && setProgress(Math.round((e.loaded / e.total) * 100));
|
|
213
|
+
xhr.onload = () => {
|
|
214
|
+
setProgress(null);
|
|
215
|
+
let body = {};
|
|
216
|
+
try {
|
|
217
|
+
body = JSON.parse(xhr.responseText);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
/* non-JSON error */
|
|
221
|
+
}
|
|
222
|
+
if (xhr.status >= 200 && xhr.status < 300)
|
|
223
|
+
onChange(body);
|
|
224
|
+
else
|
|
225
|
+
setError(body.message ?? t("fields.file.uploadFailedStatus", { status: String(xhr.status) }));
|
|
226
|
+
};
|
|
227
|
+
xhr.onerror = () => {
|
|
228
|
+
setProgress(null);
|
|
229
|
+
setError(t("fields.file.uploadFailedNetwork"));
|
|
230
|
+
};
|
|
231
|
+
setProgress(0);
|
|
232
|
+
xhr.send(form);
|
|
233
|
+
};
|
|
234
|
+
return (_jsxs("div", { children: [value ? (_jsxs("div", { className: "forge-card-flat flex items-center gap-3 p-2.5", children: [spec.image ? (_jsx("img", { src: value.url, alt: "", className: "size-14 rounded object-cover ring-1 ring-line" })) : (_jsx("span", { className: "forge-badge flex size-10 items-center justify-center", children: _jsx(FileIcon, { className: "size-4" }) })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("a", { href: value.url, target: "_blank", rel: "noreferrer", className: "block truncate text-sm font-medium text-link hover:underline", children: value.name }), _jsx("p", { className: "text-xs text-ink-muted", children: formatBytes(value.size) })] }), _jsx("button", { type: "button", className: "forge-btn forge-btn-ghost px-2.5 py-1 text-xs", onClick: () => inputRef.current?.click(), children: t("fields.file.replace") }), _jsx("button", { type: "button", className: "forge-btn forge-btn-danger-ghost px-2.5 py-1 text-xs", onClick: () => onChange(null), children: t("common.remove") })] })) : (_jsxs("button", { id: id, type: "button", "aria-invalid": invalid || undefined, onClick: () => inputRef.current?.click(), onDragOver: (e) => {
|
|
235
|
+
e.preventDefault();
|
|
236
|
+
setDragging(true);
|
|
237
|
+
}, onDragLeave: () => setDragging(false), onDrop: (e) => {
|
|
238
|
+
e.preventDefault();
|
|
239
|
+
setDragging(false);
|
|
240
|
+
const f = e.dataTransfer.files[0];
|
|
241
|
+
if (f)
|
|
242
|
+
upload(f);
|
|
243
|
+
}, className: cn("forge-input flex w-full flex-col items-center justify-center gap-1 border-dashed px-4 py-6 text-center text-sm", dragging && "ring-2 ring-primary"), children: [_jsx(UploadCloud, { className: "size-5 text-ink-muted" }), _jsx("span", { className: "text-ink", children: progress === null ? (spec.image ? t("fields.file.dropImage") : t("fields.file.dropFile")) : t("fields.file.uploading", { percent: progress }) }), _jsx("span", { className: "text-xs text-ink-subtle", children: t("fields.file.limits", { types: spec.accept.length ? spec.accept.join(", ") : t("fields.file.anyType"), size: formatBytes(spec.maxSize) }) })] })), progress !== null && (_jsx("div", { className: "mt-2 h-1.5 overflow-hidden rounded-full bg-line", role: "progressbar", "aria-valuenow": progress, "aria-valuemin": 0, "aria-valuemax": 100, children: _jsx("div", { className: "h-full bg-primary transition-all", style: { width: `${progress}%` } }) })), error && _jsx("p", { className: "mt-1 text-xs text-danger", children: error }), _jsx("input", { ref: inputRef, type: "file", hidden: true, accept: acceptAttr(spec.accept), onChange: (e) => {
|
|
244
|
+
const f = e.target.files?.[0];
|
|
245
|
+
if (f)
|
|
246
|
+
upload(f);
|
|
247
|
+
e.target.value = "";
|
|
248
|
+
} })] }));
|
|
249
|
+
}
|
|
250
|
+
/** Latitude/longitude inputs with a "use my location" shortcut. */
|
|
251
|
+
export function LocationInput({ id, value, onChange, invalid }) {
|
|
252
|
+
const t = useT();
|
|
253
|
+
const v = value ?? { lat: "", lng: "" };
|
|
254
|
+
const [locating, setLocating] = useState(false);
|
|
255
|
+
return (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("div", { className: "w-40", children: _jsx(Input, { id: id, "aria-label": t("fields.location.latitude"), "aria-invalid": invalid || undefined, inputMode: "decimal", placeholder: t("fields.location.latitude"), value: v.lat, onChange: (e) => onChange({ ...v, lat: e.target.value }) }) }), _jsx("div", { className: "w-40", children: _jsx(Input, { "aria-label": t("fields.location.longitude"), "aria-invalid": invalid || undefined, inputMode: "decimal", placeholder: t("fields.location.longitude"), value: v.lng, onChange: (e) => onChange({ ...v, lng: e.target.value }) }) }), typeof navigator !== "undefined" && "geolocation" in navigator && (_jsxs("button", { type: "button", className: "forge-btn forge-btn-ghost inline-flex h-9 items-center gap-1.5 px-2.5 text-sm", onClick: () => {
|
|
256
|
+
setLocating(true);
|
|
257
|
+
navigator.geolocation.getCurrentPosition((pos) => {
|
|
258
|
+
setLocating(false);
|
|
259
|
+
onChange({ lat: pos.coords.latitude.toFixed(6), lng: pos.coords.longitude.toFixed(6) });
|
|
260
|
+
}, () => setLocating(false), { timeout: 10_000 });
|
|
261
|
+
}, children: [_jsx(MapPin, { className: "size-4" }), " ", locating ? t("fields.location.locating") : t("fields.location.useMine")] }))] }));
|
|
262
|
+
}
|
|
263
|
+
/** Locale-aware text for scalar values (dates and numbers follow the UI language). */
|
|
264
|
+
export function displayText(field, value, locale) {
|
|
265
|
+
try {
|
|
266
|
+
if (field?.kind === "date" && typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value)) {
|
|
267
|
+
return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone: "UTC" }).format(new Date(`${value.slice(0, 10)}T00:00:00Z`));
|
|
268
|
+
}
|
|
269
|
+
if (field?.kind === "datetime")
|
|
270
|
+
return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(new Date(String(value)));
|
|
271
|
+
if ((field?.kind === "integer" || field?.kind === "decimal") && value !== "" && Number.isFinite(Number(value))) {
|
|
272
|
+
return new Intl.NumberFormat(locale, { maximumFractionDigits: field.scale ?? 6 }).format(Number(value));
|
|
273
|
+
}
|
|
274
|
+
if (field?.kind === "percentage" && Number.isFinite(Number(value)))
|
|
275
|
+
return `${new Intl.NumberFormat(locale, { maximumFractionDigits: 4 }).format(Number(value))} %`.replace(/^(.*) %$/, locale.startsWith("en") ? "$1%" : "$1 %");
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// Invalid locale or value: fall back to the neutral format.
|
|
279
|
+
}
|
|
280
|
+
return formatValue(field, value, locale);
|
|
281
|
+
}
|
|
282
|
+
/** Read-only rendering of a field value in tables and detail views. */
|
|
283
|
+
export function FieldValue({ field, value, cell }) {
|
|
284
|
+
const locale = useLocale();
|
|
285
|
+
const t = useT();
|
|
286
|
+
if (value === null || value === undefined || value === "")
|
|
287
|
+
return _jsx("span", { className: "text-ink-subtle", children: "\u2014" });
|
|
288
|
+
const kind = cell ?? field?.kind;
|
|
289
|
+
if (Array.isArray(value)) {
|
|
290
|
+
if (value.length === 0)
|
|
291
|
+
return _jsx("span", { className: "text-ink-subtle", children: "\u2014" });
|
|
292
|
+
return (_jsx("span", { className: "inline-flex flex-wrap gap-1", children: value.map((v) => (_jsx(Badge, { children: v.label }, v.id))) }));
|
|
293
|
+
}
|
|
294
|
+
if (field?.file || kind === "image" || kind === "file") {
|
|
295
|
+
const file = value;
|
|
296
|
+
const isImage = field?.kind === "image" || kind === "image";
|
|
297
|
+
if (isImage) {
|
|
298
|
+
return (_jsx("a", { href: file.url, target: "_blank", rel: "noreferrer", className: "inline-block", children: _jsx("img", { src: file.url, alt: file.name, className: cn("rounded object-cover ring-1 ring-line", cell ? "size-8" : "max-h-48 max-w-full") }) }));
|
|
299
|
+
}
|
|
300
|
+
return (_jsxs("a", { href: `${file.url}?download`, className: "inline-flex items-center gap-1.5 text-link hover:underline", children: [_jsx(FileIcon, { className: "size-3.5" }), " ", file.name, " ", _jsx("span", { className: "text-xs text-ink-subtle", children: formatBytes(file.size) })] }));
|
|
301
|
+
}
|
|
302
|
+
if (kind === "location" || field?.kind === "location") {
|
|
303
|
+
const { lat, lng } = value;
|
|
304
|
+
return (_jsxs("a", { className: "text-link hover:underline tabular-nums", href: `https://www.openstreetmap.org/?mlat=${lat}&mlon=${lng}#map=15/${lat}/${lng}`, target: "_blank", rel: "noreferrer noopener", children: [lat.toFixed(5), ", ", lng.toFixed(5)] }));
|
|
305
|
+
}
|
|
306
|
+
if (kind === "badge" || field?.kind === "enum") {
|
|
307
|
+
const index = field?.enumValues?.findIndex((v) => v.value === value) ?? 0;
|
|
308
|
+
return _jsx(Badge, { tone: index, children: formatValue(field, value, locale) });
|
|
309
|
+
}
|
|
310
|
+
if (kind === "boolean")
|
|
311
|
+
return value ? _jsx(Badge, { tone: 1, children: t("common.yes") }) : _jsx(Badge, { children: t("common.no") });
|
|
312
|
+
if (kind === "color")
|
|
313
|
+
return (_jsxs("span", { className: "inline-flex items-center gap-1.5 font-mono text-xs", children: [_jsx("span", { className: "size-3.5 rounded-sm ring-1 ring-line", style: { background: String(value) } }), String(value)] }));
|
|
314
|
+
if (kind === "email")
|
|
315
|
+
return _jsx("a", { className: "text-link hover:underline", href: `mailto:${String(value)}`, children: String(value) });
|
|
316
|
+
if (kind === "url")
|
|
317
|
+
return (_jsx("a", { className: "text-link hover:underline", href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) }));
|
|
318
|
+
if (kind === "datetime" && !field)
|
|
319
|
+
return _jsx("span", { className: "tabular-nums", children: new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(new Date(String(value))) });
|
|
320
|
+
if (kind === "json")
|
|
321
|
+
return _jsx("code", { className: "text-xs", children: JSON.stringify(value) });
|
|
322
|
+
const text = displayText(field, value, locale);
|
|
323
|
+
const numeric = ["money", "percentage", "number", "integer", "decimal"].includes(kind ?? "");
|
|
324
|
+
return _jsx("span", { className: cn(numeric && "tabular-nums", field?.kind === "text" || field?.kind === "richtext" ? "whitespace-pre-wrap" : ""), children: text });
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Messages } from "./locale.js";
|
|
2
|
+
/** Built-in UI catalogs by language. A locale without a catalog (or a missing key) falls back to English. */
|
|
3
|
+
export declare const UI_MESSAGES: Record<string, Messages>;
|
|
4
|
+
/** Native names shown in the language switcher. */
|
|
5
|
+
export declare function localeName(locale: string): string;
|
|
6
|
+
/** Catalogs to search for `locale`, most specific first ("pt-BR" → pt-BR, pt, en). */
|
|
7
|
+
export declare function uiCatalogs(locale: string): Messages[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { de } from "./messages/de.js";
|
|
2
|
+
import { en } from "./messages/en.js";
|
|
3
|
+
import { es } from "./messages/es.js";
|
|
4
|
+
import { fr } from "./messages/fr.js";
|
|
5
|
+
import { pt } from "./messages/pt.js";
|
|
6
|
+
/** Built-in UI catalogs by language. A locale without a catalog (or a missing key) falls back to English. */
|
|
7
|
+
export const UI_MESSAGES = { en, fr, es, de, pt };
|
|
8
|
+
/** Native names shown in the language switcher. */
|
|
9
|
+
export function localeName(locale) {
|
|
10
|
+
try {
|
|
11
|
+
const name = new Intl.DisplayNames([locale], { type: "language" }).of(locale);
|
|
12
|
+
return name ? name.charAt(0).toLocaleUpperCase(locale) + name.slice(1) : locale;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return locale;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Catalogs to search for `locale`, most specific first ("pt-BR" → pt-BR, pt, en). */
|
|
19
|
+
export function uiCatalogs(locale) {
|
|
20
|
+
const base = locale.split("-")[0];
|
|
21
|
+
return [UI_MESSAGES[locale], base !== locale ? UI_MESSAGES[base] : undefined, UI_MESSAGES.en].filter((c) => !!c);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/i18n/catalog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEtC,6GAA6G;AAC7G,MAAM,CAAC,MAAM,WAAW,GAA6B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAE5E,mDAAmD;AACnD,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IACnC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClI,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AppIR } from "@tekki-forge/compiler";
|
|
2
|
+
/** Cookie holding the language the user picked (read by the root layout to render <html lang>). */
|
|
3
|
+
export declare const LOCALE_COOKIE = "forge-locale";
|
|
4
|
+
/**
|
|
5
|
+
* Pick the UI language: the user's saved choice, else the best match of the browser's Accept-Language,
|
|
6
|
+
* else the app default. Safe to call from a server component.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveLocale(app: Pick<AppIR, "i18n">, saved?: string | null, acceptLanguage?: string | null): string;
|
|
9
|
+
export type Messages = Record<string, string>;
|
|
10
|
+
export type TranslateVars = Record<string, string | number>;
|
|
11
|
+
/**
|
|
12
|
+
* Look `key` up in each catalog in turn; `{name}` placeholders are filled from `vars`. When `vars.count`
|
|
13
|
+
* is a number, `key_one` / `key_other` (… Intl.PluralRules categories) are tried first.
|
|
14
|
+
*/
|
|
15
|
+
export declare function translate(catalogs: Messages[], locale: string, key: string, vars?: TranslateVars): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Cookie holding the language the user picked (read by the root layout to render <html lang>). */
|
|
2
|
+
export const LOCALE_COOKIE = "forge-locale";
|
|
3
|
+
/**
|
|
4
|
+
* Pick the UI language: the user's saved choice, else the best match of the browser's Accept-Language,
|
|
5
|
+
* else the app default. Safe to call from a server component.
|
|
6
|
+
*/
|
|
7
|
+
export function resolveLocale(app, saved, acceptLanguage) {
|
|
8
|
+
const { locales, defaultLocale } = app.i18n ?? { locales: ["en"], defaultLocale: "en" };
|
|
9
|
+
if (saved && locales.includes(saved))
|
|
10
|
+
return saved;
|
|
11
|
+
const wanted = (acceptLanguage ?? "")
|
|
12
|
+
.split(",")
|
|
13
|
+
.map((part) => {
|
|
14
|
+
const [tag, ...params] = part.trim().split(";");
|
|
15
|
+
const q = params.map((p) => p.trim()).find((p) => p.startsWith("q="));
|
|
16
|
+
return { tag: tag.trim(), q: q ? Number(q.slice(2)) || 0 : 1 };
|
|
17
|
+
})
|
|
18
|
+
.filter((x) => x.tag && x.tag !== "*" && x.q > 0)
|
|
19
|
+
.sort((a, b) => b.q - a.q);
|
|
20
|
+
for (const { tag } of wanted) {
|
|
21
|
+
const exact = locales.find((l) => l.toLowerCase() === tag.toLowerCase());
|
|
22
|
+
if (exact)
|
|
23
|
+
return exact;
|
|
24
|
+
const base = tag.split("-")[0].toLowerCase();
|
|
25
|
+
const partial = locales.find((l) => l.toLowerCase() === base) ?? locales.find((l) => l.split("-")[0].toLowerCase() === base);
|
|
26
|
+
if (partial)
|
|
27
|
+
return partial;
|
|
28
|
+
}
|
|
29
|
+
return defaultLocale;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Look `key` up in each catalog in turn; `{name}` placeholders are filled from `vars`. When `vars.count`
|
|
33
|
+
* is a number, `key_one` / `key_other` (… Intl.PluralRules categories) are tried first.
|
|
34
|
+
*/
|
|
35
|
+
export function translate(catalogs, locale, key, vars) {
|
|
36
|
+
const candidates = [key];
|
|
37
|
+
if (typeof vars?.count === "number") {
|
|
38
|
+
let category = "other";
|
|
39
|
+
try {
|
|
40
|
+
category = new Intl.PluralRules(locale).select(vars.count);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// unknown locale: "other"
|
|
44
|
+
}
|
|
45
|
+
candidates.unshift(`${key}_${category}`, `${key}_other`);
|
|
46
|
+
}
|
|
47
|
+
let text;
|
|
48
|
+
for (const c of catalogs) {
|
|
49
|
+
for (const k of candidates) {
|
|
50
|
+
if (c[k] !== undefined) {
|
|
51
|
+
text = c[k];
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (text !== undefined)
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
if (text === undefined)
|
|
59
|
+
text = key;
|
|
60
|
+
if (!vars)
|
|
61
|
+
return text;
|
|
62
|
+
return text.replace(/\{(\w+)\}/g, (m, name) => {
|
|
63
|
+
const v = vars[name];
|
|
64
|
+
if (v === undefined)
|
|
65
|
+
return m;
|
|
66
|
+
return typeof v === "number" ? v.toLocaleString(locale) : v;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=locale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/i18n/locale.ts"],"names":[],"mappings":"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"}
|