@kerfjs/ui 4.4.1 → 5.0.0-beta.4

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 (158) hide show
  1. package/README.md +234 -5
  2. package/ai/component-catalog.json +4473 -0
  3. package/ai/component-catalog.schema.json +79 -0
  4. package/ai/public-api-signatures-v1.md +619 -0
  5. package/ai/skill.md +65 -11
  6. package/ai/webawesome-jsx-signatures-v1.md +106 -0
  7. package/dist/app-tab.d.ts +12 -2
  8. package/dist/app-tab.js +2 -1
  9. package/dist/browser/app-tab.js +2 -2
  10. package/dist/browser/dialog-header.js +4 -2
  11. package/dist/browser/disclosure-arrow.js +4 -0
  12. package/dist/browser/empty-state.js +3 -3
  13. package/dist/browser/loading-spinner.js +2 -2
  14. package/dist/browser/lucide-icon.js +2 -2
  15. package/dist/browser/menu-action-row.js +3 -0
  16. package/dist/browser/menu-header.js +4 -2
  17. package/dist/browser/menu-item.js +2 -2
  18. package/dist/browser/page-header.js +2 -2
  19. package/dist/browser/resizable-region.js +2 -2
  20. package/dist/browser/segmented-control.js +2 -2
  21. package/dist/browser/select.js +3 -3
  22. package/dist/browser/state-banner.js +2 -2
  23. package/dist/browser/tab-bar.js +2 -2
  24. package/dist/browser/token-search-field.js +4 -0
  25. package/dist/browser/toolbar-control-group.js +2 -2
  26. package/dist/browser/toolbar-text.js +2 -2
  27. package/dist/browser/toolbar.js +2 -2
  28. package/dist/browser/value-table.js +2 -2
  29. package/dist/chunk-56RJXPHG.js +43 -0
  30. package/dist/chunk-56RJXPHG.js.map +1 -0
  31. package/dist/chunk-7BR3DO2A.js +31 -0
  32. package/dist/chunk-7BR3DO2A.js.map +1 -0
  33. package/dist/chunk-7LDCTU7D.js +134 -0
  34. package/dist/chunk-7LDCTU7D.js.map +1 -0
  35. package/dist/{chunk-4HHCYSGT.js → chunk-AQNKJRFH.js} +2 -2
  36. package/dist/{chunk-4HHCYSGT.js.map → chunk-AQNKJRFH.js.map} +1 -1
  37. package/dist/{chunk-NHXX4JI5.js → chunk-CTQKI2XL.js} +3 -3
  38. package/dist/chunk-CTQKI2XL.js.map +1 -0
  39. package/dist/chunk-EGHL5S4P.js +33 -0
  40. package/dist/chunk-EGHL5S4P.js.map +1 -0
  41. package/dist/chunk-H5AGGVU5.js +75 -0
  42. package/dist/chunk-H5AGGVU5.js.map +1 -0
  43. package/dist/chunk-K3G72I6D.js +24 -0
  44. package/dist/chunk-K3G72I6D.js.map +1 -0
  45. package/dist/{chunk-3O7ZEUW2.js → chunk-M5JRI6MN.js} +3 -3
  46. package/dist/chunk-M5JRI6MN.js.map +1 -0
  47. package/dist/chunk-NPPD2A6O.js +40 -0
  48. package/dist/chunk-NPPD2A6O.js.map +1 -0
  49. package/dist/chunk-R6JHHBKQ.js +19 -0
  50. package/dist/chunk-R6JHHBKQ.js.map +1 -0
  51. package/dist/chunk-S3TPM2LP.js +23 -0
  52. package/dist/chunk-S3TPM2LP.js.map +1 -0
  53. package/dist/{chunk-T5XNMVOI.js → chunk-XZXRLY5Q.js} +14 -5
  54. package/dist/chunk-XZXRLY5Q.js.map +1 -0
  55. package/dist/dialog-header.d.ts +3 -2
  56. package/dist/dialog-header.js +3 -1
  57. package/dist/disclosure-arrow.d.ts +14 -0
  58. package/dist/disclosure-arrow.js +4 -0
  59. package/dist/disclosure-arrow.js.map +1 -0
  60. package/dist/index.d.ts +5 -1
  61. package/dist/index.js +16 -11
  62. package/dist/menu-action-row.d.ts +50 -0
  63. package/dist/menu-action-row.js +4 -0
  64. package/dist/menu-action-row.js.map +1 -0
  65. package/dist/menu-header.d.ts +28 -2
  66. package/dist/menu-header.js +4 -1
  67. package/dist/menu-item.d.ts +10 -1
  68. package/dist/menu-item.js +2 -1
  69. package/dist/resizable-region.d.ts +3 -1
  70. package/dist/resizable-region.js +1 -1
  71. package/dist/select.js +1 -1
  72. package/dist/styles/app-tab.css +152 -0
  73. package/dist/styles/dialog-header.css +87 -0
  74. package/dist/styles/disclosure-arrow.css +23 -0
  75. package/dist/styles/empty-state.css +47 -0
  76. package/dist/styles/foundation.css +326 -0
  77. package/dist/styles/layout.css +73 -0
  78. package/dist/styles/loading-spinner.css +21 -0
  79. package/dist/styles/lucide-icon.css +6 -0
  80. package/dist/styles/menu-action-row.css +160 -0
  81. package/dist/styles/menu-header.css +143 -0
  82. package/dist/styles/menu-item.css +123 -0
  83. package/dist/styles/page-header.css +33 -0
  84. package/dist/styles/resizable-region.css +111 -0
  85. package/{src → dist/styles}/segmented-control.css +62 -31
  86. package/dist/styles/select.css +96 -0
  87. package/dist/styles/state-banner.css +173 -0
  88. package/dist/styles/styles.css +22 -0
  89. package/dist/styles/tab-bar.css +45 -0
  90. package/dist/styles/token-search-field.css +281 -0
  91. package/dist/styles/toolbar-control-group.css +161 -0
  92. package/dist/styles/toolbar-text.css +29 -0
  93. package/dist/styles/toolbar.css +52 -0
  94. package/dist/styles/value-table.css +75 -0
  95. package/{src → dist/styles}/webawesome.css +119 -29
  96. package/dist/token-search-field.d.ts +43 -0
  97. package/dist/token-search-field.js +4 -0
  98. package/dist/token-search-field.js.map +1 -0
  99. package/dist/value-table.d.ts +10 -2
  100. package/dist/value-table.js +1 -1
  101. package/dist/webawesome.d.ts +100 -0
  102. package/dist/webawesome.js +3 -0
  103. package/dist/webawesome.js.map +1 -0
  104. package/dist/wire-resizable-regions.js +1 -1
  105. package/dist/wire-token-search-fields.d.ts +11 -0
  106. package/dist/wire-token-search-fields.js +5 -0
  107. package/dist/wire-token-search-fields.js.map +1 -0
  108. package/docs/accessibility.md +60 -3
  109. package/docs/component-contract.md +131 -3
  110. package/docs/component-selection.md +133 -0
  111. package/docs/design-philosophy.md +38 -0
  112. package/docs/examples/command-palette-adapter.tsx +70 -0
  113. package/docs/layout.md +106 -0
  114. package/docs/recipes.md +124 -0
  115. package/docs/ux-demo.md +23 -9
  116. package/docs/webawesome-theme.md +15 -0
  117. package/llms.txt +25 -2
  118. package/package.json +70 -27
  119. package/ux-demo/recipes/app-shell.tsx +32 -0
  120. package/ux-demo/recipes/compact-toolbar.tsx +43 -0
  121. package/ux-demo/recipes/composer-form.tsx +63 -0
  122. package/ux-demo/recipes/list-workspace-states.tsx +26 -0
  123. package/ux-demo/recipes/loaders.ts +27 -0
  124. package/ux-demo/recipes/master-detail-dialog.tsx +45 -0
  125. package/ux-demo/recipes/mount-recipe.ts +38 -0
  126. package/ux-demo/recipes/navigation-sidebar.tsx +26 -0
  127. package/ux-demo/recipes/recipes.css +344 -0
  128. package/ux-demo/recipes/types.ts +11 -0
  129. package/ux-demo/recipes/workspace-header.tsx +12 -0
  130. package/dist/chunk-3O7ZEUW2.js.map +0 -1
  131. package/dist/chunk-723YNJBH.js +0 -17
  132. package/dist/chunk-723YNJBH.js.map +0 -1
  133. package/dist/chunk-NHXX4JI5.js.map +0 -1
  134. package/dist/chunk-OPCJRCYO.js +0 -19
  135. package/dist/chunk-OPCJRCYO.js.map +0 -1
  136. package/dist/chunk-T5XNMVOI.js.map +0 -1
  137. package/dist/chunk-VKH2JLDZ.js +0 -10
  138. package/dist/chunk-VKH2JLDZ.js.map +0 -1
  139. package/dist/chunk-WY4CAEPG.js +0 -14
  140. package/dist/chunk-WY4CAEPG.js.map +0 -1
  141. package/src/app-tab.css +0 -20
  142. package/src/dialog-header.css +0 -9
  143. package/src/empty-state.css +0 -6
  144. package/src/foundation.css +0 -106
  145. package/src/loading-spinner.css +0 -4
  146. package/src/lucide-icon.css +0 -1
  147. package/src/menu-header.css +0 -13
  148. package/src/menu-item.css +0 -12
  149. package/src/page-header.css +0 -3
  150. package/src/resizable-region.css +0 -19
  151. package/src/select.css +0 -18
  152. package/src/state-banner.css +0 -31
  153. package/src/styles.css +0 -18
  154. package/src/tab-bar.css +0 -4
  155. package/src/toolbar-control-group.css +0 -25
  156. package/src/toolbar-text.css +0 -4
  157. package/src/toolbar.css +0 -9
  158. package/src/value-table.css +0 -5
