@terrafirmagreg-team/ui 0.0.0-stage → 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.
Files changed (215) hide show
  1. package/package.json +93 -3
  2. package/src/components/blocks/button/icon-button.tsx +48 -0
  3. package/src/components/blocks/canvas/chevron-edge.tsx +134 -0
  4. package/src/components/blocks/canvas/flow-canvas.tsx +177 -0
  5. package/src/components/blocks/canvas/flow-toolbar.tsx +32 -0
  6. package/src/components/blocks/canvas/flow-viewport.tsx +243 -0
  7. package/src/components/blocks/git/github-info.tsx +77 -0
  8. package/src/components/blocks/lang/content.tsx +22 -0
  9. package/src/components/blocks/lang/flag.tsx +24 -0
  10. package/src/components/blocks/lang/link.tsx +22 -0
  11. package/src/components/blocks/lang/redirect.tsx +47 -0
  12. package/src/components/blocks/lang/switcher.tsx +53 -0
  13. package/src/components/blocks/lang/untranslated-callout.tsx +28 -0
  14. package/src/components/blocks/link/link-preview.tsx +256 -0
  15. package/src/components/blocks/list/row.tsx +91 -0
  16. package/src/components/blocks/media/glb/model.tsx +243 -0
  17. package/src/components/blocks/media/glb/scene.tsx +372 -0
  18. package/src/components/blocks/media/glb/viewer.tsx +51 -0
  19. package/src/components/blocks/media/image.tsx +135 -0
  20. package/src/components/blocks/media/slideshow.tsx +177 -0
  21. package/src/components/blocks/nav/breadcrumb.tsx +50 -0
  22. package/src/components/blocks/nav/link.tsx +85 -0
  23. package/src/components/blocks/nav/site-menu.tsx +77 -0
  24. package/src/components/blocks/nav/site-title.tsx +60 -0
  25. package/src/components/blocks/nav/switcher.tsx +205 -0
  26. package/src/components/blocks/page/empty-state.tsx +31 -0
  27. package/src/components/blocks/page/heading.tsx +53 -0
  28. package/src/components/blocks/page/pager.tsx +112 -0
  29. package/src/components/blocks/readability/menu.tsx +431 -0
  30. package/src/components/blocks/readability/track.tsx +164 -0
  31. package/src/components/blocks/search/command.tsx +79 -0
  32. package/src/components/blocks/search/dialog.tsx +712 -0
  33. package/src/components/blocks/search/provider.tsx +117 -0
  34. package/src/components/blocks/sidebar.tsx +406 -0
  35. package/src/components/blocks/theme/toggle.tsx +71 -0
  36. package/src/components/blocks/tooltip/hint.tsx +27 -0
  37. package/src/components/blocks/viewer/controls.tsx +279 -0
  38. package/src/components/blocks/viewer/float-bar.tsx +50 -0
  39. package/src/components/layouts/layout.tsx +93 -0
  40. package/src/components/layouts/left-sidebar/content.tsx +62 -0
  41. package/src/components/layouts/left-sidebar/context.tsx +54 -0
  42. package/src/components/layouts/left-sidebar/expand.tsx +22 -0
  43. package/src/components/layouts/left-sidebar/footer.tsx +105 -0
  44. package/src/components/layouts/left-sidebar/index.ts +28 -0
  45. package/src/components/layouts/left-sidebar/items.tsx +102 -0
  46. package/src/components/layouts/left-sidebar/search.tsx +74 -0
  47. package/src/components/layouts/left-sidebar/sidebar.tsx +188 -0
  48. package/src/components/layouts/left-sidebar/tree.tsx +156 -0
  49. package/src/components/layouts/right-sidebar.tsx +95 -0
  50. package/src/components/layouts/tree-context.tsx +41 -0
  51. package/src/components/mdx/accordion.tsx +184 -0
  52. package/src/components/mdx/banner.tsx +154 -0
  53. package/src/components/mdx/callout.tsx +96 -0
  54. package/src/components/mdx/card.tsx +49 -0
  55. package/src/components/mdx/codeblock.tsx +249 -0
  56. package/src/components/mdx/collapsible.tsx +32 -0
  57. package/src/components/mdx/files.tsx +62 -0
  58. package/src/components/mdx/glow-header.tsx +40 -0
  59. package/src/components/mdx/gradient-text.tsx +27 -0
  60. package/src/components/mdx/image-zoom.tsx +314 -0
  61. package/src/components/mdx/mermaid.tsx +16 -0
  62. package/src/components/mdx/multiblock.tsx +18 -0
  63. package/src/components/mdx/preview.tsx +100 -0
  64. package/src/components/mdx/steps.tsx +9 -0
  65. package/src/components/mdx/table.tsx +13 -0
  66. package/src/components/mdx/tabs.tsx +353 -0
  67. package/src/components/mdx/type-table.tsx +170 -0
  68. package/src/components/ui/accordion.tsx +71 -0
  69. package/src/components/ui/alert-dialog.tsx +187 -0
  70. package/src/components/ui/alert.tsx +75 -0
  71. package/src/components/ui/aspect-ratio.tsx +22 -0
  72. package/src/components/ui/attachment.tsx +207 -0
  73. package/src/components/ui/avatar.tsx +108 -0
  74. package/src/components/ui/badge.tsx +51 -0
  75. package/src/components/ui/breadcrumb.tsx +124 -0
  76. package/src/components/ui/bubble.tsx +127 -0
  77. package/src/components/ui/button-group.tsx +87 -0
  78. package/src/components/ui/button.tsx +57 -0
  79. package/src/components/ui/calendar.tsx +221 -0
  80. package/src/components/ui/card.tsx +102 -0
  81. package/src/components/ui/carousel.tsx +242 -0
  82. package/src/components/ui/chart.tsx +371 -0
  83. package/src/components/ui/checkbox.tsx +28 -0
  84. package/src/components/ui/collapsible.tsx +21 -0
  85. package/src/components/ui/combobox.tsx +297 -0
  86. package/src/components/ui/command.tsx +198 -0
  87. package/src/components/ui/context-menu.tsx +270 -0
  88. package/src/components/ui/dialog.tsx +160 -0
  89. package/src/components/ui/direction.tsx +6 -0
  90. package/src/components/ui/drawer.tsx +227 -0
  91. package/src/components/ui/dropdown-menu.tsx +269 -0
  92. package/src/components/ui/empty.tsx +103 -0
  93. package/src/components/ui/field.tsx +238 -0
  94. package/src/components/ui/hover-card.tsx +50 -0
  95. package/src/components/ui/input-group.tsx +158 -0
  96. package/src/components/ui/input-otp.tsx +86 -0
  97. package/src/components/ui/input.tsx +19 -0
  98. package/src/components/ui/item.tsx +201 -0
  99. package/src/components/ui/kbd.tsx +26 -0
  100. package/src/components/ui/label.tsx +19 -0
  101. package/src/components/ui/marker.tsx +70 -0
  102. package/src/components/ui/menubar.tsx +280 -0
  103. package/src/components/ui/message-scroller.tsx +131 -0
  104. package/src/components/ui/message.tsx +91 -0
  105. package/src/components/ui/native-select.tsx +60 -0
  106. package/src/components/ui/navigation-menu.tsx +167 -0
  107. package/src/components/ui/pagination.tsx +130 -0
  108. package/src/components/ui/popover.tsx +91 -0
  109. package/src/components/ui/progress.tsx +82 -0
  110. package/src/components/ui/questionnaire.tsx +324 -0
  111. package/src/components/ui/radio-group.tsx +37 -0
  112. package/src/components/ui/resizable.tsx +49 -0
  113. package/src/components/ui/scroll-area.tsx +54 -0
  114. package/src/components/ui/select.tsx +200 -0
  115. package/src/components/ui/separator.tsx +24 -0
  116. package/src/components/ui/sheet.tsx +138 -0
  117. package/src/components/ui/sidebar.tsx +730 -0
  118. package/src/components/ui/skeleton.tsx +13 -0
  119. package/src/components/ui/slider.tsx +51 -0
  120. package/src/components/ui/spinner.tsx +10 -0
  121. package/src/components/ui/switch.tsx +31 -0
  122. package/src/components/ui/table.tsx +115 -0
  123. package/src/components/ui/tabs.tsx +81 -0
  124. package/src/components/ui/textarea.tsx +17 -0
  125. package/src/components/ui/toast.tsx +234 -0
  126. package/src/components/ui/toggle-group.tsx +89 -0
  127. package/src/components/ui/toggle.tsx +44 -0
  128. package/src/components/ui/tooltip.tsx +65 -0
  129. package/src/hooks/canvas/use-flow-hover.ts +18 -0
  130. package/src/hooks/canvas/use-flow-viewport-persist.ts +33 -0
  131. package/src/hooks/lang.ts +8 -0
  132. package/src/hooks/layout.ts +18 -0
  133. package/src/hooks/page/use-fit-pages.ts +91 -0
  134. package/src/hooks/page/use-location-search.ts +25 -0
  135. package/src/hooks/page/use-page-preview.ts +40 -0
  136. package/src/hooks/page/use-paged-list.ts +20 -0
  137. package/src/hooks/readability/provider.ts +86 -0
  138. package/src/hooks/search/dialog.ts +41 -0
  139. package/src/hooks/search/provider.ts +25 -0
  140. package/src/hooks/search/use-highlight-query.ts +51 -0
  141. package/src/hooks/sidebar.ts +63 -0
  142. package/src/hooks/use-async-value.ts +57 -0
  143. package/src/hooks/use-close-on-scroll.ts +23 -0
  144. package/src/hooks/use-copy-button.ts +46 -0
  145. package/src/hooks/use-cycle-index.ts +75 -0
  146. package/src/hooks/use-document-title.ts +9 -0
  147. package/src/hooks/use-element-size.ts +35 -0
  148. package/src/hooks/use-external-meta.ts +132 -0
  149. package/src/hooks/use-hot-key.ts +33 -0
  150. package/src/hooks/use-hover-follow.ts +54 -0
  151. package/src/hooks/use-in-view.ts +30 -0
  152. package/src/hooks/use-last-value.ts +15 -0
  153. package/src/hooks/use-marquee.ts +51 -0
  154. package/src/hooks/use-media-query.ts +14 -0
  155. package/src/hooks/use-mobile.ts +19 -0
  156. package/src/hooks/use-modifier-keys.ts +31 -0
  157. package/src/hooks/use-on-change.ts +35 -0
  158. package/src/hooks/use-pane-keys.ts +28 -0
  159. package/src/hooks/use-swipe.ts +26 -0
  160. package/src/hooks/use-tree.ts +102 -0
  161. package/src/hooks/viewer/use-in-float-bar.ts +6 -0
  162. package/src/hooks/viewer/use-viewer-prefs.ts +77 -0
  163. package/src/lib/canvas/edge.ts +173 -0
  164. package/src/lib/canvas/geometry.ts +53 -0
  165. package/src/lib/canvas/state.ts +47 -0
  166. package/src/lib/canvas/viewport.ts +37 -0
  167. package/src/lib/canvas/xyflow.ts +1 -0
  168. package/src/lib/config.ts +81 -0
  169. package/src/lib/mdx/callout.ts +20 -0
  170. package/src/lib/mdx/gradient.ts +15 -0
  171. package/src/lib/mdx/mermaid.ts +14 -0
  172. package/src/lib/media/crop-opaque.ts +76 -0
  173. package/src/lib/media/nearby-indexes.ts +6 -0
  174. package/src/lib/media/trim-transparent.ts +117 -0
  175. package/src/lib/readability/config.ts +10 -0
  176. package/src/lib/readability/spotlight.ts +186 -0
  177. package/src/lib/readability/store.ts +146 -0
  178. package/src/lib/tree.ts +92 -0
  179. package/src/lib/utils/async-cache.ts +32 -0
  180. package/src/lib/utils/cn.ts +1 -0
  181. package/src/lib/utils/format.ts +22 -0
  182. package/src/lib/utils/history.ts +9 -0
  183. package/src/lib/utils/merge-refs.ts +13 -0
  184. package/src/lib/utils/nav-active.ts +58 -0
  185. package/src/lib/utils/stored-value.ts +136 -0
  186. package/src/lib/utils/urls.ts +17 -0
  187. package/src/locales/en_us.json +119 -0
  188. package/src/locales/pl_pl.json +35 -0
  189. package/src/locales/ru_ru.json +119 -0
  190. package/src/locales/uk_ua.json +35 -0
  191. package/src/locales/zh_cn.json +17 -0
  192. package/src/locales/zh_tw.json +17 -0
  193. package/src/locales.ts +5 -0
  194. package/src/provider.tsx +141 -0
  195. package/src/types/canvas.ts +49 -0
  196. package/src/types/glb.ts +25 -0
  197. package/src/types/nav.ts +95 -0
  198. package/src/types/preview.ts +9 -0
  199. package/src/types/readability.ts +28 -0
  200. package/src/types/search.ts +56 -0
  201. package/src/types/tree.ts +18 -0
  202. package/src/types/viewer.ts +53 -0
  203. package/styles/content/base.css +194 -0
  204. package/styles/content/default-colors.css +51 -0
  205. package/styles/content/shiki.css +108 -0
  206. package/styles/content/typography.mjs +3941 -0
  207. package/styles/content.css +7 -0
  208. package/styles/image-zoom.css +83 -0
  209. package/styles/layout.css +28 -0
  210. package/styles/left-sidebar.css +140 -0
  211. package/styles/readability.css +50 -0
  212. package/styles/right-sidebar.css +6 -0
  213. package/styles/workspace.css +26 -0
  214. package/styles.css +413 -0
  215. package/README.md +0 -3
