@revolist/ui 4.0.2-rc → 4.0.4-rc

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 (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +345 -263
  3. package/_chunks/{calendar-CpaUK7w1.js → calendar-xpZ0v3xf.js} +39 -29
  4. package/_chunks/{chart-frame-BC99KjGa.js → chart-frame-Cmc7xU1i.js} +16 -13
  5. package/_chunks/{choice-chips-Cs4D-3nH.js → choice-chips-CHQTUdLs.js} +10 -10
  6. package/_chunks/clock-BOhPNlW3.js +4 -0
  7. package/_chunks/{color-palette-BBMFmUNA.js → color-palette-D8vyPfld.js} +1 -1
  8. package/_chunks/{color-picker-D90Jg-M8.js → color-picker-CudqPYZo.js} +10 -10
  9. package/_chunks/{component-YDcfoOLz.js → component-C_T2VN5u.js} +182 -178
  10. package/_chunks/{component-metadata-BENbgTjU.js → component-metadata-BMOOmqx5.js} +0 -4
  11. package/_chunks/control-AHKXD5Eu.js +93 -0
  12. package/_chunks/{control-tooltip-ztgmsG7H.js → control-tooltip-uscKfAnV.js} +15 -15
  13. package/_chunks/{controls-DIum-E66.js → controls-DsNi8V8I.js} +144 -129
  14. package/_chunks/{date-control-BJSzu79z.js → date-control-DrVFX13g.js} +1 -1
  15. package/_chunks/{date-time-BxPJusp9.js → date-time-qIhp5vaX.js} +143 -145
  16. package/_chunks/{delete-button-Bblyah10.js → delete-button-CW9vjLnk.js} +6 -6
  17. package/_chunks/{dialog.parts-DBqo3Qwb.js → dialog.parts-CKGkC5zP.js} +20 -20
  18. package/_chunks/{duration-87U2EoMS.js → duration-CL68Em0o.js} +16 -15
  19. package/_chunks/{editor-popup-D3JdS8l3.js → editor-popup-WDdtVDNA.js} +5 -5
  20. package/_chunks/field-context-D57PnBbH.js +5 -0
  21. package/_chunks/{framework-mount-C-Zwm44H.js → framework-mount--RTLIqE-.js} +1 -1
  22. package/_chunks/history-controls-B3u3INEK.js +27 -0
  23. package/_chunks/mount-DQ1cpppK.js +257 -0
  24. package/_chunks/native-control-C_yok8_-.js +605 -0
  25. package/_chunks/{number-input-BeIadZuL.js → number-input-BKwA5FnM.js} +2 -2
  26. package/_chunks/{picker-DpP7iQLA.js → picker-h1P5RUgp.js} +2 -2
  27. package/_chunks/popup-CT2uD3go.js +367 -0
  28. package/_chunks/{rating-choice-Ca8ZBty3.js → rating-choice-DZgmaic0.js} +1 -1
  29. package/_chunks/render-m5eMMwFR.js +83 -0
  30. package/_chunks/{reorder-list-Cc3KmfAN.js → reorder-list-CSlqAGHw.js} +1 -1
  31. package/_chunks/request-trail-DSlFix6i.js +618 -0
  32. package/_chunks/rich-text-CH7gIqOS.js +636 -0
  33. package/_chunks/rotate-right-Iha5ScJ1.js +4 -0
  34. package/_form.scss +1 -1
  35. package/ai/_chat.scss +195 -0
  36. package/ai/_style.scss +105 -34
  37. package/ai/chat.d.ts +63 -0
  38. package/ai/components.d.ts +19 -3
  39. package/ai/index.d.ts +2 -0
  40. package/ai/index.js +3 -3
  41. package/ai/mount.d.ts +30 -1
  42. package/ai/prompt-history.d.ts +13 -0
  43. package/ai/transcript.d.ts +25 -0
  44. package/ai/translations.d.ts +1 -1
  45. package/angular/angular.js +0 -3
  46. package/assignee/index.js +34 -35
  47. package/buttons/delete-button.d.ts +2 -1
  48. package/buttons/delete-button.js +1 -1
  49. package/buttons/remove-button.js +1 -1
  50. package/buttons/svg-button.d.ts +1 -0
  51. package/buttons/svg-button.js +5 -5
  52. package/calendar/_calendar.scss +7 -2
  53. package/calendar/calendar.js +1 -1
  54. package/calendar/index.js +2 -2
  55. package/choice-chips/index.js +1 -1
  56. package/color-palette/color-palette.js +1 -1
  57. package/color-palette/color-picker.js +2 -2
  58. package/component-catalog.d.ts +16 -5
  59. package/control-attributes.js +7 -7
  60. package/controls.d.ts +8 -6
  61. package/controls.js +3 -3
  62. package/core/editor-popup.js +1 -1
  63. package/date-time/index.js +1 -1
  64. package/date-time/style.scss +4 -4
  65. package/dialog/dialog.dom.js +8 -8
  66. package/dialog/dialog.parts.js +1 -1
  67. package/distribution-chart/area-chart.js +1 -1
  68. package/distribution-chart/bar-chart.d.ts +5 -2
  69. package/distribution-chart/bar-chart.js +7 -3
  70. package/distribution-chart/chart-frame.d.ts +2 -1
  71. package/distribution-chart/line-chart.js +1 -1
  72. package/dropdown/content.d.ts +2 -1
  73. package/dropdown/content.js +1 -142
  74. package/dropdown/control.d.ts +14 -0
  75. package/dropdown/control.js +1 -0
  76. package/dropdown/control.view.d.ts +6 -0
  77. package/dropdown/dropdown.types.d.ts +4 -0
  78. package/dropdown/editor-dropdown.style.scss +37 -9
  79. package/dropdown/index.d.ts +1 -1
  80. package/dropdown/index.js +3 -4
  81. package/dropdown/lookup-field.js +1 -1
  82. package/dropdown/popup.js +1 -141
  83. package/duration/index.js +1 -1
  84. package/duration/style.scss +1 -1
  85. package/editor-actions.js +1 -1
  86. package/field-configurator.js +6 -6
  87. package/fieldset.d.ts +3 -0
  88. package/filter/filters/slider/single.js +1 -1
  89. package/filter-badge.js +1 -1
  90. package/filter-controls.js +7 -7
  91. package/form-controls/field-context.d.ts +5 -0
  92. package/form-controls/index.js +7 -12
  93. package/form-controls/index.view.d.ts +2 -4
  94. package/form-controls/presentation.js +51 -43
  95. package/formatting/index.js +25 -21
  96. package/framework.js +215 -207
  97. package/history-controls.d.ts +14 -0
  98. package/history-controls.js +1 -0
  99. package/masked-input/index.js +1 -1
  100. package/native-control.d.ts +6 -4
  101. package/native-control.js +3 -26
  102. package/native-styles.css +1 -1
  103. package/native.js +31 -30
  104. package/number-input/index.js +1 -1
  105. package/package.json +53 -14
  106. package/pagination.d.ts +3 -0
  107. package/pagination.js +43 -33
  108. package/pdf-viewer/index.js +1 -1
  109. package/pdf-viewer/style.scss +3 -4
  110. package/preact.d.ts +2 -0
  111. package/preact.js +62 -62
  112. package/rating-choice.js +1 -1
  113. package/react-control.d.ts +0 -1
  114. package/react-control.js +2 -2
  115. package/react.d.ts +13 -3
  116. package/react.js +71 -88
  117. package/reorder-list.js +1 -1
  118. package/resource-picker/resource-picker-popup.js +1 -1
  119. package/resource-picker/resource-picker.js +4 -4
  120. package/resource-picker/resource-picker.scss +6 -3
  121. package/rich-text/engine.d.ts +16 -19
  122. package/rich-text/index.d.ts +7 -7
  123. package/rich-text/index.js +1 -1
  124. package/rich-text/model.d.ts +4 -3
  125. package/rich-text/render-model.d.ts +4 -5
  126. package/rich-text/style.scss +3 -12
  127. package/rich-text/toolbar.d.ts +6 -6
  128. package/rich-text/translations.d.ts +3 -15
  129. package/select.d.ts +20 -0
  130. package/select.js +1 -0
  131. package/status-feedback/exit-snapshot.js +4 -4
  132. package/status-feedback/index.js +2 -2
  133. package/status-feedback/popover.js +10 -10
  134. package/status-feedback/render.js +3 -44
  135. package/status-feedback/status-feedback.scss +7 -0
  136. package/status-feedback/types.d.ts +4 -0
  137. package/status-feedback/use-auto-dismiss.d.ts +3 -0
  138. package/styles/_compositions.scss +3 -1
  139. package/styles/_control.scss +12 -4
  140. package/styles/_primitives.scss +9 -8
  141. package/styles.css +1 -1
  142. package/surfaces.js +45 -45
  143. package/svelte/UiComponent.server.js +1 -48
  144. package/svelte/UiComponent.svelte +0 -21
  145. package/svelte.js +33 -68
  146. package/time-grid.js +1 -1
  147. package/timeline-track/component.d.ts +5 -1
  148. package/timeline-track/index.js +71 -54
  149. package/timeline-track/model.d.ts +9 -0
  150. package/timeline-track/model.js +10 -1
  151. package/ui.css +1 -1
  152. package/vue.d.ts +24 -5
  153. package/vue.js +140 -164
  154. package/_chunks/compat.module-DDB2pm9O.js +0 -229
  155. package/_chunks/dropdown-voWqmwAe.js +0 -357
  156. package/_chunks/mount-DZe_6VtR.js +0 -90
  157. package/_chunks/request-trail-IdNiFvKH.js +0 -347
  158. package/_chunks/rich-text-BzI1DyfF.js +0 -477
  159. package/react-native-select.d.ts +0 -6
  160. package/rich-text/syntax.d.ts +0 -2
  161. package/vue-native-select.d.ts +0 -9
package/ai/_chat.scss ADDED
@@ -0,0 +1,195 @@
1
+ .rv-ai-chat {
2
+ display: flex;
3
+ flex-direction: column;
4
+ min-width: 0;
5
+ min-height: 0;
6
+ width: 100%;
7
+ height: 100%;
8
+ color: var(--rv-ui-text);
9
+ background: var(--rv-ui-surface);
10
+ font: 400 0.875rem/1.55 var(--rv-ai-font, system-ui, sans-serif);
11
+ }
12
+ .rv-ai-chat-scroll {
13
+ position: relative;
14
+ display: flex;
15
+ flex: 1;
16
+ min-height: 0;
17
+ min-width: 0;
18
+ }
19
+ .rv-ai-chat-viewport {
20
+ flex: 1;
21
+ min-width: 0;
22
+ overflow: auto;
23
+ overscroll-behavior: contain;
24
+ overflow-anchor: none;
25
+ scrollbar-gutter: stable;
26
+ &:focus-visible {
27
+ outline: 2px solid var(--rv-ui-accent);
28
+ outline-offset: -2px;
29
+ }
30
+ }
31
+ .rv-ai-chat-content {
32
+ display: flex;
33
+ flex-direction: column;
34
+ gap: 1.5rem;
35
+ min-height: 100%;
36
+ padding: 1.25rem;
37
+ }
38
+ .rv-ai-chat-empty {
39
+ margin: auto;
40
+ text-align: center;
41
+ max-width: 24rem;
42
+ padding-block: 2rem;
43
+ }
44
+ .rv-ai-chat-empty p {
45
+ color: var(--rv-ui-text-muted);
46
+ margin-block: 0.5rem;
47
+ }
48
+ .rv-ai-chat-jump.rv-btn {
49
+ position: absolute;
50
+ inset-block-end: 0.75rem;
51
+ inset-inline-start: 50%;
52
+ transform: translateX(-50%);
53
+ box-shadow: 0 2px 12px var(--rv-ui-focus-ring);
54
+ white-space: nowrap;
55
+ }
56
+ .rv-ai-chat-composer {
57
+ flex: none;
58
+ padding: 0.75rem 1rem 1rem;
59
+ }
60
+ .rv-ai-message {
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 0.625rem;
64
+ min-width: 0;
65
+ max-width: 100%;
66
+ align-self: flex-start;
67
+ }
68
+ .rv-ai-message-content {
69
+ white-space: pre-wrap;
70
+ overflow-wrap: anywhere;
71
+ min-width: 0;
72
+ }
73
+ .rv-ai-message--user {
74
+ align-self: flex-end;
75
+ max-width: 85%;
76
+ .rv-ai-message-content {
77
+ padding: 0.625rem 1rem;
78
+ border-radius: 1.125rem;
79
+ background: var(--rv-ui-surface-sunken);
80
+ }
81
+ .rv-ai-message-actions {
82
+ justify-content: flex-end;
83
+ }
84
+ }
85
+ .rv-ai-message--system {
86
+ color: var(--rv-ui-text-muted);
87
+ font-size: 0.8125rem;
88
+ align-self: center;
89
+ }
90
+ .rv-ai-message-actions {
91
+ display: flex;
92
+ align-items: center;
93
+ flex-wrap: wrap;
94
+ gap: 0.25rem;
95
+ }
96
+ .rv-ai-trace {
97
+ font-size: 0.8125rem;
98
+ min-width: 0;
99
+ }
100
+ .rv-ai-trace > .rv-disclosure-summary {
101
+ display: flex;
102
+ align-items: center;
103
+ gap: 0.5rem;
104
+ padding: 0.25rem 0;
105
+ color: var(--rv-ui-text-muted);
106
+ cursor: pointer;
107
+ }
108
+ .rv-ai-trace-heading {
109
+ display: inline-flex;
110
+ align-items: center;
111
+ gap: 0.5rem;
112
+ min-width: 0;
113
+ overflow-wrap: anywhere;
114
+ }
115
+ .rv-ai-trace-content {
116
+ padding: 0.625rem 0 0.25rem 1rem;
117
+ margin-inline-start: 0.5rem;
118
+ border-inline-start: 1px solid var(--rv-ui-border);
119
+ white-space: pre-wrap;
120
+ overflow-wrap: anywhere;
121
+ }
122
+ .rv-ai-task-item {
123
+ display: flex;
124
+ align-items: flex-start;
125
+ gap: 0.5rem;
126
+ padding-block: 0.3rem;
127
+ }
128
+ .rv-ai-task-icon {
129
+ display: inline-flex;
130
+ width: 1rem;
131
+ height: 1.25rem;
132
+ flex: none;
133
+ align-items: center;
134
+ justify-content: center;
135
+ svg {
136
+ width: 0.875rem;
137
+ height: 0.875rem;
138
+ }
139
+ &[data-status='error'] {
140
+ color: var(--rv-ui-danger);
141
+ }
142
+ &[data-status='running'] {
143
+ color: var(--rv-ui-accent);
144
+ }
145
+ }
146
+ @media (max-width: 480px) {
147
+ .rv-ai-chat-content {
148
+ padding: 1rem;
149
+ }
150
+ .rv-ai-message--user {
151
+ max-width: 95%;
152
+ }
153
+ }
154
+
155
+ .rv-ai-trace-chevron {
156
+ display: inline-flex;
157
+ align-items: center;
158
+ }
159
+ .rv-ai-trace[open] .rv-ai-trace-chevron {
160
+ transform: rotate(180deg);
161
+ }
162
+
163
+ .rv-ai-trace-line {
164
+ color: var(--rv-ui-text-muted);
165
+ padding-block: 0.25rem;
166
+ }
167
+
168
+ // Mounted assistants keep the composer in normal flow above the grid.
169
+ .rv-ai-mounted-chat {
170
+ height: auto;
171
+ .rv-ai-chat-viewport {
172
+ min-height: 0;
173
+ max-height: min(18rem, 40vh);
174
+ }
175
+ .rv-ai-chat-content {
176
+ min-height: 0;
177
+ padding: 0.75rem 0;
178
+ &:empty {
179
+ padding: 0;
180
+ }
181
+ }
182
+ .rv-ai-chat-composer {
183
+ padding: 0.75rem 0 0;
184
+ }
185
+ }
186
+ .rv-ai-chat-result {
187
+ max-width: 100%;
188
+ margin: 0;
189
+ padding: 0.625rem;
190
+ border-radius: 0.5rem;
191
+ background: var(--rv-ui-surface-sunken);
192
+ font: inherit;
193
+ white-space: pre-wrap;
194
+ overflow-wrap: anywhere;
195
+ }
package/ai/_style.scss CHANGED
@@ -1,3 +1,4 @@
1
+ @use './chat';
1
2
  .rv-ai-assistant {
2
3
  box-sizing: border-box;
3
4
  width: 100%;
@@ -18,11 +19,12 @@
18
19
  min-width: 0;
19
20
  }
20
21
  .rv-ai-prompt-composer {
21
- display: flex;
22
- flex-direction: column;
22
+ display: grid;
23
+ grid-template-columns: minmax(0, 1fr) auto;
24
+ align-items: end;
23
25
  min-width: 0;
24
26
  border: 1px solid var(--rv-ui-border);
25
- border-radius: calc(var(--rv-ui-radius, 6px) + 10px);
27
+ border-radius: 24px;
26
28
  background: var(--rv-ui-surface-sunken);
27
29
  transition:
28
30
  border-color var(--rv-ui-motion-fast, 120ms) var(--rv-ui-motion-ease, ease),
@@ -34,10 +36,12 @@
34
36
  }
35
37
  }
