@godxjp/ui 18.8.0 → 18.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +202 -0
  2. package/dist/components/data-display/badge.d.ts +7 -0
  3. package/dist/components/data-display/badge.js +1 -1
  4. package/dist/components/data-display/card.d.ts +3 -27
  5. package/dist/components/data-display/card.js +1 -4
  6. package/dist/components/data-display/data-table.js +2 -2
  7. package/dist/components/data-display/index.d.ts +2 -0
  8. package/dist/components/data-display/index.js +2 -0
  9. package/dist/components/data-display/permission-matrix.d.ts +26 -0
  10. package/dist/components/data-display/permission-matrix.js +219 -0
  11. package/dist/components/data-display/table.d.ts +12 -0
  12. package/dist/components/data-entry/branch-scope-picker.d.ts +43 -0
  13. package/dist/components/data-entry/branch-scope-picker.js +200 -0
  14. package/dist/components/data-entry/command-palette.js +8 -1
  15. package/dist/components/data-entry/index.d.ts +2 -0
  16. package/dist/components/data-entry/index.js +2 -0
  17. package/dist/components/data-entry/input-otp.d.ts +1 -1
  18. package/dist/components/feedback/alert.d.ts +2 -20
  19. package/dist/components/feedback/alert.js +1 -11
  20. package/dist/components/feedback/banner.d.ts +21 -0
  21. package/dist/components/feedback/banner.js +15 -0
  22. package/dist/components/feedback/index.d.ts +4 -2
  23. package/dist/components/feedback/index.js +2 -2
  24. package/dist/components/general/typography.d.ts +1 -0
  25. package/dist/components/general/typography.js +32 -13
  26. package/dist/components/layout/auth-shell.d.ts +2 -2
  27. package/dist/components/layout/index.d.ts +2 -2
  28. package/dist/components/layout/index.js +2 -2
  29. package/dist/components/layout/page-container.d.ts +1 -1
  30. package/dist/components/layout/page-container.js +45 -19
  31. package/dist/components/layout/service-role-panel.d.ts +25 -0
  32. package/dist/components/layout/service-role-panel.js +206 -0
  33. package/dist/components/navigation/filter-bar.d.ts +2 -2
  34. package/dist/components/navigation/filter-bar.js +113 -34
  35. package/dist/components/navigation/index.d.ts +1 -1
  36. package/dist/components/navigation/steps.d.ts +2 -2
  37. package/dist/components/navigation/steps.js +2 -4
  38. package/dist/components/ui/avatar.d.ts +1 -1
  39. package/dist/components/ui/avatar.js +1 -2
  40. package/dist/components/ui/input-otp.d.ts +3 -15
  41. package/dist/components/ui/input-otp.js +1 -2
  42. package/dist/email/tokens.generated.d.ts +2 -2
  43. package/dist/email/tokens.generated.js +2 -2
  44. package/dist/i18n/messages/en.json +56 -4
  45. package/dist/i18n/messages/ja.json +51 -5
  46. package/dist/i18n/messages/vi.json +50 -4
  47. package/dist/props/components/data-display.prop.d.ts +66 -16
  48. package/dist/props/components/data-entry.prop.d.ts +54 -7
  49. package/dist/props/components/feedback.prop.d.ts +3 -3
  50. package/dist/props/components/general.prop.d.ts +8 -1
  51. package/dist/props/components/layout.prop.d.ts +75 -54
  52. package/dist/props/components/navigation.prop.d.ts +77 -59
  53. package/dist/props/registry.d.ts +273 -72
  54. package/dist/props/registry.js +361 -92
  55. package/dist/props/vocabulary/content.prop.d.ts +5 -0
  56. package/dist/props/vocabulary/index.d.ts +1 -1
  57. package/dist/props/vocabulary/interaction.prop.d.ts +4 -7
  58. package/dist/props/vocabulary/layout.prop.d.ts +2 -2
  59. package/dist/styles/alert-layout.css +15 -32
  60. package/dist/styles/badge-layout.css +5 -0
  61. package/dist/styles/card-layout.css +13 -49
  62. package/dist/styles/control.css +2 -12
  63. package/dist/styles/data-display-layout.css +0 -16
  64. package/dist/styles/layout.css +102 -108
  65. package/dist/styles/navigation-layout.css +3 -8
  66. package/dist/styles/shell-layout.css +17 -17
  67. package/dist/styles/table-layout.css +77 -2
  68. package/dist/styles/text-layout.css +13 -0
  69. package/dist/tokens/base.css +1 -0
  70. package/dist/tokens/components/badge.css +5 -0
  71. package/dist/tokens/components/banner.css +16 -0
  72. package/dist/tokens/components/card.css +0 -12
  73. package/dist/tokens/components/control.css +0 -16
  74. package/dist/tokens/components/data-display.css +0 -12
  75. package/dist/tokens/components/email.css +2 -8
  76. package/dist/tokens/components/feedback.css +0 -20
  77. package/dist/tokens/components/navigation.css +10 -34
  78. package/dist/tokens/components/shell.css +24 -36
  79. package/dist/tokens/components/table.css +41 -1
  80. package/dist/tokens/semantic/layout.css +5 -12
  81. package/package.json +15 -2
  82. package/dist/components/layout/page-header.d.ts +0 -22
  83. package/dist/components/layout/page-header.js +0 -89
