@prestack/thread-ui 0.1.10 → 0.1.12

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 (209) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/dist/ui/attach.js +6 -7
  3. package/dist/ui/compositions.d.ts +0 -8
  4. package/dist/ui/compositions.js +3 -166
  5. package/dist/ui/generators/routes.js +1 -0
  6. package/package.json +2 -2
  7. package/dist/ui/animations/anm_appear.ts +0 -13
  8. package/dist/ui/animations/anm_blur_in.ts +0 -19
  9. package/dist/ui/animations/anm_blur_out.ts +0 -18
  10. package/dist/ui/animations/anm_dismiss.ts +0 -18
  11. package/dist/ui/animations/anm_drop.ts +0 -19
  12. package/dist/ui/animations/anm_fall.ts +0 -18
  13. package/dist/ui/animations/anm_flash.ts +0 -18
  14. package/dist/ui/animations/anm_glow.ts +0 -16
  15. package/dist/ui/animations/anm_lift.ts +0 -16
  16. package/dist/ui/animations/anm_nudge.ts +0 -16
  17. package/dist/ui/animations/anm_pop_in.ts +0 -23
  18. package/dist/ui/animations/anm_pop_out.ts +0 -22
  19. package/dist/ui/animations/anm_press.ts +0 -12
  20. package/dist/ui/animations/anm_pulse.ts +0 -13
  21. package/dist/ui/animations/anm_rise.ts +0 -19
  22. package/dist/ui/animations/anm_shake.ts +0 -13
  23. package/dist/ui/animations/anm_slide_in_left.ts +0 -19
  24. package/dist/ui/animations/anm_slide_in_right.ts +0 -19
  25. package/dist/ui/animations/anm_slide_out_left.ts +0 -18
  26. package/dist/ui/animations/anm_slide_out_right.ts +0 -18
  27. package/dist/ui/animations/anm_spin.ts +0 -12
  28. package/dist/ui/animations/anm_swell.ts +0 -16
  29. package/dist/ui/animations/anm_wobble.ts +0 -24
  30. package/dist/ui/animations/anm_zoom_in.ts +0 -19
  31. package/dist/ui/animations/anm_zoom_out.ts +0 -18
  32. package/dist/ui/animations.ts +0 -308
  33. package/dist/ui/attach.ts +0 -553
  34. package/dist/ui/charts.tsx +0 -69
  35. package/dist/ui/checked.ts +0 -32
  36. package/dist/ui/collector.ts +0 -140
  37. package/dist/ui/compositions.ts +0 -613
  38. package/dist/ui/consent.ts +0 -55
  39. package/dist/ui/content.tsx +0 -27
  40. package/dist/ui/contrast.ts +0 -27
  41. package/dist/ui/controls.tsx +0 -25
  42. package/dist/ui/disclosure.tsx +0 -20
  43. package/dist/ui/dismiss-layer.ts +0 -87
  44. package/dist/ui/door.ts +0 -140
  45. package/dist/ui/drag.ts +0 -316
  46. package/dist/ui/elements/accordion.tsx +0 -47
  47. package/dist/ui/elements/accordion.works.ts +0 -66
  48. package/dist/ui/elements/aspect-ratio.tsx +0 -31
  49. package/dist/ui/elements/aspect-ratio.works.ts +0 -5
  50. package/dist/ui/elements/avatar.tsx +0 -34
  51. package/dist/ui/elements/avatar.works.ts +0 -16
  52. package/dist/ui/elements/badge.tsx +0 -33
  53. package/dist/ui/elements/badge.works.ts +0 -9
  54. package/dist/ui/elements/bars.tsx +0 -50
  55. package/dist/ui/elements/bars.works.ts +0 -29
  56. package/dist/ui/elements/box.tsx +0 -36
  57. package/dist/ui/elements/breadcrumb.tsx +0 -38
  58. package/dist/ui/elements/breadcrumb.works.ts +0 -24
  59. package/dist/ui/elements/button.tsx +0 -46
  60. package/dist/ui/elements/button.works.tsx +0 -52
  61. package/dist/ui/elements/column.tsx +0 -29
  62. package/dist/ui/elements/consent.tsx +0 -71
  63. package/dist/ui/elements/consent.works.tsx +0 -132
  64. package/dist/ui/elements/donut.tsx +0 -45
  65. package/dist/ui/elements/donut.works.ts +0 -42
  66. package/dist/ui/elements/each.tsx +0 -34
  67. package/dist/ui/elements/each.works.tsx +0 -82
  68. package/dist/ui/elements/empty.tsx +0 -33
  69. package/dist/ui/elements/field.tsx +0 -45
  70. package/dist/ui/elements/field.works.ts +0 -65
  71. package/dist/ui/elements/funnel.tsx +0 -50
  72. package/dist/ui/elements/funnel.works.ts +0 -37
  73. package/dist/ui/elements/gauge.tsx +0 -40
  74. package/dist/ui/elements/gauge.works.ts +0 -42
  75. package/dist/ui/elements/glyph.tsx +0 -30
  76. package/dist/ui/elements/glyph.works.tsx +0 -42
  77. package/dist/ui/elements/grid.tsx +0 -29
  78. package/dist/ui/elements/heatmap.tsx +0 -48
  79. package/dist/ui/elements/heatmap.works.ts +0 -24
  80. package/dist/ui/elements/hit-box.tsx +0 -47
  81. package/dist/ui/elements/hit-box.works.tsx +0 -576
  82. package/dist/ui/elements/image.tsx +0 -29
  83. package/dist/ui/elements/line-chart.tsx +0 -45
  84. package/dist/ui/elements/line-chart.works.ts +0 -41
  85. package/dist/ui/elements/link.tsx +0 -38
  86. package/dist/ui/elements/link.works.ts +0 -25
  87. package/dist/ui/elements/media.tsx +0 -57
  88. package/dist/ui/elements/menu.tsx +0 -51
  89. package/dist/ui/elements/menu.works.tsx +0 -154
  90. package/dist/ui/elements/money.tsx +0 -36
  91. package/dist/ui/elements/money.works.ts +0 -9
  92. package/dist/ui/elements/pagination.tsx +0 -39
  93. package/dist/ui/elements/pagination.works.ts +0 -20
  94. package/dist/ui/elements/progress.tsx +0 -34
  95. package/dist/ui/elements/progress.works.ts +0 -8
  96. package/dist/ui/elements/radio-group.tsx +0 -50
  97. package/dist/ui/elements/radio-group.works.ts +0 -33
  98. package/dist/ui/elements/row.tsx +0 -29
  99. package/dist/ui/elements/scatter.tsx +0 -42
  100. package/dist/ui/elements/scatter.works.ts +0 -38
  101. package/dist/ui/elements/select.tsx +0 -43
  102. package/dist/ui/elements/select.works.ts +0 -5
  103. package/dist/ui/elements/separator.tsx +0 -31
  104. package/dist/ui/elements/skeleton.tsx +0 -31
  105. package/dist/ui/elements/slider.tsx +0 -34
  106. package/dist/ui/elements/slider.works.ts +0 -5
  107. package/dist/ui/elements/sparkline.tsx +0 -37
  108. package/dist/ui/elements/sparkline.works.ts +0 -32
  109. package/dist/ui/elements/spinner.tsx +0 -33
  110. package/dist/ui/elements/stack.tsx +0 -29
  111. package/dist/ui/elements/stat.tsx +0 -36
  112. package/dist/ui/elements/stat.works.ts +0 -14
  113. package/dist/ui/elements/surface.tsx +0 -36
  114. package/dist/ui/elements/surface.works.ts +0 -9
  115. package/dist/ui/elements/table.tsx +0 -62
  116. package/dist/ui/elements/table.works.ts +0 -30
  117. package/dist/ui/elements/tabs.tsx +0 -47
  118. package/dist/ui/elements/tabs.works.ts +0 -84
  119. package/dist/ui/elements/text.tsx +0 -33
  120. package/dist/ui/elements/textarea.tsx +0 -38
  121. package/dist/ui/elements/textarea.works.ts +0 -5
  122. package/dist/ui/elements/time.tsx +0 -40
  123. package/dist/ui/elements/time.works.ts +0 -29
  124. package/dist/ui/elements/toggle.tsx +0 -34
  125. package/dist/ui/elements/toggle.works.ts +0 -5
  126. package/dist/ui/elements/tooltip.tsx +0 -40
  127. package/dist/ui/elements/tooltip.works.ts +0 -77
  128. package/dist/ui/elements/value.tsx +0 -38
  129. package/dist/ui/elements/value.works.ts +0 -9
  130. package/dist/ui/elements.ts +0 -127
  131. package/dist/ui/focus-scope.ts +0 -121
  132. package/dist/ui/fonts.ts +0 -355
  133. package/dist/ui/generators/dev.d.ts +0 -1
  134. package/dist/ui/generators/dev.js +0 -62
  135. package/dist/ui/generators/dev.ts +0 -75
  136. package/dist/ui/generators/elements.ts +0 -796
  137. package/dist/ui/generators/i18n.ts +0 -283
  138. package/dist/ui/generators/icons.ts +0 -207
  139. package/dist/ui/generators/react.ts +0 -267
  140. package/dist/ui/generators/routes.ts +0 -847
  141. package/dist/ui/generators/show.ts +0 -261
  142. package/dist/ui/generators/styles.ts +0 -677
  143. package/dist/ui/generators/variants.ts +0 -196
  144. package/dist/ui/i18n/catalogs/en.ts +0 -191
  145. package/dist/ui/i18n/format.ts +0 -221
  146. package/dist/ui/i18n/locales.ts +0 -33
  147. package/dist/ui/i18n/parse.ts +0 -315
  148. package/dist/ui/i18n/translator.ts +0 -31
  149. package/dist/ui/i18n/types.ts +0 -96
  150. package/dist/ui/icons.ts +0 -331
  151. package/dist/ui/islands/map.ts +0 -58
  152. package/dist/ui/localizations.ts +0 -75
  153. package/dist/ui/material.ts +0 -236
  154. package/dist/ui/materials/mat_bordered.ts +0 -13
  155. package/dist/ui/materials/mat_ceramic.ts +0 -13
  156. package/dist/ui/materials/mat_clay.ts +0 -13
  157. package/dist/ui/materials/mat_elevated.ts +0 -24
  158. package/dist/ui/materials/mat_flat.ts +0 -34
  159. package/dist/ui/materials/mat_glass.ts +0 -20
  160. package/dist/ui/materials/mat_lit.ts +0 -13
  161. package/dist/ui/materials/mat_moulded.ts +0 -11
  162. package/dist/ui/materials.ts +0 -197
  163. package/dist/ui/modes.ts +0 -44
  164. package/dist/ui/navigation.tsx +0 -29
  165. package/dist/ui/positioning.ts +0 -90
  166. package/dist/ui/presented.tsx +0 -119
  167. package/dist/ui/provider.tsx +0 -184
  168. package/dist/ui/render-loop.ts +0 -133
  169. package/dist/ui/roving-focus.ts +0 -161
  170. package/dist/ui/screens.ts +0 -141
  171. package/dist/ui/scroll-lock.ts +0 -28
  172. package/dist/ui/series.ts +0 -97
  173. package/dist/ui/signals.ts +0 -386
  174. package/dist/ui/styleguide.ts +0 -231
  175. package/dist/ui/styleguides.ts +0 -374
  176. package/dist/ui/themes.ts +0 -22
  177. package/dist/ui/token.ts +0 -78
  178. package/dist/ui/tokens/shadow.ts +0 -25
  179. package/dist/ui/tokens.ts +0 -234
  180. package/dist/ui/validators.ts +0 -232
  181. package/dist/ui/variant.ts +0 -349
  182. package/dist/ui/variants/var_avatar-round.ts +0 -14
  183. package/dist/ui/variants/var_bubble-me.ts +0 -14
  184. package/dist/ui/variants/var_bubble-them.ts +0 -13
  185. package/dist/ui/variants/var_button-border.ts +0 -76
  186. package/dist/ui/variants/var_button-cta.ts +0 -76
  187. package/dist/ui/variants/var_button-destructive-ghost.ts +0 -72
  188. package/dist/ui/variants/var_button-destructive.ts +0 -76
  189. package/dist/ui/variants/var_button-fill.ts +0 -76
  190. package/dist/ui/variants/var_button-ghost.ts +0 -72
  191. package/dist/ui/variants/var_button-glass.ts +0 -55
  192. package/dist/ui/variants/var_button-normal.ts +0 -76
  193. package/dist/ui/variants/var_button-quiet.ts +0 -74
  194. package/dist/ui/variants/var_card.ts +0 -17
  195. package/dist/ui/variants/var_chip.ts +0 -13
  196. package/dist/ui/variants/var_choice.ts +0 -15
  197. package/dist/ui/variants/var_framed.ts +0 -10
  198. package/dist/ui/variants/var_glyph-plain.ts +0 -11
  199. package/dist/ui/variants/var_input.ts +0 -43
  200. package/dist/ui/variants/var_link-inline.ts +0 -29
  201. package/dist/ui/variants/var_list-row.ts +0 -34
  202. package/dist/ui/variants/var_rule.ts +0 -10
  203. package/dist/ui/variants/var_skeleton-block.ts +0 -12
  204. package/dist/ui/variants/var_spinner-turning.ts +0 -12
  205. package/dist/ui/variants/var_stat-tile.ts +0 -13
  206. package/dist/ui/variants/var_tab-bar.ts +0 -15
  207. package/dist/ui/variants/var_tap-target.ts +0 -25
  208. package/dist/ui/variants.ts +0 -64
  209. package/dist/ui/wrappers.tsx +0 -429