36
38
  .rv-ai-prompt-composer textarea.rv-control {
39
+ grid-column: 1;
40
+ grid-row: 1;
37
41
  display: block;
38
- min-height: 4.75rem;
42
+ min-height: 1.5rem;
39
43
  max-height: 12rem;
40
- padding: 0.875rem 1rem 0.5rem;
44
+ padding: 0.75rem 1rem;
41
45
  border: 0;
42
46
  border-radius: inherit;
43
47
  background: transparent;
@@ -52,25 +56,44 @@
52
56
  }
53
57
  }
54
58
  .rv-ai-prompt-toolbar {
59
+ grid-column: 2;
60
+ grid-row: 1;
55
61
  display: flex;
56
62
  gap: 0.75rem;
57
63
  align-items: center;
58
64
  justify-content: space-between;
59
65
  min-width: 0;
60
- padding: 0.375rem 0.625rem 0.625rem 1rem;
66
+ padding: 0.5rem 0.5rem 0.5rem 0;
61
67
  }
62
68
  .rv-ai-prompt-footer {
69
+ grid-column: 1 / -1;
70
+ grid-row: 2;
63
71
  min-width: 0;
64
72
  margin-inline: 1rem;
65
- padding-block: 0.625rem 0.25rem;
66
- border-block-start: 1px solid var(--rv-ui-border);
73
+ padding-block: 0.625rem;
67
74
  &:empty {
68
75
  display: none;
69
76
  }
70
77
  }