@@ -121,6 +121,11 @@ const VOCABULARY_REGISTRY = {
121
121
  category: "content",
122
122
  description: "Secondary line under title"
123
123
  },
124
+ StatusProp: {
125
+ file: "vocabulary/content.prop.ts",
126
+ category: "content",
127
+ description: "Status/meta band beside a title (StatusBadge, meta text)"
128
+ },
124
129
  DescriptionProp: {
125
130
  file: "vocabulary/content.prop.ts",
126
131
  category: "content",
@@ -220,7 +225,7 @@ const VOCABULARY_REGISTRY = {
220
225
  AuthShellPresetProp: {
221
226
  file: "vocabulary/layout.prop.ts",
222
227
  category: "layout",
223
- description: "AuthShell named flow geometry \u2014 default | login (stable SCR-001 identity/card/footer anchor) | device-authorization (380px card, 5px mobile gutter) | context-selection (25rem card, edge-to-edge mobile) | account-recovery (432px SCR-008 recovery/MFA panel, 15px mobile gutter)"
228
+ description: "AuthShell named flow geometry \u2014 default | login (stable SCR-001 identity/card/footer anchor) | registration (360px SCR-002 sign-up measure, start-aligned long-form scroll, own footer clearance, 15px mobile gutter) | device-authorization (380px card, 5px mobile gutter) | context-selection (25rem card, edge-to-edge mobile) | account-recovery (432px SCR-008 recovery/MFA panel, 15px mobile gutter)"
224
229
  },
225
230
  GapProp: {
226
231
  file: "vocabulary/layout.prop.ts",
@@ -321,7 +326,7 @@ const VOCABULARY_REGISTRY = {
321
326
  AlertVariantProp: {
322
327
  file: "vocabulary/interaction.prop.ts",
323
328
  category: "interaction",
324
- description: "Inline Alert banner tone"
329
+ description: "Alert structural axis: default inline card | banner full-bleed strip"
325
330
  },
326
331
  SortDirectionProp: {
327
332
  file: "vocabulary/interaction.prop.ts",
@@ -465,52 +470,18 @@ const COMPONENT_PROP_REGISTRY = {
465
470
  file: "components/layout.prop.ts",
466
471
  vocabulary: []
467
472
  },
468
- PageHeaderProp: {
469
- group: "layout",
470
- file: "components/layout.prop.ts",
471
- vocabulary: [
472
- "TitleProp",
473
- "SubtitleProp",
474
- "ExtraProp",
475
- "BreadcrumbProp",
476
- {
477
- field: "meta",
478
- local: true,
479
- reason: "Status/meta band rendered inline with the `<h1>` (a Badge tone, a record id, a timestamp). A free ReactNode slot, not a controlled value \u2014 the header never interprets what it holds."
480
- },
481
- {
482
- field: "layout",
483
- local: true,
484
- reason: "Header ARRANGEMENT of the title band vs the extra slot below the 640px step (stack | responsive-inline) \u2014 the standalone spelling of PageContainer's `headerLayout`."
485
- },
486
- {
487
- field: "loading",
488
- local: true,
489
- reason: "Pending state of the TITLE BAND only (skeleton title/subtitle + aria-busy), distinct from a page-wide DataState: breadcrumbs and actions come from the route and stay live while the record resolves."
490
- }
491
- ]
492
- },
493
473
  PageContainerProp: {
494
474
  group: "layout",
495
475
  file: "components/layout.prop.ts",
496
476
  vocabulary: [
497
477
  "TitleProp",
498
478
  "SubtitleProp",
479
+ "StatusProp",
499
480
  "ExtraProp",
500
481
  "FooterProp",
501
482
  "BreadcrumbProp",
502
483
  "DensityProp",
503
484
  "PageContainerVariantProp",
504
- {
505
- field: "meta",
506
- local: true,
507
- reason: "Forwarded verbatim to PageHeader's `meta` slot \u2014 see PageHeaderProp."
508
- },
509
- {
510
- field: "headerLoading",
511
- local: true,
512
- reason: "Forwarded to PageHeader's `loading`. Named for the BAND it skeletonises, so it can never be read as a page-wide loading flag (that is DataState's job)."
513
- },
514
485
  {
515
486
  field: "headerLayout",
516
487
  local: true,
@@ -1224,11 +1195,6 @@ const COMPONENT_PROP_REGISTRY = {
1224
1195
  file: "components/data-display.prop.ts",
1225
1196
  vocabulary: ["AvatarShapeProp", "ChildrenProp", "ClassNameProp"]
1226
1197
  },
1227
- AvatarAppearanceProp: {
1228
- group: "data-display",
1229
- file: "components/data-display.prop.ts",
1230
- vocabulary: []
1231
- },
1232
1198
  BadgeProp: {
1233
1199
  group: "data-display",
1234
1200
  file: "components/data-display.prop.ts",
@@ -1526,8 +1492,6 @@ const COMPONENT_PROP_REGISTRY = {
1526
1492
  BannerProp: {
1527
1493
  group: "feedback",
1528
1494
  file: "components/feedback.prop.ts",
1529
- // `Omit<AlertProp, "variant">` — the alias fixes the one prop it drops, so it inherits Alert's
1530
- // vocabulary exactly. Listing it again here is what keeps the guard honest if Alert's API moves.
1531
1495
  vocabulary: ["ToneProp", "IconProp", "OnValueChangeProp", "ClassNameProp", "ChildrenProp"]
1532
1496
  },
1533
1497
  AlertTitleProp: {
@@ -1559,52 +1523,33 @@ const COMPONENT_PROP_REGISTRY = {
1559
1523
  "OnClearFiltersProp",
1560
1524
  "HasActiveFiltersProp",
1561
1525
  "StickyProp",
1526
+ "ActionsProp",
1527
+ "PendingProp",
1528
+ "DisabledProp",
1529
+ "ErrorProp",
1562
1530
  "ClassNameProp",
1563
- "ChildrenProp",
1564
- {
1565
- field: "search",
1566
- local: true,
1567
- reason: "SLOT for the caller's own search control, positioned at the start of the row and measured by --filter-bar-search-width. Not a value/onValueChange pair: the bar owns the search's PLACE and WIDTH, never its state (gh#258)."
1568
- },
1569
- {
1570
- field: "chips",
1571
- local: true,
1572
- reason: "APPLIED filters as removable chips \u2014 the visible record of filters already in effect, distinct from the controls that set them. A bar-specific shape (id/label/onRemove), not a shared vocabulary type (gh#258)."
1573
- },
1574
- {
1575
- field: "onChipRemove",
1576
- local: true,
1577
- reason: "Chip-removal callback keyed by chip id. Not `onValueChange`: it reports ONE lifted filter rather than the bar's whole value, which the bar deliberately does not hold (gh#258)."
1578
- },
1579
- {
1580
- field: "resultCount",
1581
- local: true,
1582
- reason: "Number of records the current filters resolve to, announced in a polite live region and formatted via Intl.NumberFormat + CLDR plurals. Presentational output, not a controlled value (gh#258)."
1583
- },
1584
- {
1585
- field: "actions",
1586
- local: true,
1587
- reason: "Trailing action SLOT (export, column settings, saved views), ordered AFTER the reset control by the bar so `clear filters` never sits beside an unrelated primary action (gh#258)."
1588
- }
1531
+ "ChildrenProp"
1589
1532
  ]
1590
1533
  },
1591
- FilterBarChipProp: {
1534
+ FilterBarOverflowProp: {
1592
1535
  group: "navigation",
1593
1536
  file: "components/navigation.prop.ts",
1594
- vocabulary: [
1595
- "IdProp",
1596
- "LabelProp",
1597
- {
1598
- field: "onRemove",
1599
- local: true,
1600
- reason: "Per-chip removal. Omitting it is meaningful \u2014 the chip renders with NO remove control (a filter the user may not lift), rather than a disabled button that is a dead tab stop (gh#258)."
1601
- }
1602
- ]
1537
+ vocabulary: []
1603
1538
  },
1604
- FilterBarOverflowProp: {
1539
+ FilterBarSearchProp: {
1605
1540
  group: "navigation",
1606
1541
  file: "components/navigation.prop.ts",
1607
- vocabulary: []
1542
+ vocabulary: ["PlaceholderProp", "IdProp", "DisabledProp"]
1543
+ },
1544
+ FilterBarFilterProp: {
1545
+ group: "navigation",
1546
+ file: "components/navigation.prop.ts",
1547
+ vocabulary: ["LabelProp", "PlaceholderProp", "DisabledProp"]
1548
+ },
1549
+ FilterBarChipProp: {
1550
+ group: "navigation",
1551
+ file: "components/navigation.prop.ts",
1552
+ vocabulary: ["DisabledProp"]
1608
1553
  },
1609
1554
  ToolbarGroupProp: {
1610
1555
  group: "navigation",
@@ -1631,22 +1576,12 @@ const COMPONENT_PROP_REGISTRY = {
1631
1576
  file: "components/data-entry.prop.ts",
1632
1577
  vocabulary: []
1633
1578
  },
1634
- InputOTPAlignProp: {
1635
- group: "data-entry",
1636
- file: "components/data-entry.prop.ts",
1637
- vocabulary: []
1638
- },
1639
1579
  StepItemProp: {
1640
1580
  group: "navigation",
1641
1581
  file: "components/navigation.prop.ts",
1642
1582
  vocabulary: ["TitleProp", "SubtitleProp", "DescriptionProp", "IconProp", "DisabledProp"]
1643
1583
  },
1644
1584
  StepStatusProp: { group: "navigation", file: "components/navigation.prop.ts", vocabulary: [] },
1645
- StepsSeparatorProp: {
1646
- group: "navigation",
1647
- file: "components/navigation.prop.ts",
1648
- vocabulary: []
1649
- },
1650
1585
  TabsProp: {
1651
1586
  group: "navigation",
1652
1587
  file: "components/navigation.prop.ts",
@@ -1813,6 +1748,340 @@ const COMPONENT_PROP_REGISTRY = {
1813
1748
  group: "layout",
1814
1749
  file: "components/layout/split-pane.tsx",
1815
1750
  vocabulary: ["ClassNameProp", "ChildrenProp"]
1751
+ },
1752
+ PermissionMatrixRoleProp: {
1753
+ group: "data-display",
1754
+ file: "components/data-display.prop.ts",
1755
+ vocabulary: [
1756
+ "IdProp",
1757
+ {
1758
+ field: "name",
1759
+ local: true,
1760
+ reason: "Consumer-supplied role display name; a plain string so it can label cells for AT."
1761
+ },
1762
+ {
1763
+ field: "description",
1764
+ local: true,
1765
+ reason: "Secondary caption under the role column header."
1766
+ },
1767
+ {
1768
+ field: "locked",
1769
+ local: true,
1770
+ reason: "Per-role read-only flag \u2014 a locked role keeps \u2713/\u2014 cells in an editable matrix."
1771
+ }
1772
+ ]
1773
+ },
1774
+ PermissionMatrixPermissionProp: {
1775
+ group: "data-display",
1776
+ file: "components/data-display.prop.ts",
1777
+ vocabulary: [
1778
+ "IdProp",
1779
+ {
1780
+ field: "name",
1781
+ local: true,
1782
+ reason: "Consumer-supplied permission display name; plain string for accessible labels."
1783
+ },
1784
+ {
1785
+ field: "description",
1786
+ local: true,
1787
+ reason: "Secondary line under the permission name."
1788
+ },
1789
+ {
1790
+ field: "group",
1791
+ local: true,
1792
+ reason: "Optional category caption for the permission row."
1793
+ }
1794
+ ]
1795
+ },
1796
+ PermissionMatrixGrantsProp: {
1797
+ group: "data-display",
1798
+ file: "components/data-display.prop.ts",
1799
+ vocabulary: [
1800
+ {
1801
+ field: "grants",
1802
+ local: true,
1803
+ reason: "The role\xD7permission grant relation \u2014 the grantKey Set from lib/permission-grid or a pair array normalized through the same encoding."
1804
+ }
1805
+ ]
1806
+ },
1807
+ PermissionMatrixProp: {
1808
+ group: "data-display",
1809
+ file: "components/data-display.prop.ts",
1810
+ vocabulary: [
1811
+ "LabelProp",
1812
+ "HandlerProp",
1813
+ "ClassNameProp",
1814
+ "IdProp",
1815
+ {
1816
+ field: "roles",
1817
+ local: true,
1818
+ reason: "Consumer-supplied role columns (see PermissionMatrixRoleProp)."
1819
+ },
1820
+ {
1821
+ field: "permissions",
1822
+ local: true,
1823
+ reason: "Consumer-supplied permission rows (see PermissionMatrixPermissionProp)."
1824
+ },
1825
+ {
1826
+ field: "grants",
1827
+ local: true,
1828
+ reason: "The grant relation (see PermissionMatrixGrantsProp)."
1829
+ },
1830
+ {
1831
+ field: "onGrantChange",
1832
+ local: true,
1833
+ reason: "Cell toggle handler carrying the (roleId, permissionId, granted) triple; its presence switches the grid from read-only \u2713/\u2014 to editable checkboxes."
1834
+ },
1835
+ {
1836
+ field: "readOnly",
1837
+ local: true,
1838
+ reason: "Forces the read-only grid even when onGrantChange is present (viewer permission)."
1839
+ },
1840
+ {
1841
+ field: "compare",
1842
+ local: true,
1843
+ reason: "Two role ids compared side by side \u2014 the lib/permission-grid ComparePair."
1844
+ },
1845
+ {
1846
+ field: "diffOnly",
1847
+ local: true,
1848
+ reason: "\u5DEE\u5206\u306E\u307F filter: with compare set, keep only the rows where the two roles differ."
1849
+ },
1850
+ {
1851
+ field: "loading",
1852
+ local: true,
1853
+ reason: "Read-lifecycle skeleton state mirroring DataTable #216 (precedence loading \u2192 denied \u2192 error \u2192 empty)."
1854
+ },
1855
+ {
1856
+ field: "empty",
1857
+ local: true,
1858
+ reason: "Custom empty content override, mirroring DataTable's empty slot."
1859
+ },
1860
+ {
1861
+ field: "error",
1862
+ local: true,
1863
+ reason: "Read-failure state mirroring DataTable #216 (true = built-in localized message)."
1864
+ },
1865
+ {
1866
+ field: "denied",
1867
+ local: true,
1868
+ reason: "Permission-denied read state mirroring DataTable #216 \u2014 refused, not failed."
1869
+ },
1870
+ {
1871
+ field: "onRetry",
1872
+ local: true,
1873
+ reason: "Retry affordance for the built-in error state, mirroring DataTable #216."
1874
+ }
1875
+ ]
1876
+ },
1877
+ BranchScopeModeProp: {
1878
+ group: "data-entry",
1879
+ file: "components/data-entry.prop.ts",
1880
+ vocabulary: [
1881
+ {
1882
+ field: "mode",
1883
+ local: true,
1884
+ reason: "Closed scope vocabulary: all branches vs an explicit subset."
1885
+ }
1886
+ ]
1887
+ },
1888
+ BranchScopeValueProp: {
1889
+ group: "data-entry",
1890
+ file: "components/data-entry.prop.ts",
1891
+ vocabulary: [
1892
+ {
1893
+ field: "mode",
1894
+ local: true,
1895
+ reason: "The selected scope mode (see BranchScopeModeProp)."
1896
+ },
1897
+ {
1898
+ field: "branchIds",
1899
+ local: true,
1900
+ reason: "Checked branch ids, meaningful only when mode = selected."
1901
+ }
1902
+ ]
1903
+ },
1904
+ BranchScopeOptionProp: {
1905
+ group: "data-entry",
1906
+ file: "components/data-entry.prop.ts",
1907
+ vocabulary: [
1908
+ "IdProp",
1909
+ "DisabledProp",
1910
+ {
1911
+ field: "name",
1912
+ local: true,
1913
+ reason: "Consumer-supplied branch display name; plain string so it is searchable."
1914
+ },
1915
+ {
1916
+ field: "description",
1917
+ local: true,
1918
+ reason: "Secondary line under the branch name."
1919
+ }
1920
+ ]
1921
+ },
1922
+ BranchScopePickerProp: {
1923
+ group: "data-entry",
1924
+ file: "components/data-entry.prop.ts",
1925
+ vocabulary: [
1926
+ "ValueProp",
1927
+ "DefaultValueProp",
1928
+ "OnValueChangeProp",
1929
+ "DisabledProp",
1930
+ "ErrorProp",
1931
+ "NameProp",
1932
+ "IdProp",
1933
+ "ClassNameProp",
1934
+ {
1935
+ field: "branches",
1936
+ local: true,
1937
+ reason: "Consumer-supplied selectable branches (see BranchScopeOptionProp)."
1938
+ },
1939
+ {
1940
+ field: "readOnly",
1941
+ local: true,
1942
+ reason: "Locked view: render the current scope without editable affordances."
1943
+ },
1944
+ {
1945
+ field: "searchable",
1946
+ local: true,
1947
+ reason: "Toggle for the built-in branch SearchInput above the checkbox list."
1948
+ },
1949
+ {
1950
+ field: "loading",
1951
+ local: true,
1952
+ reason: "Read-lifecycle skeleton state (precedence loading \u2192 denied \u2192 listError \u2192 empty)."
1953
+ },
1954
+ {
1955
+ field: "empty",
1956
+ local: true,
1957
+ reason: "Custom empty content when there are no branches."
1958
+ },
1959
+ {
1960
+ field: "listError",
1961
+ local: true,
1962
+ reason: "Branch-collection READ failure \u2014 deliberately distinct from ErrorProp `error`, which stays field validation."
1963
+ },
1964
+ {
1965
+ field: "denied",
1966
+ local: true,
1967
+ reason: "Permission-denied read state \u2014 the branch collection was refused, not failed."
1968
+ },
1969
+ {
1970
+ field: "allLabel",
1971
+ local: true,
1972
+ reason: "Override for the localized all-branches radio label."
1973
+ },
1974
+ {
1975
+ field: "selectedLabel",
1976
+ local: true,
1977
+ reason: "Override for the localized selected-branches radio label."
1978
+ }
1979
+ ]
1980
+ },
1981
+ ServiceRoleItemProp: {
1982
+ group: "layout",
1983
+ file: "components/layout.prop.ts",
1984
+ vocabulary: [
1985
+ "IdProp",
1986
+ {
1987
+ field: "name",
1988
+ local: true,
1989
+ reason: "Consumer-supplied role display name; plain string for accessible labels."
1990
+ },
1991
+ {
1992
+ field: "description",
1993
+ local: true,
1994
+ reason: "Secondary line under the role name in the master rail."
1995
+ },
1996
+ {
1997
+ field: "memberCount",
1998
+ local: true,
1999
+ reason: "Member count caption, pluralized via CLDR categories."
2000
+ },
2001
+ {
2002
+ field: "locked",
2003
+ local: true,
2004
+ reason: "System-role flag: lock badge, no delete affordance ever."
2005
+ }
2006
+ ]
2007
+ },
2008
+ ServiceRolePanelProp: {
2009
+ group: "layout",
2010
+ file: "components/layout.prop.ts",
2011
+ vocabulary: [
2012
+ "ValueProp",
2013
+ "DefaultValueProp",
2014
+ "OnValueChangeProp",
2015
+ "ChildrenProp",
2016
+ "BreakpointProp",
2017
+ "IdProp",
2018
+ "ClassNameProp",
2019
+ {
2020
+ field: "roles",
2021
+ local: true,
2022
+ reason: "Consumer-supplied role collection (see ServiceRoleItemProp)."
2023
+ },
2024
+ {
2025
+ field: "onDeleteRole",
2026
+ local: true,
2027
+ reason: "Confirmed-deletion handler; its presence arms the built-in destructive AlertDialog per non-locked role."
2028
+ },
2029
+ {
2030
+ field: "readOnly",
2031
+ local: true,
2032
+ reason: "Locked view: hides every mutating affordance."
2033
+ },
2034
+ {
2035
+ field: "loading",
2036
+ local: true,
2037
+ reason: "Read-lifecycle skeleton state (precedence loading \u2192 denied \u2192 error \u2192 empty)."
2038
+ },
2039
+ {
2040
+ field: "empty",
2041
+ local: true,
2042
+ reason: "Custom empty content when there are no roles."
2043
+ },
2044
+ {
2045
+ field: "error",
2046
+ local: true,
2047
+ reason: "Read-failure state (true = built-in localized message, node replaces it)."
2048
+ },
2049
+ {
2050
+ field: "denied",
2051
+ local: true,
2052
+ reason: "Permission-denied read state \u2014 refused, not failed."
2053
+ },
2054
+ {
2055
+ field: "onRetry",
2056
+ local: true,
2057
+ reason: "Retry affordance for the built-in error state."
2058
+ },
2059
+ {
2060
+ field: "masterLabel",
2061
+ local: true,
2062
+ reason: "Accessible name override for the roles region (localized default otherwise)."
2063
+ },
2064
+ {
2065
+ field: "detailLabel",
2066
+ local: true,
2067
+ reason: "Accessible name override for the detail region (localized default otherwise)."
2068
+ },
2069
+ {
2070
+ field: "railWidth",
2071
+ local: true,
2072
+ reason: "Forwarded MasterDetail rail geometry preset."
2073
+ },
2074
+ {
2075
+ field: "masterViewport",
2076
+ local: true,
2077
+ reason: "Forwarded MasterDetail bounded-collection preset."
2078
+ },
2079
+ {
2080
+ field: "collapseBelow",
2081
+ local: true,
2082
+ reason: "Forwarded MasterDetail stacking threshold override."
2083
+ }
2084
+ ]
1816
2085
  }
1817
2086
  };
1818
2087
  const PROP_ALIASES_FORBIDDEN = {
@@ -9,6 +9,11 @@ export type TitleProp = React.ReactNode;
9
9
  export type SubtitleProp = React.ReactNode;
10
10
  /** Longer explanatory copy — dialog body, empty state body. */
11
11
  export type DescriptionProp = React.ReactNode;
12
+ /**
13
+ * Status/meta band beside a title — StatusBadge, environment tag, "updated …" meta text.
14
+ * Owned by the canonical page-header contract so consumers never hand-lay a badge row.
15
+ */
16
+ export type StatusProp = React.ReactNode;
12
17
  /** Top-right action slot on pages (Ant Design `extra`). */
13
18
  export type ExtraProp = React.ReactNode;
14
19
  /** Bottom action bar on pages — save/cancel, pagination controls. */
@@ -1,6 +1,6 @@
1
1
  /** Barrel — all vocabulary prop types. */
2
2
  export type { ClassNameProp, ChildrenProp, IdProp, OpenProp, DefaultOpenProp, OnOpenChangeProp, HandlerProp, PendingProp, RequiredProp, DisabledProp, LabelProp, HelperProp, ErrorProp, PlaceholderProp, NameProp, ValueProp, DefaultValueProp, OnValueChangeProp, OnChangeProp, OnClickProp, AsChildProp, WidthProp, } from "./shared.prop.js";
3
- export type { TitleProp, SubtitleProp, DescriptionProp, ExtraProp, FooterProp, ActionProp, IconProp, ConfirmLabelProp, CancelLabelProp, ActionsProp, EmptyMessageProp, } from "./content.prop.js";
3
+ export type { TitleProp, SubtitleProp, StatusProp, DescriptionProp, ExtraProp, FooterProp, ActionProp, IconProp, ConfirmLabelProp, CancelLabelProp, ActionsProp, EmptyMessageProp, } from "./content.prop.js";
4
4
  export type { PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, CenteredShellAlignProp, CenteredShellPresetProp, ErrorSurfaceModeProp, ErrorSurfaceStatusProp, AuthShellPresetProp, TableDensityProp, DensityProp, GapProp, } from "./layout.prop.js";
5
5
  export type { ButtonVariantProp, ButtonSizeProp, BadgeVariantProp, AppSettingPickerAppearanceProp, ShapeProp, AvatarShapeProp, TextSizeProp, TextToneProp, FontWeightProp, HeadingLevelProp, TextAlignProp, SizeProp, FormLayoutProp, BreakpointProp, ConfirmVariantProp, ToneProp, AlertVariantProp, SortDirectionProp, ColumnAlignProp, SortStateProp, RevealDelayProp, } from "./interaction.prop.js";
6
6
  export type { BreadcrumbItemProp, BreadcrumbProp } from "./navigation.prop.js";
@@ -55,13 +55,10 @@ export type ConfirmVariantProp = "default" | "destructive";
55
55
  /** Semantic color/status intent. */
56
56
  export type ToneProp = "default" | "success" | "warning" | "destructive" | "info" | "muted" | "neutral";
57
57
  /**
58
- * Alert visual treatment.
59
- *
60
- * `"default"` is the inset, rounded, fully-bordered INLINE alert that sits inside a page body.
61
- * `"banner"` is the page-level strip the `Banner` alias ships (gh#255): square, edge-to-edge, ruled
62
- * on the block-end edge only, so it reads as page chrome above the content rather than as a card
63
- * inside it. Both share one implementation, one tone scale and one dismiss/actions contract —
64
- * `banner` re-measures the box through `--banner-*` tokens and changes nothing else.
58
+ * Alert STRUCTURAL axis (orthogonal to `tone`, which owns colour/semantics):
59
+ * `default` — the inline card (rounded, framed on all sides);
60
+ * `banner` the full-bleed page/shell attention strip the `Banner` export renders
61
+ * (square corners, hairline block-end rule only, `--banner-*` token geometry).
65
62
  */
66
63
  export type AlertVariantProp = "default" | "banner";
67
64
  /** Sort direction for table columns. */
@@ -46,9 +46,9 @@ export type ErrorSurfaceStatusProp = 403 | 404 | 500 | 503;
46
46
  * a 5px mobile inline gutter; `"context-selection"` is the 25rem organisation/context picker
47
47
  * measure that goes edge-to-edge on mobile; `"account-recovery"` is the 432px SCR-008 measure
48
48
  * shared by the password-recovery and sign-in MFA challenge panels (15px mobile inline gutter);
49
- * `"registration"` is the 360px sign-up measure — the only START-aligned preset, because a
49
+ * `"registration"` is the 360px sign-up measure — start-aligned like `"login"`, because a
50
50
  * registration card is the tallest surface in the set and a centred tall card overflows above the
51
- * scroll origin, and the only one with its own footer-clearance knob.
51
+ * scroll origin, and the only preset with a footer-clearance knob of its own.
52
52
  * Orthogonal to AuthShell's `variant` (which owns control density and heading size) — combine them.
53
53
  */
54
54
  export type AuthShellPresetProp = "default" | "login" | "registration" | "device-authorization" | "context-selection" | "account-recovery";
@@ -47,44 +47,27 @@
47
47
  color: hsl(var(--foreground));
48
48
  }
49
49
 
50
- [data-slot="alert"][data-dismissible] {
51
- padding-inline-end: calc(var(--alert-space-inset) + var(--space-8));
52
- }
53
-
54
- /*
55
- * BANNER variant (gh#255) — the same Alert, re-measured as page chrome: edge-to-edge, square,
56
- * ruled only on the block-end edge so it separates itself from the content BELOW it. Declared
57
- * after the base box (equal specificity → source order wins) and it touches geometry only, so
58
- * every tone, the icon treatment, the actions grid and the dismiss control are inherited
59
- * unchanged from the inline alert above.
60
- */
50
+ /* variant="banner" (the <Banner> export) — the full-bleed page/shell attention strip.
51
+ * ONLY geometry changes here: every tone colour rule above applies unchanged, and the
52
+ * strip keeps its tone-coloured hairline on the block-end edge alone. All values are
53
+ * --banner-* component tokens (src/tokens/components/banner.css), so a consumer never
54
+ * writes CSS to place a banner and a service retunes the strip once via theme. */
61
55
  [data-slot="alert"][data-variant="banner"] {
62
56
  border-radius: var(--banner-radius);
63
- border-width: var(--banner-border-width);
64
- border-block-end-width: var(--banner-border-block-end-width);
65
- padding: var(--banner-space-block) var(--banner-space-inline);
57
+ border-block-start-width: 0;
58
+ border-inline-width: 0;
59
+ border-block-end-width: var(--banner-border-width);
60
+ padding-block: var(--banner-space-inset-block);
61
+ padding-inline: var(--banner-space-inset-inline);
66
62
  }
67
63
 
68
- /* The dismissible reserve is re-derived from the BANNER inset — reusing the inline-alert
69
- * calc would leave a ✕-sized hole on a strip whose own inset is half as deep. */
70
- [data-slot="alert"][data-variant="banner"][data-dismissible] {
71
- padding-inline-end: calc(var(--banner-space-inline) + var(--space-8));
72
- }
73
-
74
- [data-slot="alert"][data-variant="banner"] > [data-slot="alert-dismiss"] {
75
- top: var(--banner-dismiss-space-offset);
76
- inset-inline-end: var(--banner-dismiss-space-offset);
64
+ [data-slot="alert"][data-dismissible] {
65
+ padding-inline-end: calc(var(--alert-space-inset) + var(--space-8));
77
66
  }
78
67
 
79
- /* The compact page gutter. `.ui-page-container` steps `--space-page-active-x` down at this same
80
- * breakpoint, and a banner mounted ABOVE the container (the normal case — page/app chrome) does
81
- * not inherit that, so without this rule its text would sit 8px outside the page title at 390px.
82
- * Bound to its own `--banner-space-inline-compact` knob rather than a literal, so a service
83
- * retunes the mobile inset the same way it retunes the desktop one. */
84
- @media (max-width: 720px) {
85
- [data-slot="alert"][data-variant="banner"] {
86
- --banner-space-inline: var(--banner-space-inline-compact);
87
- }
68
+ /* The banner strip reserves dismiss clearance from ITS inline inset, not the card's. */
69
+ [data-slot="alert"][data-variant="banner"][data-dismissible] {
70
+ padding-inline-end: calc(var(--banner-space-inset-inline) + var(--space-8));
88
71
  }
89
72
 
90
73
  [data-slot="alert-icon"] {
@@ -15,6 +15,11 @@
15
15
  border-radius: var(--radius-md);
16
16
  border-width: 1px;
17
17
  font-size: var(--badge-font-size);
18
+ /* The cva used to carry `text-xs`, which set BOTH font-size and the Tailwind companion
19
+ * line-height. It was dropped (gh#260) so this components-layer rule can own font-size —
20
+ * so line-height must be restored here too, or the badge would inherit the ambient body
21
+ * leading and grow taller. Default reproduces `text-xs` exactly. */
22
+ line-height: var(--badge-line-height);
18
23
  font-weight: var(--font-weight-medium);
19
24
  /* A status chip must read as one unit — never wrap its label across lines,
20
25
  * especially inside narrow table cells. */