@@ -0,0 +1,52 @@
1
+ .kui-toolbar {
2
+ display: grid;
3
+ width: 100%;
4
+ min-height: calc(
5
+ var(--kui-toolbar-group-size, calc(2px + 2.625rem)) +
6
+ (2 * var(--kui-toolbar-gap, 0.5rem))
7
+ );
8
+ padding: var(--kui-toolbar-gap, 0.5rem);
9
+ box-sizing: border-box;
10
+ color: var(--kui-color-text);
11
+ background: transparent;
12
+ grid-template-columns: auto minmax(0, 1fr) auto;
13
+ align-items: center;
14
+ gap: var(--kui-toolbar-gap, 0.5rem);
15
+ container: kui-toolbar / inline-size;
16
+ font-family: var(--kui-font-sans);
17
+ }
18
+
19
+ .kui-toolbar[data-has-center="false"] {
20
+ grid-template-columns: minmax(0, 1fr) auto;
21
+ }
22
+
23
+ .kui-toolbar[data-divider="true"] {
24
+ box-shadow: inset 0 -1px var(--kui-color-border);
25
+ }
26
+
27
+ .kui-toolbar__leading,
28
+ .kui-toolbar__center,
29
+ .kui-toolbar__trailing {
30
+ display: flex;
31
+ min-width: 0;
32
+ align-items: center;
33
+ gap: var(--kui-toolbar-gap, 0.5rem);
34
+ }
35
+
36
+ .kui-toolbar__leading {
37
+ overflow: hidden;
38
+ }
39
+
40
+ .kui-toolbar__center {
41
+ justify-content: center;
42
+ }
43
+
44
+ .kui-toolbar__trailing {
45
+ justify-content: flex-end;
46
+ }
47
+
48
+ .kui-toolbar[data-has-center="false"] .kui-toolbar__center,
49
+ .kui-toolbar__leading:empty,
50
+ .kui-toolbar__trailing:empty {
51
+ display: none;
52
+ }
@@ -0,0 +1,75 @@
1
+ .kui-value-table {
2
+ --kui-value-table-background: var(--kui-color-surface-lowered);
3
+ --kui-value-table-border: var(--kui-color-border);
4
+ --_kui-value-table-icon-size: var(--kui-value-table-icon-size, 1.5rem);
5
+ display: grid;
6
+ margin-block: 0;
7
+ margin-inline: var(--kui-layout-inline-margin, 0.5rem);
8
+ overflow: hidden;
9
+ border: 1px solid var(--kui-value-table-border);
10
+ border-radius: var(--kui-layout-rounded-radius, calc(1px + 0.6875rem));
11
+ background: var(--kui-value-table-background);
12
+ }
13
+ .kui-value-table__row {
14
+ --_kui-value-table-inline-padding: var(
15
+ --kui-layout-item-padding,
16
+ 0.5rem
17
+ );
18
+ --_kui-value-table-separator-start: var(--_kui-value-table-inline-padding);
19
+ position: relative;
20
+ display: grid;
21
+ min-height: 2.55rem;
22
+ padding-block: 0.5rem;
23
+ padding-inline: var(--_kui-value-table-inline-padding);
24
+ box-sizing: border-box;
25
+ grid-template-columns: minmax(6rem, auto) minmax(0, 1fr);
26
+ align-items: center;
27
+ gap: var(--kui-layout-item-gap, 0.5rem);
28
+ }
29
+ .kui-value-table__row[data-has-icon="true"] {
30
+ --_kui-value-table-separator-start: calc(
31
+ var(--_kui-value-table-inline-padding) + var(--_kui-value-table-icon-size) +
32
+ var(--kui-layout-item-gap, 0.5rem)
33
+ );
34
+ }
35
+ .kui-value-table__row + .kui-value-table__row::before {
36
+ position: absolute;
37
+ top: 0;
38
+ right: var(--_kui-value-table-inline-padding);
39
+ left: var(--_kui-value-table-separator-start);
40
+ border-top: 1px solid var(--kui-value-table-border);
41
+ content: "";
42
+ }
43
+ .kui-value-table__row dt {
44
+ display: flex;
45
+ min-width: 0;
46
+ color: var(--kui-color-text-quiet);
47
+ align-items: center;
48
+ gap: var(--kui-layout-item-gap, 0.5rem);
49
+ }
50
+ .kui-value-table__icon {
51
+ display: grid;
52
+ width: var(--_kui-value-table-icon-size);
53
+ height: var(--_kui-value-table-icon-size);
54
+ flex: none;
55
+ place-items: center;
56
+ }
57
+ .kui-value-table__icon svg {
58
+ width: 100%;
59
+ height: 100%;
60
+ }
61
+ .kui-value-table__label {
62
+ min-width: 0;
63
+ }
64
+ .kui-value-table__row dd {
65
+ display: flex;
66
+ min-width: 0;
67
+ margin: 0;
68
+ overflow-wrap: anywhere;
69
+ color: var(--kui-color-text);
70
+ align-items: center;
71
+ justify-content: flex-end;
72
+ gap: var(--kui-space-2xs);
73
+ font-weight: var(--kui-font-weight-semibold);
74
+ text-align: end;
75
+ }
@@ -6,7 +6,7 @@
6
6
  * used by Hot Sheet 2. Component JavaScript remains independently importable