78
+ .rv-ai-prompt-composer:has(.rv-ai-prompt-hint) {
79
+ grid-template-columns: minmax(0, 1fr);
80
+ .rv-ai-prompt-toolbar {
81
+ grid-column: 1;
82
+ grid-row: 3;
83
+ padding-inline-start: 1rem;
84
+ }
85
+ }
71
86
  .rv-ai-request-trail {
72
87
  min-width: 0;
73
88
  }
89
+ .rv-ai-request-trail .rv-ai-trail-trigger {
90
+ color: var(--rv-ui-accent-text);
91
+ background: var(--rv-ui-selected-bg);
92
+ &:hover:not(:disabled), &:focus-visible {
93
+ color: var(--rv-ui-accent-text);
94
+ background: var(--rv-ui-selected-bg);
95
+ }
96
+ }
74
97
  .rv-ai-trail-trigger .rv-svg-icon {
75
98
  transition: transform var(--rv-ui-motion-fast, 120ms)
76
99
  var(--rv-ui-motion-ease, ease);
@@ -84,63 +107,86 @@
84
107
  max-width: calc(100% - 16px);
85
108
  max-height: min(30rem, calc(100dvh - 16px));
86
109
  padding: 0;
110
+ border-radius: 12px;
87
111
  font: inherit;
88
112
  &:focus {
89
113
  outline: none;
90
114
  }
91
115
  }
