@godxjp/ui 6.0.0 → 6.0.2
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/index.d.ts +140 -0
- package/dist/app/index.js +38 -0
- package/dist/app.prop-IobwLwaM.d.ts +90 -0
- package/dist/checkbox-NkFkqsQ8.d.ts +13 -0
- package/dist/chunk-2XW7J3EI.js +226 -0
- package/dist/chunk-3F2AKYRD.js +416 -0
- package/dist/chunk-3KPEZ5CF.js +37 -0
- package/dist/chunk-3UGU5TYP.js +89 -0
- package/{src/props/registry.ts → dist/chunk-6RA3KSVK.js} +118 -133
- package/dist/chunk-7NZFVD24.js +122 -0
- package/dist/chunk-7PWBC4BY.js +25 -0
- package/dist/chunk-7S7MYFXE.js +61 -0
- package/dist/chunk-7WRZG2IG.js +71 -0
- package/dist/chunk-B775Y6BE.js +1 -0
- package/dist/chunk-BHV2FUOA.js +111 -0
- package/dist/chunk-BI3HERR7.js +70 -0
- package/dist/chunk-BPSKQUL2.js +68 -0
- package/dist/chunk-CDWPQ5RP.js +187 -0
- package/dist/chunk-CP2LET6N.js +244 -0
- package/dist/chunk-CQBADMFG.js +20 -0
- package/dist/chunk-CRERCLIZ.js +33 -0
- package/dist/chunk-DU6ZYZRP.js +238 -0
- package/dist/chunk-DY5C44UP.js +55 -0
- package/dist/chunk-E4HJNQ62.js +117 -0
- package/dist/chunk-E76QIYSY.js +93 -0
- package/dist/chunk-F7PG4OEV.js +37 -0
- package/dist/chunk-GDSVW62T.js +171 -0
- package/dist/chunk-H2FHJOLU.js +178 -0
- package/dist/chunk-HJEBRCXL.js +55 -0
- package/dist/chunk-ICM6XBST.js +16 -0
- package/{src/components/data-entry/calendar.tsx → dist/chunk-IK7I3ABN.js} +33 -35
- package/dist/chunk-L6J44O74.js +144 -0
- package/dist/chunk-LDSLS6HE.js +1 -0
- package/dist/chunk-LVNUHUEZ.js +191 -0
- package/dist/chunk-M64MVRLS.js +92 -0
- package/dist/chunk-NGQW3KEM.js +402 -0
- package/dist/chunk-NZ4FOC5N.js +559 -0
- package/dist/chunk-PIIRNAXA.js +26 -0
- package/dist/chunk-S66TJXJU.js +33 -0
- package/dist/chunk-SMLKNECP.js +133 -0
- package/dist/chunk-TAHBM3F2.js +66 -0
- package/dist/chunk-TO33OY4L.js +150 -0
- package/dist/chunk-TO7URV7U.js +51 -0
- package/dist/chunk-TOO5AEKL.js +81 -0
- package/dist/chunk-U3GHAOIJ.js +299 -0
- package/dist/chunk-U7N2A7A3.js +9 -0
- package/dist/chunk-UX634MYF.js +123 -0
- package/dist/chunk-V6UWJKZF.js +28 -0
- package/{src/components/data-entry/input.tsx → dist/chunk-VOHTRR5X.js} +18 -16
- package/dist/chunk-WRFKVUPW.js +332 -0
- package/dist/chunk-WXW43RK5.js +24 -0
- package/{src/components/navigation/tabs.tsx → dist/chunk-XG7XDYIM.js} +46 -53
- package/dist/chunk-YFCQKO3B.js +842 -0
- package/dist/chunk-ZDWXGWLY.js +73 -0
- package/dist/chunk-ZLK5SPT6.js +11 -0
- package/dist/chunk-ZS6DTAM2.js +31 -0
- package/dist/chunk-ZT5UEUBO.js +1 -0
- package/dist/components/admin/index.d.ts +80 -0
- package/dist/components/admin/index.js +38 -0
- package/dist/components/data-display/badge.d.ts +12 -0
- package/dist/components/data-display/badge.js +3 -0
- package/dist/components/data-display/card.d.ts +87 -0
- package/dist/components/data-display/card.js +2 -0
- package/dist/components/data-display/index.d.ts +72 -0
- package/dist/components/data-display/index.js +89 -0
- package/dist/components/data-display/popover.d.ts +13 -0
- package/dist/components/data-display/popover.js +2 -0
- package/dist/components/data-display/scroll-area.d.ts +7 -0
- package/dist/components/data-display/scroll-area.js +2 -0
- package/dist/components/data-display/table.d.ts +10 -0
- package/dist/components/data-display/table.js +3 -0
- package/dist/components/data-entry/autocomplete.d.ts +16 -0
- package/dist/components/data-entry/autocomplete.js +8 -0
- package/dist/components/data-entry/calendar.d.ts +16 -0
- package/dist/components/data-entry/calendar.js +4 -0
- package/dist/components/data-entry/cascader.d.ts +32 -0
- package/dist/components/data-entry/cascader.js +13 -0
- package/dist/components/data-entry/checkbox.d.ts +13 -0
- package/dist/components/data-entry/checkbox.js +4 -0
- package/dist/components/data-entry/color-picker.d.ts +16 -0
- package/dist/components/data-entry/color-picker.js +6 -0
- package/dist/components/data-entry/command.d.ts +69 -0
- package/dist/components/data-entry/command.js +3 -0
- package/dist/components/data-entry/date-picker.d.ts +16 -0
- package/dist/components/data-entry/date-picker.js +8 -0
- package/dist/components/data-entry/date-range-picker.d.ts +16 -0
- package/dist/components/data-entry/date-range-picker.js +8 -0
- package/dist/components/data-entry/index.d.ts +53 -0
- package/dist/components/data-entry/index.js +152 -0
- package/dist/components/data-entry/input.d.ts +6 -0
- package/dist/components/data-entry/input.js +2 -0
- package/dist/components/data-entry/label.d.ts +8 -0
- package/dist/components/data-entry/label.js +2 -0
- package/dist/components/data-entry/radio.d.ts +24 -0
- package/dist/components/data-entry/radio.js +4 -0
- package/dist/components/data-entry/select.d.ts +18 -0
- package/dist/components/data-entry/select.js +3 -0
- package/dist/components/data-entry/slider.d.ts +16 -0
- package/dist/components/data-entry/slider.js +2 -0
- package/dist/components/data-entry/switch.d.ts +17 -0
- package/dist/components/data-entry/switch.js +2 -0
- package/dist/components/data-entry/textarea.d.ts +6 -0
- package/dist/components/data-entry/textarea.js +3 -0
- package/dist/components/data-entry/time-picker.d.ts +16 -0
- package/dist/components/data-entry/time-picker.js +7 -0
- package/dist/components/data-entry/transfer.d.ts +17 -0
- package/dist/components/data-entry/transfer.js +11 -0
- package/dist/components/data-entry/tree-select.d.ts +26 -0
- package/dist/components/data-entry/tree-select.js +13 -0
- package/dist/components/data-entry/upload.d.ts +42 -0
- package/dist/components/data-entry/upload.js +11 -0
- package/dist/components/feedback/alert.d.ts +60 -0
- package/dist/components/feedback/alert.js +7 -0
- package/dist/components/feedback/dialog.d.ts +64 -0
- package/dist/components/feedback/dialog.js +7 -0
- package/dist/components/feedback/index.d.ts +16 -0
- package/dist/components/feedback/index.js +14 -0
- package/dist/components/feedback/sheet.d.ts +24 -0
- package/dist/components/feedback/sheet.js +2 -0
- package/dist/components/feedback/sonner.d.ts +6 -0
- package/dist/components/feedback/sonner.js +1 -0
- package/dist/components/general/button.d.ts +20 -0
- package/dist/components/general/button.js +2 -0
- package/dist/components/general/index.d.ts +6 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/layout/index.d.ts +71 -0
- package/dist/components/layout/index.js +5 -0
- package/dist/components/navigation/dropdown-menu.d.ts +28 -0
- package/dist/components/navigation/dropdown-menu.js +2 -0
- package/dist/components/navigation/index.d.ts +32 -0
- package/dist/components/navigation/index.js +12 -0
- package/dist/components/navigation/pagination.d.ts +11 -0
- package/dist/components/navigation/pagination.js +7 -0
- package/dist/components/navigation/steps.d.ts +12 -0
- package/dist/components/navigation/steps.js +3 -0
- package/dist/components/navigation/tabs-items.d.ts +12 -0
- package/dist/components/navigation/tabs-items.js +3 -0
- package/dist/components/navigation/tabs.d.ts +12 -0
- package/dist/components/navigation/tabs.js +2 -0
- package/dist/components/query/index.d.ts +43 -0
- package/dist/components/query/index.js +8 -0
- package/dist/components/ui/index.d.ts +57 -0
- package/dist/components/ui/index.js +37 -0
- package/{src/props/vocabulary/content.prop.ts → dist/content.prop-D1Dd3TAc.d.ts} +16 -20
- package/dist/data-display.prop-DNTAzmDy.d.ts +58 -0
- package/dist/data-entry.prop-BEGA1lTq.d.ts +323 -0
- package/dist/data-table-D1u_rKLK.d.ts +83 -0
- package/dist/data.prop-BVvfKC_g.d.ts +41 -0
- package/dist/feedback.prop-BmxUlpAW.d.ts +64 -0
- package/dist/filter-bar-B7OGFO9S.d.ts +10 -0
- package/dist/form/index.d.ts +21 -0
- package/dist/form/index.js +4 -0
- package/dist/form.prop-BHgpuFFm.d.ts +41 -0
- package/dist/format-date-ByyZoqI5.d.ts +51 -0
- package/dist/general.prop-D7brMPNL.d.ts +16 -0
- package/dist/i18n/index.d.ts +217 -0
- package/dist/i18n/index.js +2 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +39 -0
- package/dist/inline-C5u6ptJV.d.ts +10 -0
- package/dist/interaction.prop-Cdn7wOtq.d.ts +25 -0
- package/{src/props/vocabulary/layout.prop.ts → dist/layout.prop-4TCNvyQZ.d.ts} +9 -14
- package/dist/layout.prop-C795F0qg.d.ts +112 -0
- package/dist/lib/datetime/index.d.ts +31 -0
- package/dist/lib/datetime/index.js +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +1 -0
- package/dist/navigation.prop-DpZqcXey.d.ts +78 -0
- package/dist/navigation.prop-DxBiClEH.d.ts +20 -0
- package/dist/props/components/index.d.ts +27 -0
- package/dist/props/components/index.js +1 -0
- package/dist/props/index.d.ts +28 -0
- package/dist/props/index.js +3 -0
- package/dist/props/registry.d.ts +649 -0
- package/dist/props/registry.js +1 -0
- package/dist/props/vocabulary/index.d.ts +7 -0
- package/dist/props/vocabulary/index.js +1 -0
- package/dist/query.prop-hIPrk2zI.d.ts +71 -0
- package/dist/search-input-uP01rY1L.d.ts +22 -0
- package/dist/shared.prop-BNRJc9K0.d.ts +45 -0
- package/{src → dist}/styles/control.css +1 -1
- package/dist/types-mvzYGrma.d.ts +37 -0
- package/dist/use-toast-Dol5bdY3.d.ts +34 -0
- package/package.json +234 -68
- package/src/app/__tests__/app-provider.test.tsx +0 -232
- package/src/app/__tests__/date-format-labels.test.ts +0 -36
- package/src/app/__tests__/date-formats.test.ts +0 -44
- package/src/app/__tests__/timezones.test.ts +0 -65
- package/src/app/app-provider.tsx +0 -227
- package/src/app/date-format-labels.ts +0 -21
- package/src/app/date-formats.ts +0 -30
- package/src/app/index.ts +0 -40
- package/src/app/locales.ts +0 -32
- package/src/app/request-headers.ts +0 -31
- package/src/app/storage.ts +0 -44
- package/src/app/time-format-labels.ts +0 -19
- package/src/app/time-formats.ts +0 -15
- package/src/app/timezones.ts +0 -208
- package/src/app/types.ts +0 -39
- package/src/app/use-formatting.ts +0 -47
- package/src/components/__tests__/accessibility-primitives.test.tsx +0 -65
- package/src/components/__tests__/docs-parity.test.ts +0 -41
- package/src/components/__tests__/shadcn-release-guardrails.test.ts +0 -71
- package/src/components/__tests__/theme-axes-integration.test.tsx +0 -242
- package/src/components/admin/index.ts +0 -76
- package/src/components/data-display/__tests__/card-table.test.tsx +0 -328
- package/src/components/data-display/__tests__/data-display.test.tsx +0 -73
- package/src/components/data-display/__tests__/data-table.test.tsx +0 -84
- package/src/components/data-display/__tests__/popover.test.tsx +0 -92
- package/src/components/data-display/__tests__/scroll-area-collapsible.test.tsx +0 -66
- package/src/components/data-display/badge.tsx +0 -27
- package/src/components/data-display/card.tsx +0 -194
- package/src/components/data-display/code-badge.tsx +0 -28
- package/src/components/data-display/collapsible.tsx +0 -5
- package/src/components/data-display/data-table.tsx +0 -476
- package/src/components/data-display/empty-state.tsx +0 -22
- package/src/components/data-display/index.ts +0 -41
- package/src/components/data-display/key-value-grid.tsx +0 -46
- package/src/components/data-display/popover.tsx +0 -62
- package/src/components/data-display/progress-meter.tsx +0 -20
- package/src/components/data-display/scan-panel.tsx +0 -16
- package/src/components/data-display/scroll-area.tsx +0 -42
- package/src/components/data-display/status-badge.tsx +0 -83
- package/src/components/data-display/table.tsx +0 -59
- package/src/components/data-display/timeline.tsx +0 -42
- package/src/components/data-display/tree-list.tsx +0 -42
- package/src/components/data-entry/__fixtures__/tree-options.ts +0 -80
- package/src/components/data-entry/__tests__/cascader-tree-transfer.test.tsx +0 -417
- package/src/components/data-entry/__tests__/checkbox-group.test.tsx +0 -40
- package/src/components/data-entry/__tests__/checkbox.test.tsx +0 -20
- package/src/components/data-entry/__tests__/date-autocomplete.test.tsx +0 -94
- package/src/components/data-entry/__tests__/form-field.test.tsx +0 -49
- package/src/components/data-entry/__tests__/input-textarea.test.tsx +0 -38
- package/src/components/data-entry/__tests__/label-select.test.tsx +0 -62
- package/src/components/data-entry/__tests__/pickers.test.tsx +0 -74
- package/src/components/data-entry/__tests__/radio.test.tsx +0 -46
- package/src/components/data-entry/__tests__/search-input.test.tsx +0 -32
- package/src/components/data-entry/__tests__/switch-field.test.tsx +0 -52
- package/src/components/data-entry/__tests__/upload.test.tsx +0 -125
- package/src/components/data-entry/autocomplete.tsx +0 -91
- package/src/components/data-entry/cascader.tsx +0 -305
- package/src/components/data-entry/checkbox-group.tsx +0 -90
- package/src/components/data-entry/checkbox.tsx +0 -30
- package/src/components/data-entry/choice-field.tsx +0 -27
- package/src/components/data-entry/choice-option.ts +0 -20
- package/src/components/data-entry/color-picker.tsx +0 -75
- package/src/components/data-entry/command.tsx +0 -56
- package/src/components/data-entry/country-select.tsx +0 -88
- package/src/components/data-entry/date-picker.tsx +0 -69
- package/src/components/data-entry/date-range-picker.tsx +0 -75
- package/src/components/data-entry/form-field.tsx +0 -59
- package/src/components/data-entry/index.ts +0 -62
- package/src/components/data-entry/label.tsx +0 -25
- package/src/components/data-entry/radio.tsx +0 -109
- package/src/components/data-entry/search-input.tsx +0 -103
- package/src/components/data-entry/select.tsx +0 -149
- package/src/components/data-entry/slider.tsx +0 -38
- package/src/components/data-entry/switch-field.tsx +0 -91
- package/src/components/data-entry/switch.tsx +0 -24
- package/src/components/data-entry/textarea.tsx +0 -12
- package/src/components/data-entry/time-picker.tsx +0 -214
- package/src/components/data-entry/transfer.tsx +0 -231
- package/src/components/data-entry/tree-select-strategy.ts +0 -6
- package/src/components/data-entry/tree-select.tsx +0 -279
- package/src/components/data-entry/tree-utils.ts +0 -221
- package/src/components/data-entry/upload-crop-dialog.tsx +0 -109
- package/src/components/data-entry/upload-types.ts +0 -86
- package/src/components/data-entry/upload.tsx +0 -498
- package/src/components/data-entry/use-upload-draft.ts +0 -93
- package/src/components/feedback/__tests__/alert.test.tsx +0 -127
- package/src/components/feedback/__tests__/dialog.test.tsx +0 -290
- package/src/components/feedback/__tests__/sheet.test.tsx +0 -94
- package/src/components/feedback/__tests__/skeleton.test.tsx +0 -25
- package/src/components/feedback/__tests__/toast.test.tsx +0 -52
- package/src/components/feedback/alert.tsx +0 -167
- package/src/components/feedback/dialog.tsx +0 -325
- package/src/components/feedback/index.ts +0 -53
- package/src/components/feedback/sheet.tsx +0 -130
- package/src/components/feedback/skeleton.tsx +0 -95
- package/src/components/feedback/sonner.tsx +0 -54
- package/src/components/feedback/toaster.tsx +0 -1
- package/src/components/feedback/use-toast.ts +0 -62
- package/src/components/general/__tests__/button.test.tsx +0 -71
- package/src/components/general/button.tsx +0 -61
- package/src/components/general/index.ts +0 -2
- package/src/components/layout/__tests__/page-container.test.tsx +0 -69
- package/src/components/layout/__tests__/page-inset.test.tsx +0 -14
- package/src/components/layout/__tests__/stack-inline.test.tsx +0 -39
- package/src/components/layout/app-shell.tsx +0 -42
- package/src/components/layout/breadcrumb.tsx +0 -35
- package/src/components/layout/index.ts +0 -31
- package/src/components/layout/inline.tsx +0 -13
- package/src/components/layout/menu.tsx +0 -34
- package/src/components/layout/mobile-frame.tsx +0 -57
- package/src/components/layout/page-container.tsx +0 -81
- package/src/components/layout/page-inset.tsx +0 -16
- package/src/components/layout/responsive-grid.tsx +0 -14
- package/src/components/layout/shell-app.tsx +0 -30
- package/src/components/layout/sidebar.tsx +0 -98
- package/src/components/layout/split-pane.tsx +0 -16
- package/src/components/layout/stack.tsx +0 -13
- package/src/components/layout/topbar.tsx +0 -108
- package/src/components/navigation/__tests__/app-pickers.test.tsx +0 -118
- package/src/components/navigation/__tests__/dropdown-menu.test.tsx +0 -104
- package/src/components/navigation/__tests__/navigation.test.tsx +0 -61
- package/src/components/navigation/__tests__/pagination-steps-tabs.test.tsx +0 -76
- package/src/components/navigation/date-format-picker.tsx +0 -55
- package/src/components/navigation/dropdown-menu.tsx +0 -190
- package/src/components/navigation/filter-bar.tsx +0 -38
- package/src/components/navigation/index.ts +0 -28
- package/src/components/navigation/locale-picker.tsx +0 -49
- package/src/components/navigation/page-header.tsx +0 -50
- package/src/components/navigation/pagination-utils.ts +0 -35
- package/src/components/navigation/pagination.tsx +0 -168
- package/src/components/navigation/steps.tsx +0 -163
- package/src/components/navigation/tabs-items.tsx +0 -69
- package/src/components/navigation/time-format-picker.tsx +0 -55
- package/src/components/navigation/timezone-picker.tsx +0 -63
- package/src/components/query/__tests__/data-state.test.tsx +0 -214
- package/src/components/query/__tests__/infinite-prefetch.test.tsx +0 -105
- package/src/components/query/__tests__/query-helpers.test.tsx +0 -61
- package/src/components/query/data-state.tsx +0 -58
- package/src/components/query/index.ts +0 -10
- package/src/components/query/infinite-query-state.tsx +0 -99
- package/src/components/query/mutation-feedback.tsx +0 -31
- package/src/components/query/prefetch-link.tsx +0 -45
- package/src/components/query/query-refetch-button.tsx +0 -41
- package/src/components/ui/alert-dialog.tsx +0 -1
- package/src/components/ui/alert.tsx +0 -1
- package/src/components/ui/autocomplete.tsx +0 -1
- package/src/components/ui/badge.tsx +0 -1
- package/src/components/ui/button.tsx +0 -1
- package/src/components/ui/calendar.tsx +0 -1
- package/src/components/ui/card.tsx +0 -1
- package/src/components/ui/checkbox.tsx +0 -1
- package/src/components/ui/color-picker.tsx +0 -1
- package/src/components/ui/command.tsx +0 -1
- package/src/components/ui/date-picker.tsx +0 -1
- package/src/components/ui/date-range-picker.tsx +0 -1
- package/src/components/ui/dialog.tsx +0 -1
- package/src/components/ui/dropdown-menu.tsx +0 -1
- package/src/components/ui/index.tsx +0 -31
- package/src/components/ui/input.tsx +0 -1
- package/src/components/ui/label.tsx +0 -1
- package/src/components/ui/pagination.tsx +0 -1
- package/src/components/ui/popover.tsx +0 -1
- package/src/components/ui/radio.tsx +0 -1
- package/src/components/ui/scroll-area.tsx +0 -1
- package/src/components/ui/select.tsx +0 -1
- package/src/components/ui/sheet.tsx +0 -1
- package/src/components/ui/slider.tsx +0 -1
- package/src/components/ui/sonner.tsx +0 -1
- package/src/components/ui/switch.tsx +0 -1
- package/src/components/ui/table.tsx +0 -1
- package/src/components/ui/tabs-items.tsx +0 -1
- package/src/components/ui/tabs.tsx +0 -1
- package/src/components/ui/textarea.tsx +0 -1
- package/src/components/ui/time-picker.tsx +0 -1
- package/src/components/ui/upload.tsx +0 -1
- package/src/form/__tests__/use-zod-form.test.tsx +0 -97
- package/src/form/form-field-control.tsx +0 -44
- package/src/form/form-root.tsx +0 -29
- package/src/form/index.ts +0 -7
- package/src/form/use-zod-form.ts +0 -29
- package/src/i18n/__tests__/translate.test.ts +0 -23
- package/src/i18n/index.ts +0 -9
- package/src/i18n/messages/en.json +0 -171
- package/src/i18n/messages/ja.json +0 -171
- package/src/i18n/messages/vi.json +0 -171
- package/src/i18n/translate.ts +0 -74
- package/src/i18n/use-translation.ts +0 -53
- package/src/index.ts +0 -3
- package/src/lib/__tests__/control-styles.test.ts +0 -78
- package/src/lib/__tests__/datetime.test.ts +0 -77
- package/src/lib/__tests__/format-date.test.ts +0 -97
- package/src/lib/__tests__/format.test.ts +0 -62
- package/src/lib/__tests__/theme-tokens-audit.test.ts +0 -176
- package/src/lib/__tests__/theme-tokens-css.test.ts +0 -118
- package/src/lib/__tests__/token-governance.test.ts +0 -191
- package/src/lib/__tests__/variants.test.ts +0 -18
- package/src/lib/control-styles.ts +0 -33
- package/src/lib/datetime/detect.ts +0 -25
- package/src/lib/datetime/format-date.ts +0 -100
- package/src/lib/datetime/format.ts +0 -140
- package/src/lib/datetime/index.ts +0 -25
- package/src/lib/datetime/parse.ts +0 -51
- package/src/lib/datetime/sync.ts +0 -48
- package/src/lib/format.ts +0 -114
- package/src/lib/hooks.ts +0 -54
- package/src/lib/utils.ts +0 -6
- package/src/lib/variants.ts +0 -40
- package/src/props/components/app.prop.ts +0 -99
- package/src/props/components/data-display.prop.ts +0 -73
- package/src/props/components/data-entry.prop.ts +0 -334
- package/src/props/components/feedback.prop.ts +0 -80
- package/src/props/components/form.prop.ts +0 -46
- package/src/props/components/general.prop.ts +0 -18
- package/src/props/components/index.ts +0 -99
- package/src/props/components/layout.prop.ts +0 -130
- package/src/props/components/navigation.prop.ts +0 -88
- package/src/props/components/query.prop.ts +0 -94
- package/src/props/index.ts +0 -17
- package/src/props/vocabulary/data.prop.ts +0 -46
- package/src/props/vocabulary/index.ts +0 -73
- package/src/props/vocabulary/interaction.prop.ts +0 -42
- package/src/props/vocabulary/navigation.prop.ts +0 -19
- package/src/props/vocabulary/shared.prop.ts +0 -59
- package/src/test/__tests__/render-loop-guard.test.tsx +0 -38
- package/src/test/jest-dom.d.ts +0 -4
- package/src/test/render-loop-guard.tsx +0 -50
- package/src/test/render.tsx +0 -29
- package/src/test/theme-globals.test.ts +0 -77
- package/src/test/theme-globals.ts +0 -134
- package/src/test/theme-test-utils.tsx +0 -67
- /package/{src → dist}/styles/alert-layout.css +0 -0
- /package/{src → dist}/styles/badge-layout.css +0 -0
- /package/{src → dist}/styles/card-layout.css +0 -0
- /package/{src → dist}/styles/data-display-layout.css +0 -0
- /package/{src → dist}/styles/density.css +0 -0
- /package/{src → dist}/styles/dialog-layout.css +0 -0
- /package/{src → dist}/styles/index.css +0 -0
- /package/{src → dist}/styles/layout.css +0 -0
- /package/{src → dist}/styles/shell-layout.css +0 -0
- /package/{src → dist}/styles/table-layout.css +0 -0
- /package/{src → dist}/theme/example.service.css +0 -0
- /package/{src → dist}/tokens/base.css +0 -0
- /package/{src → dist}/tokens/foundation.css +0 -0
- /package/{src → dist}/tokens/primitives/badge.css +0 -0
- /package/{src → dist}/tokens/primitives/card.css +0 -0
- /package/{src → dist}/tokens/primitives/control.css +0 -0
- /package/{src → dist}/tokens/primitives/feedback.css +0 -0
- /package/{src → dist}/tokens/primitives/layout.css +0 -0
- /package/{src → dist}/tokens/primitives/navigation.css +0 -0
- /package/{src → dist}/tokens/primitives/table.css +0 -0
package/src/app/locales.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { Locale } from "date-fns";
|
|
2
|
-
import { enUS, ja, vi } from "date-fns/locale";
|
|
3
|
-
import {
|
|
4
|
-
enUS as enUSDayPicker,
|
|
5
|
-
ja as jaDayPicker,
|
|
6
|
-
vi as viDayPicker,
|
|
7
|
-
} from "react-day-picker/locale";
|
|
8
|
-
import type { AppLocale } from "./types";
|
|
9
|
-
|
|
10
|
-
export type AppLocaleConfig = {
|
|
11
|
-
code: AppLocale;
|
|
12
|
-
dateFns: Locale;
|
|
13
|
-
dayPicker: typeof viDayPicker;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const APP_LOCALE_CONFIG: Record<AppLocale, AppLocaleConfig> = {
|
|
17
|
-
vi: { code: "vi", dateFns: vi, dayPicker: viDayPicker },
|
|
18
|
-
en: { code: "en", dateFns: enUS, dayPicker: enUSDayPicker },
|
|
19
|
-
ja: { code: "ja", dateFns: ja, dayPicker: jaDayPicker },
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export function isAppLocale(value: string | null | undefined): value is AppLocale {
|
|
23
|
-
return value === "vi" || value === "en" || value === "ja";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getDateFnsLocale(locale: AppLocale): Locale {
|
|
27
|
-
return APP_LOCALE_CONFIG[locale].dateFns;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function getDayPickerLocale(locale: AppLocale) {
|
|
31
|
-
return APP_LOCALE_CONFIG[locale].dayPicker;
|
|
32
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { AppRequestHeaders } from "./types";
|
|
2
|
-
import {
|
|
3
|
-
APP_REQUEST_HEADER_DATE_FORMAT,
|
|
4
|
-
APP_REQUEST_HEADER_LOCALE,
|
|
5
|
-
APP_REQUEST_HEADER_TIME_FORMAT,
|
|
6
|
-
APP_REQUEST_HEADER_TIMEZONE,
|
|
7
|
-
} from "./types";
|
|
8
|
-
|
|
9
|
-
const DEFAULT_HEADERS: AppRequestHeaders = {
|
|
10
|
-
[APP_REQUEST_HEADER_LOCALE]: "vi",
|
|
11
|
-
[APP_REQUEST_HEADER_TIMEZONE]: "Asia/Ho_Chi_Minh",
|
|
12
|
-
[APP_REQUEST_HEADER_TIME_FORMAT]: "24h",
|
|
13
|
-
[APP_REQUEST_HEADER_DATE_FORMAT]: "dmy",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
let currentHeaders: AppRequestHeaders = { ...DEFAULT_HEADERS };
|
|
17
|
-
|
|
18
|
-
/** Sync locale/timezone into module state for HTTP clients (via `getAppRequestHeaders`). */
|
|
19
|
-
export function syncAppRequestHeaders(headers: Partial<AppRequestHeaders>): void {
|
|
20
|
-
currentHeaders = { ...currentHeaders, ...headers };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Read current app preference headers — wire to API client `setAppHeaderProvider`. */
|
|
24
|
-
export function getAppRequestHeaders(): AppRequestHeaders {
|
|
25
|
-
return { ...currentHeaders };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Reset to defaults — for tests only. */
|
|
29
|
-
export function resetAppRequestHeaders(): void {
|
|
30
|
-
currentHeaders = { ...DEFAULT_HEADERS };
|
|
31
|
-
}
|
package/src/app/storage.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { isAppLocale } from "./locales";
|
|
2
|
-
import { isAppDateFormat } from "./date-formats";
|
|
3
|
-
import { isAppTimeFormat } from "./time-formats";
|
|
4
|
-
import type { AppLocale, AppTimezone, AppTimeFormat, AppDateFormat } from "./types";
|
|
5
|
-
|
|
6
|
-
const DEFAULT_STORAGE_KEY = "godxjp.app";
|
|
7
|
-
|
|
8
|
-
export type StoredAppPreferences = {
|
|
9
|
-
locale?: AppLocale;
|
|
10
|
-
timezone?: AppTimezone;
|
|
11
|
-
timeFormat?: AppTimeFormat;
|
|
12
|
-
dateFormat?: AppDateFormat;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export function readStoredPreferences(storageKey: string): StoredAppPreferences {
|
|
16
|
-
if (typeof window === "undefined") return {};
|
|
17
|
-
try {
|
|
18
|
-
const raw = window.localStorage.getItem(storageKey);
|
|
19
|
-
if (!raw) return {};
|
|
20
|
-
const parsed = JSON.parse(raw) as StoredAppPreferences;
|
|
21
|
-
return {
|
|
22
|
-
locale: isAppLocale(parsed.locale) ? parsed.locale : undefined,
|
|
23
|
-
timezone: typeof parsed.timezone === "string" ? parsed.timezone : undefined,
|
|
24
|
-
timeFormat: isAppTimeFormat(parsed.timeFormat) ? parsed.timeFormat : undefined,
|
|
25
|
-
dateFormat: isAppDateFormat(parsed.dateFormat) ? parsed.dateFormat : undefined,
|
|
26
|
-
};
|
|
27
|
-
} catch {
|
|
28
|
-
return {};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function writeStoredPreferences(
|
|
33
|
-
storageKey: string,
|
|
34
|
-
preferences: StoredAppPreferences,
|
|
35
|
-
): void {
|
|
36
|
-
if (typeof window === "undefined") return;
|
|
37
|
-
try {
|
|
38
|
-
window.localStorage.setItem(storageKey, JSON.stringify(preferences));
|
|
39
|
-
} catch {
|
|
40
|
-
// Quota or private mode — ignore.
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export { DEFAULT_STORAGE_KEY };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { APP_TIME_FORMATS } from "./time-formats";
|
|
2
|
-
import type { AppLocale } from "./types";
|
|
3
|
-
import type { AppTimeFormat } from "./time-formats";
|
|
4
|
-
import { translate } from "../i18n/translate";
|
|
5
|
-
|
|
6
|
-
export const APP_TIME_FORMAT_OPTIONS = APP_TIME_FORMATS.map((value) => ({ value }));
|
|
7
|
-
|
|
8
|
-
export function getTimeFormatLabel(
|
|
9
|
-
timeFormat: AppTimeFormat,
|
|
10
|
-
locale: AppLocale,
|
|
11
|
-
fallbackLocale: AppLocale = "en",
|
|
12
|
-
): string {
|
|
13
|
-
return translate(locale, fallbackLocale, `timeFormat.${timeFormat}`);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** Suggested default per locale — vi/ja → 24h, en → 12h. */
|
|
17
|
-
export function resolveDefaultTimeFormat(locale: AppLocale): AppTimeFormat {
|
|
18
|
-
return locale === "en" ? "12h" : "24h";
|
|
19
|
-
}
|
package/src/app/time-formats.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/** Clock display — sent as `x-time-format` to backend. */
|
|
2
|
-
export type AppTimeFormat = "24h" | "12h";
|
|
3
|
-
|
|
4
|
-
export const APP_TIME_FORMATS = ["24h", "12h"] as const satisfies readonly AppTimeFormat[];
|
|
5
|
-
|
|
6
|
-
export const APP_REQUEST_HEADER_TIME_FORMAT = "x-time-format" as const;
|
|
7
|
-
|
|
8
|
-
/** date-fns pattern for time-only display. */
|
|
9
|
-
export function getTimePattern(timeFormat: AppTimeFormat): string {
|
|
10
|
-
return timeFormat === "24h" ? "HH:mm" : "h:mm a";
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function isAppTimeFormat(value: string | null | undefined): value is AppTimeFormat {
|
|
14
|
-
return value === "24h" || value === "12h";
|
|
15
|
-
}
|
package/src/app/timezones.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { translate } from "../i18n/translate";
|
|
2
|
-
import type { AppLocale } from "./types";
|
|
3
|
-
|
|
4
|
-
/** Curated preset — pass to `<AppProvider timezoneOptions={APP_TIMEZONE_PRESET} />`. */
|
|
5
|
-
export const APP_TIMEZONE_PRESET = [
|
|
6
|
-
"UTC",
|
|
7
|
-
"Asia/Ho_Chi_Minh",
|
|
8
|
-
"Asia/Bangkok",
|
|
9
|
-
"Asia/Singapore",
|
|
10
|
-
"Asia/Jakarta",
|
|
11
|
-
"Asia/Manila",
|
|
12
|
-
"Asia/Kuala_Lumpur",
|
|
13
|
-
"Asia/Yangon",
|
|
14
|
-
"Asia/Phnom_Penh",
|
|
15
|
-
"Asia/Vientiane",
|
|
16
|
-
"Asia/Brunei",
|
|
17
|
-
"Asia/Tokyo",
|
|
18
|
-
"Asia/Seoul",
|
|
19
|
-
"Asia/Shanghai",
|
|
20
|
-
"Asia/Hong_Kong",
|
|
21
|
-
"Asia/Taipei",
|
|
22
|
-
"Asia/Ulaanbaatar",
|
|
23
|
-
"Asia/Kolkata",
|
|
24
|
-
"Asia/Karachi",
|
|
25
|
-
"Asia/Dhaka",
|
|
26
|
-
"Asia/Colombo",
|
|
27
|
-
"Asia/Dubai",
|
|
28
|
-
"Asia/Riyadh",
|
|
29
|
-
"Asia/Qatar",
|
|
30
|
-
"Asia/Tehran",
|
|
31
|
-
"Asia/Jerusalem",
|
|
32
|
-
"Europe/London",
|
|
33
|
-
"Europe/Paris",
|
|
34
|
-
"Europe/Berlin",
|
|
35
|
-
"Europe/Amsterdam",
|
|
36
|
-
"Europe/Rome",
|
|
37
|
-
"Europe/Madrid",
|
|
38
|
-
"Europe/Moscow",
|
|
39
|
-
"Europe/Istanbul",
|
|
40
|
-
"America/New_York",
|
|
41
|
-
"America/Chicago",
|
|
42
|
-
"America/Denver",
|
|
43
|
-
"America/Los_Angeles",
|
|
44
|
-
"America/Toronto",
|
|
45
|
-
"America/Vancouver",
|
|
46
|
-
"America/Mexico_City",
|
|
47
|
-
"America/Sao_Paulo",
|
|
48
|
-
"America/Buenos_Aires",
|
|
49
|
-
"Australia/Sydney",
|
|
50
|
-
"Australia/Melbourne",
|
|
51
|
-
"Australia/Perth",
|
|
52
|
-
"Pacific/Auckland",
|
|
53
|
-
] as const;
|
|
54
|
-
|
|
55
|
-
/** @deprecated Use `APP_TIMEZONE_PRESET` or `getAllIanaTimezones()`. */
|
|
56
|
-
export const APP_TIMEZONE_OPTIONS = APP_TIMEZONE_PRESET;
|
|
57
|
-
|
|
58
|
-
export type AppTimezonePreset = (typeof APP_TIMEZONE_PRESET)[number];
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Preferred IANA ids not returned by all runtimes (e.g. Node lists `Asia/Saigon` only).
|
|
62
|
-
* Keys are app-facing ids; values are Intl-canonical ids for offset lookup.
|
|
63
|
-
*/
|
|
64
|
-
export const TIMEZONE_ALIASES: Record<string, string> = {
|
|
65
|
-
"Asia/Ho_Chi_Minh": "Asia/Saigon",
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const PREFERRED_TIMEZONE_IDS = Object.keys(TIMEZONE_ALIASES);
|
|
69
|
-
|
|
70
|
-
/** Map app id → Intl id for `DateTimeFormat` / validation. */
|
|
71
|
-
export function resolveTimezoneForIntl(timezone: string): string {
|
|
72
|
-
return TIMEZONE_ALIASES[timezone] ?? timezone;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** Minimal fallback when `Intl.supportedValuesOf("timeZone")` is unavailable. */
|
|
76
|
-
const FALLBACK_IANA_TIMEZONES = [...APP_TIMEZONE_PRESET] as const;
|
|
77
|
-
|
|
78
|
-
let cachedAllTimezones: readonly string[] | null = null;
|
|
79
|
-
let cachedTimezoneSet: ReadonlySet<string> | null = null;
|
|
80
|
-
|
|
81
|
-
function enrichTimezoneList(base: readonly string[]): readonly string[] {
|
|
82
|
-
const set = new Set(base);
|
|
83
|
-
for (const preferred of PREFERRED_TIMEZONE_IDS) {
|
|
84
|
-
if (!set.has(preferred)) {
|
|
85
|
-
const canonical = TIMEZONE_ALIASES[preferred];
|
|
86
|
-
if (!canonical || set.has(canonical)) set.add(preferred);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return [...set].sort();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Full IANA list from runtime — sorted lexicographically. */
|
|
93
|
-
export function getAllIanaTimezones(): readonly string[] {
|
|
94
|
-
if (cachedAllTimezones) return cachedAllTimezones;
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const intl = Intl as typeof Intl & { supportedValuesOf?: (key: string) => string[] };
|
|
98
|
-
if (typeof intl.supportedValuesOf === "function") {
|
|
99
|
-
cachedAllTimezones = enrichTimezoneList(intl.supportedValuesOf("timeZone").slice().sort());
|
|
100
|
-
return cachedAllTimezones;
|
|
101
|
-
}
|
|
102
|
-
} catch {
|
|
103
|
-
/* use fallback */
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
cachedAllTimezones = FALLBACK_IANA_TIMEZONES;
|
|
107
|
-
return cachedAllTimezones;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function getIanaTimezoneSet(): ReadonlySet<string> {
|
|
111
|
-
cachedTimezoneSet ??= new Set(getAllIanaTimezones());
|
|
112
|
-
return cachedTimezoneSet;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function isValidIanaTimezone(value: string): boolean {
|
|
116
|
-
const set = getIanaTimezoneSet();
|
|
117
|
-
if (set.has(value)) return true;
|
|
118
|
-
const canonical = TIMEZONE_ALIASES[value];
|
|
119
|
-
return canonical ? set.has(canonical) : false;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** @deprecated Use `isValidIanaTimezone`. */
|
|
123
|
-
export function isKnownAppTimezone(value: string): value is AppTimezonePreset {
|
|
124
|
-
return (APP_TIMEZONE_PRESET as readonly string[]).includes(value);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Options for TimezonePicker.
|
|
129
|
-
* - `configured` omitted/empty → full IANA list
|
|
130
|
-
* - `configured` set → only those ids (+ `current` if missing)
|
|
131
|
-
*/
|
|
132
|
-
export function resolveTimezonePickerOptions(
|
|
133
|
-
configured?: readonly string[] | null,
|
|
134
|
-
current?: string,
|
|
135
|
-
): readonly string[] {
|
|
136
|
-
const base = configured && configured.length > 0 ? [...configured] : [...getAllIanaTimezones()];
|
|
137
|
-
|
|
138
|
-
if (current && !base.includes(current)) {
|
|
139
|
-
return [current, ...base];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return base;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export function getBrowserTimezone(): string {
|
|
146
|
-
try {
|
|
147
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
148
|
-
} catch {
|
|
149
|
-
return "UTC";
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/** City/region segment from IANA id — `Asia/Ho_Chi_Minh` → `Ho Chi Minh`. */
|
|
154
|
-
export function getTimezoneCityName(timezone: string): string {
|
|
155
|
-
const segment = timezone.split("/").pop();
|
|
156
|
-
if (!segment) return timezone;
|
|
157
|
-
return segment.replace(/_/g, " ");
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** UTC/GMT offset via Intl — e.g. `GMT+7`, `UTC`. */
|
|
161
|
-
export function getTimezoneOffsetLabel(timezone: string, locale: AppLocale = "en"): string {
|
|
162
|
-
if (timezone === "UTC") return "UTC";
|
|
163
|
-
try {
|
|
164
|
-
const parts = new Intl.DateTimeFormat(locale, {
|
|
165
|
-
timeZone: resolveTimezoneForIntl(timezone),
|
|
166
|
-
timeZoneName: "shortOffset",
|
|
167
|
-
}).formatToParts(new Date());
|
|
168
|
-
return parts.find((part) => part.type === "timeZoneName")?.value ?? "";
|
|
169
|
-
} catch {
|
|
170
|
-
return "";
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/** Intl fallback when no i18n override — `Ho Chi Minh (GMT+7)`. */
|
|
175
|
-
export function formatTimezoneDisplayLabel(timezone: string, locale: AppLocale = "en"): string {
|
|
176
|
-
const city = getTimezoneCityName(timezone);
|
|
177
|
-
const offset = getTimezoneOffsetLabel(timezone, locale);
|
|
178
|
-
return offset ? `${city} (${offset})` : city;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function getTimezoneLabel(
|
|
182
|
-
timezone: string,
|
|
183
|
-
locale: AppLocale,
|
|
184
|
-
fallbackLocale: AppLocale = "en",
|
|
185
|
-
): string {
|
|
186
|
-
const key = `timezone.${timezone}`;
|
|
187
|
-
const translated = translate(locale, fallbackLocale, key);
|
|
188
|
-
if (translated !== key) return translated;
|
|
189
|
-
|
|
190
|
-
const offset = getTimezoneOffsetLabel(timezone, locale);
|
|
191
|
-
const city = getTimezoneCityName(timezone);
|
|
192
|
-
return offset ? `${city} (${offset})` : city;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function resolveDefaultTimezone(
|
|
196
|
-
defaultTimezone: "browser" | "system" | (string & {}),
|
|
197
|
-
systemTimezone?: string,
|
|
198
|
-
): string {
|
|
199
|
-
if (defaultTimezone === "browser") return getBrowserTimezone();
|
|
200
|
-
if (defaultTimezone === "system") return systemTimezone ?? "UTC";
|
|
201
|
-
return defaultTimezone;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** Vitest only — reset cached IANA list between cases. */
|
|
205
|
-
export function resetIanaTimezoneCacheForTests(): void {
|
|
206
|
-
cachedAllTimezones = null;
|
|
207
|
-
cachedTimezoneSet = null;
|
|
208
|
-
}
|
package/src/app/types.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { AppTimeFormat } from "./time-formats";
|
|
2
|
-
import type { AppDateFormat } from "./date-formats";
|
|
3
|
-
|
|
4
|
-
/** Supported UI locales — sent as `x-locale` to backend. */
|
|
5
|
-
export type AppLocale = "vi" | "en" | "ja";
|
|
6
|
-
|
|
7
|
-
/** IANA timezone identifier — sent as `x-timezone` to backend. */
|
|
8
|
-
export type AppTimezone = string;
|
|
9
|
-
|
|
10
|
-
/** How to resolve the initial timezone when nothing is stored. */
|
|
11
|
-
export type AppTimezoneDefault = "browser" | "system" | (AppTimezone & {});
|
|
12
|
-
|
|
13
|
-
export type { AppTimeFormat } from "./time-formats";
|
|
14
|
-
export type { AppDateFormat } from "./date-formats";
|
|
15
|
-
export {
|
|
16
|
-
APP_TIME_FORMATS,
|
|
17
|
-
APP_REQUEST_HEADER_TIME_FORMAT,
|
|
18
|
-
getTimePattern,
|
|
19
|
-
isAppTimeFormat,
|
|
20
|
-
} from "./time-formats";
|
|
21
|
-
export {
|
|
22
|
-
APP_DATE_FORMATS,
|
|
23
|
-
APP_REQUEST_HEADER_DATE_FORMAT,
|
|
24
|
-
getDatePattern,
|
|
25
|
-
getDateTimePattern,
|
|
26
|
-
isAppDateFormat,
|
|
27
|
-
} from "./date-formats";
|
|
28
|
-
|
|
29
|
-
export const APP_LOCALES = ["vi", "en", "ja"] as const satisfies readonly AppLocale[];
|
|
30
|
-
|
|
31
|
-
export const APP_REQUEST_HEADER_LOCALE = "x-locale" as const;
|
|
32
|
-
export const APP_REQUEST_HEADER_TIMEZONE = "x-timezone" as const;
|
|
33
|
-
|
|
34
|
-
export type AppRequestHeaders = {
|
|
35
|
-
"x-locale": AppLocale;
|
|
36
|
-
"x-timezone": AppTimezone;
|
|
37
|
-
"x-time-format": AppTimeFormat;
|
|
38
|
-
"x-date-format": AppDateFormat;
|
|
39
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
2
|
-
import { formatDate, type FormatDateOptions } from "../lib/datetime";
|
|
3
|
-
import { useAppContext } from "./app-provider";
|
|
4
|
-
|
|
5
|
-
/** Date/time formatters bound to the current AppProvider preferences. */
|
|
6
|
-
export function useFormatting() {
|
|
7
|
-
const { locale, timezone, timeFormat, dateFormat, dateFnsLocale } = useAppContext();
|
|
8
|
-
|
|
9
|
-
const defaults = useMemo(
|
|
10
|
-
() => ({ locale: dateFnsLocale, timezone, timeFormat, dateFormat }),
|
|
11
|
-
[dateFnsLocale, timezone, timeFormat, dateFormat],
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const bind = useMemo(
|
|
15
|
-
() => (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
16
|
-
formatDate(value, { ...defaults, ...options }),
|
|
17
|
-
[defaults],
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
return useMemo(
|
|
21
|
-
() => ({
|
|
22
|
-
locale,
|
|
23
|
-
timezone,
|
|
24
|
-
timeFormat,
|
|
25
|
-
dateFormat,
|
|
26
|
-
/** Primary formatter — auto-detect + AppProvider defaults. */
|
|
27
|
-
format: bind,
|
|
28
|
-
formatDate: bind,
|
|
29
|
-
formatCalendarDate: (value: Date | null | undefined, options?: FormatDateOptions) =>
|
|
30
|
-
formatDate(value, { ...defaults, ...options, kind: "calendar" }),
|
|
31
|
-
formatTime: (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
32
|
-
formatDate(value, { ...defaults, ...options, kind: "time" }),
|
|
33
|
-
formatDateTime: (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
34
|
-
formatDate(value, { ...defaults, ...options, kind: "datetime" }),
|
|
35
|
-
formatDateLong: (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
36
|
-
formatDate(value, { ...defaults, ...options, kind: "long" }),
|
|
37
|
-
formatRelative: (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
38
|
-
formatDate(value, { ...defaults, ...options, kind: "relative" }),
|
|
39
|
-
formatTimeOfDay: (value: Parameters<typeof formatDate>[0], options?: FormatDateOptions) =>
|
|
40
|
-
formatDate(value, { ...defaults, ...options, kind: "time" }),
|
|
41
|
-
}),
|
|
42
|
-
[locale, timezone, timeFormat, dateFormat, defaults, bind],
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Alias for useFormatting — emphasises timezone-aware datetime helpers. */
|
|
47
|
-
export const useDateTime = useFormatting;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { renderWithUi, screen } from "@/test/render";
|
|
3
|
-
import { Checkbox } from "../data-entry/checkbox";
|
|
4
|
-
import { Command, CommandInput } from "../data-entry/command";
|
|
5
|
-
import { Radio } from "../data-entry/radio";
|
|
6
|
-
import { Select, SelectTrigger, SelectValue } from "../data-entry/select";
|
|
7
|
-
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "../feedback/dialog";
|
|
8
|
-
import { Sheet, SheetContent, SheetDescription, SheetTitle } from "../feedback/sheet";
|
|
9
|
-
|
|
10
|
-
function expectDecorativeIconsHidden(container: HTMLElement) {
|
|
11
|
-
container.querySelectorAll("svg").forEach((icon) => {
|
|
12
|
-
expect(icon).toHaveAttribute("aria-hidden", "true");
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
describe("primitive accessibility", () => {
|
|
17
|
-
it("hides decorative icons from accessibility tree", () => {
|
|
18
|
-
const { baseElement } = renderWithUi(
|
|
19
|
-
<>
|
|
20
|
-
<Select>
|
|
21
|
-
<SelectTrigger aria-label="Hub">
|
|
22
|
-
<SelectValue placeholder="Hub" />
|
|
23
|
-
</SelectTrigger>
|
|
24
|
-
</Select>
|
|
25
|
-
<Checkbox defaultChecked aria-label="Accept" />
|
|
26
|
-
<Radio.Root defaultValue="air">
|
|
27
|
-
<Radio.Item value="air" aria-label="Air" />
|
|
28
|
-
</Radio.Root>
|
|
29
|
-
<Command>
|
|
30
|
-
<CommandInput aria-label="Search" />
|
|
31
|
-
</Command>
|
|
32
|
-
</>,
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
expectDecorativeIconsHidden(baseElement);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("keeps dialog close button named while hiding close icon", () => {
|
|
39
|
-
const { baseElement } = renderWithUi(
|
|
40
|
-
<Dialog open onOpenChange={() => undefined}>
|
|
41
|
-
<DialogContent>
|
|
42
|
-
<DialogTitle>Dialog title</DialogTitle>
|
|
43
|
-
<DialogDescription>Dialog description</DialogDescription>
|
|
44
|
-
</DialogContent>
|
|
45
|
-
</Dialog>,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
expect(screen.getByRole("button", { name: "Close" })).toBeInTheDocument();
|
|
49
|
-
expectDecorativeIconsHidden(baseElement);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("keeps sheet close button named while hiding close icon", () => {
|
|
53
|
-
const { baseElement } = renderWithUi(
|
|
54
|
-
<Sheet open onOpenChange={() => undefined}>
|
|
55
|
-
<SheetContent>
|
|
56
|
-
<SheetTitle>Sheet title</SheetTitle>
|
|
57
|
-
<SheetDescription>Sheet description</SheetDescription>
|
|
58
|
-
</SheetContent>
|
|
59
|
-
</Sheet>,
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
expect(screen.getByRole("button", { name: "Close" })).toBeInTheDocument();
|
|
63
|
-
expectDecorativeIconsHidden(baseElement);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { describe, expect, it } from "vitest";
|
|
4
|
-
|
|
5
|
-
const root = process.cwd();
|
|
6
|
-
|
|
7
|
-
function read(path: string) {
|
|
8
|
-
return readFileSync(join(root, path), "utf8");
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe("docs and story parity", () => {
|
|
12
|
-
it("documents shadcn-compatible compound exports", () => {
|
|
13
|
-
expect(read("docs/primitives/data-entry/select/index.md")).toContain("SelectLabel");
|
|
14
|
-
expect(read("docs/primitives/data-entry/select/index.md")).toContain("SelectSeparator");
|
|
15
|
-
|
|
16
|
-
const dropdownDocs = read("docs/primitives/navigation/dropdown-menu/index.md");
|
|
17
|
-
expect(dropdownDocs).toContain("DropdownMenuCheckboxItem");
|
|
18
|
-
expect(dropdownDocs).toContain("DropdownMenuRadioItem");
|
|
19
|
-
expect(dropdownDocs).toContain("DropdownMenuShortcut");
|
|
20
|
-
|
|
21
|
-
const popoverDocs = read("docs/primitives/data-display/popover/index.md");
|
|
22
|
-
expect(popoverDocs).toContain("PopoverHeader");
|
|
23
|
-
expect(popoverDocs).toContain("PopoverTitle");
|
|
24
|
-
expect(popoverDocs).toContain("PopoverDescription");
|
|
25
|
-
|
|
26
|
-
expect(read("docs/primitives/feedback/sheet/index.md")).toContain("SheetFooter");
|
|
27
|
-
expect(read("docs/primitives/navigation/tabs/index.md")).toContain("variant");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("has preview examples for new shadcn parity surfaces", () => {
|
|
31
|
-
expect(
|
|
32
|
-
read("docs/primitives/navigation/dropdown-menu/examples/checked-radio-items.tsx"),
|
|
33
|
-
).toContain("DropdownMenuCheckboxItem");
|
|
34
|
-
expect(read("docs/primitives/navigation/tabs/examples/line-variant.tsx")).toContain(
|
|
35
|
-
'variant="line"',
|
|
36
|
-
);
|
|
37
|
-
expect(read("docs/primitives/data-display/popover/examples/shipment-summary.tsx")).toContain(
|
|
38
|
-
"PopoverHeader",
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { describe, expect, it } from "vitest";
|
|
4
|
-
|
|
5
|
-
const root = process.cwd();
|
|
6
|
-
|
|
7
|
-
function readJson<T>(path: string): T {
|
|
8
|
-
return JSON.parse(readFileSync(join(root, path), "utf8")) as T;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe("shadcn release guardrails", () => {
|
|
12
|
-
it("keeps components.json aligned to the package UI bridge", () => {
|
|
13
|
-
const config = readJson<{
|
|
14
|
-
aliases?: Record<string, string>;
|
|
15
|
-
tailwind?: { css?: string; cssVariables?: boolean };
|
|
16
|
-
iconLibrary?: string;
|
|
17
|
-
}>("components.json");
|
|
18
|
-
|
|
19
|
-
expect(config.aliases?.ui).toBe("@/components/ui");
|
|
20
|
-
expect(config.aliases?.utils).toBe("@/lib/utils");
|
|
21
|
-
expect(config.tailwind?.css).toBe("src/styles/index.css");
|
|
22
|
-
expect(config.tailwind?.cssVariables).toBe(true);
|
|
23
|
-
expect(config.iconLibrary).toBe("lucide");
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("exports shadcn-compatible entrypoints from package.json", () => {
|
|
27
|
-
const pkg = readJson<{ exports?: Record<string, string>; scripts?: Record<string, string> }>(
|
|
28
|
-
"package.json",
|
|
29
|
-
);
|
|
30
|
-
const exports = pkg.exports ?? {};
|
|
31
|
-
|
|
32
|
-
expect(exports["./ui"]).toBe("./src/components/ui/index.tsx");
|
|
33
|
-
for (const key of [
|
|
34
|
-
"button",
|
|
35
|
-
"select",
|
|
36
|
-
"checkbox",
|
|
37
|
-
"radio",
|
|
38
|
-
"switch",
|
|
39
|
-
"slider",
|
|
40
|
-
"dialog",
|
|
41
|
-
"sheet",
|
|
42
|
-
"popover",
|
|
43
|
-
"dropdown-menu",
|
|
44
|
-
"tabs",
|
|
45
|
-
"command",
|
|
46
|
-
]) {
|
|
47
|
-
expect(exports[`./ui/${key}`], `missing ./ui/${key}`).toBeDefined();
|
|
48
|
-
}
|
|
49
|
-
expect(pkg.scripts?.["verify:release"]).toContain("preview:build");
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("keeps bridge files present for installed shadcn components", () => {
|
|
53
|
-
for (const file of [
|
|
54
|
-
"button",
|
|
55
|
-
"select",
|
|
56
|
-
"checkbox",
|
|
57
|
-
"radio",
|
|
58
|
-
"switch",
|
|
59
|
-
"slider",
|
|
60
|
-
"dialog",
|
|
61
|
-
"sheet",
|
|
62
|
-
"popover",
|
|
63
|
-
"dropdown-menu",
|
|
64
|
-
"tabs",
|
|
65
|
-
"command",
|
|
66
|
-
"index",
|
|
67
|
-
]) {
|
|
68
|
-
expect(existsSync(join(root, `src/components/ui/${file}.tsx`)), `${file}.tsx`).toBe(true);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
});
|