7
7
  * and tree-shakeable.
8
8
  */
9
- @import '@awesome.me/webawesome/dist/styles/webawesome.css';
9
+ @import "@awesome.me/webawesome/dist/styles/webawesome.css";
10
10
 
11
11
  @layer wa-theme-overrides {
12
12
  :where(:root),
@@ -33,15 +33,38 @@
33
33
  --wa-color-text-quiet: light-dark(#6e6e73, #aeaeb2);
34
34
  --wa-color-text-link: var(--wa-color-brand-on-quiet);
35
35
 
36
- --wa-color-overlay-modal: light-dark(rgb(29 29 31 / .34), rgb(0 0 0 / .6));
37
- --wa-color-overlay-inline: color-mix(in srgb, var(--wa-color-neutral-fill-normal) 25%, transparent);
38
- --wa-color-shadow: light-dark(rgb(0 0 0 / .14), rgb(0 0 0 / .5));
36
+ --wa-color-overlay-modal: light-dark(
37
+ rgb(29 29 31 / 0.34),
38
+ rgb(0 0 0 / 0.6)
39
+ );
40
+ --wa-color-overlay-inline: color-mix(
41
+ in srgb,
42
+ var(--wa-color-neutral-fill-normal) 25%,
43
+ transparent
44
+ );
45
+ --wa-color-shadow: light-dark(rgb(0 0 0 / 0.14), rgb(0 0 0 / 0.5));
39
46
  --wa-color-focus: light-dark(#007aff, #64d2ff);
40
47
  --wa-color-brand-fill-loud: light-dark(#0088ff, #64d2ff);
41
- --wa-color-brand-fill-quiet: color-mix(in srgb, var(--wa-color-brand-fill-loud) 8%, var(--wa-color-surface-default));
42
- --wa-color-brand-fill-normal: color-mix(in srgb, var(--wa-color-brand-fill-loud) 16%, var(--wa-color-surface-default));
43
- --wa-color-brand-border-quiet: color-mix(in srgb, var(--wa-color-brand-fill-loud) 35%, var(--wa-color-surface-default));
44
- --wa-color-brand-border-normal: color-mix(in srgb, var(--wa-color-brand-fill-loud) 58%, var(--wa-color-surface-default));
48
+ --wa-color-brand-fill-quiet: color-mix(
49
+ in srgb,
50
+ var(--wa-color-brand-fill-loud) 8%,
51
+ var(--wa-color-surface-default)
52
+ );
53
+ --wa-color-brand-fill-normal: color-mix(
54
+ in srgb,
55
+ var(--wa-color-brand-fill-loud) 16%,
56
+ var(--wa-color-surface-default)
57
+ );
58
+ --wa-color-brand-border-quiet: color-mix(
59
+ in srgb,
60
+ var(--wa-color-brand-fill-loud) 35%,
61
+ var(--wa-color-surface-default)
62
+ );
63
+ --wa-color-brand-border-normal: color-mix(
64
+ in srgb,
65
+ var(--wa-color-brand-fill-loud) 58%,
66
+ var(--wa-color-surface-default)
67
+ );
45
68
  --wa-color-brand-border-loud: var(--wa-color-brand-fill-loud);
46
69
  --wa-color-brand-on-quiet: light-dark(#1e6ef4, #8acbff);
47
70
  --wa-color-brand-on-normal: var(--wa-color-brand-on-quiet);
@@ -58,31 +81,91 @@
58
81
  --wa-color-neutral-on-loud: var(--wa-color-surface-default);
59
82
 
60
83
  --wa-color-success-fill-loud: #34c759;
61
- --wa-color-success-fill-quiet: color-mix(in srgb, var(--wa-color-success-fill-loud) 14%, var(--wa-color-surface-default));
62
- --wa-color-success-fill-normal: color-mix(in srgb, var(--wa-color-success-fill-loud) 72%, var(--wa-color-surface-default));
63
- --wa-color-success-border-quiet: color-mix(in srgb, var(--wa-color-success-fill-loud) 32%, var(--wa-color-surface-default));
64
- --wa-color-success-border-normal: color-mix(in srgb, var(--wa-color-success-fill-loud) 50%, var(--wa-color-surface-default));
65
- --wa-color-success-border-loud: color-mix(in srgb, var(--wa-color-success-fill-loud) 78%, var(--wa-color-neutral-on-normal));
84
+ --wa-color-success-fill-quiet: color-mix(
85
+ in srgb,
86
+ var(--wa-color-success-fill-loud) 14%,
87
+ var(--wa-color-surface-default)
88
+ );
89
+ --wa-color-success-fill-normal: color-mix(
90
+ in srgb,
91
+ var(--wa-color-success-fill-loud) 72%,
92
+ var(--wa-color-surface-default)
93
+ );
94
+ --wa-color-success-border-quiet: color-mix(
95
+ in srgb,
96
+ var(--wa-color-success-fill-loud) 32%,
97
+ var(--wa-color-surface-default)
98
+ );
99
+ --wa-color-success-border-normal: color-mix(
100
+ in srgb,
101
+ var(--wa-color-success-fill-loud) 50%,
102
+ var(--wa-color-surface-default)
103
+ );
104
+ --wa-color-success-border-loud: color-mix(
105
+ in srgb,
106
+ var(--wa-color-success-fill-loud) 78%,
107
+ var(--wa-color-neutral-on-normal)
108
+ );
66
109
  --wa-color-success-on-quiet: light-dark(#008932, #63e685);
67
110
  --wa-color-success-on-normal: light-dark(#006d28, #8cea9f);
68
111
  --wa-color-success-on-loud: #fff;
69
112
 
70
113
  --wa-color-warning-fill-loud: #ffcc00;
71
- --wa-color-warning-fill-quiet: color-mix(in srgb, var(--wa-color-warning-fill-loud) 9%, var(--wa-color-surface-default));
72
- --wa-color-warning-fill-normal: color-mix(in srgb, var(--wa-color-warning-fill-loud) 22%, var(--wa-color-surface-default));
73
- --wa-color-warning-border-quiet: color-mix(in srgb, var(--wa-color-warning-fill-loud) 35%, var(--wa-color-surface-default));
74
- --wa-color-warning-border-normal: color-mix(in srgb, var(--wa-color-warning-fill-loud) 58%, var(--wa-color-neutral-on-normal));
75
- --wa-color-warning-border-loud: color-mix(in srgb, var(--wa-color-warning-fill-loud) 78%, var(--wa-color-neutral-on-normal));
114
+ --wa-color-warning-fill-quiet: color-mix(
115
+ in srgb,
116
+ var(--wa-color-warning-fill-loud) 9%,
117
+ var(--wa-color-surface-default)
118
+ );
119
+ --wa-color-warning-fill-normal: color-mix(
120
+ in srgb,
121
+ var(--wa-color-warning-fill-loud) 22%,
122
+ var(--wa-color-surface-default)
123
+ );
124
+ --wa-color-warning-border-quiet: color-mix(
125
+ in srgb,
126
+ var(--wa-color-warning-fill-loud) 35%,
127
+ var(--wa-color-surface-default)
128
+ );
129
+ --wa-color-warning-border-normal: color-mix(
130
+ in srgb,
131
+ var(--wa-color-warning-fill-loud) 58%,
132
+ var(--wa-color-neutral-on-normal)
133
+ );
134
+ --wa-color-warning-border-loud: color-mix(
135
+ in srgb,
136
+ var(--wa-color-warning-fill-loud) 78%,
137
+ var(--wa-color-neutral-on-normal)
138
+ );
76
139
  --wa-color-warning-on-quiet: light-dark(#a16a00, #ffd84a);
77
140
  --wa-color-warning-on-normal: light-dark(#5f3f00, #ffe27a);
78
141
  --wa-color-warning-on-loud: #1d1d1f;
79
142
 
80
143
  --wa-color-danger-fill-loud: #ff383c;
81
- --wa-color-danger-fill-quiet: color-mix(in srgb, var(--wa-color-danger-fill-loud) 7%, var(--wa-color-surface-default));
82
- --wa-color-danger-fill-normal: color-mix(in srgb, var(--wa-color-danger-fill-loud) 14%, var(--wa-color-surface-default));
83
- --wa-color-danger-border-quiet: color-mix(in srgb, var(--wa-color-danger-fill-loud) 32%, var(--wa-color-surface-default));
84
- --wa-color-danger-border-normal: color-mix(in srgb, var(--wa-color-danger-fill-loud) 50%, var(--wa-color-surface-default));
85
- --wa-color-danger-border-loud: color-mix(in srgb, var(--wa-color-danger-fill-loud) 78%, var(--wa-color-neutral-on-normal));
144
+ --wa-color-danger-fill-quiet: color-mix(
145
+ in srgb,
146
+ var(--wa-color-danger-fill-loud) 7%,
147
+ var(--wa-color-surface-default)
148
+ );
149
+ --wa-color-danger-fill-normal: color-mix(
150
+ in srgb,
151
+ var(--wa-color-danger-fill-loud) 14%,
152
+ var(--wa-color-surface-default)
153
+ );
154
+ --wa-color-danger-border-quiet: color-mix(
155
+ in srgb,
156
+ var(--wa-color-danger-fill-loud) 32%,
157
+ var(--wa-color-surface-default)
158
+ );
159
+ --wa-color-danger-border-normal: color-mix(
160
+ in srgb,
161
+ var(--wa-color-danger-fill-loud) 50%,
162
+ var(--wa-color-surface-default)
163
+ );
164
+ --wa-color-danger-border-loud: color-mix(
165
+ in srgb,
166
+ var(--wa-color-danger-fill-loud) 78%,
167
+ var(--wa-color-neutral-on-normal)
168
+ );
86
169
  --wa-color-danger-on-quiet: light-dark(#c20b20, #ff696c);
87
170
  --wa-color-danger-on-normal: light-dark(#8e0717, #ff8a8c);
88
171
  --wa-color-danger-on-loud: #fff;
@@ -101,10 +184,10 @@
101
184
  --kui-wa-carousel-dot-hit-size: 20px;
102
185
  --kui-wa-carousel-control-size: 28px;
103
186
  --kui-wa-carousel-icon-size: 16px;
104
- --kui-disclosure-icon-scale: .5;
105
- --wa-shadow-s: 0 1px 3px rgb(0 0 0 / .14);
106
- --wa-shadow-m: 0 .35rem 1rem rgb(0 0 0 / .11);
107
- --wa-shadow-l: 0 .75rem 2rem rgb(0 0 0 / .09);
187
+ --kui-disclosure-icon-scale: 0.5;
188
+ --wa-shadow-s: 0 1px 3px rgb(0 0 0 / 0.14);
189
+ --wa-shadow-m: 0 0.35rem 1rem rgb(0 0 0 / 0.11);
190
+ --wa-shadow-l: 0 0.75rem 2rem rgb(0 0 0 / 0.09);
108
191
  }
109
192
 
110
193
  :where(:root),
@@ -129,7 +212,10 @@
129
212
  box-sizing: border-box;
130
213
  width: var(--kui-wa-carousel-control-size);
131
214
  height: var(--kui-wa-carousel-control-size);
132
- padding: calc((var(--kui-wa-carousel-control-size) - var(--kui-wa-carousel-icon-size)) / 2);
215
+ padding: calc(
216
+ (var(--kui-wa-carousel-control-size) - var(--kui-wa-carousel-icon-size)) /
217
+ 2
218
+ );
133
219
  font-size: var(--kui-wa-carousel-icon-size);
134
220
  }
135
221
 
@@ -142,7 +228,11 @@
142
228
  height: var(--kui-wa-carousel-dot-hit-size);
143
229
  color: var(--wa-color-neutral-fill-normal);
144
230
  background-color: transparent;
145
- background-image: radial-gradient(circle, currentcolor 0 calc(var(--kui-wa-carousel-dot-size) / 2), transparent calc(var(--kui-wa-carousel-dot-size) / 2 + .5px));
231
+ background-image: radial-gradient(
232
+ circle,
233
+ currentcolor 0 calc(var(--kui-wa-carousel-dot-size) / 2),
234
+ transparent calc(var(--kui-wa-carousel-dot-size) / 2 + 0.5px)
235
+ );
146
236
  transform: none;
147
237
  }
148
238
 
@@ -0,0 +1,43 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ interface TokenSearchToken {
4
+ value: string;
5
+ label: string;
6
+ offset?: number;
7
+ accessibleLabel?: string;
8
+ }
9
+ interface TokenSearchFieldProps {
10
+ id: string;
11
+ label: string;
12
+ query?: string;
13
+ tokens?: readonly TokenSearchToken[];
14
+ placeholder?: string;
15
+ tokenPlaceholder?: string;
16
+ disabled?: boolean;
17
+ autofocus?: boolean;
18
+ /** Allow an empty field to render as one iconic action. */
19
+ collapsible?: boolean;
20
+ /** Keep an empty collapsible field open while the application owns focus. */
21
+ expanded?: boolean;
22
+ expandAction?: string;
23
+ expandLabel?: string;
24
+ leading?: SafeHtml;
25
+ trailing?: SafeHtml;
26
+ editAction?: string;
27
+ removeAction?: string;
28
+ clearAction?: string;
29
+ clearLabel?: string;
30
+ className?: string;
31
+ editorAttributes?: Readonly<Record<`data-${string}`, string>>;
32
+ }
33
+ interface TokenSearchFieldValue {
34
+ query: string;
35
+ tokens: TokenSearchToken[];
36
+ }
37
+ declare function TokenSearchField({ id, label, query, tokens, placeholder, tokenPlaceholder, disabled, autofocus, collapsible, expanded, expandAction, expandLabel, leading, trailing, editAction, removeAction, clearAction, clearLabel, className, editorAttributes, }: TokenSearchFieldProps): SafeHtml;
38
+ /** Read editable text and ordered token offsets from a rendered TokenSearchField editor. */
39
+ declare function readTokenSearchField(editor: HTMLElement, knownTokens?: readonly TokenSearchToken[]): TokenSearchFieldValue;
40
+ /** Focus an editor and place its caret at a text offset, skipping atomic token chips. */
41
+ declare function placeTokenSearchCaret(editor: HTMLElement, offset?: number): void;
42
+
43
+ export { TokenSearchField, type TokenSearchFieldProps, type TokenSearchFieldValue, type TokenSearchToken, placeTokenSearchCaret, readTokenSearchField };
@@ -0,0 +1,4 @@
1
+ export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-7LDCTU7D.js';
2
+
3
+
4
+ //# sourceMappingURL=token-search-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"token-search-field.js"}
@@ -1,10 +1,18 @@
1
1
  import { SafeHtml } from 'kerfjs';
2
2
 
3
+ interface ValueTableRowProps {
4
+ label: string | SafeHtml;
5
+ value: string | SafeHtml;
6
+ icon?: SafeHtml;
7
+ className?: string;
8
+ }
9
+ declare function ValueTableRow({ label, value, icon, className }: ValueTableRowProps): SafeHtml;
10
+
3
11
  interface ValueTableProps {
4
12
  label: string;
5
13
  className?: string;
6
- children: SafeHtml | SafeHtml[];
14
+ children: SafeHtml | readonly SafeHtml[];
7
15
  }
8
16
  declare function ValueTable({ label, className, children }: ValueTableProps): SafeHtml;
9
17
 
10
- export { ValueTable, type ValueTableProps };
18
+ export { ValueTable, type ValueTableProps, ValueTableRow, type ValueTableRowProps };
@@ -1,3 +1,3 @@
1
- export { ValueTable } from './chunk-VKH2JLDZ.js';
1
+ export { ValueTable, ValueTableRow } from './chunk-R6JHHBKQ.js';
2
2
 
3
3
  //# sourceMappingURL=value-table.js.map
@@ -0,0 +1,100 @@
1
+ import { KerfCustomElement } from 'kerfjs/jsx-runtime';
2
+
3
+ /**
4
+ * Opt-in Kerf JSX declarations for the Web Awesome elements supported by the
5
+ * @kerfjs/ui catalog. Import this module for type effects only; component
6
+ * registration remains an explicit application concern.
7
+ */
8
+ declare module 'kerfjs/jsx-runtime' {
9
+ namespace JSX {
10
+ interface IntrinsicElements {
11
+ 'wa-accordion': KerfCustomElement;
12
+ 'wa-accordion-item': KerfCustomElement;
13
+ 'wa-animated-image': KerfCustomElement;
14
+ 'wa-animation': KerfCustomElement;
15
+ 'wa-avatar': KerfCustomElement;
16
+ 'wa-badge': KerfCustomElement;
17
+ 'wa-breadcrumb': KerfCustomElement;
18
+ 'wa-breadcrumb-item': KerfCustomElement;
19
+ 'wa-select': KerfCustomElement & {
20
+ class?: string;
21
+ name?: string;
22
+ label?: string;
23
+ 'aria-label'?: string;
24
+ value?: string;
25
+ placeholder?: string;
26
+ disabled?: boolean;
27
+ };
28
+ 'wa-option': KerfCustomElement & {
29
+ value?: string;
30
+ };
31
+ 'wa-button-group': KerfCustomElement;
32
+ 'wa-callout': KerfCustomElement;
33
+ 'wa-card': KerfCustomElement;
34
+ 'wa-carousel': KerfCustomElement;
35
+ 'wa-carousel-item': KerfCustomElement;
36
+ 'wa-checkbox': KerfCustomElement;
37
+ 'wa-checkbox-group': KerfCustomElement;
38
+ 'wa-color-picker': KerfCustomElement;
39
+ 'wa-comparison': KerfCustomElement;
40
+ 'wa-copy-button': KerfCustomElement;
41
+ 'wa-details': KerfCustomElement;
42
+ 'wa-divider': KerfCustomElement;
43
+ 'wa-dialog': KerfCustomElement;
44
+ 'wa-drawer': KerfCustomElement;
45
+ 'wa-button': KerfCustomElement & {
46
+ slot?: string;
47
+ appearance?: string;
48
+ 'with-caret'?: boolean;
49
+ 'aria-label'?: string;
50
+ };
51
+ 'wa-dropdown': KerfCustomElement & {
52
+ placement?: string;
53
+ };
54
+ 'wa-dropdown-item': KerfCustomElement;
55
+ 'wa-format-bytes': KerfCustomElement;
56
+ 'wa-format-date': KerfCustomElement;
57
+ 'wa-format-number': KerfCustomElement;
58
+ 'wa-icon': KerfCustomElement;
59
+ 'wa-include': KerfCustomElement;
60
+ 'wa-input': KerfCustomElement;
61
+ 'wa-intersection-observer': KerfCustomElement;
62
+ 'wa-known-date': KerfCustomElement;
63
+ 'wa-markdown': KerfCustomElement;
64
+ 'wa-mutation-observer': KerfCustomElement;
65
+ 'wa-number-input': KerfCustomElement;
66
+ 'wa-otp-input': KerfCustomElement;
67
+ 'wa-page': KerfCustomElement;
68
+ 'wa-pagination': KerfCustomElement;
69
+ 'wa-popover': KerfCustomElement;
70
+ 'wa-popup': KerfCustomElement;
71
+ 'wa-progress-bar': KerfCustomElement;
72
+ 'wa-progress-ring': KerfCustomElement;
73
+ 'wa-qr-code': KerfCustomElement;
74
+ 'wa-radio': KerfCustomElement;
75
+ 'wa-radio-group': KerfCustomElement;
76
+ 'wa-random-content': KerfCustomElement;
77
+ 'wa-rating': KerfCustomElement;
78
+ 'wa-relative-time': KerfCustomElement;
79
+ 'wa-resize-observer': KerfCustomElement;
80
+ 'wa-scroller': KerfCustomElement;
81
+ 'wa-skeleton': KerfCustomElement;
82
+ 'wa-slider': KerfCustomElement;
83
+ 'wa-spinner': KerfCustomElement;
84
+ 'wa-split-panel': KerfCustomElement;
85
+ 'wa-switch': KerfCustomElement;
86
+ 'wa-tab': KerfCustomElement;
87
+ 'wa-tab-group': KerfCustomElement;
88
+ 'wa-tab-panel': KerfCustomElement;
89
+ 'wa-tag': KerfCustomElement;
90
+ 'wa-textarea': KerfCustomElement;
91
+ 'wa-time-input': KerfCustomElement;
92
+ 'wa-toast': KerfCustomElement;
93
+ 'wa-toast-item': KerfCustomElement;
94
+ 'wa-tooltip': KerfCustomElement;
95
+ 'wa-tree': KerfCustomElement;
96
+ 'wa-tree-item': KerfCustomElement;
97
+ 'wa-zoomable-frame': KerfCustomElement;
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,3 @@
1
+
2
+
3
+ //# sourceMappingURL=webawesome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"webawesome.js"}
@@ -1,4 +1,4 @@
1
- export { wireResizableRegions } from './chunk-4HHCYSGT.js';
1
+ export { wireResizableRegions } from './chunk-AQNKJRFH.js';
2
2
 
3
3
 
4
4
  //# sourceMappingURL=wire-resizable-regions.js.map
@@ -0,0 +1,11 @@
1
+ interface TokenSearchSubmit {
2
+ id: string;
3
+ editor: HTMLElement;
4
+ }
5
+ interface WireTokenSearchFieldsOptions {
6
+ onSubmit: (submission: TokenSearchSubmit) => void;
7
+ }
8
+ /** Keep TokenSearchField wrapping, submit Enter, and preserve its caret across controlled token deletion. */
9
+ declare function wireTokenSearchFields(root: HTMLElement, { onSubmit }: WireTokenSearchFieldsOptions): () => void;
10
+
11
+ export { type TokenSearchSubmit, type WireTokenSearchFieldsOptions, wireTokenSearchFields };
@@ -0,0 +1,5 @@
1
+ export { wireTokenSearchFields } from './chunk-H5AGGVU5.js';
2
+
3
+
4
+
5
+ //# sourceMappingURL=wire-token-search-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"wire-token-search-fields.js"}
@@ -6,11 +6,28 @@ These are normative contracts for package components and consuming applications.
6
6
 
7
7
  - All controls have accessible names and visible `:focus-visible` treatment.
8
8
  - Decorative `LucideIcon` output is `aria-hidden`; pass `label` only when the SVG itself conveys meaning.
9
- - `MenuItem` uses native button Enter/Space behavior. `selected` maps to `aria-current="page"`; `pressed` maps to `aria-pressed`. It deliberately does not emit `role="menuitem"` in isolation—a true ARIA menu must own arrow, Home/End, Escape, and focus behavior as one widget.
9
+ - `MenuItem` uses native button Enter/Space behavior. `selected` maps to `aria-current="page"`; `pressed` maps to `aria-pressed`. Its `trailing` content is dormant and must not contain controls. Its `rootAttributes` slot accepts only application `data-*` metadata and deliberately cannot emit `role="menuitem"` in isolation—a true ARIA menu must own arrow, Home/End, Escape, and focus behavior as one widget.
10
+ - `MenuHeader` owns action naming, disabled state, and disclosure `aria-expanded`. Toggle mode supplies one decorative 18px `DisclosureArrow` when `actionIcon` is omitted; it mirrors `expanded` while the native button's accessible name stays stable. The application must update that controlled state and reveal or hide real content. A valid `count` is visually rendered in an `aria-hidden` neutral pill while the required localized `countLabel` becomes part of the owning heading or disclosure button's accessible name; zero remains a real count. Its narrow `triggerAttributes` slot may describe a native popover or controlled-content relationship with `popoverTarget`, `popoverTargetAction`, `aria-controls`, and `aria-haspopup`; the application owns the target surface and its focus/dismissal behavior.
11
+ - In any `.kui-pane`, menu rows, `MenuHeader` actions, and toolbar groups keep a minimum 44px target in both dimensions. A `MenuHeader` fills the available inline width and keeps that action at the logical end, including in RTL. Its action visual defaults to 18px through `--kui-menu-header-action-icon-size`; do not reduce the target to the visible icon.
10
12
  - `LoadingSpinner` is either labeled (`role="img"`) or hidden. Its rotation stops for reduced motion.
11
13
  - `StateBanner` defaults to polite `role="status"`; use `urgency="alert"` only for an attention-requiring failure.
12
14
  - `EmptyState` reports busy state through `aria-busy` and never relies on an illustration as its label.
13
- - `Select` follows the Web Awesome host's standard `input`/`change` events. Application tests verify the live `value`, focus, and events—not attributes alone.
15
+ - `Select` follows the Web Awesome host's standard `input`/`change` events. Application tests verify the live `value`, focus, and events—not attributes alone. Its decorative option icons and value-dependent selected content remain present after controlled rerenders, so the visible choice does not silently lose its non-text cue.
16
+ - `DisclosureArrow` is an 18px root-scaled decorative visual by default, not an interaction target. Its owning native control supplies a stable accessible name, pointer and keyboard interaction, and `aria-expanded`; multiple arrows keep independently controlled state. Consumers may override `--kui-disclosure-arrow-size` without changing that ownership. Configured directions animate over the shortest path; a 180-degree closed-to-open tie uses counterclockwise rotation.
17
+
18
+ ## MenuActionRow
19
+
20
+ `MenuActionRow` renders a noninteractive visual root containing primary and
21
+ trailing native buttons as siblings. The primary comes first in DOM and Tab
22
+ order and alone receives `aria-current` or `aria-pressed`; the trailing button
23
+ has its own required accessible name and disabled state. Both controls carry
24
+ the row's item id for application delegation, while the root deliberately has
25
+ no action or role. `label`, `icon`, and `trailingActionIcon` are dormant visual
26
+ content and must not contain buttons, links, interactive roles, or other
27
+ controls. A trailing click, double click, context menu, Enter, or Space
28
+ must never activate the primary control. The application owns controlled
29
+ selection and the lifecycle, focus, and dismissal policy of any related
30
+ popover or context menu.
14
31
 
15
32
  ## ResizableRegion
16
33
 
@@ -22,12 +39,28 @@ The handle exposes separator role, orientation, name, minimum, maximum, and curr
22
39
  - primary-pointer drag with clamping;
23
40
  - preview callbacks while dragging and one commit callback on release.
24
41
 
25
- The application owns persistence and collapsed/expanded policy. Keep the last expanded size outside the component and restore it when reopening.
42
+ The application owns persistence and collapsed/expanded policy. Keep the last expanded size outside the component and restore it when reopening. An optional `handleIcon` replaces only decorative dormant content; it must not contain controls or interactive roles because the separator remains the sole focus and interaction owner.
43
+
44
+ ## DialogHeader
45
+
46
+ `DialogHeader` keeps its icon and `h2` together in the leading borderless
47
+ `ToolbarControlGroup`, with optional actions in a separate trailing group. Pass
48
+ localized `actionsLabel` text when the action group needs an accessible name;
49
+ the component does not synthesize an English label. The application connects
50
+ `titleId` and an optional `summaryId` to the owning dialog through
51
+ `aria-labelledby` and `aria-describedby`. Pass action children directly so the
52
+ component can group them; existing pre-grouped actions remain compatible, but
53
+ their inner groups retain their own labels and semantics.
26
54
 
27
55
  ## Tabs
28
56
 
29
57
  `AppTab` renders one controlled tab. `TabBar` supplies the containing tab list,
30
58
  fixed leading/trailing regions, and a horizontally scrollable strip.
59
+ `AppTab.rootAttributes` accepts application `data-*` metadata only; runtime
60
+ filtering rejects roles plus case variants of component- or wiring-owned
61
+ action, identity, selection, drag, drop, and component attributes. An optional
62
+ `closeIcon` is decorative dormant content inside the already named close button
63
+ and must not contain interactive descendants.
31
64
  `wireTabBars()` adds Left/Right wrapping, Home/End, Delete/Backspace close
32
65
  activation, same-bar pointer reordering, `Alt+Shift+ArrowLeft/ArrowRight`
33
66
  reordering, focus restoration, scroll-into-view, and pointer-proximity
@@ -51,6 +84,30 @@ re-renders. Keep labels unique and meaningful even when `content` shows only an
51
84
  icon. Use tabs—not a segmented control—when choices switch page regions that
52
85
  need `tab`/`tabpanel` semantics.
53
86
 
87
+ ## TokenSearchField
88
+
89
+ `TokenSearchField` exposes the editable surface as a named `searchbox`. Each
90
+ chip is atomic (`contenteditable="false"`) and contains separately named edit
91
+ and remove buttons; the clear action is also named. Disabled fields publish
92
+ `aria-disabled` and stop editing without hiding the current expression. The
93
+ application owns query parsing and must announce result-count or loading
94
+ changes separately when that feedback is useful. Use `readTokenSearchField()`
95
+ to ignore the chip buttons' visible text when reading browser-edited content,
96
+ and `placeTokenSearchCaret()` to restore a text caret without landing inside a
97
+ chip. Call `wireTokenSearchFields()` once at a stable root so Enter submits
98
+ without inserting a contenteditable line break and keyboard chip deletion
99
+ restores focus plus the text-relative caret after controlled rendering replaces
100
+ the editor; the editor still wraps text visually at its inline edge. Editable text is DOM-owned between token changes; a clear handler empties
101
+ the editor's `textContent` before updating application state. Leading and
102
+ trailing controls share the first text line's fixed vertical center and remain
103
+ there as the editor wraps. In `collapsible` mode, the closed state is one named
104
+ iconic search button and the open state is the same named searchbox, whether
105
+ the field stands alone or is composed inside `ToolbarControlGroup`.
106
+ Applications set `expanded` while the field is focused, move focus from the
107
+ trigger into the revealed editor, and clear `expanded` only after focus leaves
108
+ the complete component. Text or tokens keep the field expanded even when that
109
+ transient state is false. Width animation is disabled under reduced motion.
110
+
54
111
  ## Verification matrix
55
112
 
56
113
  For each changed component, inspect default, hover, focus, disabled, selected/pressed, busy/error, long-content, wide, narrow, light, dark, increased-contrast, reduced-motion, keyboard-only, and 200%-zoom states where applicable. DOM order must match reading and focus order, with no clipping or unreachable action.