92
116
  .rv-ai-trail-header {
93
- padding: 0.75rem 0.875rem 0.5rem;
117
+ padding: 0.875rem 1rem 0.625rem;
94
118
  }
95
119
  .rv-ai-trail-label {
96
120
  display: flex;
97
121
  align-items: center;
98
122
  gap: 0.5rem;
99
- color: var(--rv-ui-text-muted);
123
+ color: var(--rv-ui-text);
100
124
  font-size: 0.75rem;
101
125
  font-weight: var(--rv-ui-font-weight-medium, 500);
102
126
  }
103
127
  .rv-ai-trail-steps {
104
128
  display: flex;
105
129
  flex-direction: column;
106
- gap: 0.375rem;
130
+ gap: 0.25rem;
107
131
  min-width: 0;
108
132
  margin: 0;
109
- padding: 0 0.5rem 0.5rem;
133
+ padding: 0 0.5rem 0.625rem;
110
134
  list-style: none;
111
135
  }
136
+ .rv-ai-step {
137
+ position: relative;
138
+ &:not(:last-child)::before {
139
+ content: '';
140
+ position: absolute;
141
+ left: 20px;
142
+ top: 32px;
143
+ bottom: -12px;
144
+ width: 1px;
145
+ background: var(--rv-ui-border);
146
+ }
147
+ }
112
148
  .rv-ai-step-chip {
113
149
  display: flex;
114
150
  align-items: flex-start;
115
151
  gap: 0.625rem;
116
152
  min-width: 0;
117
153
  padding: 0.5rem;
118
- border: 1px solid var(--rv-ui-border);
119
- border-radius: var(--rv-ui-radius, 6px);
120
- background: var(--rv-ui-surface);
154
+ border: 0;
155
+ border-radius: 8px;
156
+ background: transparent;
121
157
  color: var(--rv-ui-text);
122
158
  }
