@godxjp/ui 23.2.1 → 23.4.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/app/timezones.js +2 -1
- package/dist/components/charts/chart-cartesian.js +2 -4
- package/dist/components/charts/chart-frame.js +2 -1
- package/dist/components/data-display/card.d.ts +87 -1
- package/dist/components/data-display/card.js +88 -15
- package/dist/components/data-display/index.d.ts +5 -1
- package/dist/components/data-display/index.js +5 -0
- package/dist/components/data-display/thought-chain.d.ts +42 -0
- package/dist/components/data-display/thought-chain.js +177 -0
- package/dist/components/data-display/welcome.d.ts +26 -0
- package/dist/components/data-display/welcome.js +37 -0
- package/dist/components/data-entry/attachments.d.ts +19 -0
- package/dist/components/data-entry/attachments.js +322 -0
- package/dist/components/data-entry/date-picker.js +12 -14
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/number-input.js +2 -1
- package/dist/components/feedback/dialog.d.ts +10 -7
- package/dist/components/feedback/dialog.js +40 -17
- package/dist/components/feedback/index.d.ts +3 -3
- package/dist/components/feedback/index.js +2 -0
- package/dist/components/feedback/skeleton.d.ts +11 -2
- package/dist/components/feedback/skeleton.js +8 -0
- package/dist/components/general/actions.d.ts +59 -0
- package/dist/components/general/actions.js +253 -0
- package/dist/components/general/activity.js +1 -0
- package/dist/components/general/button.js +2 -1
- package/dist/components/general/float-button.d.ts +41 -0
- package/dist/components/general/float-button.js +336 -0
- package/dist/components/general/index.d.ts +6 -2
- package/dist/components/general/index.js +12 -1
- package/dist/components/general/typography.d.ts +79 -4
- package/dist/components/general/typography.js +598 -54
- package/dist/components/layout/draggable-panel.d.ts +18 -0
- package/dist/components/layout/draggable-panel.js +189 -0
- package/dist/components/layout/error-surface.js +3 -2
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/navigation/conversations.d.ts +39 -0
- package/dist/components/navigation/conversations.js +371 -0
- package/dist/components/navigation/index.d.ts +2 -0
- package/dist/components/navigation/index.js +2 -0
- package/dist/components/ui/card.js +1 -0
- package/dist/components/ui/toggle.js +2 -1
- package/dist/i18n/messages/en.json +53 -0
- package/dist/i18n/messages/ja.json +53 -0
- package/dist/i18n/messages/vi.json +53 -0
- package/dist/i18n/translate.js +3 -2
- package/dist/lib/datetime/picker-format.js +2 -1
- package/dist/lib/format.js +3 -2
- package/dist/lib/intl-cache.d.ts +32 -0
- package/dist/lib/intl-cache.js +29 -0
- package/dist/props/components/data-display.prop.d.ts +143 -1
- package/dist/props/components/data-entry.prop.d.ts +87 -0
- package/dist/props/components/feedback.prop.d.ts +53 -1
- package/dist/props/components/general.prop.d.ts +440 -3
- package/dist/props/components/index.d.ts +2 -2
- package/dist/props/components/layout.prop.d.ts +63 -1
- package/dist/props/components/navigation.prop.d.ts +150 -0
- package/dist/props/registry.d.ts +431 -0
- package/dist/props/registry.js +551 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +113 -0
- package/dist/styles/alert-layout.css +22 -0
- package/dist/styles/card-layout.css +34 -0
- package/dist/styles/core.css +1 -0
- package/dist/styles/data-display-layout.css +236 -0
- package/dist/styles/float-button-layout.css +168 -0
- package/dist/styles/form-layout.css +11 -1
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +196 -0
- package/dist/styles/navigation-layout.css +139 -0
- package/dist/styles/text-layout.css +156 -0
- package/dist/tokens/axes.css +5 -0
- package/dist/tokens/base.css +7 -0
- package/dist/tokens/components/actions.css +14 -0
- package/dist/tokens/components/attachments.css +15 -0
- package/dist/tokens/components/conversations.css +28 -0
- package/dist/tokens/components/draggable-panel.css +25 -0
- package/dist/tokens/components/float-button.css +39 -0
- package/dist/tokens/components/text.css +13 -0
- package/dist/tokens/components/thought-chain.css +31 -0
- package/dist/tokens/components/welcome.css +19 -0
- package/dist/tokens/foundation.css +6 -4
- package/docs/DESIGN-AUTHORITY.md +133 -20
- package/docs/FRAME-COVERAGE-REPORT.md +5 -2
- package/docs/data-display/card/examples/tab-list.tsx +97 -0
- package/docs/data-display/thought-chain.tsx +176 -0
- package/docs/data-display/welcome.tsx +115 -0
- package/docs/data-entry/attachments.tsx +160 -0
- package/docs/feedback/dialog.tsx +50 -0
- package/docs/general/actions.tsx +175 -0
- package/docs/general/float-button.tsx +133 -0
- package/docs/general/typography.tsx +63 -1
- package/docs/layout/draggable-panel.tsx +127 -0
- package/docs/navigation/conversations.tsx +176 -0
- package/docs/roadmap/parity-audit-layout-navigation-general.md +17 -16
- package/package.json +20 -4
- package/scripts/_agent-setup.mjs +36 -5
- package/scripts/guinea-pig-skill.md +14 -0
- package/scripts/ui-audit.mjs +69 -9
|
@@ -29,9 +29,11 @@ import {
|
|
|
29
29
|
DropdownMenuSubTrigger,
|
|
30
30
|
DropdownMenuTrigger
|
|
31
31
|
} from "./dropdown-menu.js";
|
|
32
|
+
import { Conversations } from "./conversations.js";
|
|
32
33
|
export {
|
|
33
34
|
AppSettingPicker,
|
|
34
35
|
AppSettingToggle,
|
|
36
|
+
Conversations,
|
|
35
37
|
DropdownMenu,
|
|
36
38
|
DropdownMenuCheckboxItem,
|
|
37
39
|
DropdownMenuContent,
|
|
@@ -5,6 +5,7 @@ import { ToggleButton } from "react-aria-components";
|
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
7
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
8
|
+
import { numberFormat } from "../../lib/intl-cache.js";
|
|
8
9
|
const toggleVariants = cva("ui-toggle", {
|
|
9
10
|
variants: {
|
|
10
11
|
variant: {
|
|
@@ -33,7 +34,7 @@ function useCounterPill({
|
|
|
33
34
|
const visible = count != null && (count !== 0 || showZero);
|
|
34
35
|
const formatted = React.useMemo(() => {
|
|
35
36
|
if (count == null) return "";
|
|
36
|
-
const format =
|
|
37
|
+
const format = numberFormat(locale);
|
|
37
38
|
return count > overflowCount ? `${format.format(overflowCount)}+` : format.format(count);
|
|
38
39
|
}, [count, locale, overflowCount]);
|
|
39
40
|
if (!visible) {
|
|
@@ -178,6 +178,16 @@
|
|
|
178
178
|
"one": "{count} suggestion",
|
|
179
179
|
"other": "{count} suggestions"
|
|
180
180
|
}
|
|
181
|
+
},
|
|
182
|
+
"attachments": {
|
|
183
|
+
"placeholderTitle": "Upload files",
|
|
184
|
+
"placeholderDescription": "Click or drag files here",
|
|
185
|
+
"dropLabel": "Drop files ({type})",
|
|
186
|
+
"inputLabel": "Choose attachment files",
|
|
187
|
+
"add": "Add attachment",
|
|
188
|
+
"remove": "Remove {name}",
|
|
189
|
+
"uploading": "Uploading attachment",
|
|
190
|
+
"error": "Upload failed"
|
|
181
191
|
}
|
|
182
192
|
},
|
|
183
193
|
"feedback": {
|
|
@@ -263,6 +273,9 @@
|
|
|
263
273
|
"hintMove": "Move",
|
|
264
274
|
"hintSelect": "Select",
|
|
265
275
|
"hintClose": "Close"
|
|
276
|
+
},
|
|
277
|
+
"draggablePanel": {
|
|
278
|
+
"moveLabel": "Move panel. Use the arrow keys to move it, or hold Shift for larger steps."
|
|
266
279
|
}
|
|
267
280
|
},
|
|
268
281
|
"dataDisplay": {
|
|
@@ -317,6 +330,15 @@
|
|
|
317
330
|
"loading": "Loading child nodes…",
|
|
318
331
|
"empty": "Nothing to show",
|
|
319
332
|
"selected": "Selected"
|
|
333
|
+
},
|
|
334
|
+
"thoughtChain": {
|
|
335
|
+
"label": "Reasoning steps",
|
|
336
|
+
"status": {
|
|
337
|
+
"loading": "in progress",
|
|
338
|
+
"success": "done",
|
|
339
|
+
"error": "failed",
|
|
340
|
+
"abort": "stopped"
|
|
341
|
+
}
|
|
320
342
|
}
|
|
321
343
|
},
|
|
322
344
|
"ui": {
|
|
@@ -344,11 +366,22 @@
|
|
|
344
366
|
"download": "Download secret",
|
|
345
367
|
"acknowledge": "I've saved it"
|
|
346
368
|
},
|
|
369
|
+
"floatButton": {
|
|
370
|
+
"backTop": "Back to top",
|
|
371
|
+
"actions": "Actions"
|
|
372
|
+
},
|
|
347
373
|
"numberInput": {
|
|
348
374
|
"increment": "Increase",
|
|
349
375
|
"decrement": "Decrease",
|
|
350
376
|
"incrementField": "Increase {label}",
|
|
351
377
|
"decrementField": "Decrease {label}"
|
|
378
|
+
},
|
|
379
|
+
"typography": {
|
|
380
|
+
"copy": "Copy",
|
|
381
|
+
"copied": "Copied",
|
|
382
|
+
"edit": "Edit",
|
|
383
|
+
"expand": "Expand",
|
|
384
|
+
"collapse": "Collapse"
|
|
352
385
|
}
|
|
353
386
|
},
|
|
354
387
|
"navigation": {
|
|
@@ -437,6 +470,11 @@
|
|
|
437
470
|
},
|
|
438
471
|
"settingToggle": {
|
|
439
472
|
"label": "{setting}: {value}"
|
|
473
|
+
},
|
|
474
|
+
"conversations": {
|
|
475
|
+
"label": "Conversations",
|
|
476
|
+
"creation": "New conversation",
|
|
477
|
+
"rowActions": "More actions for {label}"
|
|
440
478
|
}
|
|
441
479
|
},
|
|
442
480
|
"locale": {
|
|
@@ -591,5 +629,20 @@
|
|
|
591
629
|
"other": "{count} new messages"
|
|
592
630
|
}
|
|
593
631
|
}
|
|
632
|
+
},
|
|
633
|
+
"general": {
|
|
634
|
+
"actions": {
|
|
635
|
+
"label": "Message actions",
|
|
636
|
+
"copy": "Copy",
|
|
637
|
+
"copied": "Copied",
|
|
638
|
+
"feedback": "Was this answer helpful?",
|
|
639
|
+
"like": "Helpful",
|
|
640
|
+
"dislike": "Not helpful",
|
|
641
|
+
"status": {
|
|
642
|
+
"running": "running",
|
|
643
|
+
"loading": "loading",
|
|
644
|
+
"error": "failed"
|
|
645
|
+
}
|
|
646
|
+
}
|
|
594
647
|
}
|
|
595
648
|
}
|
|
@@ -174,6 +174,16 @@
|
|
|
174
174
|
"count": {
|
|
175
175
|
"other": "候補 {count} 件"
|
|
176
176
|
}
|
|
177
|
+
},
|
|
178
|
+
"attachments": {
|
|
179
|
+
"placeholderTitle": "ファイルをアップロード",
|
|
180
|
+
"placeholderDescription": "クリックまたはドラッグしてファイルを追加",
|
|
181
|
+
"dropLabel": "ファイルをドロップ ({type})",
|
|
182
|
+
"inputLabel": "添付ファイルを選択",
|
|
183
|
+
"add": "添付を追加",
|
|
184
|
+
"remove": "{name} を削除",
|
|
185
|
+
"uploading": "添付をアップロード中",
|
|
186
|
+
"error": "アップロードに失敗しました"
|
|
177
187
|
}
|
|
178
188
|
},
|
|
179
189
|
"feedback": {
|
|
@@ -256,6 +266,9 @@
|
|
|
256
266
|
"hintMove": "移動",
|
|
257
267
|
"hintSelect": "選択",
|
|
258
268
|
"hintClose": "閉じる"
|
|
269
|
+
},
|
|
270
|
+
"draggablePanel": {
|
|
271
|
+
"moveLabel": "パネルを移動。矢印キーで移動、Shift キーを押しながらで大きく移動します。"
|
|
259
272
|
}
|
|
260
273
|
},
|
|
261
274
|
"dataDisplay": {
|
|
@@ -310,6 +323,15 @@
|
|
|
310
323
|
"loading": "子ノードを読み込み中…",
|
|
311
324
|
"empty": "表示する項目がありません",
|
|
312
325
|
"selected": "選択中"
|
|
326
|
+
},
|
|
327
|
+
"thoughtChain": {
|
|
328
|
+
"label": "思考の手順",
|
|
329
|
+
"status": {
|
|
330
|
+
"loading": "実行中",
|
|
331
|
+
"success": "完了",
|
|
332
|
+
"error": "失敗",
|
|
333
|
+
"abort": "中断"
|
|
334
|
+
}
|
|
313
335
|
}
|
|
314
336
|
},
|
|
315
337
|
"ui": {
|
|
@@ -337,11 +359,22 @@
|
|
|
337
359
|
"download": "シークレットをダウンロード",
|
|
338
360
|
"acknowledge": "保存しました"
|
|
339
361
|
},
|
|
362
|
+
"floatButton": {
|
|
363
|
+
"backTop": "トップへ戻る",
|
|
364
|
+
"actions": "アクション"
|
|
365
|
+
},
|
|
340
366
|
"numberInput": {
|
|
341
367
|
"increment": "増やす",
|
|
342
368
|
"decrement": "減らす",
|
|
343
369
|
"incrementField": "{label}を増やす",
|
|
344
370
|
"decrementField": "{label}を減らす"
|
|
371
|
+
},
|
|
372
|
+
"typography": {
|
|
373
|
+
"copy": "コピー",
|
|
374
|
+
"copied": "コピーしました",
|
|
375
|
+
"edit": "編集",
|
|
376
|
+
"expand": "展開",
|
|
377
|
+
"collapse": "折りたたむ"
|
|
345
378
|
}
|
|
346
379
|
},
|
|
347
380
|
"navigation": {
|
|
@@ -424,6 +457,11 @@
|
|
|
424
457
|
},
|
|
425
458
|
"settingToggle": {
|
|
426
459
|
"label": "{setting}:{value}"
|
|
460
|
+
},
|
|
461
|
+
"conversations": {
|
|
462
|
+
"label": "会話一覧",
|
|
463
|
+
"creation": "新しい会話",
|
|
464
|
+
"rowActions": "「{label}」のその他の操作"
|
|
427
465
|
}
|
|
428
466
|
},
|
|
429
467
|
"locale": {
|
|
@@ -577,5 +615,20 @@
|
|
|
577
615
|
"other": "新着 {count} 件"
|
|
578
616
|
}
|
|
579
617
|
}
|
|
618
|
+
},
|
|
619
|
+
"general": {
|
|
620
|
+
"actions": {
|
|
621
|
+
"label": "メッセージの操作",
|
|
622
|
+
"copy": "コピー",
|
|
623
|
+
"copied": "コピーしました",
|
|
624
|
+
"feedback": "この回答は役に立ちましたか",
|
|
625
|
+
"like": "役に立った",
|
|
626
|
+
"dislike": "役に立たなかった",
|
|
627
|
+
"status": {
|
|
628
|
+
"running": "実行中",
|
|
629
|
+
"loading": "読み込み中",
|
|
630
|
+
"error": "失敗"
|
|
631
|
+
}
|
|
632
|
+
}
|
|
580
633
|
}
|
|
581
634
|
}
|
|
@@ -175,6 +175,16 @@
|
|
|
175
175
|
"one": "{count} gợi ý",
|
|
176
176
|
"other": "{count} gợi ý"
|
|
177
177
|
}
|
|
178
|
+
},
|
|
179
|
+
"attachments": {
|
|
180
|
+
"placeholderTitle": "Tải tệp lên",
|
|
181
|
+
"placeholderDescription": "Nhấp hoặc kéo thả tệp vào đây",
|
|
182
|
+
"dropLabel": "Thả tệp ({type})",
|
|
183
|
+
"inputLabel": "Chọn tệp đính kèm",
|
|
184
|
+
"add": "Thêm tệp đính kèm",
|
|
185
|
+
"remove": "Xóa {name}",
|
|
186
|
+
"uploading": "Đang tải tệp đính kèm",
|
|
187
|
+
"error": "Tải lên thất bại"
|
|
178
188
|
}
|
|
179
189
|
},
|
|
180
190
|
"feedback": {
|
|
@@ -257,6 +267,9 @@
|
|
|
257
267
|
"hintMove": "Di chuyển",
|
|
258
268
|
"hintSelect": "Chọn",
|
|
259
269
|
"hintClose": "Đóng"
|
|
270
|
+
},
|
|
271
|
+
"draggablePanel": {
|
|
272
|
+
"moveLabel": "Di chuyển bảng. Dùng phím mũi tên để dời, giữ Shift để bước dài hơn."
|
|
260
273
|
}
|
|
261
274
|
},
|
|
262
275
|
"dataDisplay": {
|
|
@@ -311,6 +324,15 @@
|
|
|
311
324
|
"loading": "Đang tải nút con…",
|
|
312
325
|
"empty": "Không có gì để hiển thị",
|
|
313
326
|
"selected": "Đã chọn"
|
|
327
|
+
},
|
|
328
|
+
"thoughtChain": {
|
|
329
|
+
"label": "Các bước suy luận",
|
|
330
|
+
"status": {
|
|
331
|
+
"loading": "đang chạy",
|
|
332
|
+
"success": "xong",
|
|
333
|
+
"error": "thất bại",
|
|
334
|
+
"abort": "đã dừng"
|
|
335
|
+
}
|
|
314
336
|
}
|
|
315
337
|
},
|
|
316
338
|
"ui": {
|
|
@@ -338,11 +360,22 @@
|
|
|
338
360
|
"download": "Tải khóa bí mật",
|
|
339
361
|
"acknowledge": "Tôi đã lưu"
|
|
340
362
|
},
|
|
363
|
+
"floatButton": {
|
|
364
|
+
"backTop": "Về đầu trang",
|
|
365
|
+
"actions": "Hành động"
|
|
366
|
+
},
|
|
341
367
|
"numberInput": {
|
|
342
368
|
"increment": "Tăng",
|
|
343
369
|
"decrement": "Giảm",
|
|
344
370
|
"incrementField": "Tăng {label}",
|
|
345
371
|
"decrementField": "Giảm {label}"
|
|
372
|
+
},
|
|
373
|
+
"typography": {
|
|
374
|
+
"copy": "Sao chép",
|
|
375
|
+
"copied": "Đã sao chép",
|
|
376
|
+
"edit": "Sửa",
|
|
377
|
+
"expand": "Mở rộng",
|
|
378
|
+
"collapse": "Thu gọn"
|
|
346
379
|
}
|
|
347
380
|
},
|
|
348
381
|
"navigation": {
|
|
@@ -425,6 +458,11 @@
|
|
|
425
458
|
},
|
|
426
459
|
"settingToggle": {
|
|
427
460
|
"label": "{setting}: {value}"
|
|
461
|
+
},
|
|
462
|
+
"conversations": {
|
|
463
|
+
"label": "Danh sách hội thoại",
|
|
464
|
+
"creation": "Hội thoại mới",
|
|
465
|
+
"rowActions": "Thao tác khác cho {label}"
|
|
428
466
|
}
|
|
429
467
|
},
|
|
430
468
|
"locale": {
|
|
@@ -578,5 +616,20 @@
|
|
|
578
616
|
"other": "{count} tin nhắn mới"
|
|
579
617
|
}
|
|
580
618
|
}
|
|
619
|
+
},
|
|
620
|
+
"general": {
|
|
621
|
+
"actions": {
|
|
622
|
+
"label": "Thao tác với tin nhắn",
|
|
623
|
+
"copy": "Sao chép",
|
|
624
|
+
"copied": "Đã sao chép",
|
|
625
|
+
"feedback": "Câu trả lời này có hữu ích không",
|
|
626
|
+
"like": "Hữu ích",
|
|
627
|
+
"dislike": "Không hữu ích",
|
|
628
|
+
"status": {
|
|
629
|
+
"running": "đang chạy",
|
|
630
|
+
"loading": "đang tải",
|
|
631
|
+
"error": "thất bại"
|
|
632
|
+
}
|
|
633
|
+
}
|
|
581
634
|
}
|
|
582
635
|
}
|
package/dist/i18n/translate.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import en from "./messages/en.json" with { type: "json" };
|
|
2
2
|
import ja from "./messages/ja.json" with { type: "json" };
|
|
3
3
|
import vi from "./messages/vi.json" with { type: "json" };
|
|
4
|
+
import { numberFormat, pluralRules } from "../lib/intl-cache.js";
|
|
4
5
|
const MESSAGE_CATALOG = {
|
|
5
6
|
vi,
|
|
6
7
|
en,
|
|
@@ -56,7 +57,7 @@ function selectPlural(value, locale, params) {
|
|
|
56
57
|
if (count === void 0) {
|
|
57
58
|
return value.other ?? Object.values(value)[0] ?? "";
|
|
58
59
|
}
|
|
59
|
-
const category =
|
|
60
|
+
const category = pluralRules(locale).select(count);
|
|
60
61
|
return value[category] ?? value.other ?? Object.values(value)[0] ?? "";
|
|
61
62
|
}
|
|
62
63
|
function interpolate(template, locale, params) {
|
|
@@ -64,7 +65,7 @@ function interpolate(template, locale, params) {
|
|
|
64
65
|
return Object.entries(params).reduce(
|
|
65
66
|
(text, [key, value]) => text.replaceAll(
|
|
66
67
|
`{${key}}`,
|
|
67
|
-
typeof value === "number" ?
|
|
68
|
+
typeof value === "number" ? numberFormat(locale).format(value) : String(value)
|
|
68
69
|
),
|
|
69
70
|
template
|
|
70
71
|
);
|
|
@@ -9,10 +9,11 @@ import {
|
|
|
9
9
|
startOfYear
|
|
10
10
|
} from "date-fns";
|
|
11
11
|
import { parseDateInput, toIsoDate } from "./parse.js";
|
|
12
|
+
import { dateTimeFormat } from "../intl-cache.js";
|
|
12
13
|
function formatPickerDate(date, format, locale, withTime = false) {
|
|
13
14
|
if (!date || !isValid(date)) return "";
|
|
14
15
|
if (typeof format === "function") return format(date);
|
|
15
|
-
if (typeof format === "object") return
|
|
16
|
+
if (typeof format === "object") return dateTimeFormat(locale, format).format(date);
|
|
16
17
|
if (typeof format === "string") return formatDate(date, format);
|
|
17
18
|
return withTime ? formatDate(date, "yyyy-MM-dd HH:mm") : toIsoDate(date);
|
|
18
19
|
}
|
package/dist/lib/format.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getSyncedLocale, translateCurrent } from "../i18n/translate.js";
|
|
2
|
+
import { numberFormat } from "./intl-cache.js";
|
|
2
3
|
function formatBytes(n, locale = getSyncedLocale()) {
|
|
3
4
|
if (n == null) return "\u2014";
|
|
4
|
-
const num = (digits, scaled) =>
|
|
5
|
+
const num = (digits, scaled) => numberFormat(locale, {
|
|
5
6
|
minimumFractionDigits: digits,
|
|
6
7
|
maximumFractionDigits: digits
|
|
7
8
|
}).format(scaled);
|
|
@@ -12,7 +13,7 @@ function formatBytes(n, locale = getSyncedLocale()) {
|
|
|
12
13
|
}
|
|
13
14
|
function formatCurrency(amountMinor, currency, locale = getSyncedLocale()) {
|
|
14
15
|
if (amountMinor == null || !currency) return "\u2014";
|
|
15
|
-
const formatter =
|
|
16
|
+
const formatter = numberFormat(locale, { style: "currency", currency });
|
|
16
17
|
const minorUnitDigits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
|
|
17
18
|
const major = amountMinor / Math.pow(10, minorUnitDigits);
|
|
18
19
|
return formatter.format(major);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memoised `Intl` formatters, keyed by locale + options.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS, AS A MEASUREMENT (gh#557). A consumer ported a legacy CakePHP grid that keeps
|
|
5
|
+
* every row in the DOM — 8,262 rows, no virtualisation available — and measured 27-30s against
|
|
6
|
+
* 2.3s for the same markup built from native `<input>` / `<select>`. They had already ruled out
|
|
7
|
+
* the obvious suspect: deleting `Popover` / `PopoverContent` from `DatePicker` entirely changed
|
|
8
|
+
* nothing.
|
|
9
|
+
*
|
|
10
|
+
* Rendered here through `react-dom/server`, 2,000 rows at a time, one CLOSED `DatePicker` costs
|
|
11
|
+
* **412.6us** against **4.2us** for `<input type="date">` — 98x. Counting constructor calls during
|
|
12
|
+
* that render, each closed instance built:
|
|
13
|
+
*
|
|
14
|
+
* 12 x new Intl.DateTimeFormat
|
|
15
|
+
* 1 x new Intl.NumberFormat
|
|
16
|
+
*
|
|
17
|
+
* Constructing an `Intl` formatter is one of the most expensive things a JS engine does: it
|
|
18
|
+
* resolves locale data and compiles a pattern. Routing those same constructions through this
|
|
19
|
+
* cache, changing nothing else, took the instance from **412.6us to 178us — a 57% cut**. For the
|
|
20
|
+
* reporter's grid that is roughly 99,000 formatter constructions that no longer happen.
|
|
21
|
+
*
|
|
22
|
+
* WHY A SHARED MODULE AND NOT A `useMemo` AT EACH CALL SITE. `useMemo` memoises per INSTANCE, and
|
|
23
|
+
* the instance is exactly what there are 8,262 of. Two rows formatting dates in the same locale
|
|
24
|
+
* want the same formatter object, and nothing below module scope can give them one.
|
|
25
|
+
*
|
|
26
|
+
* SAFETY. `Intl` formatters are immutable and stateless — `format()` mutates nothing — so a single
|
|
27
|
+
* instance is safely shared across every caller and every React tree, concurrent SSR included.
|
|
28
|
+
*/
|
|
29
|
+
export declare function dateTimeFormat(locale: string, options?: Intl.DateTimeFormatOptions): Intl.DateTimeFormat;
|
|
30
|
+
export declare function numberFormat(locale: string, options?: Intl.NumberFormatOptions): Intl.NumberFormat;
|
|
31
|
+
export declare function pluralRules(locale: string, options?: Intl.PluralRulesOptions): Intl.PluralRules;
|
|
32
|
+
export declare function listFormat(locale: string, options?: Intl.ListFormatOptions): Intl.ListFormat;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const MAX_ENTRIES = 256;
|
|
2
|
+
const cache = /* @__PURE__ */ new Map();
|
|
3
|
+
function memoise(kind, locale, options, make) {
|
|
4
|
+
const key = `${kind} ${locale} ${options === void 0 ? "" : JSON.stringify(options)}`;
|
|
5
|
+
const hit = cache.get(key);
|
|
6
|
+
if (hit !== void 0) return hit;
|
|
7
|
+
const made = make();
|
|
8
|
+
if (cache.size >= MAX_ENTRIES) cache.delete(cache.keys().next().value);
|
|
9
|
+
cache.set(key, made);
|
|
10
|
+
return made;
|
|
11
|
+
}
|
|
12
|
+
function dateTimeFormat(locale, options) {
|
|
13
|
+
return memoise("dtf", locale, options, () => new Intl.DateTimeFormat(locale, options));
|
|
14
|
+
}
|
|
15
|
+
function numberFormat(locale, options) {
|
|
16
|
+
return memoise("nf", locale, options, () => new Intl.NumberFormat(locale, options));
|
|
17
|
+
}
|
|
18
|
+
function pluralRules(locale, options) {
|
|
19
|
+
return memoise("pr", locale, options, () => new Intl.PluralRules(locale, options));
|
|
20
|
+
}
|
|
21
|
+
function listFormat(locale, options) {
|
|
22
|
+
return memoise("lf", locale, options, () => new Intl.ListFormat(locale, options));
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
dateTimeFormat,
|
|
26
|
+
listFormat,
|
|
27
|
+
numberFormat,
|
|
28
|
+
pluralRules
|
|
29
|
+
};
|
|
@@ -28,7 +28,7 @@ export type ProseProp = {
|
|
|
28
28
|
className?: ClassNameProp;
|
|
29
29
|
children?: ChildrenProp;
|
|
30
30
|
};
|
|
31
|
-
import type { ActionProp, ClassNameProp, DescriptionProp, IconProp, TitleProp, ColumnDefProp, GetRowIdProp, GetRowLabelProp, OnRowClickProp, OnSelectChangeProp, OnSortChangeProp, OnTableDensityChangeProp, SelectedIdsProp, SortStateProp, TableDensityProp, TablePresetProp, BreakpointProp, DensityProp, ChildrenProp, PendingProp, ToneProp, AvatarShapeProp, HeadingLevelProp, HandlerProp, SizeProp, LabelProp, IdProp, DescriptionsLayoutProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, SortDirectionProp, OnColumnFilterChangeProp, OnRowProp, TableExpandableProp, TableRowSelectionProp, TableScrollProp, TableStickyProp, TableSummaryProp, DisabledProp, ValueProp, DefaultValueProp, OnValueChangeProp } from "../vocabulary/index.js";
|
|
31
|
+
import type { ActionProp, ClassNameProp, DescriptionProp, IconProp, TitleProp, ColumnDefProp, GetRowIdProp, GetRowLabelProp, OnRowClickProp, OnSelectChangeProp, OnSortChangeProp, OnTableDensityChangeProp, SelectedIdsProp, SortStateProp, TableDensityProp, TablePresetProp, BreakpointProp, DensityProp, ChildrenProp, PendingProp, ToneProp, AvatarShapeProp, HeadingLevelProp, HandlerProp, SizeProp, LabelProp, IdProp, DescriptionsLayoutProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, SortDirectionProp, OnColumnFilterChangeProp, OnRowProp, TableExpandableProp, TableRowSelectionProp, TableScrollProp, TableStickyProp, TableSummaryProp, DisabledProp, OnClickProp, ValueProp, DefaultValueProp, OnValueChangeProp } from "../vocabulary/index.js";
|
|
32
32
|
import type { TreeFieldNamesProp, TreeOptionProp } from "./data-entry.prop.js";
|
|
33
33
|
/**
|
|
34
34
|
* One key in a `Legend`: a tone, and the words that tone stands for.
|
|
@@ -789,3 +789,145 @@ export type ChatBubbleListProp = {
|
|
|
789
789
|
className?: ClassNameProp;
|
|
790
790
|
id?: IdProp;
|
|
791
791
|
};
|
|
792
|
+
/**
|
|
793
|
+
* Ant Design X `Welcome variant`. `filled` gives the block its own tinted ground; `borderless`
|
|
794
|
+
* lets it sit directly on the page.
|
|
795
|
+
* @see Welcome
|
|
796
|
+
*/
|
|
797
|
+
export type WelcomeVariantProp = "filled" | "borderless";
|
|
798
|
+
/**
|
|
799
|
+
* @see Welcome — the greeting block at the head of an empty conversation (Ant Design X `Welcome`).
|
|
800
|
+
*
|
|
801
|
+
* Ant X's own slots, field for field: `icon`, `title`, `description`, `extra`, `variant`. The one
|
|
802
|
+
* behaviour worth naming is the `icon` STRING: Ant renders a `string` beginning with `http` as an
|
|
803
|
+
* `<img>` rather than as text (`es/welcome/index.js`), and that is ported — with `alt=""`, because
|
|
804
|
+
* the glyph beside a title it duplicates is decorative, where Ant hardcodes `alt="icon"`.
|
|
805
|
+
*/
|
|
806
|
+
export type WelcomeProp = {
|
|
807
|
+
/** Leading glyph, or an `http(s)` URL rendered as a decorative image. Ant Design X `icon`. */
|
|
808
|
+
icon?: React.ReactNode;
|
|
809
|
+
/** The greeting itself. Ant Design X `title`. */
|
|
810
|
+
title?: React.ReactNode;
|
|
811
|
+
/** The line under it. Ant Design X `description`. */
|
|
812
|
+
description?: React.ReactNode;
|
|
813
|
+
/** Trailing slot on the title row — a dismiss button, a model picker. Ant Design X `extra`. */
|
|
814
|
+
extra?: React.ReactNode;
|
|
815
|
+
/** Ant Design X `variant`. Default `filled`. */
|
|
816
|
+
variant?: WelcomeVariantProp;
|
|
817
|
+
id?: IdProp;
|
|
818
|
+
className?: ClassNameProp;
|
|
819
|
+
};
|
|
820
|
+
/**
|
|
821
|
+
* Ant Design X `THOUGHT_CHAIN_ITEM_STATUS` — how one step of the chain ended, or that it has not.
|
|
822
|
+
* @see ThoughtChain
|
|
823
|
+
*/
|
|
824
|
+
export type ThoughtChainStatusProp = "loading" | "success" | "error" | "abort";
|
|
825
|
+
/**
|
|
826
|
+
* Ant Design X `ThoughtChainProps.line` — the connector drawn between two steps. `true` is the
|
|
827
|
+
* default solid rule, `false` draws none, and the three strings pick its stroke.
|
|
828
|
+
*
|
|
829
|
+
* Ant's own type spells the third `'dotted'` with a trailing U+200C ZERO WIDTH NON-JOINER
|
|
830
|
+
* (`es/thought-chain/interface.d.ts`), so `line="dotted"` does not type-check against it. The
|
|
831
|
+
* clean spelling is used here; that is a typo fix, not an API change.
|
|
832
|
+
* @see ThoughtChain
|
|
833
|
+
*/
|
|
834
|
+
export type ThoughtChainLineProp = boolean | "solid" | "dashed" | "dotted";
|
|
835
|
+
/**
|
|
836
|
+
* Ant Design X `ThoughtChainItemProps.variant` — the chrome of a STANDALONE step.
|
|
837
|
+
* @see ThoughtChainItem
|
|
838
|
+
*/
|
|
839
|
+
export type ThoughtChainVariantProp = "solid" | "outlined" | "text";
|
|
840
|
+
/** @see ThoughtChain — one step. Ant Design X `ThoughtChainItemType`, field for field. */
|
|
841
|
+
export type ThoughtChainItemsProp = {
|
|
842
|
+
/** Identity, and what `expandedKeys` addresses. Ant Design X `key`. */
|
|
843
|
+
key?: string;
|
|
844
|
+
/**
|
|
845
|
+
* The step's glyph. `false` removes it entirely; omitted, the step shows its 1-based ORDINAL,
|
|
846
|
+
* which is Ant's default (`es/thought-chain/Node.js`). Ant Design X `icon`.
|
|
847
|
+
*/
|
|
848
|
+
icon?: React.ReactNode | false;
|
|
849
|
+
/** Ant Design X `title`. */
|
|
850
|
+
title?: React.ReactNode;
|
|
851
|
+
/** The line under the title, always visible. Ant Design X `description`. */
|
|
852
|
+
description?: React.ReactNode;
|
|
853
|
+
/** The body the step collapses. Ant Design X `content`. */
|
|
854
|
+
content?: React.ReactNode;
|
|
855
|
+
/** Below the body, always visible. Ant Design X `footer`. */
|
|
856
|
+
footer?: React.ReactNode;
|
|
857
|
+
/** Ant Design X `status`. */
|
|
858
|
+
status?: ThoughtChainStatusProp;
|
|
859
|
+
/** Turn the title into a disclosure for `content`. Ant Design X `collapsible`. */
|
|
860
|
+
collapsible?: boolean;
|
|
861
|
+
/** Pulse the title and body while the step is still being written. Ant Design X `blink`. */
|
|
862
|
+
blink?: boolean;
|
|
863
|
+
/** Unmount the body while collapsed. Default `true`, as in Ant. Ant Design X `destroyOnHidden`. */
|
|
864
|
+
destroyOnHidden?: boolean;
|
|
865
|
+
};
|
|
866
|
+
/**
|
|
867
|
+
* @see ThoughtChain — the assistant's reasoning, step by step (Ant Design X `ThoughtChain`).
|
|
868
|
+
*
|
|
869
|
+
* An ordered list: each step carries an ordinal or a glyph, a status, a title, and a body it can
|
|
870
|
+
* collapse. `Timeline` is the neighbour to check first — it is the same vertical rail for EVENTS
|
|
871
|
+
* that already happened; a thought chain is a run in progress, which is why a step has `loading`
|
|
872
|
+
* and `abort` states and a body that opens.
|
|
873
|
+
*/
|
|
874
|
+
export type ThoughtChainProp = {
|
|
875
|
+
/** The steps, in order. Ant Design X `items`. */
|
|
876
|
+
items?: readonly ThoughtChainItemsProp[];
|
|
877
|
+
/** Uncontrolled initially-open steps. Ant Design X `defaultExpandedKeys`. */
|
|
878
|
+
defaultExpandedKeys?: readonly string[];
|
|
879
|
+
/** Controlled open steps. Ant Design X `expandedKeys`. */
|
|
880
|
+
expandedKeys?: readonly string[];
|
|
881
|
+
/** Fires with the next open set. Ant Design X `onExpand`. */
|
|
882
|
+
onExpand?: (keys: string[]) => void;
|
|
883
|
+
/** The connector between steps. Default `true`. Ant Design X `line`. */
|
|
884
|
+
line?: ThoughtChainLineProp;
|
|
885
|
+
/**
|
|
886
|
+
* Accessible name of the chain — a plain STRING (it lands on `aria-label`). Ant X has no
|
|
887
|
+
* equivalent; a localized default applies when omitted.
|
|
888
|
+
*/
|
|
889
|
+
label?: string;
|
|
890
|
+
id?: IdProp;
|
|
891
|
+
className?: ClassNameProp;
|
|
892
|
+
};
|
|
893
|
+
/**
|
|
894
|
+
* @see ThoughtChainItem — one step OUTSIDE a chain (Ant Design X `ThoughtChain.Item`): the chip an
|
|
895
|
+
* assistant drops inline to say which tool it just reached for.
|
|
896
|
+
*
|
|
897
|
+
* Ant renders it as a `<div onClick>`; here an item with `onClick` renders a real `<button>`, so
|
|
898
|
+
* the one interactive shape this component has is reachable by keyboard.
|
|
899
|
+
*/
|
|
900
|
+
export type ThoughtChainItemProp = {
|
|
901
|
+
title?: React.ReactNode;
|
|
902
|
+
description?: React.ReactNode;
|
|
903
|
+
icon?: React.ReactNode;
|
|
904
|
+
status?: ThoughtChainStatusProp;
|
|
905
|
+
/** Ant Design X `variant`. Default `solid`. */
|
|
906
|
+
variant?: ThoughtChainVariantProp;
|
|
907
|
+
/** Ant Design X `blink`. */
|
|
908
|
+
blink?: boolean;
|
|
909
|
+
disabled?: DisabledProp;
|
|
910
|
+
onClick?: OnClickProp;
|
|
911
|
+
id?: IdProp;
|
|
912
|
+
className?: ClassNameProp;
|
|
913
|
+
};
|
|
914
|
+
/**
|
|
915
|
+
* @see Card — one entry in the card-head tab strip. Ant Design `CardTabListType`, field for
|
|
916
|
+
* field: `key`, `tab`, `disabled`.
|
|
917
|
+
*
|
|
918
|
+
* IT KEEPS ANTD'S SPELLING, and that is the standing rule rather than an oversight
|
|
919
|
+
* (docs/DESIGN-AUTHORITY.md — "where antd names a capability, this library takes antd's name and
|
|
920
|
+
* antd's semantics"). It therefore does NOT read `TabItemProp`, whose `value`/`label`/`content`
|
|
921
|
+
* are the `Tabs` component's own API: that item carries the PANEL as well as the trigger, and a
|
|
922
|
+
* card-head tab carries only the trigger — the panel is the card body. Two different shapes, and
|
|
923
|
+
* folding them into one would mean publishing a `content` field on a card tab that the card can
|
|
924
|
+
* never render.
|
|
925
|
+
*/
|
|
926
|
+
export type CardTabItemProp = {
|
|
927
|
+
/** Ant Design `key` — the tab's identity, and what `activeTabKey` / `onTabChange` speak in. */
|
|
928
|
+
key: string;
|
|
929
|
+
/** Ant Design `tab` — the trigger's label. Any node. */
|
|
930
|
+
tab: React.ReactNode;
|
|
931
|
+
/** Ant Design `disabled` — the tab stays in the strip and in the roving focus, unselectable. */
|
|
932
|
+
disabled?: boolean;
|
|
933
|
+
};
|