@@ -1,315 +0,0 @@
1
-
2
-
3
- export interface Money {
4
- readonly amount: number
5
-
6
- readonly currency: string
7
- }
8
-
9
- export type Node =
10
- | { readonly kind: 'text'; readonly value: string }
11
- | { readonly kind: 'arg'; readonly name: string }
12
- | { readonly kind: 'number'; readonly name: string; readonly style?: string }
13
- | { readonly kind: 'date'; readonly name: string; readonly style?: string }
14
- | { readonly kind: 'time'; readonly name: string; readonly style?: string }
15
- | { readonly kind: 'money'; readonly name: string }
16
- | {
17
- readonly kind: 'plural'
18
- readonly name: string
19
- readonly ordinal: boolean
20
- readonly offset: number
21
- readonly options: ReadonlyMap<string, readonly Node[]>
22
- }
23
- | {
24
- readonly kind: 'select'
25
- readonly name: string
26
- readonly options: ReadonlyMap<string, readonly Node[]>
27
- }
28
-
29
- | { readonly kind: 'pound' }
30
-
31
- export class MessageSyntaxError extends Error {
32
- readonly source: string
33
- readonly position: number
34
-
35
- constructor(message: string, source: string, position: number) {
36
- super(`${message} (at ${position} in ${JSON.stringify(source)})`)
37
- this.name = 'MessageSyntaxError'
38
- this.source = source
39
- this.position = position
40
- }
41
- }
42
-
43
- const ARG_TYPES = new Set(['number', 'date', 'time', 'money', 'plural', 'selectordinal', 'select'])
44
-
45
- class Parser {
46
- readonly #src: string
47
- #pos = 0
48
-
49
- constructor(src: string) {
50
- this.#src = src
51
- }
52
-
53
- parse(): readonly Node[] {
54
- const nodes = this.#parseBody(false)
55
- if (this.#pos < this.#src.length) {
56
- throw new MessageSyntaxError('unexpected "}"', this.#src, this.#pos)
57
- }
58
- return nodes
59
- }
60
-
61
- #parseBody(inSub: boolean): readonly Node[] {
62
- const nodes: Node[] = []
63
- let text = ''
64
-
65
- const flush = (): void => {
66
- if (text !== '') {
67
- nodes.push({ kind: 'text', value: text })
68
- text = ''
69
- }
70
- }
71
-
72
- while (this.#pos < this.#src.length) {
73
- const ch = this.#src[this.#pos]
74
-
75
- if (ch === "'") {
76
-
77
- const next = this.#src[this.#pos + 1]
78
- if (next === "'") {
79
- text += "'"
80
- this.#pos += 2
81
- continue
82
- }
83
- if (next === '{' || next === '}' || next === '#') {
84
- this.#pos += 1
85
- while (this.#pos < this.#src.length) {
86
- if (this.#src[this.#pos] === "'") {
87
- if (this.#src[this.#pos + 1] === "'") {
88
- text += "'"
89
- this.#pos += 2
90
- continue
91
- }
92
- this.#pos += 1
93
- break
94
- }
95
- text += this.#src[this.#pos]
96
- this.#pos += 1
97
- }
98
- continue
99
- }
100
-
101
- text += "'"
102
- this.#pos += 1
103
- continue
104
- }
105
-
106
- if (ch === '#' && inSub) {
107
- flush()
108
- nodes.push({ kind: 'pound' })
109
- this.#pos += 1
110
- continue
111
- }
112
-
113
- if (ch === '}') {
114
- if (inSub) break
115
- throw new MessageSyntaxError('unexpected "}"', this.#src, this.#pos)
116
- }
117
-
118
- if (ch === '{') {
119
- flush()
120
- nodes.push(this.#parseArg())
121
- continue
122
- }
123
-
124
- text += ch
125
- this.#pos += 1
126
- }
127
-
128
- flush()
129
- return nodes
130
- }
131
-
132
- #parseArg(): Node {
133
- const start = this.#pos
134
- this.#pos += 1
135
- this.#skipWs()
136
-
137
- const name = this.#readIdent()
138
- if (name === '') throw new MessageSyntaxError('expected an argument name', this.#src, start)
139
-
140
- this.#skipWs()
141
-
142
- if (this.#peek() === '}') {
143
- this.#pos += 1
144
- return { kind: 'arg', name }
145
- }
146
-
147
- if (this.#peek() !== ',') {
148
- throw new MessageSyntaxError(`expected "," or "}" after "${name}"`, this.#src, this.#pos)
149
- }
150
- this.#pos += 1
151
- this.#skipWs()
152
-
153
- const type = this.#readIdent()
154
- if (!ARG_TYPES.has(type)) {
155
- throw new MessageSyntaxError(`unknown argument type "${type}"`, this.#src, this.#pos)
156
- }
157
- this.#skipWs()
158
-
159
- if (type === 'plural' || type === 'selectordinal') {
160
- return this.#parsePlural(name, type === 'selectordinal')
161
- }
162
- if (type === 'select') {
163
- return this.#parseSelect(name)
164
- }
165
-
166
- let style: string | undefined
167
- if (this.#peek() === ',') {
168
- this.#pos += 1
169
- this.#skipWs()
170
- style = this.#readUntil('}').trim()
171
- }
172
- this.#expect('}')
173
-
174
- if (type === 'money') {
175
- if (style !== undefined && style !== '') {
176
- throw new MessageSyntaxError('money takes no style — the currency travels with the value', this.#src, this.#pos)
177
- }
178
- return { kind: 'money', name }
179
- }
180
- if (type === 'number') return style ? { kind: 'number', name, style } : { kind: 'number', name }
181
- if (type === 'date') return style ? { kind: 'date', name, style } : { kind: 'date', name }
182
- return style ? { kind: 'time', name, style } : { kind: 'time', name }
183
- }
184
-
185
- #parsePlural(name: string, ordinal: boolean): Node {
186
- if (this.#peek() !== ',') {
187
- throw new MessageSyntaxError('expected "," before plural options', this.#src, this.#pos)
188
- }
189
- this.#pos += 1
190
- this.#skipWs()
191
-
192
- let offset = 0
193
- if (this.#src.startsWith('offset:', this.#pos)) {
194
- this.#pos += 'offset:'.length
195
- this.#skipWs()
196
- const digits = this.#readWhile((c) => c >= '0' && c <= '9')
197
- if (digits === '') throw new MessageSyntaxError('expected a number after "offset:"', this.#src, this.#pos)
198
- offset = Number(digits)
199
- this.#skipWs()
200
- }
201
-
202
- const options = this.#parseOptions()
203
- if (!options.has('other')) {
204
-
205
- throw new MessageSyntaxError(`plural "${name}" is missing the required "other" branch`, this.#src, this.#pos)
206
- }
207
- return { kind: 'plural', name, ordinal, offset, options }
208
- }
209
-
210
- #parseSelect(name: string): Node {
211
- if (this.#peek() !== ',') {
212
- throw new MessageSyntaxError('expected "," before select options', this.#src, this.#pos)
213
- }
214
- this.#pos += 1
215
- this.#skipWs()
216
-
217
- const options = this.#parseOptions()
218
- if (!options.has('other')) {
219
- throw new MessageSyntaxError(`select "${name}" is missing the required "other" branch`, this.#src, this.#pos)
220
- }
221
- return { kind: 'select', name, options }
222
- }
223
-
224
- #parseOptions(): ReadonlyMap<string, readonly Node[]> {
225
- const options = new Map<string, readonly Node[]>()
226
-
227
- while (this.#pos < this.#src.length && this.#peek() !== '}') {
228
- this.#skipWs()
229
- if (this.#peek() === '}') break
230
-
231
- const key = this.#readWhile((c) => !/\s/.test(c) && c !== '{')
232
- if (key === '') throw new MessageSyntaxError('expected an option key', this.#src, this.#pos)
233
- if (options.has(key)) {
234
- throw new MessageSyntaxError(`duplicate option "${key}"`, this.#src, this.#pos)
235
- }
236
-
237
- this.#skipWs()
238
- this.#expect('{')
239
- options.set(key, this.#parseBody(true))
240
- this.#expect('}')
241
- this.#skipWs()
242
- }
243
-
244
- this.#expect('}')
245
- return options
246
- }
247
-
248
- #peek(): string | undefined {
249
- return this.#src[this.#pos]
250
- }
251
-
252
- #expect(ch: string): void {
253
- if (this.#src[this.#pos] !== ch) {
254
- throw new MessageSyntaxError(`expected "${ch}"`, this.#src, this.#pos)
255
- }
256
- this.#pos += 1
257
- }
258
-
259
- #skipWs(): void {
260
- while (this.#pos < this.#src.length && /\s/.test(this.#src[this.#pos] ?? '')) this.#pos += 1
261
- }
262
-
263
- #readWhile(pred: (c: string) => boolean): string {
264
- let out = ''
265
- while (this.#pos < this.#src.length) {
266
- const c = this.#src[this.#pos]
267
- if (c === undefined || !pred(c)) break
268
- out += c
269
- this.#pos += 1
270
- }
271
- return out
272
- }
273
-
274
- #readIdent(): string {
275
- return this.#readWhile((c) => /[A-Za-z0-9_]/.test(c))
276
- }
277
-
278
- #readUntil(stop: string): string {
279
- return this.#readWhile((c) => c !== stop)
280
- }
281
- }
282
-
283
- const cache = new Map<string, readonly Node[]>()
284
-
285
- export function parseMessage(src: string): readonly Node[] {
286
- const hit = cache.get(src)
287
- if (hit) return hit
288
- const parsed = new Parser(src).parse()
289
- cache.set(src, parsed)
290
- return parsed
291
- }
292
-
293
- export function messageArgs(src: string): ReadonlySet<string> {
294
- const names = new Set<string>()
295
-
296
- const pass = (nodes: readonly Node[]): void => {
297
- for (const node of nodes) {
298
- switch (node.kind) {
299
- case 'text':
300
- case 'pound':
301
- break
302
- case 'plural':
303
- case 'select':
304
- names.add(node.name)
305
- for (const body of node.options.values()) pass(body)
306
- break
307
- default:
308
- names.add(node.name)
309
- }
310
- }
311
- }
312
-
313
- pass(parseMessage(src))
314
- return names
315
- }
@@ -1,31 +0,0 @@
1
- import { formatMessage } from './format.ts'
2
- import { type CatalogShape, type Locale, type Translator, entryText } from './types.ts'
3
-
4
- export class UnknownMessageKeyError extends Error {
5
- readonly key: string
6
- constructor(key: string, locale: Locale) {
7
- super(`no message "${key}" in locale "${locale}"`)
8
- this.name = 'UnknownMessageKeyError'
9
- this.key = key
10
- }
11
- }
12
-
13
- export interface TranslatorOptions {
14
- readonly locale: Locale
15
- readonly timeZone?: string
16
- }
17
-
18
- export function createTranslator<C extends CatalogShape>(
19
- catalog: C,
20
- options: TranslatorOptions,
21
- ): Translator<C> {
22
- const translate = (key: string, params?: Readonly<Record<string, unknown>>): string => {
23
- const entry = catalog[key]
24
- if (entry === undefined) throw new UnknownMessageKeyError(key, options.locale)
25
- return formatMessage(entryText(entry), params ?? {}, {
26
- locale: options.locale,
27
- timeZone: options.timeZone,
28
- })
29
- }
30
- return translate as Translator<C>
31
- }
@@ -1,96 +0,0 @@
1
-
2
-
3
- import type { Money } from './parse.ts'
4
-
5
- export type { Money } from './parse.ts'
6
-
7
- export type Locale = string
8
-
9
- type Trim<S extends string> = S extends ` ${infer R}`
10
- ? Trim<R>
11
- : S extends `${infer R} `
12
- ? Trim<R>
13
- : S
14
-
15
- type HasSubMessages<S extends string> = S extends `${string},plural${string}`
16
- ? true
17
- : S extends `${string}, plural${string}`
18
- ? true
19
- : S extends `${string},select${string}`
20
- ? true
21
- : S extends `${string}, select${string}`
22
- ? true
23
- : false
24
-
25
- type ArgName<Inner extends string> = Inner extends `${infer N},${string}` ? Trim<N> : Trim<Inner>
26
-
27
- type ArgValue<Inner extends string> = Inner extends `${string},${infer Rest}`
28
- ? Trim<Rest> extends `number${string}`
29
- ? number
30
- : Trim<Rest> extends `date${string}`
31
- ? Date | number
32
- : Trim<Rest> extends `time${string}`
33
- ? Date | number
34
- : Trim<Rest> extends `money${string}`
35
- ? Money
36
- : string | number
37
- : string | number
38
-
39
- type SimpleParams<S extends string> = S extends `${string}{${infer Inner}}${infer Rest}`
40
- ? { [K in ArgName<Inner>]: ArgValue<Inner> } & SimpleParams<Rest>
41
- : unknown
42
-
43
- type Prettify<T> = { [K in keyof T]: T[K] } & {}
44
-
45
- export type MessageParams<S extends string> = Prettify<SimpleParams<S>>
46
-
47
- declare const PARAMS: unique symbol
48
-
49
- export interface DeclaredMessage<P extends Record<string, unknown>> {
50
- readonly text: string
51
- readonly [PARAMS]?: P
52
- }
53
-
54
- export function msg<P extends Record<string, unknown>>(text: string): DeclaredMessage<P> {
55
- return { text }
56
- }
57
-
58
- export type MessageEntry = string | DeclaredMessage<Record<string, unknown>>
59
-
60
- export interface RequiresExplicitParams {
61
- readonly __error: 'plural/select messages must declare params: use msg<{ ... }>(text)'
62
- }
63
-
64
- export type ValidEntry<E> = E extends string
65
- ? HasSubMessages<E> extends true
66
- ? RequiresExplicitParams
67
- : E
68
- : E
69
-
70
- export type CatalogShape = Readonly<Record<string, MessageEntry>>
71
-
72
- export type ParamsOf<E> =
73
- E extends DeclaredMessage<infer P>
74
- ? P
75
- : E extends string
76
- ? MessageParams<E>
77
- : never
78
-
79
- type HasNoKeys<T> = [keyof T] extends [never] ? true : false
80
-
81
- export type Translator<C extends CatalogShape> = <K extends keyof C & string>(
82
- key: K,
83
- ...args: HasNoKeys<ParamsOf<C[K]>> extends true
84
- ? [params?: Record<string, never>]
85
- : [params: ParamsOf<C[K]>]
86
- ) => string
87
-
88
- export function entryText(entry: MessageEntry): string {
89
- return typeof entry === 'string' ? entry : entry.text
90
- }
91
-
92
- export function defineCatalog<const C extends Record<string, MessageEntry>>(catalog: {
93
- [K in keyof C]: ValidEntry<C[K]>
94
- }): C {
95
- return catalog as unknown as C
96
- }