159
+ .rv-ai-step:hover .rv-ai-step-chip,
160
+ .rv-ai-step:focus-within .rv-ai-step-chip {
161
+ background: var(--rv-ui-surface-hover);
162
+ }
123
163
  .rv-ai-step[data-current] .rv-ai-step-chip {
124
- background: var(--rv-ui-selected-bg);
125
- border-color: color-mix(
126
- in srgb,
127
- var(--rv-ui-accent) 30%,
128
- var(--rv-ui-border)
129
- );
164
+ background: color-mix(in srgb, var(--rv-ui-selected-bg) 55%, var(--rv-ui-surface));
130
165
  }
131
166
  .rv-ai-step-number {
167
+ position: relative;
168
+ box-sizing: border-box;
132
169
  flex: none;
133
- min-width: 1.25rem;
134
- padding-block: 0.25rem;
170
+ min-width: 24px;
171
+ height: 24px;
172
+ margin-block: 2px;
173
+ padding: 0 4px;
174
+ border-radius: 999px;
175
+ background: var(--rv-ui-surface-sunken);
135
176
  color: var(--rv-ui-text-muted);
136
177
  font-size: 0.6875rem;
137
178
  font-variant-numeric: tabular-nums;
138
179
  text-align: center;
180
+ line-height: 24px;
181
+ }
182
+ .rv-ai-step[data-current] .rv-ai-step-number {
183
+ background: var(--rv-ui-accent);
184
+ color: var(--rv-ui-accent-contrast, #fff);
139
185
  }
140
186
  .rv-ai-step-label {
141
187
  flex: 1;
142
188
  min-width: 0;
143
- padding-block: 0.1875rem;
189
+ padding-block: 0.25rem;
144
190
  overflow-wrap: anywhere;
145
191
  white-space: pre-wrap;
146
192
  font-size: 0.75rem;
@@ -178,27 +224,43 @@
178
224
  overflow-wrap: anywhere;
179
225
  }
180
226
  .rv-ai-prompt-toolbar .rv-ai-prompt-submit {
181
- --rv-icon-button-size: 32px;
227
+ --rv-icon-button-size: 30px;
228
+ min-height: var(--rv-icon-button-size);
182
229
  flex: 0 0 auto;
183
- padding: 0.5rem;
230
+ padding: 0.25rem;
184
231
  border-radius: 50%;
185
232
  }
186
233
  .rv-ai-suggestions {
187
234
  display: flex;
188
- gap: 0.5rem;
235
+ flex-wrap: wrap;
236
+ align-items: center;
237
+ gap: 0.375rem;
189
238
  min-width: 0;
190
- overflow-x: auto;
191
- overscroll-behavior-x: contain;
192
- scroll-padding-inline: 4px;
193
- scrollbar-width: thin;
194
- // Give keyboard focus outlines room inside the scrolling row.
239
+ // Leave room for focus outlines.
195
240
  padding: 4px;
196
241
  margin: -4px;
197
242
  }
243
+ .rv-ai-suggestions .dropdown-container.rv-ai-examples {
244
+ flex: 0 0 28px;
245
+ width: 28px;
246
+ height: 28px;
247
+ }
248
+ .rv-ai-examples .dropdown-trigger {
249
+ justify-content: center;
250
+ width: 28px;
251
+ height: 28px;
252
+ padding: 0;
253
+ border: 0;
254
+ border-radius: var(--rv-ui-radius, 6px);
255
+ background: transparent;
256
+ color: var(--rv-ui-text);
257
+ font-size: 0.75rem;
258
+ line-height: 1.25;
259
+ }
198
260
  .rv-ai-suggestions .rv-ai-suggestion {
199
261
  flex: 0 0 auto;
200
- min-height: 32px;
201
- padding: 0.5rem 0.75rem;
262
+ min-height: 28px;
263
+ padding: 0.25rem 0.625rem;
202
264
  border-radius: 999px;
203
265
  font-size: 0.75rem;
204
266
  line-height: 1.25;
@@ -250,3 +312,12 @@
250
312
  outline-offset: 2px;
251
313
  }
252
314
  }
