@green-on-grey/ui-kit 1.8.0 → 1.10.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/dist/chat/Attachments.d.ts +29 -8
- package/dist/chat/MessageView.d.ts +6 -2
- package/dist/chat/index.d.ts +3 -3
- package/dist/chat/types.d.ts +42 -0
- package/dist/chat.js +728 -515
- package/dist/chat.js.map +1 -1
- package/dist/index.js +32 -56
- package/dist/index.js.map +1 -1
- package/dist/locales/index.d.ts +95 -0
- package/dist/locales.js +100 -5
- package/dist/locales.js.map +1 -1
- package/dist/manifest.json +13 -1
- package/dist/styles.css +20 -0
- package/dist/{ui-DvmjcG-d.js → ui-sV5t0cp1.js} +38 -14
- package/dist/ui-sV5t0cp1.js.map +1 -0
- package/package.json +1 -1
- package/dist/ui-DvmjcG-d.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as e, c as t, d as n,
|
|
2
|
-
import { n as
|
|
3
|
-
import { jsx as
|
|
4
|
-
import { useCallback as
|
|
1
|
+
import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./ui-sV5t0cp1.js";
|
|
2
|
+
import { n as f, t as p } from "./i18n-BJ8rsBp6.js";
|
|
3
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
4
|
+
import { useCallback as g, useEffect as _, useState as v } from "react";
|
|
5
5
|
//#region src/components/Button.tsx
|
|
6
6
|
function y({ variant: e, size: t, className: n, type: r = "button", ...i }) {
|
|
7
7
|
let a = [
|
|
@@ -10,7 +10,7 @@ function y({ variant: e, size: t, className: n, type: r = "button", ...i }) {
|
|
|
10
10
|
t,
|
|
11
11
|
n
|
|
12
12
|
].filter(Boolean).join(" ");
|
|
13
|
-
return /* @__PURE__ */
|
|
13
|
+
return /* @__PURE__ */ m("button", {
|
|
14
14
|
type: r,
|
|
15
15
|
className: a,
|
|
16
16
|
...i
|
|
@@ -23,7 +23,7 @@ function b({ label: e, fill: t, on: n, className: r, type: i = "button", ...a })
|
|
|
23
23
|
n && "on",
|
|
24
24
|
r
|
|
25
25
|
].filter(Boolean).join(" ");
|
|
26
|
-
return /* @__PURE__ */
|
|
26
|
+
return /* @__PURE__ */ m("button", {
|
|
27
27
|
type: i,
|
|
28
28
|
className: o,
|
|
29
29
|
"aria-label": e,
|
|
@@ -31,37 +31,13 @@ function b({ label: e, fill: t, on: n, className: r, type: i = "button", ...a })
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
|
-
//#region src/components/Tabs.tsx
|
|
35
|
-
function x({ items: e, value: t, onChange: n, label: r }) {
|
|
36
|
-
let i = _(null);
|
|
37
|
-
return /* @__PURE__ */ p("div", {
|
|
38
|
-
className: "tabs",
|
|
39
|
-
role: "tablist",
|
|
40
|
-
"aria-label": r,
|
|
41
|
-
ref: i,
|
|
42
|
-
onKeyDown: (r) => {
|
|
43
|
-
let a = e.findIndex((e) => e.key === t), o = r.key === "ArrowRight" ? (a + 1) % e.length : r.key === "ArrowLeft" ? (a - 1 + e.length) % e.length : r.key === "Home" ? 0 : r.key === "End" ? e.length - 1 : -1;
|
|
44
|
-
o < 0 || (r.preventDefault(), n(e[o].key), i.current?.querySelectorAll("[role=\"tab\"]")[o]?.focus());
|
|
45
|
-
},
|
|
46
|
-
children: e.map((e) => /* @__PURE__ */ p("button", {
|
|
47
|
-
type: "button",
|
|
48
|
-
role: "tab",
|
|
49
|
-
"aria-selected": e.key === t,
|
|
50
|
-
tabIndex: e.key === t ? 0 : -1,
|
|
51
|
-
className: e.key === t ? "on" : void 0,
|
|
52
|
-
onClick: () => n(e.key),
|
|
53
|
-
children: e.label
|
|
54
|
-
}, e.key))
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
//#endregion
|
|
58
34
|
//#region src/components/Menu.tsx
|
|
59
|
-
function
|
|
60
|
-
let i =
|
|
61
|
-
return
|
|
35
|
+
function x({ onClose: e, label: t, className: n, children: r }) {
|
|
36
|
+
let i = l(!0, e);
|
|
37
|
+
return _(() => {
|
|
62
38
|
let e = document.activeElement;
|
|
63
39
|
return () => e?.focus?.();
|
|
64
|
-
}, []), /* @__PURE__ */
|
|
40
|
+
}, []), /* @__PURE__ */ m("div", {
|
|
65
41
|
className: `menu${n ? ` ${n}` : ""}`,
|
|
66
42
|
role: "dialog",
|
|
67
43
|
"aria-label": t,
|
|
@@ -71,68 +47,68 @@ function S({ onClose: e, label: t, className: n, children: r }) {
|
|
|
71
47
|
}
|
|
72
48
|
//#endregion
|
|
73
49
|
//#region src/components/TopBar.tsx
|
|
74
|
-
function
|
|
75
|
-
let
|
|
50
|
+
function S({ logo: e, name: t, home: n = "/", sections: i, Link: a, center: o, actions: s, avatar: c, profileMenu: u, menu: d }) {
|
|
51
|
+
let p = f(), [_, y] = v(!1), [b, x] = v(!1), S = g(() => x(!1), []), C = g(() => y(!1), []), w = l(b, S), T = i.map((e) => /* @__PURE__ */ m(a, {
|
|
76
52
|
href: e.href,
|
|
77
53
|
className: e.active ? "on" : void 0,
|
|
78
54
|
"aria-current": e.active ? "page" : void 0,
|
|
79
55
|
onClick: S,
|
|
80
56
|
children: e.label
|
|
81
57
|
}, e.key));
|
|
82
|
-
return /* @__PURE__ */
|
|
58
|
+
return /* @__PURE__ */ h("div", {
|
|
83
59
|
className: "topbar",
|
|
84
60
|
children: [
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
-
href:
|
|
61
|
+
/* @__PURE__ */ h(a, {
|
|
62
|
+
href: n,
|
|
87
63
|
className: "brand",
|
|
88
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ m("img", {
|
|
89
65
|
src: e,
|
|
90
66
|
alt: ""
|
|
91
|
-
}), /* @__PURE__ */
|
|
67
|
+
}), /* @__PURE__ */ m("span", {
|
|
92
68
|
className: "hide-m",
|
|
93
69
|
children: t
|
|
94
70
|
})]
|
|
95
71
|
}),
|
|
96
|
-
/* @__PURE__ */
|
|
72
|
+
/* @__PURE__ */ m("nav", {
|
|
97
73
|
className: "nav hide-m",
|
|
98
|
-
"aria-label":
|
|
74
|
+
"aria-label": p("topbar.sections"),
|
|
99
75
|
children: T
|
|
100
76
|
}),
|
|
101
77
|
o,
|
|
102
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ h("div", {
|
|
103
79
|
className: "top-actions",
|
|
104
80
|
children: [
|
|
105
81
|
s,
|
|
106
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ m("button", {
|
|
107
83
|
className: "avatar",
|
|
108
84
|
style: _ ? { boxShadow: "0 0 0 2px var(--violet)" } : void 0,
|
|
109
85
|
onClick: () => {
|
|
110
86
|
x(!1), y((e) => !e);
|
|
111
87
|
},
|
|
112
|
-
"aria-label":
|
|
88
|
+
"aria-label": p("topbar.profile"),
|
|
113
89
|
"aria-expanded": _,
|
|
114
|
-
children:
|
|
90
|
+
children: c
|
|
115
91
|
}),
|
|
116
|
-
/* @__PURE__ */
|
|
92
|
+
/* @__PURE__ */ h("div", {
|
|
117
93
|
className: "burger",
|
|
118
94
|
ref: w,
|
|
119
|
-
children: [/* @__PURE__ */
|
|
95
|
+
children: [/* @__PURE__ */ m("button", {
|
|
120
96
|
className: `iconbtn${b ? " on" : ""}`,
|
|
121
97
|
onClick: () => {
|
|
122
98
|
y(!1), x((e) => !e);
|
|
123
99
|
},
|
|
124
|
-
"aria-label":
|
|
100
|
+
"aria-label": d?.label ?? p("topbar.sections"),
|
|
125
101
|
"aria-expanded": b,
|
|
126
102
|
"aria-controls": "nav-sections",
|
|
127
|
-
children: /* @__PURE__ */
|
|
128
|
-
}), b && (
|
|
103
|
+
children: /* @__PURE__ */ m(r, { name: b ? "x" : "menu" })
|
|
104
|
+
}), b && (d ? /* @__PURE__ */ m("div", {
|
|
129
105
|
id: "nav-sections",
|
|
130
106
|
className: "navmenu",
|
|
131
|
-
children:
|
|
132
|
-
}) : /* @__PURE__ */
|
|
107
|
+
children: d.render(S)
|
|
108
|
+
}) : /* @__PURE__ */ m("nav", {
|
|
133
109
|
id: "nav-sections",
|
|
134
110
|
className: "navmenu",
|
|
135
|
-
"aria-label":
|
|
111
|
+
"aria-label": p("topbar.sections"),
|
|
136
112
|
children: T
|
|
137
113
|
}))]
|
|
138
114
|
})
|
|
@@ -143,6 +119,6 @@ function C({ logo: e, name: t, home: r = "/", sections: i, Link: a, center: o, a
|
|
|
143
119
|
});
|
|
144
120
|
}
|
|
145
121
|
//#endregion
|
|
146
|
-
export {
|
|
122
|
+
export { u as Avatar, y as Button, o as Empty, n as GitHubIcon, r as Icon, b as IconButton, c as Loading, d as Markdown, x as Menu, i as Modal, e as Switch, a as Tabs, s as ToastProvider, S as TopBar, p as UIKIT_NS, l as useOutside, t as useToast };
|
|
147
123
|
|
|
148
124
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Switch","useToast","Icon","Modal","Markdown","Empty","Loading","useOutside","Avatar","useKitT","UIKIT_NS","Button","rest","cls","variant","size","className","IconButton","fill","on","label","Tabs","ref","useRef","i","items","it","value","to","e","onChange","Menu","onClose","useEffect","opener","TopBar","t","profileOpen","setProfileOpen","useState","sectionsOpen","setSectionsOpen","closeSections","useCallback","closeProfile","links","sections","Link","s","home","logo","name","center","actions","v","avatar","menu","profileMenu","GitHubIcon","ToastProvider"],"sources":["../src/components/Button.tsx","../src/components/Tabs.tsx","../src/components/Menu.tsx","../src/components/TopBar.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\n\ntype Native = ButtonHTMLAttributes<HTMLButtonElement>;\n\n/** `button.btn` with its variants. The classes stay a legitimate way to use a\n * button (FTR.NAB.CMN-0005 tech, decision 1); the component is for new code. */\nexport function Button({ variant, size, className, type = \"button\", ...rest }: Native & {\n variant?: \"primary\" | \"ghost\" | \"danger\"; size?: \"sm\";\n}) {\n const cls = [\"btn\", variant, size, className].filter(Boolean).join(\" \");\n return <button type={type} className={cls} {...rest} />;\n}\n\n/** `button.iconbtn`: a button with an icon only, so the label is required. */\nexport function IconButton({ label, fill, on, className, type = \"button\", ...rest }: Omit<Native, \"aria-label\"> & {\n label: string; fill?: boolean; on?: boolean;\n}) {\n const cls = [\"iconbtn\", fill && \"fill\", on && \"on\", className].filter(Boolean).join(\" \");\n return <button type={type} className={cls} aria-label={label} {...rest} />;\n}\n","import { useRef, type KeyboardEvent, type ReactNode } from \"react\";\n\n/** `.tabs` with the keyboard of a tab list: arrows, Home and End move the choice. */\nexport function Tabs<K extends string>({ items, value, onChange, label }: {\n items: { key: K; label: ReactNode }[]; value: K; onChange: (key: K) => void; label?: string;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const onKey = (e: KeyboardEvent) => {\n const i = items.findIndex((it) => it.key === value);\n const to = e.key === \"ArrowRight\" ? (i + 1) % items.length\n : e.key === \"ArrowLeft\" ? (i - 1 + items.length) % items.length\n : e.key === \"Home\" ? 0 : e.key === \"End\" ? items.length - 1 : -1;\n if (to < 0) return;\n e.preventDefault();\n onChange(items[to].key);\n ref.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]')[to]?.focus();\n };\n return (\n <div className=\"tabs\" role=\"tablist\" aria-label={label} ref={ref} onKeyDown={onKey}>\n {items.map((it) => (\n <button key={it.key} type=\"button\" role=\"tab\" aria-selected={it.key === value} tabIndex={it.key === value ? 0 : -1}\n className={it.key === value ? \"on\" : undefined} onClick={() => onChange(it.key)}>\n {it.label}\n </button>\n ))}\n </div>\n );\n}\n","import { useEffect, type ReactNode } from \"react\";\nimport { useOutside } from \"./ui\";\n\n/** `.menu`: a popover closed by Escape and by a click outside; it is mounted while\n * open. `onClose` must keep its identity between renders. What is inside\n * (sections `.sec`, lines `.line`, actions `.action`) belongs to the product. */\nexport function Menu({ onClose, label, className, children }: {\n onClose: () => void; label?: string; className?: string; children: ReactNode;\n}) {\n const ref = useOutside<HTMLDivElement>(true, onClose);\n // the focus returns to what opened the menu (CMP-05)\n useEffect(() => {\n const opener = document.activeElement as HTMLElement | null;\n return () => opener?.focus?.();\n }, []);\n return (\n <div className={`menu${className ? ` ${className}` : \"\"}`} role=\"dialog\" aria-label={label} ref={ref}>\n {children}\n </div>\n );\n}\n","import { useCallback, useState, type ReactNode } from \"react\";\nimport { useKitT } from \"../i18n\";\nimport { Icon } from \"./Icon\";\nimport { useOutside } from \"./ui\";\n\n/** The link of the product: the kit does not depend on a router (arch §4.2). */\nexport type LinkComponent = (props: {\n href: string; className?: string; onClick?: () => void; \"aria-current\"?: \"page\"; children: ReactNode;\n}) => ReactNode;\n\nexport interface TopBarSection { key: string; label: ReactNode; href: string; active: boolean }\n\n/** The top bar (FTR.NAB.CMN-0005 R5, design §4): the logo and the name, the\n * sections in a row and behind the burger on a phone, the actions of the product,\n * the avatar that opens the profile menu. The profile menu and the list of\n * sections are never open together. A part of the product with its own\n * navigation (the administration) puts it behind the burger in place of the\n * sections: `menu`, with the side panel marked `in-burger`, hidden on a phone. */\nexport function TopBar({ logo, name, home = \"/\", sections, Link, center, actions, avatar, profileMenu, menu }: {\n logo: string; name: string; home?: string; sections: TopBarSection[]; Link: LinkComponent;\n /** Between the sections and the actions: the search of Hammurapi. */\n center?: ReactNode;\n /** Before the avatar. */\n actions?: ReactNode;\n avatar: ReactNode;\n profileMenu: (close: () => void) => ReactNode;\n /** The burger of a phone in place of the sections: the navigation of the current part of the product and\n * its name, which the burger is called by. */\n menu?: { label: string; render: (close: () => void) => ReactNode };\n}) {\n const t = useKitT();\n const [profileOpen, setProfileOpen] = useState(false);\n const [sectionsOpen, setSectionsOpen] = useState(false);\n const closeSections = useCallback(() => setSectionsOpen(false), []);\n const closeProfile = useCallback(() => setProfileOpen(false), []);\n const ref = useOutside<HTMLDivElement>(sectionsOpen, closeSections);\n const links = sections.map((s) => (\n <Link key={s.key} href={s.href} className={s.active ? \"on\" : undefined} aria-current={s.active ? \"page\" : undefined} onClick={closeSections}>\n {s.label}\n </Link>\n ));\n return (\n <div className=\"topbar\">\n <Link href={home} className=\"brand\">\n <img src={logo} alt=\"\" />\n <span className=\"hide-m\">{name}</span>\n </Link>\n <nav className=\"nav hide-m\" aria-label={t(\"topbar.sections\")}>{links}</nav>\n {center}\n <div className=\"top-actions\">\n {actions}\n <button className=\"avatar\" style={profileOpen ? { boxShadow: \"0 0 0 2px var(--violet)\" } : undefined}\n onClick={() => { setSectionsOpen(false); setProfileOpen((v) => !v); }} aria-label={t(\"topbar.profile\")} aria-expanded={profileOpen}>\n {avatar}\n </button>\n <div className=\"burger\" ref={ref}>\n <button className={`iconbtn${sectionsOpen ? \" on\" : \"\"}`} onClick={() => { setProfileOpen(false); setSectionsOpen((v) => !v); }}\n aria-label={menu?.label ?? t(\"topbar.sections\")} aria-expanded={sectionsOpen} aria-controls=\"nav-sections\">\n <Icon name={sectionsOpen ? \"x\" : \"menu\"} />\n </button>\n {sectionsOpen && (menu\n ? <div id=\"nav-sections\" className=\"navmenu\">{menu.render(closeSections)}</div>\n : <nav id=\"nav-sections\" className=\"navmenu\" aria-label={t(\"topbar.sections\")}>{links}</nav>)}\n </div>\n </div>\n {profileOpen && profileMenu(closeProfile)}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Switch","useToast","GitHubIcon","Icon","Tabs","Empty","ToastProvider","Loading","useOutside","Avatar","Markdown","useKitT","UIKIT_NS","Button","rest","cls","variant","size","className","IconButton","fill","on","label","Menu","ref","onClose","useEffect","opener","TopBar","t","profileOpen","setProfileOpen","useState","sectionsOpen","setSectionsOpen","closeSections","useCallback","closeProfile","links","sections","Link","s","home","logo","name","center","actions","v","avatar","menu","profileMenu","Modal"],"sources":["../src/components/Button.tsx","../src/components/Menu.tsx","../src/components/TopBar.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\n\ntype Native = ButtonHTMLAttributes<HTMLButtonElement>;\n\n/** `button.btn` with its variants. The classes stay a legitimate way to use a\n * button (FTR.NAB.CMN-0005 tech, decision 1); the component is for new code. */\nexport function Button({ variant, size, className, type = \"button\", ...rest }: Native & {\n variant?: \"primary\" | \"ghost\" | \"danger\"; size?: \"sm\";\n}) {\n const cls = [\"btn\", variant, size, className].filter(Boolean).join(\" \");\n return <button type={type} className={cls} {...rest} />;\n}\n\n/** `button.iconbtn`: a button with an icon only, so the label is required. */\nexport function IconButton({ label, fill, on, className, type = \"button\", ...rest }: Omit<Native, \"aria-label\"> & {\n label: string; fill?: boolean; on?: boolean;\n}) {\n const cls = [\"iconbtn\", fill && \"fill\", on && \"on\", className].filter(Boolean).join(\" \");\n return <button type={type} className={cls} aria-label={label} {...rest} />;\n}\n","import { useEffect, type ReactNode } from \"react\";\nimport { useOutside } from \"./ui\";\n\n/** `.menu`: a popover closed by Escape and by a click outside; it is mounted while\n * open. `onClose` must keep its identity between renders. What is inside\n * (sections `.sec`, lines `.line`, actions `.action`) belongs to the product. */\nexport function Menu({ onClose, label, className, children }: {\n onClose: () => void; label?: string; className?: string; children: ReactNode;\n}) {\n const ref = useOutside<HTMLDivElement>(true, onClose);\n // the focus returns to what opened the menu (CMP-05)\n useEffect(() => {\n const opener = document.activeElement as HTMLElement | null;\n return () => opener?.focus?.();\n }, []);\n return (\n <div className={`menu${className ? ` ${className}` : \"\"}`} role=\"dialog\" aria-label={label} ref={ref}>\n {children}\n </div>\n );\n}\n","import { useCallback, useState, type ReactNode } from \"react\";\nimport { useKitT } from \"../i18n\";\nimport { Icon } from \"./Icon\";\nimport { useOutside } from \"./ui\";\n\n/** The link of the product: the kit does not depend on a router (arch §4.2). */\nexport type LinkComponent = (props: {\n href: string; className?: string; onClick?: () => void; \"aria-current\"?: \"page\"; children: ReactNode;\n}) => ReactNode;\n\nexport interface TopBarSection { key: string; label: ReactNode; href: string; active: boolean }\n\n/** The top bar (FTR.NAB.CMN-0005 R5, design §4): the logo and the name, the\n * sections in a row and behind the burger on a phone, the actions of the product,\n * the avatar that opens the profile menu. The profile menu and the list of\n * sections are never open together. A part of the product with its own\n * navigation (the administration) puts it behind the burger in place of the\n * sections: `menu`, with the side panel marked `in-burger`, hidden on a phone. */\nexport function TopBar({ logo, name, home = \"/\", sections, Link, center, actions, avatar, profileMenu, menu }: {\n logo: string; name: string; home?: string; sections: TopBarSection[]; Link: LinkComponent;\n /** Between the sections and the actions: the search of Hammurapi. */\n center?: ReactNode;\n /** Before the avatar. */\n actions?: ReactNode;\n avatar: ReactNode;\n profileMenu: (close: () => void) => ReactNode;\n /** The burger of a phone in place of the sections: the navigation of the current part of the product and\n * its name, which the burger is called by. */\n menu?: { label: string; render: (close: () => void) => ReactNode };\n}) {\n const t = useKitT();\n const [profileOpen, setProfileOpen] = useState(false);\n const [sectionsOpen, setSectionsOpen] = useState(false);\n const closeSections = useCallback(() => setSectionsOpen(false), []);\n const closeProfile = useCallback(() => setProfileOpen(false), []);\n const ref = useOutside<HTMLDivElement>(sectionsOpen, closeSections);\n const links = sections.map((s) => (\n <Link key={s.key} href={s.href} className={s.active ? \"on\" : undefined} aria-current={s.active ? \"page\" : undefined} onClick={closeSections}>\n {s.label}\n </Link>\n ));\n return (\n <div className=\"topbar\">\n <Link href={home} className=\"brand\">\n <img src={logo} alt=\"\" />\n <span className=\"hide-m\">{name}</span>\n </Link>\n <nav className=\"nav hide-m\" aria-label={t(\"topbar.sections\")}>{links}</nav>\n {center}\n <div className=\"top-actions\">\n {actions}\n <button className=\"avatar\" style={profileOpen ? { boxShadow: \"0 0 0 2px var(--violet)\" } : undefined}\n onClick={() => { setSectionsOpen(false); setProfileOpen((v) => !v); }} aria-label={t(\"topbar.profile\")} aria-expanded={profileOpen}>\n {avatar}\n </button>\n <div className=\"burger\" ref={ref}>\n <button className={`iconbtn${sectionsOpen ? \" on\" : \"\"}`} onClick={() => { setProfileOpen(false); setSectionsOpen((v) => !v); }}\n aria-label={menu?.label ?? t(\"topbar.sections\")} aria-expanded={sectionsOpen} aria-controls=\"nav-sections\">\n <Icon name={sectionsOpen ? \"x\" : \"menu\"} />\n </button>\n {sectionsOpen && (menu\n ? <div id=\"nav-sections\" className=\"navmenu\">{menu.render(closeSections)}</div>\n : <nav id=\"nav-sections\" className=\"navmenu\" aria-label={t(\"topbar.sections\")}>{links}</nav>)}\n </div>\n </div>\n {profileOpen && profileMenu(closeProfile)}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/locales/index.d.ts
CHANGED
|
@@ -90,6 +90,25 @@ export declare const resources: {
|
|
|
90
90
|
rows: string;
|
|
91
91
|
source: string;
|
|
92
92
|
page: string;
|
|
93
|
+
converted: string;
|
|
94
|
+
pagesShown: string;
|
|
95
|
+
firstPages: string;
|
|
96
|
+
cols: string;
|
|
97
|
+
preparing: string;
|
|
98
|
+
preparingHint: string;
|
|
99
|
+
unavailable: string;
|
|
100
|
+
formulaHint: string;
|
|
101
|
+
sheets: string;
|
|
102
|
+
reasons: {
|
|
103
|
+
too_large: string;
|
|
104
|
+
timeout: string;
|
|
105
|
+
broken: string;
|
|
106
|
+
busy: string;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
notice: {
|
|
110
|
+
more: string;
|
|
111
|
+
less: string;
|
|
93
112
|
};
|
|
94
113
|
};
|
|
95
114
|
agent: {
|
|
@@ -193,6 +212,25 @@ export declare const resources: {
|
|
|
193
212
|
rows: string;
|
|
194
213
|
source: string;
|
|
195
214
|
page: string;
|
|
215
|
+
converted: string;
|
|
216
|
+
pagesShown: string;
|
|
217
|
+
firstPages: string;
|
|
218
|
+
cols: string;
|
|
219
|
+
preparing: string;
|
|
220
|
+
preparingHint: string;
|
|
221
|
+
unavailable: string;
|
|
222
|
+
formulaHint: string;
|
|
223
|
+
sheets: string;
|
|
224
|
+
reasons: {
|
|
225
|
+
too_large: string;
|
|
226
|
+
timeout: string;
|
|
227
|
+
broken: string;
|
|
228
|
+
busy: string;
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
notice: {
|
|
232
|
+
more: string;
|
|
233
|
+
less: string;
|
|
196
234
|
};
|
|
197
235
|
};
|
|
198
236
|
agent: {
|
|
@@ -296,6 +334,25 @@ export declare const resources: {
|
|
|
296
334
|
rows: string;
|
|
297
335
|
source: string;
|
|
298
336
|
page: string;
|
|
337
|
+
converted: string;
|
|
338
|
+
pagesShown: string;
|
|
339
|
+
firstPages: string;
|
|
340
|
+
cols: string;
|
|
341
|
+
preparing: string;
|
|
342
|
+
preparingHint: string;
|
|
343
|
+
unavailable: string;
|
|
344
|
+
formulaHint: string;
|
|
345
|
+
sheets: string;
|
|
346
|
+
reasons: {
|
|
347
|
+
too_large: string;
|
|
348
|
+
timeout: string;
|
|
349
|
+
broken: string;
|
|
350
|
+
busy: string;
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
notice: {
|
|
354
|
+
more: string;
|
|
355
|
+
less: string;
|
|
299
356
|
};
|
|
300
357
|
};
|
|
301
358
|
agent: {
|
|
@@ -399,6 +456,25 @@ export declare const resources: {
|
|
|
399
456
|
rows: string;
|
|
400
457
|
source: string;
|
|
401
458
|
page: string;
|
|
459
|
+
converted: string;
|
|
460
|
+
pagesShown: string;
|
|
461
|
+
firstPages: string;
|
|
462
|
+
cols: string;
|
|
463
|
+
preparing: string;
|
|
464
|
+
preparingHint: string;
|
|
465
|
+
unavailable: string;
|
|
466
|
+
formulaHint: string;
|
|
467
|
+
sheets: string;
|
|
468
|
+
reasons: {
|
|
469
|
+
too_large: string;
|
|
470
|
+
timeout: string;
|
|
471
|
+
broken: string;
|
|
472
|
+
busy: string;
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
notice: {
|
|
476
|
+
more: string;
|
|
477
|
+
less: string;
|
|
402
478
|
};
|
|
403
479
|
};
|
|
404
480
|
agent: {
|
|
@@ -502,6 +578,25 @@ export declare const resources: {
|
|
|
502
578
|
rows: string;
|
|
503
579
|
source: string;
|
|
504
580
|
page: string;
|
|
581
|
+
converted: string;
|
|
582
|
+
pagesShown: string;
|
|
583
|
+
firstPages: string;
|
|
584
|
+
cols: string;
|
|
585
|
+
preparing: string;
|
|
586
|
+
preparingHint: string;
|
|
587
|
+
unavailable: string;
|
|
588
|
+
formulaHint: string;
|
|
589
|
+
sheets: string;
|
|
590
|
+
reasons: {
|
|
591
|
+
too_large: string;
|
|
592
|
+
timeout: string;
|
|
593
|
+
broken: string;
|
|
594
|
+
busy: string;
|
|
595
|
+
};
|
|
596
|
+
};
|
|
597
|
+
notice: {
|
|
598
|
+
more: string;
|
|
599
|
+
less: string;
|
|
505
600
|
};
|
|
506
601
|
};
|
|
507
602
|
agent: {
|
package/dist/locales.js
CHANGED
|
@@ -88,7 +88,26 @@ var t = {
|
|
|
88
88
|
notUtf8: "The file is not in UTF-8 — download it",
|
|
89
89
|
rows: "Showing {shown} of {total, plural, one {# row} other {# rows}}",
|
|
90
90
|
source: "Code",
|
|
91
|
-
page: "Page"
|
|
91
|
+
page: "Page",
|
|
92
|
+
converted: "Preview · converted from {format}",
|
|
93
|
+
pagesShown: "Showing {shown} of {total} pages",
|
|
94
|
+
firstPages: "Showing the first {shown} pages",
|
|
95
|
+
cols: "and {shown} of {total} columns",
|
|
96
|
+
preparing: "Preparing the preview…",
|
|
97
|
+
preparingHint: "Usually a few seconds",
|
|
98
|
+
unavailable: "Preview unavailable",
|
|
99
|
+
formulaHint: "The value is calculated when opened in Excel",
|
|
100
|
+
sheets: "Sheets",
|
|
101
|
+
reasons: {
|
|
102
|
+
too_large: "The file is over {limit} MB",
|
|
103
|
+
timeout: "Took longer than 30 seconds",
|
|
104
|
+
broken: "The file is damaged or the format is not supported",
|
|
105
|
+
busy: "The service is busy, try again later"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
notice: {
|
|
109
|
+
more: "Show in full",
|
|
110
|
+
less: "Collapse"
|
|
92
111
|
}
|
|
93
112
|
},
|
|
94
113
|
agent: {
|
|
@@ -189,7 +208,26 @@ var t = {
|
|
|
189
208
|
notUtf8: "Файл не в кодировке UTF-8 — скачайте его",
|
|
190
209
|
rows: "Показаны {shown} из {total, plural, one {# строки} other {# строк}}",
|
|
191
210
|
source: "Код",
|
|
192
|
-
page: "Страница"
|
|
211
|
+
page: "Страница",
|
|
212
|
+
converted: "Предпросмотр · сконвертировано из {format}",
|
|
213
|
+
pagesShown: "Показаны {shown} из {total} страниц",
|
|
214
|
+
firstPages: "Показаны первые {shown} страниц",
|
|
215
|
+
cols: "и {shown} из {total} столбцов",
|
|
216
|
+
preparing: "Готовим предпросмотр…",
|
|
217
|
+
preparingHint: "Обычно несколько секунд",
|
|
218
|
+
unavailable: "Предпросмотр недоступен",
|
|
219
|
+
formulaHint: "Значение посчитается при открытии в Excel",
|
|
220
|
+
sheets: "Листы",
|
|
221
|
+
reasons: {
|
|
222
|
+
too_large: "Файл больше {limit} МБ",
|
|
223
|
+
timeout: "Не успели за 30 секунд",
|
|
224
|
+
broken: "Файл повреждён или формат не поддерживается",
|
|
225
|
+
busy: "Сервис занят, попробуйте позже"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
notice: {
|
|
229
|
+
more: "Показать полностью",
|
|
230
|
+
less: "Свернуть"
|
|
193
231
|
}
|
|
194
232
|
},
|
|
195
233
|
agent: {
|
|
@@ -290,7 +328,26 @@ var t = {
|
|
|
290
328
|
notUtf8: "Die Datei ist nicht in UTF-8 — bitte herunterladen",
|
|
291
329
|
rows: "{shown} von {total, plural, one {# Zeile} other {# Zeilen}} angezeigt",
|
|
292
330
|
source: "Code",
|
|
293
|
-
page: "Seite"
|
|
331
|
+
page: "Seite",
|
|
332
|
+
converted: "Vorschau · konvertiert aus {format}",
|
|
333
|
+
pagesShown: "{shown} von {total} Seiten werden angezeigt",
|
|
334
|
+
firstPages: "Die ersten {shown} Seiten werden angezeigt",
|
|
335
|
+
cols: "und {shown} von {total} Spalten",
|
|
336
|
+
preparing: "Vorschau wird vorbereitet…",
|
|
337
|
+
preparingHint: "Meist nur wenige Sekunden",
|
|
338
|
+
unavailable: "Vorschau nicht verfügbar",
|
|
339
|
+
formulaHint: "Der Wert wird beim Öffnen in Excel berechnet",
|
|
340
|
+
sheets: "Blätter",
|
|
341
|
+
reasons: {
|
|
342
|
+
too_large: "Die Datei ist größer als {limit} MB",
|
|
343
|
+
timeout: "Hat länger als 30 Sekunden gedauert",
|
|
344
|
+
broken: "Die Datei ist beschädigt oder das Format wird nicht unterstützt",
|
|
345
|
+
busy: "Der Dienst ist ausgelastet, versuchen Sie es später erneut"
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
notice: {
|
|
349
|
+
more: "Vollständig anzeigen",
|
|
350
|
+
less: "Einklappen"
|
|
294
351
|
}
|
|
295
352
|
},
|
|
296
353
|
agent: {
|
|
@@ -391,7 +448,26 @@ var t = {
|
|
|
391
448
|
notUtf8: "El archivo no está en UTF-8: descárguelo",
|
|
392
449
|
rows: "Se muestran {shown} de {total, plural, one {# fila} other {# filas}}",
|
|
393
450
|
source: "Código",
|
|
394
|
-
page: "Página"
|
|
451
|
+
page: "Página",
|
|
452
|
+
converted: "Vista previa · convertido desde {format}",
|
|
453
|
+
pagesShown: "Se muestran {shown} de {total} páginas",
|
|
454
|
+
firstPages: "Se muestran las primeras {shown} páginas",
|
|
455
|
+
cols: "y {shown} de {total} columnas",
|
|
456
|
+
preparing: "Preparando la vista previa…",
|
|
457
|
+
preparingHint: "Suele tardar unos segundos",
|
|
458
|
+
unavailable: "Vista previa no disponible",
|
|
459
|
+
formulaHint: "El valor se calcula al abrir el archivo en Excel",
|
|
460
|
+
sheets: "Hojas",
|
|
461
|
+
reasons: {
|
|
462
|
+
too_large: "El archivo supera {limit} MB",
|
|
463
|
+
timeout: "Tardó más de 30 segundos",
|
|
464
|
+
broken: "El archivo está dañado o el formato no es compatible",
|
|
465
|
+
busy: "El servicio está ocupado, inténtalo más tarde"
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
notice: {
|
|
469
|
+
more: "Mostrar completo",
|
|
470
|
+
less: "Contraer"
|
|
395
471
|
}
|
|
396
472
|
},
|
|
397
473
|
agent: {
|
|
@@ -492,7 +568,26 @@ var t = {
|
|
|
492
568
|
notUtf8: "文件不是 UTF-8 编码,请下载",
|
|
493
569
|
rows: "显示 {total} 行中的 {shown} 行",
|
|
494
570
|
source: "代码",
|
|
495
|
-
page: "页面"
|
|
571
|
+
page: "页面",
|
|
572
|
+
converted: "预览 · 由 {format} 转换",
|
|
573
|
+
pagesShown: "显示 {shown} / {total} 页",
|
|
574
|
+
firstPages: "显示前 {shown} 页",
|
|
575
|
+
cols: "以及 {shown} / {total} 列",
|
|
576
|
+
preparing: "正在准备预览…",
|
|
577
|
+
preparingHint: "通常只需几秒",
|
|
578
|
+
unavailable: "无法预览",
|
|
579
|
+
formulaHint: "在 Excel 中打开时计算该值",
|
|
580
|
+
sheets: "工作表",
|
|
581
|
+
reasons: {
|
|
582
|
+
too_large: "文件大于 {limit} MB",
|
|
583
|
+
timeout: "超过 30 秒未完成",
|
|
584
|
+
broken: "文件已损坏或格式不受支持",
|
|
585
|
+
busy: "服务繁忙,请稍后重试"
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
notice: {
|
|
589
|
+
more: "显示全部",
|
|
590
|
+
less: "收起"
|
|
496
591
|
}
|
|
497
592
|
},
|
|
498
593
|
agent: {
|