@godxjp/ui 18.9.0 → 18.11.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/LICENSE +202 -0
- package/dist/components/data-display/badge.d.ts +7 -0
- package/dist/components/data-display/badge.js +1 -1
- package/dist/components/data-display/data-table.js +2 -2
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/permission-matrix.d.ts +26 -0
- package/dist/components/data-display/permission-matrix.js +219 -0
- package/dist/components/data-display/table.d.ts +12 -0
- package/dist/components/data-entry/branch-scope-picker.d.ts +43 -0
- package/dist/components/data-entry/branch-scope-picker.js +200 -0
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/select.d.ts +7 -1
- package/dist/components/data-entry/select.js +46 -26
- package/dist/components/feedback/alert.d.ts +2 -20
- package/dist/components/feedback/alert.js +1 -11
- package/dist/components/feedback/banner.d.ts +21 -0
- package/dist/components/feedback/banner.js +19 -0
- package/dist/components/feedback/index.d.ts +4 -2
- package/dist/components/feedback/index.js +2 -2
- package/dist/components/general/typography.d.ts +1 -0
- package/dist/components/general/typography.js +32 -13
- package/dist/components/layout/auth-shell.d.ts +2 -2
- package/dist/components/layout/index.d.ts +2 -2
- package/dist/components/layout/index.js +2 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +61 -15
- package/dist/components/layout/resizable.d.ts +1 -1
- package/dist/components/layout/resizable.js +26 -8
- package/dist/components/layout/service-role-panel.d.ts +25 -0
- package/dist/components/layout/service-role-panel.js +206 -0
- package/dist/components/navigation/filter-bar.d.ts +2 -2
- package/dist/components/navigation/filter-bar.js +113 -34
- package/dist/components/navigation/index.d.ts +1 -1
- package/dist/components/navigation/pagination.js +20 -1
- package/dist/components/navigation/tabs.js +6 -1
- package/dist/i18n/messages/en.json +59 -4
- package/dist/i18n/messages/ja.json +54 -5
- package/dist/i18n/messages/vi.json +53 -4
- package/dist/lib/field-a11y.d.ts +7 -0
- package/dist/lib/field-a11y.js +6 -0
- package/dist/lib/hooks.d.ts +15 -0
- package/dist/lib/hooks.js +37 -0
- package/dist/props/components/data-display.prop.d.ts +66 -0
- package/dist/props/components/data-entry.prop.d.ts +54 -0
- package/dist/props/components/feedback.prop.d.ts +3 -3
- package/dist/props/components/general.prop.d.ts +8 -1
- package/dist/props/components/layout.prop.d.ts +80 -51
- package/dist/props/components/navigation.prop.d.ts +77 -50
- package/dist/props/registry.d.ts +274 -54
- package/dist/props/registry.js +362 -73
- package/dist/props/vocabulary/content.prop.d.ts +5 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +4 -7
- package/dist/props/vocabulary/layout.prop.d.ts +2 -2
- package/dist/styles/alert-layout.css +15 -32
- package/dist/styles/badge-layout.css +5 -0
- package/dist/styles/control.css +5 -0
- package/dist/styles/layout.css +118 -108
- package/dist/styles/shell-layout.css +16 -7
- package/dist/styles/table-layout.css +92 -2
- package/dist/styles/text-layout.css +13 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +5 -0
- package/dist/tokens/components/banner.css +16 -0
- package/dist/tokens/components/navigation.css +10 -25
- package/dist/tokens/components/shell.css +20 -9
- package/dist/tokens/components/table.css +41 -1
- package/dist/tokens/semantic/layout.css +8 -7
- package/package.json +15 -2
- package/dist/components/layout/page-header.d.ts +0 -22
- package/dist/components/layout/page-header.js +0 -89
|
@@ -106,7 +106,12 @@ const TabsList = React.forwardRef(({ className, variant = "default", ...props },
|
|
|
106
106
|
// active trigger when a resize would otherwise strand it off-strip (gh#204). Vertical
|
|
107
107
|
// orientation is untouched — it already stacks in a column and is sized by its own
|
|
108
108
|
// `h-*`/`w-*` overrides.
|
|
109
|
-
|
|
109
|
+
// justify-center-SAFE: the strip is a centred flex box that also scrolls. Plain `center`
|
|
110
|
+
// splits the overflow across BOTH edges, and scrollLeft only ever covers the trailing one
|
|
111
|
+
// — so the leading tab sat permanently outside the scrollport (an unreachable control at
|
|
112
|
+
// 320px, WCAG 2.2 SC 2.1.1). `safe` falls back to start alignment exactly when it
|
|
113
|
+
// overflows, and still centres whenever the tabs fit.
|
|
114
|
+
"group/tabs-list text-muted-foreground data-[variant=default]:bg-muted inline-flex w-fit max-w-full min-w-0 items-center justify-center-safe rounded-lg p-1 group-data-[orientation=vertical]/tabs:flex-col data-[orientation=horizontal]:[scrollbar-width:none] data-[orientation=horizontal]:overflow-x-auto data-[orientation=horizontal]:overflow-y-hidden data-[variant=line]:gap-1 data-[variant=line]:rounded-none data-[variant=line]:bg-transparent [&[data-orientation=horizontal]::-webkit-scrollbar]:hidden",
|
|
110
115
|
className
|
|
111
116
|
),
|
|
112
117
|
...props
|
|
@@ -110,6 +110,24 @@
|
|
|
110
110
|
"previousYear": "Previous year",
|
|
111
111
|
"nextYear": "Next year",
|
|
112
112
|
"placeholder": "yyyy/mm"
|
|
113
|
+
},
|
|
114
|
+
"branchScope": {
|
|
115
|
+
"label": "Branch scope",
|
|
116
|
+
"all": "All branches",
|
|
117
|
+
"allDescription": "Applies to every current and future branch",
|
|
118
|
+
"selected": "Selected branches only",
|
|
119
|
+
"selectedDescription": "Applies only to the branches checked below",
|
|
120
|
+
"listLabel": "Branches",
|
|
121
|
+
"searchPlaceholder": "Search branches",
|
|
122
|
+
"selectedCount": {
|
|
123
|
+
"one": "{count} branch selected",
|
|
124
|
+
"other": "{count} branches selected"
|
|
125
|
+
},
|
|
126
|
+
"empty": "No branches to choose from",
|
|
127
|
+
"error": "Could not load branches",
|
|
128
|
+
"denied": "You do not have permission to view branches",
|
|
129
|
+
"loading": "Loading branches…",
|
|
130
|
+
"noMatches": "No branches match your search"
|
|
113
131
|
}
|
|
114
132
|
},
|
|
115
133
|
"feedback": {
|
|
@@ -124,6 +142,9 @@
|
|
|
124
142
|
}
|
|
125
143
|
},
|
|
126
144
|
"layout": {
|
|
145
|
+
"pageHeader": {
|
|
146
|
+
"loading": "Loading page…"
|
|
147
|
+
},
|
|
127
148
|
"sidebar": {
|
|
128
149
|
"ariaLabel": "Primary"
|
|
129
150
|
},
|
|
@@ -135,9 +156,6 @@
|
|
|
135
156
|
"openNav": "Open navigation menu",
|
|
136
157
|
"navLabel": "Menu"
|
|
137
158
|
},
|
|
138
|
-
"pageHeader": {
|
|
139
|
-
"loading": "Loading page…"
|
|
140
|
-
},
|
|
141
159
|
"authShell": {
|
|
142
160
|
"brandLabel": "Brand",
|
|
143
161
|
"mainLabel": "Main content",
|
|
@@ -167,6 +185,28 @@
|
|
|
167
185
|
"searchPlaceholder": "Search...",
|
|
168
186
|
"notifications": "Notifications",
|
|
169
187
|
"tweaks": "Open settings"
|
|
188
|
+
},
|
|
189
|
+
"serviceRolePanel": {
|
|
190
|
+
"rolesLabel": "Roles",
|
|
191
|
+
"detailLabel": "Role detail",
|
|
192
|
+
"locked": "Locked",
|
|
193
|
+
"memberCount": {
|
|
194
|
+
"one": "{count} member",
|
|
195
|
+
"other": "{count} members"
|
|
196
|
+
},
|
|
197
|
+
"selectRole": "Select {role}",
|
|
198
|
+
"deleteRole": "Delete {role}",
|
|
199
|
+
"deleteTitle": "Delete this role?",
|
|
200
|
+
"deleteDescription": "Deleting {role} removes its permissions from every assigned member. This cannot be undone.",
|
|
201
|
+
"deleteConfirm": "Delete role",
|
|
202
|
+
"empty": "No roles yet",
|
|
203
|
+
"emptyDescription": "Create a role to start assigning permissions.",
|
|
204
|
+
"error": "Could not load roles",
|
|
205
|
+
"errorDescription": "The data could not be fetched. Try again shortly.",
|
|
206
|
+
"denied": "You do not have permission to view roles",
|
|
207
|
+
"deniedDescription": "Ask an administrator to grant you access.",
|
|
208
|
+
"loading": "Loading roles…",
|
|
209
|
+
"noDetail": "Select a role to see its detail"
|
|
170
210
|
}
|
|
171
211
|
},
|
|
172
212
|
"dataDisplay": {
|
|
@@ -182,6 +222,21 @@
|
|
|
182
222
|
"listRow": {
|
|
183
223
|
"unread": "Unread",
|
|
184
224
|
"read": "Read"
|
|
225
|
+
},
|
|
226
|
+
"permissionMatrix": {
|
|
227
|
+
"caption": "Role and permission matrix",
|
|
228
|
+
"permissionColumn": "Permission",
|
|
229
|
+
"granted": "Granted",
|
|
230
|
+
"notGranted": "Not granted",
|
|
231
|
+
"difference": "Difference",
|
|
232
|
+
"toggle": "Grant {permission} to {role}",
|
|
233
|
+
"locked": "Locked",
|
|
234
|
+
"empty": "No permissions to show",
|
|
235
|
+
"error": "Could not load the permission matrix",
|
|
236
|
+
"errorDescription": "The data could not be fetched. Try again shortly.",
|
|
237
|
+
"denied": "You do not have permission to view this matrix",
|
|
238
|
+
"deniedDescription": "Ask an administrator to grant you access.",
|
|
239
|
+
"loading": "Loading permissions…"
|
|
185
240
|
}
|
|
186
241
|
},
|
|
187
242
|
"ui": {
|
|
@@ -232,7 +287,7 @@
|
|
|
232
287
|
},
|
|
233
288
|
"filterBar": {
|
|
234
289
|
"appliedFilters": "Applied filters",
|
|
235
|
-
"removeFilter": "Remove filter {label}",
|
|
290
|
+
"removeFilter": "Remove filter: {label}",
|
|
236
291
|
"resultCount": {
|
|
237
292
|
"one": "{count} result",
|
|
238
293
|
"other": "{count} results"
|
|
@@ -110,6 +110,21 @@
|
|
|
110
110
|
"previousYear": "前年へ",
|
|
111
111
|
"nextYear": "翌年へ",
|
|
112
112
|
"placeholder": "yyyy/mm"
|
|
113
|
+
},
|
|
114
|
+
"branchScope": {
|
|
115
|
+
"label": "ブランチ範囲",
|
|
116
|
+
"all": "すべてのブランチ",
|
|
117
|
+
"allDescription": "現在および今後のすべてのブランチに適用",
|
|
118
|
+
"selected": "選択したブランチのみ",
|
|
119
|
+
"selectedDescription": "下で選択したブランチにのみ適用",
|
|
120
|
+
"listLabel": "ブランチ",
|
|
121
|
+
"searchPlaceholder": "ブランチを検索",
|
|
122
|
+
"selectedCount": "{count} 件選択中",
|
|
123
|
+
"empty": "選択できるブランチがありません",
|
|
124
|
+
"error": "ブランチを取得できませんでした",
|
|
125
|
+
"denied": "ブランチを表示する権限がありません",
|
|
126
|
+
"loading": "ブランチを読み込み中…",
|
|
127
|
+
"noMatches": "検索に一致するブランチがありません"
|
|
113
128
|
}
|
|
114
129
|
},
|
|
115
130
|
"feedback": {
|
|
@@ -124,6 +139,9 @@
|
|
|
124
139
|
}
|
|
125
140
|
},
|
|
126
141
|
"layout": {
|
|
142
|
+
"pageHeader": {
|
|
143
|
+
"loading": "ページを読み込んでいます…"
|
|
144
|
+
},
|
|
127
145
|
"sidebar": {
|
|
128
146
|
"ariaLabel": "メインナビゲーション"
|
|
129
147
|
},
|
|
@@ -135,9 +153,6 @@
|
|
|
135
153
|
"openNav": "ナビゲーションメニューを開く",
|
|
136
154
|
"navLabel": "メニュー"
|
|
137
155
|
},
|
|
138
|
-
"pageHeader": {
|
|
139
|
-
"loading": "ページを読み込んでいます…"
|
|
140
|
-
},
|
|
141
156
|
"authShell": {
|
|
142
157
|
"brandLabel": "ブランド",
|
|
143
158
|
"mainLabel": "メインコンテンツ",
|
|
@@ -167,6 +182,25 @@
|
|
|
167
182
|
"searchPlaceholder": "検索...",
|
|
168
183
|
"notifications": "通知",
|
|
169
184
|
"tweaks": "設定を開く"
|
|
185
|
+
},
|
|
186
|
+
"serviceRolePanel": {
|
|
187
|
+
"rolesLabel": "ロール一覧",
|
|
188
|
+
"detailLabel": "ロールの詳細",
|
|
189
|
+
"locked": "変更不可",
|
|
190
|
+
"memberCount": "{count} 名",
|
|
191
|
+
"selectRole": "{role} を選択",
|
|
192
|
+
"deleteRole": "{role} を削除",
|
|
193
|
+
"deleteTitle": "ロールを削除しますか?",
|
|
194
|
+
"deleteDescription": "{role} を削除すると、割り当てられたメンバーはこのロールの権限を失います。この操作は取り消せません。",
|
|
195
|
+
"deleteConfirm": "ロールを削除",
|
|
196
|
+
"empty": "ロールがありません",
|
|
197
|
+
"emptyDescription": "ロールを作成して権限の割り当てを始めましょう。",
|
|
198
|
+
"error": "ロールを取得できませんでした",
|
|
199
|
+
"errorDescription": "データを取得できませんでした。時間をおいて再試行してください。",
|
|
200
|
+
"denied": "ロールを表示する権限がありません",
|
|
201
|
+
"deniedDescription": "閲覧するには管理者に権限の付与を依頼してください。",
|
|
202
|
+
"loading": "ロールを読み込み中…",
|
|
203
|
+
"noDetail": "ロールを選択すると詳細が表示されます"
|
|
170
204
|
}
|
|
171
205
|
},
|
|
172
206
|
"dataDisplay": {
|
|
@@ -182,6 +216,21 @@
|
|
|
182
216
|
"listRow": {
|
|
183
217
|
"unread": "未読",
|
|
184
218
|
"read": "既読"
|
|
219
|
+
},
|
|
220
|
+
"permissionMatrix": {
|
|
221
|
+
"caption": "ロールと権限のマトリクス",
|
|
222
|
+
"permissionColumn": "権限",
|
|
223
|
+
"granted": "許可",
|
|
224
|
+
"notGranted": "不許可",
|
|
225
|
+
"difference": "差分",
|
|
226
|
+
"toggle": "{role} に {permission} を付与",
|
|
227
|
+
"locked": "変更不可",
|
|
228
|
+
"empty": "表示できる権限がありません",
|
|
229
|
+
"error": "権限マトリクスを取得できませんでした",
|
|
230
|
+
"errorDescription": "データを取得できませんでした。時間をおいて再試行してください。",
|
|
231
|
+
"denied": "このマトリクスを表示する権限がありません",
|
|
232
|
+
"deniedDescription": "閲覧するには管理者に権限の付与を依頼してください。",
|
|
233
|
+
"loading": "権限を読み込み中…"
|
|
185
234
|
}
|
|
186
235
|
},
|
|
187
236
|
"ui": {
|
|
@@ -232,8 +281,8 @@
|
|
|
232
281
|
},
|
|
233
282
|
"filterBar": {
|
|
234
283
|
"appliedFilters": "適用中のフィルター",
|
|
235
|
-
"removeFilter": "
|
|
236
|
-
"resultCount": "{count}
|
|
284
|
+
"removeFilter": "フィルターを解除: {label}",
|
|
285
|
+
"resultCount": "{count} 件の結果"
|
|
237
286
|
},
|
|
238
287
|
"localePicker": {
|
|
239
288
|
"ariaLabel": "言語"
|
|
@@ -110,6 +110,21 @@
|
|
|
110
110
|
"previousYear": "Năm trước",
|
|
111
111
|
"nextYear": "Năm sau",
|
|
112
112
|
"placeholder": "yyyy/mm"
|
|
113
|
+
},
|
|
114
|
+
"branchScope": {
|
|
115
|
+
"label": "Phạm vi chi nhánh",
|
|
116
|
+
"all": "Tất cả chi nhánh",
|
|
117
|
+
"allDescription": "Áp dụng cho mọi chi nhánh hiện tại và sau này",
|
|
118
|
+
"selected": "Chỉ chi nhánh đã chọn",
|
|
119
|
+
"selectedDescription": "Chỉ áp dụng cho các chi nhánh được chọn bên dưới",
|
|
120
|
+
"listLabel": "Chi nhánh",
|
|
121
|
+
"searchPlaceholder": "Tìm chi nhánh",
|
|
122
|
+
"selectedCount": "Đã chọn {count} chi nhánh",
|
|
123
|
+
"empty": "Chưa có chi nhánh để chọn",
|
|
124
|
+
"error": "Không tải được danh sách chi nhánh",
|
|
125
|
+
"denied": "Bạn không có quyền xem chi nhánh",
|
|
126
|
+
"loading": "Đang tải chi nhánh…",
|
|
127
|
+
"noMatches": "Không có chi nhánh khớp với tìm kiếm"
|
|
113
128
|
}
|
|
114
129
|
},
|
|
115
130
|
"feedback": {
|
|
@@ -124,6 +139,9 @@
|
|
|
124
139
|
}
|
|
125
140
|
},
|
|
126
141
|
"layout": {
|
|
142
|
+
"pageHeader": {
|
|
143
|
+
"loading": "Đang tải trang…"
|
|
144
|
+
},
|
|
127
145
|
"sidebar": {
|
|
128
146
|
"ariaLabel": "Điều hướng chính"
|
|
129
147
|
},
|
|
@@ -135,9 +153,6 @@
|
|
|
135
153
|
"openNav": "Mở menu điều hướng",
|
|
136
154
|
"navLabel": "Menu"
|
|
137
155
|
},
|
|
138
|
-
"pageHeader": {
|
|
139
|
-
"loading": "Đang tải trang…"
|
|
140
|
-
},
|
|
141
156
|
"authShell": {
|
|
142
157
|
"brandLabel": "Thương hiệu",
|
|
143
158
|
"mainLabel": "Nội dung chính",
|
|
@@ -167,6 +182,25 @@
|
|
|
167
182
|
"searchPlaceholder": "Tìm kiếm...",
|
|
168
183
|
"notifications": "Thông báo",
|
|
169
184
|
"tweaks": "Mở tùy chỉnh"
|
|
185
|
+
},
|
|
186
|
+
"serviceRolePanel": {
|
|
187
|
+
"rolesLabel": "Danh sách vai trò",
|
|
188
|
+
"detailLabel": "Chi tiết vai trò",
|
|
189
|
+
"locked": "Đã khóa",
|
|
190
|
+
"memberCount": "{count} thành viên",
|
|
191
|
+
"selectRole": "Chọn {role}",
|
|
192
|
+
"deleteRole": "Xóa {role}",
|
|
193
|
+
"deleteTitle": "Xóa vai trò này?",
|
|
194
|
+
"deleteDescription": "Xóa {role} sẽ gỡ quyền của vai trò này khỏi mọi thành viên được gán. Không thể hoàn tác.",
|
|
195
|
+
"deleteConfirm": "Xóa vai trò",
|
|
196
|
+
"empty": "Chưa có vai trò",
|
|
197
|
+
"emptyDescription": "Tạo một vai trò để bắt đầu gán quyền.",
|
|
198
|
+
"error": "Không tải được vai trò",
|
|
199
|
+
"errorDescription": "Không lấy được dữ liệu. Vui lòng thử lại sau giây lát.",
|
|
200
|
+
"denied": "Bạn không có quyền xem vai trò",
|
|
201
|
+
"deniedDescription": "Hãy đề nghị quản trị viên cấp quyền truy cập.",
|
|
202
|
+
"loading": "Đang tải vai trò…",
|
|
203
|
+
"noDetail": "Chọn một vai trò để xem chi tiết"
|
|
170
204
|
}
|
|
171
205
|
},
|
|
172
206
|
"dataDisplay": {
|
|
@@ -182,6 +216,21 @@
|
|
|
182
216
|
"listRow": {
|
|
183
217
|
"unread": "Chưa đọc",
|
|
184
218
|
"read": "Đã đọc"
|
|
219
|
+
},
|
|
220
|
+
"permissionMatrix": {
|
|
221
|
+
"caption": "Ma trận vai trò và quyền",
|
|
222
|
+
"permissionColumn": "Quyền",
|
|
223
|
+
"granted": "Được phép",
|
|
224
|
+
"notGranted": "Không được phép",
|
|
225
|
+
"difference": "Khác biệt",
|
|
226
|
+
"toggle": "Cấp {permission} cho {role}",
|
|
227
|
+
"locked": "Đã khóa",
|
|
228
|
+
"empty": "Chưa có quyền nào để hiển thị",
|
|
229
|
+
"error": "Không tải được ma trận quyền",
|
|
230
|
+
"errorDescription": "Không lấy được dữ liệu. Vui lòng thử lại sau giây lát.",
|
|
231
|
+
"denied": "Bạn không có quyền xem ma trận này",
|
|
232
|
+
"deniedDescription": "Hãy đề nghị quản trị viên cấp quyền truy cập.",
|
|
233
|
+
"loading": "Đang tải quyền…"
|
|
185
234
|
}
|
|
186
235
|
},
|
|
187
236
|
"ui": {
|
|
@@ -232,7 +281,7 @@
|
|
|
232
281
|
},
|
|
233
282
|
"filterBar": {
|
|
234
283
|
"appliedFilters": "Bộ lọc đang áp dụng",
|
|
235
|
-
"removeFilter": "Bỏ bộ lọc {label}",
|
|
284
|
+
"removeFilter": "Bỏ bộ lọc: {label}",
|
|
236
285
|
"resultCount": "{count} kết quả"
|
|
237
286
|
},
|
|
238
287
|
"localePicker": {
|
package/dist/lib/field-a11y.d.ts
CHANGED
|
@@ -39,6 +39,13 @@ export declare function mergeAriaIds(...values: Array<string | undefined>): stri
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
export declare function pickFieldA11y(props: FieldA11yProps): FieldA11yProps;
|
|
42
|
+
/**
|
|
43
|
+
* The inverse of {@link pickFieldA11y}: everything EXCEPT the field-a11y attributes. Use it when a
|
|
44
|
+
* component must route the contract somewhere other than the element the remaining props land on —
|
|
45
|
+
* e.g. `Select`'s compound API, where the props bag belongs to `SelectPrimitive.Root` (a
|
|
46
|
+
* context-only component that renders no DOM) while the accessible name has to reach the trigger.
|
|
47
|
+
*/
|
|
48
|
+
export declare function omitFieldA11y<T extends FieldA11yProps>(props: T): Omit<T, keyof FieldA11yProps>;
|
|
42
49
|
/**
|
|
43
50
|
* As {@link pickFieldA11y}, but resolves the accessible **name** for a control that also has an
|
|
44
51
|
* intrinsic `aria-label` (e.g. SearchInput's built-in "Search"): when the FormField supplies an
|
package/dist/lib/field-a11y.js
CHANGED
|
@@ -19,6 +19,11 @@ function pickFieldA11y(props) {
|
|
|
19
19
|
}
|
|
20
20
|
return out;
|
|
21
21
|
}
|
|
22
|
+
function omitFieldA11y(props) {
|
|
23
|
+
const out = { ...props };
|
|
24
|
+
for (const key of FIELD_A11Y_KEYS) delete out[key];
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
22
27
|
function resolveFieldA11y(props, intrinsicAriaLabel) {
|
|
23
28
|
const picked = pickFieldA11y(props);
|
|
24
29
|
if (picked["aria-labelledby"]) {
|
|
@@ -38,6 +43,7 @@ function pickGroupFieldA11y(props) {
|
|
|
38
43
|
}
|
|
39
44
|
export {
|
|
40
45
|
mergeAriaIds,
|
|
46
|
+
omitFieldA11y,
|
|
41
47
|
pickFieldA11y,
|
|
42
48
|
pickGroupFieldA11y,
|
|
43
49
|
resolveFieldA11y
|
package/dist/lib/hooks.d.ts
CHANGED
|
@@ -28,3 +28,18 @@ export declare function useTimeoutFlag(signal: unknown, ms?: number): boolean;
|
|
|
28
28
|
export declare function useControlledLatch(valueIsDefined: boolean): boolean;
|
|
29
29
|
export declare function useMediaQuery(query: string): boolean;
|
|
30
30
|
export declare function useIsMobile(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* WCAG 2.1.1 — a region that scrolls must be operable by keyboard. Tabbing to a focusable child
|
|
33
|
+
* scrolls the container, so a region whose content IS focusable needs nothing; one whose content is
|
|
34
|
+
* inert (plain text) strands its overflow for anyone not using a pointer and must therefore take
|
|
35
|
+
* focus itself via `tabindex="0"`. Which case applies depends on the RENDERED size and content —
|
|
36
|
+
* the same pagination strip is fine at 1440px and unreachable at 375px, and a panel full of text
|
|
37
|
+
* only overflows once it is resized — so it is measured at runtime and kept in sync as the element
|
|
38
|
+
* resizes or its content changes.
|
|
39
|
+
*
|
|
40
|
+
* The attribute is written imperatively rather than rendered: `react-resizable-panels` applies our
|
|
41
|
+
* className to a nested div it owns, which no prop can reach.
|
|
42
|
+
*
|
|
43
|
+
* @param element the scroll container itself (state, not a ref, so the effect re-runs when it mounts)
|
|
44
|
+
*/
|
|
45
|
+
export declare function useScrollableRegionTabIndex(element: HTMLElement | null): void;
|
package/dist/lib/hooks.js
CHANGED
|
@@ -68,10 +68,47 @@ function useMediaQuery(query) {
|
|
|
68
68
|
function useIsMobile() {
|
|
69
69
|
return useMediaQuery("(max-width: 767px)");
|
|
70
70
|
}
|
|
71
|
+
const SCROLLABLE_REGION_FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
72
|
+
function useScrollableRegionTabIndex(element) {
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!element) return;
|
|
75
|
+
const sync = () => {
|
|
76
|
+
const scrolls = element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
|
|
77
|
+
const hasFocusableContent = element.querySelector(SCROLLABLE_REGION_FOCUSABLE_SELECTOR) !== null;
|
|
78
|
+
if (scrolls && !hasFocusableContent) {
|
|
79
|
+
if (element.getAttribute("tabindex") !== "0") element.setAttribute("tabindex", "0");
|
|
80
|
+
} else if (element.getAttribute("tabindex") === "0") {
|
|
81
|
+
element.removeAttribute("tabindex");
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
sync();
|
|
85
|
+
const observers = [];
|
|
86
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
87
|
+
const resizeObserver = new ResizeObserver(sync);
|
|
88
|
+
resizeObserver.observe(element);
|
|
89
|
+
for (const child of Array.from(element.children)) resizeObserver.observe(child);
|
|
90
|
+
observers.push(resizeObserver);
|
|
91
|
+
}
|
|
92
|
+
if (typeof MutationObserver !== "undefined") {
|
|
93
|
+
const mutationObserver = new MutationObserver(sync);
|
|
94
|
+
mutationObserver.observe(element, {
|
|
95
|
+
childList: true,
|
|
96
|
+
subtree: true,
|
|
97
|
+
attributes: true,
|
|
98
|
+
attributeFilter: ["disabled", "href", "tabindex"]
|
|
99
|
+
});
|
|
100
|
+
observers.push(mutationObserver);
|
|
101
|
+
}
|
|
102
|
+
return () => {
|
|
103
|
+
for (const observer of observers) observer.disconnect();
|
|
104
|
+
};
|
|
105
|
+
}, [element]);
|
|
106
|
+
}
|
|
71
107
|
export {
|
|
72
108
|
useControlledLatch,
|
|
73
109
|
useDebouncedValue,
|
|
74
110
|
useIsMobile,
|
|
75
111
|
useMediaQuery,
|
|
112
|
+
useScrollableRegionTabIndex,
|
|
76
113
|
useTimeoutFlag
|
|
77
114
|
};
|
|
@@ -229,3 +229,69 @@ export type ListRowProp = {
|
|
|
229
229
|
unread?: boolean;
|
|
230
230
|
className?: ClassNameProp;
|
|
231
231
|
};
|
|
232
|
+
/** @see PermissionMatrix — one role COLUMN. Domain data is consumer-supplied; nothing is encoded. */
|
|
233
|
+
export type PermissionMatrixRoleProp = {
|
|
234
|
+
/** Stable role id — the `roleId` half of a grant key. */
|
|
235
|
+
id: string;
|
|
236
|
+
/** Human role name (also used in accessible cell labels, so a plain string). */
|
|
237
|
+
name: string;
|
|
238
|
+
/** Short hint under the role name (e.g. member count or scope). */
|
|
239
|
+
description?: string;
|
|
240
|
+
/** A locked role renders read-only cells even when the matrix is editable. */
|
|
241
|
+
locked?: boolean;
|
|
242
|
+
};
|
|
243
|
+
/** @see PermissionMatrix — one permission ROW. */
|
|
244
|
+
export type PermissionMatrixPermissionProp = {
|
|
245
|
+
/** Stable permission id — the `permissionId` half of a grant key. */
|
|
246
|
+
id: string;
|
|
247
|
+
/** Human permission name (also used in accessible cell labels, so a plain string). */
|
|
248
|
+
name: string;
|
|
249
|
+
/** Secondary line under the permission name. */
|
|
250
|
+
description?: string;
|
|
251
|
+
/** Optional category caption rendered with the description (e.g. 請求 / レポート). */
|
|
252
|
+
group?: string;
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* @see PermissionMatrix — the grant relation. Either the `grantKey(roleId, permissionId)` `Set`
|
|
256
|
+
* from `@godxjp/ui/lib/permission-grid` (O(1), the canonical form) or a plain pair array, which the
|
|
257
|
+
* matrix normalizes through the same `grantKey` encoding.
|
|
258
|
+
*/
|
|
259
|
+
export type PermissionMatrixGrantsProp = ReadonlySet<string> | readonly {
|
|
260
|
+
roleId: string;
|
|
261
|
+
permissionId: string;
|
|
262
|
+
}[];
|
|
263
|
+
/** @see PermissionMatrix */
|
|
264
|
+
export type PermissionMatrixProp = {
|
|
265
|
+
/** Role columns, in render order. */
|
|
266
|
+
roles: readonly PermissionMatrixRoleProp[];
|
|
267
|
+
/** Permission rows, in render order. */
|
|
268
|
+
permissions: readonly PermissionMatrixPermissionProp[];
|
|
269
|
+
/** The grant relation (see {@link PermissionMatrixGrantsProp}). */
|
|
270
|
+
grants: PermissionMatrixGrantsProp;
|
|
271
|
+
/**
|
|
272
|
+
* Grant toggle handler. Its PRESENCE makes the matrix editable (checkbox cells); omitted, the
|
|
273
|
+
* matrix is the canonical read-only ✓/— grid. Locked roles and `readOnly` stay read-only
|
|
274
|
+
* regardless.
|
|
275
|
+
*/
|
|
276
|
+
onGrantChange?: (roleId: string, permissionId: string, granted: boolean) => void;
|
|
277
|
+
/** Force the read-only grid even when `onGrantChange` is present (e.g. viewer permission). */
|
|
278
|
+
readOnly?: boolean;
|
|
279
|
+
/** Two role ids to compare side by side; highlights their columns and the differing rows. */
|
|
280
|
+
compare?: readonly [string, string] | null;
|
|
281
|
+
/** With `compare`, keep only the rows on which the two roles differ (差分のみ). */
|
|
282
|
+
diffOnly?: boolean;
|
|
283
|
+
/** Accessible name for the grid. Defaults to the localized caption. */
|
|
284
|
+
label?: LabelProp;
|
|
285
|
+
/** Show the loading skeleton instead of the grid. Precedence: loading → denied → error → empty. */
|
|
286
|
+
loading?: boolean;
|
|
287
|
+
/** Custom empty content when `permissions` is empty; defaults to a localized EmptyState. */
|
|
288
|
+
empty?: React.ReactNode;
|
|
289
|
+
/** Failure state (mirrors DataTable #216): `true` = built-in localized message, node = replace. */
|
|
290
|
+
error?: React.ReactNode;
|
|
291
|
+
/** Permission-denied state — refused, not failed. Takes precedence over `error`. */
|
|
292
|
+
denied?: React.ReactNode;
|
|
293
|
+
/** Retry handler for the built-in `error` state; omit to hide the retry action. */
|
|
294
|
+
onRetry?: HandlerProp;
|
|
295
|
+
className?: ClassNameProp;
|
|
296
|
+
id?: IdProp;
|
|
297
|
+
};
|
|
@@ -517,3 +517,57 @@ export type TransferProp = FieldA11yProps & {
|
|
|
517
517
|
selectedKeys?: [string[], string[]];
|
|
518
518
|
onSelectChange?: (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => void;
|
|
519
519
|
};
|
|
520
|
+
/** @see BranchScopePicker — scope mode: every branch, or an explicit subset. */
|
|
521
|
+
export type BranchScopeModeProp = "all" | "selected";
|
|
522
|
+
/**
|
|
523
|
+
* @see BranchScopePicker — the picker value. `mode: "all"` ignores `branchIds`; `mode: "selected"`
|
|
524
|
+
* carries the checked branch ids.
|
|
525
|
+
*/
|
|
526
|
+
export type BranchScopeValueProp = {
|
|
527
|
+
mode: BranchScopeModeProp;
|
|
528
|
+
branchIds?: readonly string[];
|
|
529
|
+
};
|
|
530
|
+
/** @see BranchScopePicker — one selectable branch. Domain data is consumer-supplied. */
|
|
531
|
+
export type BranchScopeOptionProp = {
|
|
532
|
+
/** Stable branch id. */
|
|
533
|
+
id: string;
|
|
534
|
+
/** Human branch name (also the search haystack, so a plain string). */
|
|
535
|
+
name: string;
|
|
536
|
+
/** Secondary line under the branch name (e.g. an address or code). */
|
|
537
|
+
description?: string;
|
|
538
|
+
/** Keep the branch visible but unselectable. */
|
|
539
|
+
disabled?: boolean;
|
|
540
|
+
};
|
|
541
|
+
/** @see BranchScopePicker */
|
|
542
|
+
export type BranchScopePickerProp = FieldA11yProps & {
|
|
543
|
+
/** The selectable branches. */
|
|
544
|
+
branches: readonly BranchScopeOptionProp[];
|
|
545
|
+
/** Controlled value. */
|
|
546
|
+
value?: BranchScopeValueProp;
|
|
547
|
+
/** Uncontrolled initial value. Default `{ mode: "all" }`. */
|
|
548
|
+
defaultValue?: BranchScopeValueProp;
|
|
549
|
+
/** Value change handler (fires for mode switches AND branch checks). */
|
|
550
|
+
onValueChange?: (value: BranchScopeValueProp) => void;
|
|
551
|
+
/** Disable the whole control. */
|
|
552
|
+
disabled?: DisabledProp;
|
|
553
|
+
/** Render the current value without any editable affordance (locked view). */
|
|
554
|
+
readOnly?: boolean;
|
|
555
|
+
/** Show a branch search input above the list once there is anything to search. Default `true`. */
|
|
556
|
+
searchable?: boolean;
|
|
557
|
+
/** Validation message under the control (wired via `aria-errormessage`/`aria-invalid`). */
|
|
558
|
+
error?: ErrorProp;
|
|
559
|
+
/** Show the loading skeleton instead of the list. Precedence: loading → denied → listError → empty. */
|
|
560
|
+
loading?: boolean;
|
|
561
|
+
/** Custom empty content when `branches` is empty; defaults to a localized message. */
|
|
562
|
+
empty?: React.ReactNode;
|
|
563
|
+
/** Branch-collection READ failure (distinct from `error`, which is field validation). */
|
|
564
|
+
listError?: React.ReactNode;
|
|
565
|
+
/** Permission-denied state — the branch read was refused. Takes precedence over `listError`. */
|
|
566
|
+
denied?: React.ReactNode;
|
|
567
|
+
/** Radio labels override (localized defaults otherwise). */
|
|
568
|
+
allLabel?: React.ReactNode;
|
|
569
|
+
selectedLabel?: React.ReactNode;
|
|
570
|
+
name?: NameProp;
|
|
571
|
+
id?: IdProp;
|
|
572
|
+
className?: ClassNameProp;
|
|
573
|
+
};
|
|
@@ -43,9 +43,9 @@ export type AlertProp = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
43
43
|
children?: ChildrenProp;
|
|
44
44
|
};
|
|
45
45
|
/**
|
|
46
|
-
* @see Banner —
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
* @see Banner — the full-bleed attention strip (`<Alert variant="banner">` with the variant fixed).
|
|
47
|
+
* Same contract as {@link AlertProp} minus `variant`: `tone` owns colour + live-region politeness,
|
|
48
|
+
* `icon`/`icon={false}` owns the leading glyph, `onDismiss` renders the built-in dismiss button.
|
|
49
49
|
*/
|
|
50
50
|
export type BannerProp = Omit<AlertProp, "variant">;
|
|
51
51
|
/** @see AlertTitle */
|
|
@@ -12,8 +12,15 @@ export type TextProp = Omit<React.HTMLAttributes<HTMLElement>, "color"> & {
|
|
|
12
12
|
/** Weight (system 2-weight: 400/500). Default `regular`. */
|
|
13
13
|
weight?: FontWeightProp;
|
|
14
14
|
align?: TextAlignProp;
|
|
15
|
-
/** Single-line ellipsis. */
|
|
15
|
+
/** Single-line ellipsis. Mutually exclusive with `clamp` — when both are set, `clamp` wins. */
|
|
16
16
|
truncate?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Multi-line clamp — max rendered lines (integer ≥ 1); overflow ends in an ellipsis.
|
|
19
|
+
* Token-owned line-clamp styling (never write the `line-clamp-N` utility page-side).
|
|
20
|
+
* Visual-only: the full text stays in the DOM / accessible name. Mutually exclusive with
|
|
21
|
+
* `truncate` — when both are set, `clamp` wins (dev builds warn).
|
|
22
|
+
*/
|
|
23
|
+
clamp?: number;
|
|
17
24
|
/** Tabular figures for aligned numbers. */
|
|
18
25
|
tabular?: boolean;
|
|
19
26
|
/** Monospace family (codes, ids). */
|