315
+
316
+ .rv-ai-result-details {
317
+ margin: 0;
318
+ max-height: 16rem;
319
+ overflow: auto;
320
+ white-space: pre-wrap;
321
+ overflow-wrap: anywhere;
322
+ font-size: 0.875em;
323
+ }
package/ai/chat.d.ts ADDED
@@ -0,0 +1,63 @@
1
+ import { h, ComponentChildren, JSX } from '../_vendor/preact/src/index';
2
+ import { AiPromptInputProps } from './components';
3
+ import { AiUiTranslations } from './translations';
4
+ export interface AiChatPartProps {
5
+ children?: ComponentChildren;
6
+ className?: string;
7
+ translations?: AiUiTranslations;
8
+ }
9
+ export interface AiChatProps extends AiChatPartProps {
10
+ label?: string;
11
+ style?: JSX.CSSProperties;
12
+ }
13
+ /** Presentation only. The host owns transcript, provider, actions and persistence. */
14
+ export declare function AiChat({ children, className, label, style, translations, }: AiChatProps): h.JSX.Element;
15
+ export interface AiChatContentProps extends AiChatPartProps {
16
+ label?: string;
17
+ /** Follow updates only while the reader remains at the live edge. */
18
+ autoScroll?: boolean;
19
+ busy?: boolean;
20
+ jumpLabel?: string;
21
+ }
22
+ /** Scroll measurement belongs to this visual viewport, never to a grid/data owner. */
23
+ export declare function AiChatContent({ children, className, autoScroll, busy, label, jumpLabel, translations, }: AiChatContentProps): h.JSX.Element;
24
+ export interface AiChatEmptyStateProps extends AiChatPartProps {
25
+ title?: string;
26
+ description?: string;
27
+ }
28
+ export declare function AiChatEmptyState({ title, description, children, className, translations, }: AiChatEmptyStateProps): h.JSX.Element;
29
+ /** Existing composer behavior, with chat-specific defaults. */
30
+ export declare function AiChatComposer(props: AiPromptInputProps): h.JSX.Element;
31
+ export interface AiMessageProps extends AiChatPartProps {
32
+ from: 'user' | 'assistant' | 'system';
33
+ label?: string;
34
+ isStreaming?: boolean;
35
+ }
36
+ export declare function AiMessage({ from, label, isStreaming, children, className, translations, }: AiMessageProps): h.JSX.Element;
37
+ /** Text stays text. Hosts can supply their own trusted Markdown renderer as children. */
38
+ export declare function AiMessageContent({ children, className, }: AiChatPartProps): h.JSX.Element;
39
+ export interface AiMessageActionsProps extends AiChatPartProps {
40
+ label?: string;
41
+ }
42
+ export declare function AiMessageActions({ children, className, label, translations, }: AiMessageActionsProps): h.JSX.Element;
43
+ export type AiTaskStatus = 'pending' | 'running' | 'completed' | 'error' | 'cancelled';
44
+ export interface AiTaskProps extends AiChatPartProps {
45
+ title: string;
46
+ status?: AiTaskStatus;
47
+ open?: boolean;
48
+ defaultOpen?: boolean;
49
+ onOpenChange?(open: boolean): void;
50
+ }
51
+ export declare function AiTask(props: AiTaskProps): h.JSX.Element;
52
+ export interface AiTaskItemProps extends AiChatPartProps {
53
+ status?: AiTaskStatus;
54
+ }
55
+ export declare function AiTaskItem({ status, children, className, translations, }: AiTaskItemProps): h.JSX.Element;
56
+ export interface AiReasoningProps extends Omit<AiTaskProps, 'title' | 'status'> {
57
+ title?: string;
58
+ isStreaming?: boolean;
59
+ /** Host-supplied elapsed seconds; no hidden timer or invented reasoning. */
60
+ duration?: number;
61
+ }
62
+ /** Render only reasoning/summary text explicitly supplied by the host or provider. */
63
+ export declare function AiReasoning({ title, isStreaming, duration, children, translations, ...props }: AiReasoningProps): h.JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { AiUiTranslations } from './translations';
2
2
  import { h, ComponentChildren, ComponentProps } from '../_vendor/preact/src/index';
3
3
  import { Textarea } from '../controls';