@@ -0,0 +1,13 @@
1
+ import type * as React from 'react';
2
+
3
+ export function mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {
4
+ return (value) => {
5
+ refs.forEach((ref) => {
6
+ if (typeof ref === 'function') {
7
+ ref(value);
8
+ } else if (ref) {
9
+ ref.current = value;
10
+ }
11
+ });
12
+ };
13
+ }
@@ -0,0 +1,58 @@
1
+ import type * as PageTree from '@terrafirmagreg-team/translate/types/tree';
2
+
3
+ export type NavItemMatch = (url: string) => boolean;
4
+
5
+ function sameValue(want: string, have: string | null): boolean {
6
+ return have === want;
7
+ }
8
+
9
+ export function isNavItemActive(
10
+ href: string,
11
+ pathname: string,
12
+ search: string,
13
+ navKeys?: ReadonlySet<string>,
14
+ nested = false,
15
+ ) {
16
+ const q = href.indexOf('?');
17
+ const query = q >= 0 ? href.slice(q + 1) : undefined;
18
+ let path = q >= 0 ? href.slice(0, q) : href;
19
+ if (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1);
20
+ if (pathname.length > 1 && pathname.endsWith('/'))
21
+ pathname = pathname.slice(0, -1);
22
+ if (path !== pathname && !(nested && pathname.startsWith(`${path}/`)))
23
+ return false;
24
+ const want = new URLSearchParams(query ?? '');
25
+ const have = new URLSearchParams(search);
26
+ const keys = new Set<string>();
27
+ for (const key of want.keys()) keys.add(key);
28
+ for (const key of have.keys()) if (navKeys?.has(key)) keys.add(key);
29
+ for (const key of keys) {
30
+ const wantValue = want.get(key);
31
+ if (wantValue === null) return false;
32
+ if (!sameValue(wantValue, have.get(key))) return false;
33
+ }
34
+ return true;
35
+ }
36
+
37
+ export function hasActiveDescendant(
38
+ node: PageTree.Node,
39
+ match: NavItemMatch,
40
+ ): boolean {
41
+ if (node.type === 'page') return match(node.url);
42
+ if (node.type === 'folder') {
43
+ return (
44
+ (node.index !== undefined && match(node.index.url)) ||
45
+ node.children.some((child) => hasActiveDescendant(child, match))
46
+ );
47
+ }
48
+ return false;
49
+ }
50
+
51
+ export function langScopeKey(
52
+ id: string | undefined,
53
+ languages: readonly string[],
54
+ ) {
55
+ for (const lang of languages)
56
+ id = id?.replaceAll(`:${lang}`, '').replaceAll(`/${lang}`, '');
57
+ return id;
58
+ }
@@ -0,0 +1,136 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useSyncExternalStore } from 'react';
4
+
5
+ export type StoredCodec<T> = {
6
+ read: (raw: string | null) => T;
7
+ write: (value: T) => string;
8
+ };
9
+
10
+ const listenersByKey = new Map<string, Set<() => void>>();
11
+ const memoryByKey = new Map<string, string>();
12
+
13
+ export function subscribeStoredValue(
14
+ key: string,
15
+ onChange: () => void,
16
+ ): () => void {
17
+ let set = listenersByKey.get(key);
18
+ if (!set) {
19
+ set = new Set();
20
+ listenersByKey.set(key, set);
21
+ }
22
+ set.add(onChange);
23
+ const onStorage = (event: StorageEvent) => {
24
+ if (event.key === null || event.key === key) onChange();
25
+ };
26
+ window.addEventListener('storage', onStorage);
27
+ return () => {
28
+ set.delete(onChange);
29
+ window.removeEventListener('storage', onStorage);
30
+ };
31
+ }
32
+
33
+ export function readStoredValue<T>(
34
+ key: string,
35
+ read: (raw: string | null) => T,
36
+ ): T {
37
+ const memory = memoryByKey.get(key) ?? null;
38
+ try {
39
+ return read(memory ?? localStorage.getItem(key));
40
+ } catch {
41
+ return read(memory);
42
+ }
43
+ }
44
+
45
+ export function writeStoredValue<T>(
46
+ key: string,
47
+ value: T,
48
+ write: (v: T) => string,
49
+ ) {
50
+ const raw = write(value);
51
+ try {
52
+ localStorage.setItem(key, raw);
53
+ memoryByKey.delete(key);
54
+ } catch {
55
+ memoryByKey.set(key, raw);
56
+ }
57
+ for (const listener of listenersByKey.get(key) ?? []) listener();
58
+ }
59
+
60
+ export function createStoredValue<T>(key: string, codec: StoredCodec<T>) {
61
+ let cache: { raw: string | null; value: T } | undefined;
62
+ const fallback = codec.read(null);
63
+
64
+ const getSnapshot = (): T => {
65
+ let raw: string | null = memoryByKey.get(key) ?? null;
66
+ if (raw === null) {
67
+ try {
68
+ raw = localStorage.getItem(key);
69
+ } catch {
70
+
71
+ }
72
+ }
73
+ if (cache?.raw === raw) return cache.value;
74
+ try {
75
+ const value = codec.read(raw);
76
+ cache = { raw, value };
77
+ return value;
78
+ } catch {
79
+ return fallback;
80
+ }
81
+ };
82
+
83
+ return function useStoredValue() {
84
+ const value = useSyncExternalStore(
85
+ (onChange) => subscribeStoredValue(key, onChange),
86
+ getSnapshot,
87
+ () => fallback,
88
+ );
89
+ const set = useCallback((next: T | ((prev: T) => T)) => {
90
+ const value =
91
+ typeof next === 'function' ? (next as (p: T) => T)(getSnapshot()) : next;
92
+ writeStoredValue(key, value, codec.write);
93
+ }, []);
94
+ return [value, set] as const;
95
+ };
96
+ }
97
+
98
+ export function boolCodec(defaultValue: boolean): StoredCodec<boolean> {
99
+ return {
100
+ read: (raw) => (raw == null ? defaultValue : raw !== '0' && raw !== 'false'),
101
+ write: (value) => (value ? '1' : '0'),
102
+ };
103
+ }
104
+
105
+ export function literalCodec<T extends string>(
106
+ values: readonly T[],
107
+ defaultValue: T,
108
+ ): StoredCodec<T> {
109
+ return {
110
+ read: (raw) =>
111
+ raw != null && (values as readonly string[]).includes(raw)
112
+ ? (raw as T)
113
+ : defaultValue,
114
+ write: (value) => value,
115
+ };
116
+ }
117
+
118
+ export function jsonCodec<T>(defaultValue: T): StoredCodec<T> {
119
+ return {
120
+ read: (raw) => (raw == null ? defaultValue : (JSON.parse(raw) as T)),
121
+ write: (value) => JSON.stringify(value),
122
+ };
123
+ }
124
+
125
+ export function numberCodec(
126
+ defaultValue: number,
127
+ min: number,
128
+ max: number,
129
+ ): StoredCodec<number> {
130
+ const clamp = (value: number) =>
131
+ Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : defaultValue;
132
+ return {
133
+ read: (raw) => (raw == null ? defaultValue : clamp(Number(raw))),
134
+ write: (value) => String(clamp(value)),
135
+ };
136
+ }
@@ -0,0 +1,17 @@
1
+ export function safeURL(value?: string): string | undefined {
2
+ // oxlint-disable-next-line no-control-regex
3
+ if (!value || /[\u0000-\u0020\\]/.test(value)) return undefined;
4
+ return /^(https?:\/\/|\/(?!\/)|#)/i.test(value) ? value : undefined;
5
+ }
6
+
7
+ export function normalize(urlOrPath: string) {
8
+ if (urlOrPath.length > 1 && urlOrPath.endsWith('/')) return urlOrPath.slice(0, -1);
9
+ return urlOrPath;
10
+ }
11
+
12
+ export function isActive(href: string, pathname: string, nested = false): boolean {
13
+ href = normalize(href);
14
+ pathname = normalize(pathname);
15
+
16
+ return href === pathname || (nested && pathname.startsWith(`${href}/`));
17
+ }
@@ -0,0 +1,119 @@
1
+ {
2
+ "ui": {
3
+ "on_this_page": "On this page",
4
+ "search_trigger": "Search",
5
+ "search_dialog": "Search",
6
+ "search_empty": "No results found",
7
+ "choose_language": "Choose a language",
8
+ "last_updated": "Last updated on",
9
+ "copy_markdown": "Copy Markdown",
10
+ "open_github": "Open in GitHub",
11
+ "open": "Open",
12
+ "next_page": "Next Page",
13
+ "prev_page": "Previous Page",
14
+ "edit_github": "Edit on GitHub",
15
+ "copied_markdown": "Copied Markdown",
16
+ "sidebar_open": "Open Sidebar",
17
+ "sidebar_close": "Close Sidebar",
18
+ "sidebar_collapse": "Collapse Sidebar",
19
+ "no_headings": "No Headings",
20
+ "copy_anchor": "Copy Anchor Link",
21
+ "copied_anchor": "Copied Anchor Link",
22
+ "search_close": "Close Search",
23
+ "search_failed": "Search failed",
24
+ "search_failed_results": "Search failed, showing results for {query}",
25
+ "open_search": "Open Search",
26
+ "menu_toggle": "Toggle Menu",
27
+ "theme_light": "Light",
28
+ "theme_dark": "Dark",
29
+ "theme_system": "System",
30
+ "banner_close": "Close Banner",
31
+ "copy_link": "Copy Link",
32
+ "copied_link": "Copied Link",
33
+ "close": "Close",
34
+ "next_image": "Next Image",
35
+ "prev_image": "Previous Image",
36
+ "image_viewer": "Image Viewer",
37
+ "copy_text": "Copy Text",
38
+ "copied_text": "Copied Text",
39
+ "type": "Type",
40
+ "default": "Default",
41
+ "parameters": "Parameters",
42
+ "prop": "Prop",
43
+ "returns": "Returns",
44
+ "readability": {
45
+ "menu": "Readability",
46
+ "layout": "Layout",
47
+ "layout.unavailable": "Layout switch is not available on small screens",
48
+ "layout.help": "Adjust the site layout to fit different reading needs and screens",
49
+ "layout.full": "Expand all",
50
+ "layout.full.help": "The article takes the full panel width; the sidebar stays at the screen edge",
51
+ "layout.sidebar": "Adjustable page width",
52
+ "layout.sidebar.help": "The slider narrows the whole page block — the sidebar moves with it",
53
+ "layout.both": "Adjustable page and content",
54
+ "layout.both.help": "Both sliders apply: page block width and the text column inside",
55
+ "layout.original": "Original width",
56
+ "layout.original.help": "Default centered page width",
57
+ "page_width": "Page width",
58
+ "page_width.help": "Adjust the maximum width of the page layout to fit different reading needs and screens",
59
+ "page_width.slider": "Page width slider",
60
+ "page_width.slider.help": "A ranged slider to choose the maximum width of the page layout",
61
+ "content_width": "Content width",
62
+ "content_width.help": "Adjust the maximum width of the text column to fit different reading needs and screens",
63
+ "content_width.slider": "Content width slider",
64
+ "content_width.slider.help": "A ranged slider to choose the maximum width of the content column",
65
+ "spotlight": "Spotlight",
66
+ "spotlight.help": "Highlight the line or block under the cursor to help readers stay focused",
67
+ "spotlight.unavailable": "Spotlight is not available on touch screens",
68
+ "spotlight.on": "On",
69
+ "spotlight.on.help": "Turn on Spotlight",
70
+ "spotlight.off": "Off",
71
+ "spotlight.off.help": "Turn off Spotlight",
72
+ "spotlight.styles": "Style",
73
+ "spotlight.styles.help": "Adjust how the spotlight highlight is drawn",
74
+ "spotlight.under": "Under",
75
+ "spotlight.under.help": "A solid background under the hovered block shows where the cursor is",
76
+ "spotlight.aside": "Aside",
77
+ "spotlight.aside.help": "A solid line beside the hovered element shows where the cursor is"
78
+ },
79
+ "canvas": {
80
+ "zoom_in": "Zoom in",
81
+ "zoom_out": "Zoom out",
82
+ "fit": "Fit view",
83
+ "prev": "Previous",
84
+ "next": "Next",
85
+ "fullscreen": "Fullscreen",
86
+ "exit_fullscreen": "Exit fullscreen"
87
+ },
88
+ "viewer": {
89
+ "settings": "Viewer settings",
90
+ "autoplay": "Autoplay",
91
+ "autoplay_speed": "Autoplay speed",
92
+ "spin": "Spin",
93
+ "grid": "Grid",
94
+ "rotate_speed": "Rotate speed",
95
+ "reset_view": "Reset view",
96
+ "label": "3D model",
97
+ "loading": "Loading…",
98
+ "width": "Width",
99
+ "height": "Height"
100
+ },
101
+ "redirecting": "Redirecting…",
102
+ "input": "Input",
103
+ "output": "Output",
104
+ "image_unavailable": "Image unavailable",
105
+ "back": "Back",
106
+ "not_found": "Page not found",
107
+ "site_menu": "Site menu",
108
+ "sign_in": "Sign in",
109
+ "sign_out": "Sign out",
110
+ "website": "Website"
111
+ },
112
+ "untranslated": {
113
+ "title": "This page is not translated",
114
+ "body": "Showing the English version. A translation is not available yet.",
115
+ "partial_title": "This page is not fully translated",
116
+ "partial_body": "Some content is still shown in English.",
117
+ "translate": "Translate on Crowdin"
118
+ }
119
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "ui": {
3
+ "sidebar_open": "Otwórz panel",
4
+ "sidebar_close": "Zamknij panel",
5
+ "sidebar_collapse": "Zwiń panel",
6
+ "no_headings": "Brak nagłówków",
7
+ "copy_anchor": "Kopiuj link do nagłówka",
8
+ "copied_anchor": "Link do nagłówka skopiowany",
9
+ "search_close": "Zamknij wyszukiwanie",
10
+ "search_failed": "Wyszukiwanie nie powiodło się",
11
+ "search_failed_results": "Wyszukiwanie nie powiodło się, wyniki dla {query}",
12
+ "open_search": "Otwórz wyszukiwanie",
13
+ "menu_toggle": "Przełącz menu",
14
+ "theme_light": "Jasny",
15
+ "theme_dark": "Ciemny",
16
+ "theme_system": "Systemowy",
17
+ "banner_close": "Zamknij baner",
18
+ "copy_link": "Kopiuj link",
19
+ "copied_link": "Link skopiowany",
20
+ "close": "Zamknij",
21
+ "next_image": "Następny obraz",
22
+ "prev_image": "Poprzedni obraz",
23
+ "image_viewer": "Przeglądarka obrazów",
24
+ "copy_text": "Kopiuj tekst",
25
+ "copied_text": "Tekst skopiowany",
26
+ "type": "Typ",
27
+ "default": "Domyślne",
28
+ "parameters": "Parametry",
29
+ "prop": "Właściwość",
30
+ "returns": "Zwraca",
31
+ "search_trigger": "Szukaj",
32
+ "search_dialog": "Szukaj",
33
+ "search_empty": "Brak wyników"
34
+ }
35
+ }
@@ -0,0 +1,119 @@
1
+ {
2
+ "ui": {
3
+ "on_this_page": "На этой странице",
4
+ "search_trigger": "Поиск",
5
+ "search_dialog": "Поиск",
6
+ "search_empty": "Ничего не найдено",
7
+ "choose_language": "Выберите язык",
8
+ "last_updated": "Обновлено",
9
+ "copy_markdown": "Скопировать Markdown",
10
+ "open_github": "Открыть в GitHub",
11
+ "open": "Открыть",
12
+ "next_page": "Следующая",
13
+ "prev_page": "Предыдущая",
14
+ "edit_github": "Редактировать на GitHub",
15
+ "copied_markdown": "Markdown скопирован",
16
+ "sidebar_open": "Открыть панель",
17
+ "sidebar_close": "Закрыть панель",
18
+ "sidebar_collapse": "Свернуть панель",
19
+ "no_headings": "Нет заголовков",
20
+ "copy_anchor": "Скопировать ссылку на заголовок",
21
+ "copied_anchor": "Ссылка на заголовок скопирована",
22
+ "search_close": "Закрыть поиск",
23
+ "search_failed": "Поиск не удался",
24
+ "search_failed_results": "Поиск не удался, результаты для {query}",
25
+ "open_search": "Открыть поиск",
26
+ "menu_toggle": "Переключить меню",
27
+ "theme_light": "Светлая",
28
+ "theme_dark": "Тёмная",
29
+ "theme_system": "Системная",
30
+ "banner_close": "Закрыть баннер",
31
+ "copy_link": "Копировать ссылку",
32
+ "copied_link": "Ссылка скопирована",
33
+ "close": "Закрыть",
34
+ "next_image": "Следующее изображение",
35
+ "prev_image": "Предыдущее изображение",
36
+ "image_viewer": "Просмотр изображения",
37
+ "copy_text": "Копировать текст",
38
+ "copied_text": "Текст скопирован",
39
+ "type": "Тип",
40
+ "default": "По умолчанию",
41
+ "parameters": "Параметры",
42
+ "prop": "Свойство",
43
+ "returns": "Возвращает",
44
+ "readability": {
45
+ "menu": "Читаемость",
46
+ "layout": "Макет",
47
+ "layout.unavailable": "Недоступно на маленьких экранах",
48
+ "layout.help": "Настройка макета сайта под разные задачи чтения и экраны",
49
+ "layout.full": "Во всю ширину",
50
+ "layout.full.help": "Статья занимает всю ширину панели, сайдбар остаётся у края",
51
+ "layout.sidebar": "Настраиваемая страница",
52
+ "layout.sidebar.help": "Слайдер сужает весь блок страницы — сайдбар двигается вместе с ним",
53
+ "layout.both": "Настраиваемая страница и текст",
54
+ "layout.both.help": "Работают оба слайдера: ширина страницы и текстовой колонки",
55
+ "layout.original": "Обычная ширина",
56
+ "layout.original.help": "Стандартная центрированная ширина страницы",
57
+ "page_width": "Ширина страницы",
58
+ "page_width.help": "Максимальная ширина страницы под разные задачи чтения и экраны",
59
+ "page_width.slider": "Слайдер ширины страницы",
60
+ "page_width.slider.help": "Ползунок для выбора максимальной ширины блока страницы",
61
+ "content_width": "Ширина текста",
62
+ "content_width.help": "Максимальная ширина текстовой колонки под разные задачи чтения и экраны",
63
+ "content_width.slider": "Слайдер ширины текста",
64
+ "content_width.slider.help": "Ползунок для выбора максимальной ширины текстовой колонки",
65
+ "spotlight": "Подсветка",
66
+ "spotlight.help": "Подсвечивает строку или блок под курсором, помогая держать фокус при чтении",
67
+ "spotlight.unavailable": "Недоступно на сенсорных экранах",
68
+ "spotlight.on": "Вкл",
69
+ "spotlight.on.help": "Включить подсветку",
70
+ "spotlight.off": "Выкл",
71
+ "spotlight.off.help": "Выключить подсветку",
72
+ "spotlight.styles": "Стиль",
73
+ "spotlight.styles.help": "Как отображается подсветка",
74
+ "spotlight.under": "Под текстом",
75
+ "spotlight.under.help": "Подложка под наведённым блоком показывает, где находится курсор",
76
+ "spotlight.aside": "Сбоку",
77
+ "spotlight.aside.help": "Цветная полоса у левого края блока показывает, где находится курсор"
78
+ },
79
+ "canvas": {
80
+ "zoom_in": "Приблизить",
81
+ "zoom_out": "Отдалить",
82
+ "fit": "По размеру",
83
+ "prev": "Назад",
84
+ "next": "Вперёд",
85
+ "fullscreen": "Во весь экран",
86
+ "exit_fullscreen": "Выйти из полноэкранного режима"
87
+ },
88
+ "viewer": {
89
+ "settings": "Настройки просмотра",
90
+ "autoplay": "Автопрокрутка",
91
+ "autoplay_speed": "Скорость автопрокрутки",
92
+ "spin": "Вращение",
93
+ "grid": "Сетка",
94
+ "rotate_speed": "Скорость вращения",
95
+ "reset_view": "Сбросить вид",
96
+ "label": "3D-модель",
97
+ "loading": "Загрузка…",
98
+ "width": "Ширина",
99
+ "height": "Высота"
100
+ },
101
+ "redirecting": "Перенаправление…",
102
+ "input": "Исходник",
103
+ "output": "Результат",
104
+ "image_unavailable": "Изображение недоступно",
105
+ "back": "Назад",
106
+ "not_found": "Страница не найдена",
107
+ "site_menu": "Меню сайта",
108
+ "sign_in": "Войти",
109
+ "sign_out": "Выйти",
110
+ "website": "Сайт"
111
+ },
112
+ "untranslated": {
113
+ "title": "Страница не переведена",
114
+ "body": "Показана английская версия. Перевод пока недоступен.",
115
+ "partial_title": "Страница переведена не полностью",
116
+ "partial_body": "Часть содержимого показана на английском.",
117
+ "translate": "Перевести на Crowdin"
118
+ }
119
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "ui": {
3
+ "sidebar_open": "Відкрити панель",
4
+ "sidebar_close": "Закрити панель",
5
+ "sidebar_collapse": "Згорнути панель",
6
+ "no_headings": "Немає заголовків",
7
+ "copy_anchor": "Скопіювати посилання на заголовок",
8
+ "copied_anchor": "Посилання на заголовок скопійовано",
9
+ "search_close": "Закрити пошук",
10
+ "search_failed": "Пошук не вдався",
11
+ "search_failed_results": "Пошук не вдався, результати для {query}",
12
+ "open_search": "Відкрити пошук",
13
+ "menu_toggle": "Перемкнути меню",
14
+ "theme_light": "Світла",
15
+ "theme_dark": "Темна",
16
+ "theme_system": "Системна",
17
+ "banner_close": "Закрити банер",
18
+ "copy_link": "Копіювати посилання",
19
+ "copied_link": "Посилання скопійовано",
20
+ "close": "Закрити",
21
+ "next_image": "Наступне зображення",
22
+ "prev_image": "Попереднє зображення",
23
+ "image_viewer": "Перегляд зображення",
24
+ "copy_text": "Копіювати текст",
25
+ "copied_text": "Текст скопійовано",
26
+ "type": "Тип",
27
+ "default": "За замовчуванням",
28
+ "parameters": "Параметри",
29
+ "prop": "Властивість",
30
+ "returns": "Повертає",
31
+ "search_trigger": "Пошук",
32
+ "search_dialog": "Пошук",
33
+ "search_empty": "Нічого не знайдено"
34
+ }
35
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "ui": {
3
+ "sidebar_open": "Open Sidebar",
4
+ "sidebar_close": "Close Sidebar",
5
+ "sidebar_collapse": "Collapse Sidebar",
6
+ "no_headings": "No Headings",
7
+ "copy_anchor": "Copy Anchor Link",
8
+ "copied_anchor": "Copied Anchor Link",
9
+ "search_close": "Close Search",
10
+ "search_failed": "Search failed",
11
+ "search_failed_results": "Search failed, showing results for {query}",
12
+ "search_trigger": "搜索",
13
+ "search_dialog": "搜索",
14
+ "search_empty": "未找到结果",
15
+ "open_search": "打开搜索"
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "ui": {
3
+ "sidebar_open": "Open Sidebar",
4
+ "sidebar_close": "Close Sidebar",
5
+ "sidebar_collapse": "Collapse Sidebar",
6
+ "no_headings": "No Headings",
7
+ "copy_anchor": "Copy Anchor Link",
8
+ "copied_anchor": "Copied Anchor Link",
9
+ "search_close": "Close Search",
10
+ "search_failed": "Search failed",
11
+ "search_failed_results": "Search failed, showing results for {query}",
12
+ "search_trigger": "搜尋",
13
+ "search_dialog": "搜尋",
14
+ "search_empty": "找不到結果",
15
+ "open_search": "開啟搜尋"
16
+ }
17
+ }
package/src/locales.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { createLocaleCatalog } from '@terrafirmagreg-team/translate/lib/locales';
2
+
3
+ export const locales = createLocaleCatalog(
4
+ import.meta.glob('./locales/*.json', { eager: true, import: 'default' }),
5
+ );