4
- export type AiActionPhase = 'idle' | 'understanding' | 'applying' | 'completed' | 'clarification' | 'unsupported' | 'error' | 'cancelled';
4
+ export type AiActionPhase = 'idle' | 'understanding' | 'applying' | 'preview' | 'completed' | 'clarification' | 'unsupported' | 'error' | 'cancelled';
5
5
  export interface AiPromptInputProps {
6
6
  translations?: AiUiTranslations;
7
7
  value: string;
@@ -14,6 +14,8 @@ export interface AiPromptInputProps {
14
14
  placeholder?: string;
15
15
  submitLabel?: string;
16
16
  stopLabel?: string;
17
+ /** Opt-in local prompt recall. Arrow keys retain normal multiline behavior away from text edges. */
18
+ promptHistory?: readonly string[];
17
19
  /** Empty-draft keyboard guidance. An empty string lets toolbar context replace it. */
18
20
  hint?: string;
19
21
  /** Host-supported actions or context, displayed in the composer toolbar. */
@@ -24,10 +26,14 @@ export interface AiPromptInputProps {
24
26
  textareaProps?: Pick<ComponentProps<typeof Textarea>, 'className' | 'style' | 'rows'>;
25
27
  }
26
28
  /** Shared composer: Enter submits, Shift+Enter inserts a line; IME never submits. */
27
- export declare function AiPromptInput({ translations, value, onValueChange, onSubmit, onStop, busy, disabled, label, placeholder, submitLabel, stopLabel, hint, actions, footer, textareaProps, }: AiPromptInputProps): h.JSX.Element;
29
+ export declare function AiPromptInput({ translations, value, onValueChange, onSubmit, onStop, busy, disabled, label, placeholder, submitLabel, stopLabel, promptHistory, hint, actions, footer, textareaProps, }: AiPromptInputProps): h.JSX.Element;
30
+ export interface AiSuggestionChoice {
31
+ label: string;
32
+ prompt: string;
33
+ }
28
34
  export interface AiSuggestionsProps {
29
35
  translations?: AiUiTranslations;
30
- items: readonly string[];
36
+ items: readonly (string | AiSuggestionChoice)[];
31
37
  onSelect(value: string): void;
32
38
  disabled?: boolean;
33
39
  label?: string;
@@ -57,3 +63,13 @@ export interface AiAssistantProps {
57
63
  }
58
64
  /** Neutral composition; grid/model/query policy remains in the consuming product. */
59
65
  export declare function AiAssistant({ translations, label, children, footer, busy, }: AiAssistantProps): h.JSX.Element;
66
+ export interface AiChangePreviewProps {
67
+ translations?: AiUiTranslations;
68
+ summary: string;
69
+ details?: string;
70
+ disabled?: boolean;
71
+ onApply(): void;
72
+ onCancel(): void;
73
+ }
74
+ /** Generic approval surface; the host retains the prepared command and its mutation policy. */
75
+ export declare function AiChangePreview({ translations, summary, details, disabled, onApply, onCancel, }: AiChangePreviewProps): h.JSX.Element;
package/ai/index.d.ts CHANGED
@@ -2,4 +2,6 @@ export * from './components';
2
2
  export * from './mount';
3
3
  export * from './request-trail';
4
4
  export * from './translations';
5
+ export type { AiPromptHistoryOptions } from './prompt-history';
5
6
  export { AiTranslationProvider } from './translation-context';
7
+ export * from './chat';
package/ai/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "../_chunks/request-trail-IdNiFvKH.js";
2
- import { t as l } from "../_chunks/mount-DZe_6VtR.js";
3
- export { t as AI_UI_MESSAGES, i as AiActionStatus, o as AiAssistant, n as AiPromptInput, c as AiRequestTrail, e as AiResult, a as AiSuggestions, s as AiTranslationProvider, l as mountAiAssistant, r as translateAiText };
1
+ import { t as e } from "../_chunks/mount-DQ1cpppK.js";
2
+ import { _ as t, a as n, b as r, c as i, d as a, f as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, p as m, r as h, s as g, t as _, u as v, x as y, y as b } from "../_chunks/request-trail-DSlFix6i.js";
3
+ export { r as AI_UI_MESSAGES, o as AiActionStatus, m as AiAssistant, d as AiChangePreview, f as AiChat, h as AiChatComposer, l as AiChatContent, n as AiChatEmptyState, p as AiMessage, g as AiMessageActions, i as AiMessageContent, c as AiPromptInput, u as AiReasoning, _ as AiRequestTrail, s as AiResult, t as AiSuggestions, v as AiTask, a as AiTaskItem, b as AiTranslationProvider, e as mountAiAssistant, y as translateAiText };
package/ai/mount.d.ts CHANGED
@@ -1,17 +1,44 @@
1
1
  import { AiUiTranslations } from './translations';
2
- import { AiActionPhase, AiPromptInputProps } from './components';
2
+ import { AiActionPhase, AiPromptInputProps, AiSuggestionChoice } from './components';
3
3
  import { AiRequestTrailItem, AiRequestTrailProps } from './request-trail';
4
+ import { AiPromptHistoryOptions } from './prompt-history';
4
5
  export interface AiAssistantMountState {
5
6
  phase: AiActionPhase;
7
+ /** Accepted public user request only; never an internal model prompt. */
8
+ request?: {
9
+ id: string;
10
+ prompt: string;
11
+ };
12
+ /** Increment to clear the local chat transcript and composer. */
13
+ chatKey?: number;
6
14
  message: string;
15
+ /** Plain text from a bounded host-owned action result. */
16
+ resultDetails?: string;
17
+ pendingAction?: {
18
+ summary: string;
19
+ details?: string;
20
+ };
21
+ canUndoData?: boolean;
22
+ canRedoData?: boolean;
7
23
  matchedRows?: number;
8
24
  canRestore?: boolean;
9
25
  suggestions?: readonly string[];
26
+ choices?: readonly AiSuggestionChoice[];
10
27
  steps?: readonly AiRequestTrailItem[];
11
28
  canEditSteps?: boolean;
12
29
  }
13
30
  export interface AiAssistantMountOptions {
31
+ mode?: 'toolbar' | 'chat';
32
+ onClearChat?(): void;
33
+ /** Local input recall and optional host persistence; never sent to the model automatically. */
34
+ promptHistory?: AiPromptHistoryOptions;
35
+ /** Auto-dismiss settled activity messages; disabled unless configured. */
36
+ activityDurationMs?: number;
14
37
  translations?: AiUiTranslations;
38
+ onApplyAction?(): void;
39
+ onCancelAction?(): void;
40
+ onUndoData?(): void;
41
+ onRedoData?(): void;
15
42
  onSubmit(prompt: string): void;
16
43
  onStop(): void;
17
44
  onRestore(): void;
@@ -29,5 +56,7 @@ export interface AiAssistantMountOptions {
29
56
  /** Framework-independent mount of the same TSX used by the public components. */
30
57
  export declare function mountAiAssistant(host: HTMLElement, options: AiAssistantMountOptions): {
31
58
  update(state: AiAssistantMountState): void;
59
+ /** Update example choices without remounting the composer or losing its draft. */
60
+ setSuggestions(items: readonly string[]): void;
32
61
  destroy(): void;
33
62
  };
@@ -0,0 +1,13 @@
1
+ /** Recall stays local to the UI; it never becomes model conversation automatically. */
2
+ export interface AiPromptHistoryOptions {
3
+ /** Initial prompts loaded by the host from its preferred storage. Newest comes last. */
4
+ items?: readonly string[];
5
+ /** Optional host-owned persistence. No browser storage is read or written by the component. */
6
+ onChange?(items: readonly string[]): void;
7
+ }
8
+ export declare function boundAiPromptHistory(items: readonly string[]): string[];
9
+ export declare class AiPromptRecall {
10
+ private state?;
11
+ reset(): void;
12
+ move(value: string, direction: 'up' | 'down', items: readonly string[]): string | undefined;
13
+ }
@@ -0,0 +1,25 @@
1
+ import { AiAssistantMountState } from './mount';
2
+ export interface AiTranscriptMessage {
3
+ id: string;
4
+ group: string;
5
+ from: 'user' | 'assistant' | 'system';
6
+ text: string;
7
+ phase?: AiAssistantMountState['phase'];
8
+ details?: string;
9
+ pending?: boolean;
10
+ }
11
+ /** Local presentation state only. Never supplies model context or persists values. */
12
+ export declare class AiTranscript {
13
+ messages: readonly AiTranscriptMessage[];
14
+ private epoch;
15
+ private initialized;
16
+ private requestId?;
17
+ private ignoredRequest?;
18
+ private currentId?;
19
+ private active;
20
+ private lastPhase?;
21
+ private key;
22
+ private sequence;
23
+ update(state: AiAssistantMountState): void;
24
+ clear(): void;
25
+ }
@@ -1,4 +1,4 @@
1
1
  /** English message IDs and fallbacks; hosts supply translated values. */
2
- export declare const AI_UI_MESSAGES: readonly ["Ask AI to change this view", "Filter or sort your data…", "Send", "Stop", "Enter to send · Shift+Enter for a new line", "Suggested requests", "AI view assistant", "View steps", "Clear all", "Restore the starting view", "Restore previous view", "Reset view", "The view changed manually. Start a new request to continue.", "Remove request: {label}", "{count} step", "{count} steps", "{count} applied request", "{count} applied requests", "{count} matching rows"];
2
+ export declare const AI_UI_MESSAGES: readonly ["AI chat", "Clear chat", "Conversation messages", "Jump to latest", "You", "Assistant", "System", "Message actions", "Start a conversation", "Ask a question to get started.", "Message", "Type a message…", "Working…", "Reasoning summary", "Pending", "Running", "Completed", "Failed", "Cancelled", "{seconds}s", "Data history", "Review changes", "Apply changes", "Cancel changes", "Undo data change", "Redo data change", "Ask AI to change this view", "Filter or sort your data…", "Send", "Stop", "Enter to send · Shift+Enter for a new line", "Suggested requests", "More", "Activity", "Collapse activity", "Expand activity", "AI view assistant", "View steps", "Clear all", "Restore the starting view", "Restore previous view", "Reset view", "The view changed manually. Start a new request to continue.", "Remove request: {label}", "{count} step", "{count} steps", "{count} applied request", "{count} applied requests", "{count} matching rows"];
3
3
  export type AiUiTranslations = Partial<Record<(typeof AI_UI_MESSAGES)[number], string>>;
4
4
  export declare function translateAiText(text: string, translations?: Readonly<Record<string, string | undefined>>, values?: Readonly<Record<string, string | number>>): string;
@@ -61,9 +61,6 @@ export class UiComponent {
61
61
  };
62
62
  }
63
63
  const slots = Object.fromEntries(this.slots?.map(slot => [slot.rvUiSlot, slot]) ?? []);
64
- if (this.component === 'NativeSelect' && Object.keys(slots).length) {
65
- throw new Error('Use <select rvControl> for native Angular option templates.');
66
- }
67
64
  this.mount.render(component, props, (props, content) => withFrameworkContent(this.component, props, slots, content));
68
65
  }
69
66
  renderTemplates(targets) {