one-design-next 0.0.45 → 0.0.47

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.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Interrupt · 对话中断协议(无 UI)
3
+ *
4
+ * Clarify(要信息)与 Approval(要授权)分轨组件,只共享本协议。
5
+ * 见讲演录:interrupt-clarify-approval-split
6
+ *
7
+ * 业界对照:
8
+ * - Claude `canUseTool`(AskUserQuestion vs tool permission)
9
+ * - LangChain `interrupt` + approve/edit/reject/respond
10
+ * - OpenAI Agents `interruption` / `needsApproval`
11
+ */
12
+ /** 中断意图:收集信息 | 授权副作用 */
13
+ export type InterruptIntent = 'clarify' | 'approve';
14
+ /** 中断生命周期 */
15
+ export type InterruptStatus = 'pending' | 'resolved' | 'skipped';
16
+ /**
17
+ * 中断最小信封。
18
+ * `payload` 由 intent 分发:clarify → Clarify*Spec;approve → ApprovalSpec。
19
+ * 具体 Spec 类型在各组件目录定义,协议层不反向依赖 UI。
20
+ */
21
+ export interface InterruptBase<TPayload = unknown> {
22
+ id: string;
23
+ intent: InterruptIntent;
24
+ status: InterruptStatus;
25
+ payload: TPayload;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ import * as React from 'react';
2
+ import './style';
3
+ export type ApprovalDecision = 'approve' | 'reject';
4
+ /** 参数摘要一行:Host 已格式化的 label → 展示文案(可含换行) */
5
+ export interface ApprovalSummaryItem {
6
+ label: string;
7
+ value: string;
8
+ }
9
+ export interface ApprovalSpec {
10
+ /** 待授权动作说明(标题);14px / regular / black-12;原样展示,Host 自行决定是否带问号 */
11
+ description: string;
12
+ /** 写操作工具名;可选元数据,UI 不渲染 */
13
+ title?: string;
14
+ actionLabel: string;
15
+ rejectLabel?: string;
16
+ destructive?: boolean;
17
+ /** 同意锁态文案;省略时由 description「确认…」推导为「已确认…」 */
18
+ resolvedLabel?: string;
19
+ /** 拒绝锁态文案;省略时由 description「确认创建…」推导为「暂不创建…」 */
20
+ rejectedLabel?: string;
21
+ /**
22
+ * 参数摘要。Clarify 收齐后由 **Host 格式化**再传入;
23
+ * 组件不解析原始 tool args。省略或空数组 = 轻量 yes/no。
24
+ * 未决:默认展开;锁态:默认折叠,右侧可展开回看。
25
+ */
26
+ summary?: ApprovalSummaryItem[];
27
+ }
28
+ export interface ApprovalResolvePayload {
29
+ decision: ApprovalDecision;
30
+ }
31
+ export interface ApprovalProps {
32
+ spec: ApprovalSpec;
33
+ resolved?: ApprovalDecision | null;
34
+ onResolve?: (payload: ApprovalResolvePayload) => void;
35
+ className?: string;
36
+ }
37
+ export declare function Approval({ spec, resolved: resolvedProp, onResolve, className, }: ApprovalProps): React.JSX.Element;
38
+ export declare namespace Approval {
39
+ var displayName: string;
40
+ }
41
+ export default Approval;
@@ -0,0 +1,221 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import * as React from 'react';
8
+ import clsx from 'clsx';
9
+ import Button from "../button";
10
+ import Icon from "../icon";
11
+ import "./style";
12
+
13
+ /* ------------------------------------------------------------------ */
14
+ /* Types */
15
+ /* ------------------------------------------------------------------ */
16
+
17
+ /** 参数摘要一行:Host 已格式化的 label → 展示文案(可含换行) */
18
+
19
+ function lockedTitle(description, decision, explicit) {
20
+ if (explicit) return explicit;
21
+ var base = description.trim().replace(/[\?\uFF1F]+$/, '');
22
+ if (decision === 'approve') {
23
+ return base.startsWith('确认') ? "\u5DF2".concat(base) : base;
24
+ }
25
+ if (base.startsWith('确认创建')) {
26
+ return "\u6682\u4E0D\u521B\u5EFA".concat(base.slice('确认创建'.length));
27
+ }
28
+ if (base.startsWith('确认')) {
29
+ return "\u6682\u4E0D".concat(base.slice('确认'.length));
30
+ }
31
+ return base;
32
+ }
33
+
34
+ /** 单列小票:标签列宽 = 全部标签中最长者 */
35
+ function ApprovalReceipt(_ref) {
36
+ var summary = _ref.summary;
37
+ var rootRef = React.useRef(null);
38
+ React.useLayoutEffect(function () {
39
+ var root = rootRef.current;
40
+ if (!root) return;
41
+ var measure = function measure() {
42
+ var labels = root.querySelectorAll('[data-odn-approval-receipt-label]');
43
+ var max = 0;
44
+ labels.forEach(function (el) {
45
+ el.style.width = 'auto';
46
+ max = Math.max(max, el.getBoundingClientRect().width);
47
+ });
48
+ if (max > 0) {
49
+ root.style.setProperty('--odn-approval-label-width', "".concat(Math.ceil(max), "px"));
50
+ }
51
+ };
52
+ measure();
53
+ var ro = new ResizeObserver(measure);
54
+ ro.observe(root);
55
+ return function () {
56
+ return ro.disconnect();
57
+ };
58
+ }, [summary]);
59
+ return /*#__PURE__*/React.createElement("dl", {
60
+ "data-odn-approval-receipt": true,
61
+ ref: rootRef
62
+ }, summary.map(function (item, index) {
63
+ return /*#__PURE__*/React.createElement("div", {
64
+ key: "".concat(item.label, "-").concat(index),
65
+ "data-odn-approval-receipt-row": true
66
+ }, /*#__PURE__*/React.createElement("dt", {
67
+ "data-odn-approval-receipt-label": true
68
+ }, item.label), /*#__PURE__*/React.createElement("dd", {
69
+ "data-odn-approval-receipt-value": true,
70
+ "data-multiline": item.value.includes('\n') ? '' : undefined
71
+ }, item.value));
72
+ }));
73
+ }
74
+
75
+ /* ------------------------------------------------------------------ */
76
+ /* Approval */
77
+ /* ------------------------------------------------------------------ */
78
+
79
+ export function Approval(_ref2) {
80
+ var _spec$summary;
81
+ var spec = _ref2.spec,
82
+ resolvedProp = _ref2.resolved,
83
+ onResolve = _ref2.onResolve,
84
+ className = _ref2.className;
85
+ var _React$useState = React.useState(null),
86
+ _React$useState2 = _slicedToArray(_React$useState, 2),
87
+ internalResolved = _React$useState2[0],
88
+ setInternalResolved = _React$useState2[1];
89
+ var resolveLockRef = React.useRef(false);
90
+ var isResolvedControlled = resolvedProp !== undefined;
91
+ var resolved = isResolvedControlled ? resolvedProp : internalResolved;
92
+ var locked = !!resolved;
93
+ var summary = (_spec$summary = spec.summary) !== null && _spec$summary !== void 0 ? _spec$summary : [];
94
+ var hasSummary = summary.length > 0;
95
+
96
+ /* 未决默认展开;锁态 / 挂载即已决议 → 默认折叠 */
97
+ var _React$useState3 = React.useState(function () {
98
+ return !locked && hasSummary;
99
+ }),
100
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
101
+ summaryExpanded = _React$useState4[0],
102
+ setSummaryExpanded = _React$useState4[1];
103
+ /* 收合动画结束后再卸掉 panel 占位,避免残高顶偏锁态文字;动画中保留 8px 间距 */
104
+ var _React$useState5 = React.useState(function () {
105
+ return !(!locked && hasSummary);
106
+ }),
107
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
108
+ summaryCollapsedSettled = _React$useState6[0],
109
+ setSummaryCollapsedSettled = _React$useState6[1];
110
+ var wasLockedRef = React.useRef(locked);
111
+ React.useEffect(function () {
112
+ if (resolvedProp === null || resolvedProp === undefined) {
113
+ resolveLockRef.current = false;
114
+ }
115
+ }, [resolvedProp]);
116
+ React.useEffect(function () {
117
+ if (locked && !wasLockedRef.current && hasSummary) {
118
+ setSummaryExpanded(false);
119
+ }
120
+ wasLockedRef.current = locked;
121
+ }, [locked, hasSummary]);
122
+ React.useEffect(function () {
123
+ if (summaryExpanded) {
124
+ setSummaryCollapsedSettled(false);
125
+ return;
126
+ }
127
+ var id = window.setTimeout(function () {
128
+ return setSummaryCollapsedSettled(true);
129
+ }, 230);
130
+ return function () {
131
+ return window.clearTimeout(id);
132
+ };
133
+ }, [summaryExpanded]);
134
+ var handleResolve = function handleResolve(decision) {
135
+ if (locked || resolveLockRef.current) return;
136
+ resolveLockRef.current = true;
137
+ if (hasSummary) setSummaryExpanded(false);
138
+ if (!isResolvedControlled) setInternalResolved(decision);
139
+ onResolve === null || onResolve === void 0 || onResolve({
140
+ decision: decision
141
+ });
142
+ };
143
+ var handleToggleSummary = function handleToggleSummary() {
144
+ if (summaryExpanded) {
145
+ setSummaryExpanded(false);
146
+ return;
147
+ }
148
+ setSummaryCollapsedSettled(false);
149
+ requestAnimationFrame(function () {
150
+ return setSummaryExpanded(true);
151
+ });
152
+ };
153
+ var resolvedMain = resolved ? lockedTitle(spec.description, resolved, resolved === 'approve' ? spec.resolvedLabel : spec.rejectedLabel) : null;
154
+ return /*#__PURE__*/React.createElement("div", {
155
+ "data-odn-approval": true,
156
+ "data-destructive": spec.destructive || undefined,
157
+ "data-resolved": resolved || undefined,
158
+ "data-has-summary": hasSummary || undefined,
159
+ "data-summary-expanded": hasSummary && summaryExpanded ? '' : undefined,
160
+ className: clsx(className)
161
+ }, /*#__PURE__*/React.createElement("div", {
162
+ "data-odn-approval-body": true
163
+ }, /*#__PURE__*/React.createElement("div", {
164
+ "data-odn-approval-heading": true
165
+ }, /*#__PURE__*/React.createElement("div", {
166
+ "data-odn-approval-title-row": true
167
+ }, /*#__PURE__*/React.createElement("p", {
168
+ "data-odn-approval-text": true
169
+ }, resolved ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Icon, {
170
+ name: resolved === 'approve' ? 'check' : 'x',
171
+ size: 14,
172
+ "data-odn-approval-icon": true
173
+ }), /*#__PURE__*/React.createElement("span", {
174
+ "data-odn-approval-resolved-main": true
175
+ }, resolvedMain)) : /*#__PURE__*/React.createElement(React.Fragment, null, spec.destructive ? /*#__PURE__*/React.createElement(Icon, {
176
+ name: "alert-triangle",
177
+ size: 14,
178
+ "data-odn-approval-icon": true,
179
+ "data-destructive": true
180
+ }) : null, /*#__PURE__*/React.createElement("span", null, spec.description))), hasSummary ? /*#__PURE__*/React.createElement("button", {
181
+ type: "button",
182
+ "data-odn-approval-summary-toggle": true,
183
+ "aria-expanded": summaryExpanded,
184
+ onClick: handleToggleSummary
185
+ }, /*#__PURE__*/React.createElement("span", null, summaryExpanded ? '收起' : '展开'), /*#__PURE__*/React.createElement(Icon, {
186
+ name: "chevron-down",
187
+ size: 14,
188
+ "data-odn-approval-summary-chevron": true
189
+ })) : null), hasSummary && !resolved ? /*#__PURE__*/React.createElement("span", {
190
+ "data-odn-approval-summary-count": true
191
+ }, summary.length, " \u9879\u53C2\u6570") : null), hasSummary ? /*#__PURE__*/React.createElement("div", {
192
+ "data-odn-approval-summary-panel": true,
193
+ "data-open": summaryExpanded ? 'true' : 'false',
194
+ "data-collapsed-settled": summaryCollapsedSettled ? '' : undefined,
195
+ "aria-hidden": !summaryExpanded
196
+ }, /*#__PURE__*/React.createElement("div", {
197
+ "data-odn-approval-summary-panel-inner": true
198
+ }, /*#__PURE__*/React.createElement("div", {
199
+ "data-odn-approval-summary-surface": true
200
+ }, /*#__PURE__*/React.createElement("div", {
201
+ "data-odn-approval-summary-fade": true
202
+ }, /*#__PURE__*/React.createElement(ApprovalReceipt, {
203
+ summary: summary
204
+ }))))) : null), !resolved ? /*#__PURE__*/React.createElement("div", {
205
+ "data-odn-approval-actions": true
206
+ }, spec.rejectLabel ? /*#__PURE__*/React.createElement(Button, {
207
+ size: "small",
208
+ intent: "normal",
209
+ onClick: function onClick() {
210
+ return handleResolve('reject');
211
+ }
212
+ }, spec.rejectLabel) : null, /*#__PURE__*/React.createElement(Button, {
213
+ size: "small",
214
+ intent: spec.destructive ? 'danger' : 'primary',
215
+ onClick: function onClick() {
216
+ return handleResolve('approve');
217
+ }
218
+ }, spec.actionLabel)) : null);
219
+ }
220
+ Approval.displayName = 'Approval';
221
+ export default Approval;
@@ -0,0 +1,321 @@
1
+ @charset "UTF-8";
2
+ /**
3
+ * Approval · 授权确认(小票)
4
+ * 轻量态:文案 + 按钮垂直居中。
5
+ * 带 summary:只读参数小票,无编辑;改参走 Composer / Clarify。
6
+ */
7
+ [data-odn-approval] {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ gap: 12px;
12
+ width: 100%;
13
+ box-sizing: border-box;
14
+ padding: 12px 16px;
15
+ border-radius: 10px;
16
+ border: 1px solid var(--odn-color-black-5);
17
+ background: var(--odn-color-bg-elevated);
18
+ }
19
+
20
+ [data-odn-approval][data-has-summary] {
21
+ flex-direction: column;
22
+ align-items: stretch;
23
+ gap: 0;
24
+ padding: 0;
25
+ border-radius: 12px;
26
+ border: 1px solid var(--odn-color-black-6);
27
+ }
28
+
29
+ [data-odn-approval-body] {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 12px;
33
+ min-width: 0;
34
+ flex: 1;
35
+ }
36
+
37
+ [data-odn-approval][data-has-summary] [data-odn-approval-body] {
38
+ padding: 10px 12px 12px;
39
+ flex: none;
40
+ gap: 0;
41
+ }
42
+
43
+ [data-odn-approval-heading] {
44
+ display: flex;
45
+ flex-direction: column;
46
+ align-items: stretch;
47
+ gap: 4px;
48
+ min-width: 0;
49
+ }
50
+
51
+ /* 标题与「收起/展开」同一行 */
52
+ [data-odn-approval-title-row] {
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: space-between;
56
+ gap: 12px;
57
+ min-width: 0;
58
+ }
59
+
60
+ [data-odn-approval-text] {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 6px;
64
+ margin: 0;
65
+ min-width: 0;
66
+ flex: 1;
67
+ font-size: 14px;
68
+ font-weight: 400;
69
+ line-height: 1.5;
70
+ color: var(--odn-color-black-12);
71
+ }
72
+ [data-odn-approval-text] > span {
73
+ min-width: 0;
74
+ }
75
+
76
+ [data-odn-approval-summary-count] {
77
+ font-size: 12px;
78
+ font-weight: 400;
79
+ line-height: 1.4;
80
+ color: var(--odn-color-black-9);
81
+ }
82
+
83
+ [data-odn-approval-summary-toggle] {
84
+ display: inline-flex;
85
+ align-items: center;
86
+ gap: 2px;
87
+ flex-shrink: 0;
88
+ margin: 0;
89
+ padding: 0;
90
+ border: none;
91
+ background: transparent;
92
+ cursor: pointer;
93
+ font-size: 12px;
94
+ font-weight: 400;
95
+ line-height: 1.4;
96
+ color: var(--odn-color-black-9);
97
+ white-space: nowrap;
98
+ }
99
+ [data-odn-approval-summary-toggle]:hover {
100
+ color: var(--odn-color-black-11);
101
+ }
102
+
103
+ [data-odn-approval-summary-chevron] {
104
+ transition: transform 0.2s ease-out;
105
+ }
106
+
107
+ [data-odn-approval][data-summary-expanded] [data-odn-approval-summary-chevron] {
108
+ transform: rotate(180deg);
109
+ }
110
+
111
+ [data-odn-approval-icon] {
112
+ flex-shrink: 0;
113
+ color: var(--odn-color-black-9);
114
+ }
115
+ [data-odn-approval-icon][data-destructive] {
116
+ color: var(--odn-color-danger, #dc2626);
117
+ }
118
+
119
+ /**
120
+ * 展开/折叠:grid 0fr→1fr。
121
+ * 标题↔灰底 8px 用 inner::before(裁切层内),折叠归零;
122
+ * 勿用 inner padding(会挡住 0fr)。灰底自然高度、自下裁切,顶边不位移。
123
+ */
124
+ [data-odn-approval-summary-panel] {
125
+ display: grid;
126
+ grid-template-rows: minmax(0, 0fr);
127
+ overflow: hidden;
128
+ transition: grid-template-rows 0.22s ease-out;
129
+ }
130
+
131
+ [data-odn-approval-summary-panel][data-open=true] {
132
+ grid-template-rows: minmax(0, 1fr);
133
+ }
134
+
135
+ /* 动画结束后卸掉内部占位,消除 0fr 残高;收合过程中不改 spacer,灰底不瞬移 */
136
+ [data-odn-approval-summary-panel][data-collapsed-settled] {
137
+ height: 0;
138
+ min-height: 0;
139
+ visibility: hidden;
140
+ pointer-events: none;
141
+ }
142
+
143
+ [data-odn-approval-summary-panel][data-collapsed-settled] [data-odn-approval-summary-panel-inner] {
144
+ display: none;
145
+ }
146
+
147
+ [data-odn-approval-summary-panel-inner] {
148
+ display: flex;
149
+ flex-direction: column;
150
+ min-height: 0;
151
+ overflow: hidden;
152
+ border-radius: 8px;
153
+ }
154
+
155
+ [data-odn-approval-summary-panel-inner]::before {
156
+ content: "";
157
+ flex: 0 0 8px;
158
+ }
159
+
160
+ [data-odn-approval-summary-surface] {
161
+ flex-shrink: 0;
162
+ box-sizing: border-box;
163
+ border-radius: 8px;
164
+ background: var(--odn-color-black-2);
165
+ }
166
+
167
+ [data-odn-approval-summary-fade] {
168
+ transition: opacity 0.18s ease-out;
169
+ }
170
+
171
+ /* 折叠中/已折叠:自下而上渐隐文字,灰底仍撑满裁切高度 */
172
+ [data-odn-approval-summary-panel][data-open=false] [data-odn-approval-summary-fade] {
173
+ -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 18%, rgba(0, 0, 0, 0.35) 45%, transparent 78%);
174
+ mask-image: linear-gradient(to bottom, #000 0%, #000 18%, rgba(0, 0, 0, 0.35) 45%, transparent 78%);
175
+ opacity: 0.55;
176
+ }
177
+
178
+ @media (prefers-reduced-motion: reduce) {
179
+ [data-odn-approval-summary-panel],
180
+ [data-odn-approval-summary-fade],
181
+ [data-odn-approval-summary-chevron] {
182
+ transition: none;
183
+ }
184
+ [data-odn-approval-summary-panel][data-open=false] [data-odn-approval-summary-fade] {
185
+ -webkit-mask-image: none;
186
+ mask-image: none;
187
+ opacity: 0;
188
+ }
189
+ }
190
+ /* 小票:单列;标签宽 = 全部标签最长者(灰底在 surface) */
191
+ [data-odn-approval-receipt] {
192
+ display: flex;
193
+ flex-direction: column;
194
+ gap: 6px;
195
+ margin: 0;
196
+ padding: 10px;
197
+ box-sizing: border-box;
198
+ }
199
+
200
+ [data-odn-approval-receipt-row] {
201
+ display: grid;
202
+ grid-template-columns: var(--odn-approval-label-width, max-content) minmax(0, 1fr);
203
+ column-gap: 12px;
204
+ align-items: baseline;
205
+ min-width: 0;
206
+ }
207
+
208
+ [data-odn-approval-receipt-label] {
209
+ margin: 0;
210
+ font-size: 12px;
211
+ line-height: 1.5;
212
+ font-weight: 400;
213
+ color: var(--odn-color-black-9);
214
+ white-space: nowrap;
215
+ }
216
+
217
+ [data-odn-approval-receipt-value] {
218
+ margin: 0;
219
+ font-size: 12px;
220
+ line-height: 1.5;
221
+ color: var(--odn-color-black-12);
222
+ word-break: break-word;
223
+ white-space: pre-line;
224
+ }
225
+ [data-odn-approval-receipt-value][data-multiline] {
226
+ line-height: 20px;
227
+ }
228
+
229
+ [data-odn-approval-actions] {
230
+ display: flex;
231
+ align-items: center;
232
+ justify-content: flex-end;
233
+ gap: 8px;
234
+ flex-shrink: 0;
235
+ }
236
+
237
+ [data-odn-approval][data-has-summary] [data-odn-approval-actions] {
238
+ width: 100%;
239
+ box-sizing: border-box;
240
+ margin: 0;
241
+ padding: 10px 12px;
242
+ border-top: 1px solid var(--odn-color-black-4);
243
+ }
244
+
245
+ [data-odn-approval-attach] {
246
+ padding-left: 16px;
247
+ padding-right: 16px;
248
+ margin-bottom: 4px;
249
+ }
250
+
251
+ /* 锁态:无参仍横条居中;有参保留卡片列,折叠紧凑 / 展开复用小票 */
252
+ [data-odn-approval][data-resolved]:not([data-has-summary]) {
253
+ align-items: center;
254
+ }
255
+
256
+ [data-odn-approval][data-has-summary][data-resolved] {
257
+ flex-direction: column;
258
+ padding: 0;
259
+ border-radius: 12px;
260
+ }
261
+
262
+ [data-odn-approval][data-has-summary][data-resolved] [data-odn-approval-body] {
263
+ padding: 10px 12px;
264
+ gap: 0;
265
+ }
266
+
267
+ [data-odn-approval][data-has-summary][data-resolved][data-summary-expanded] [data-odn-approval-body] {
268
+ padding: 10px 12px 12px;
269
+ }
270
+
271
+ [data-odn-approval][data-resolved] [data-odn-approval-heading] {
272
+ gap: 0;
273
+ }
274
+
275
+ [data-odn-approval][data-resolved] [data-odn-approval-title-row] {
276
+ gap: 12px;
277
+ }
278
+
279
+ [data-odn-approval][data-resolved] [data-odn-approval-text] {
280
+ flex: 1;
281
+ gap: 6px;
282
+ font-size: 13px;
283
+ font-weight: 400;
284
+ line-height: 1.4;
285
+ }
286
+
287
+ [data-odn-approval][data-resolved=approve] {
288
+ border-color: color-mix(in srgb, var(--odn-color-brand-6) 28%, var(--odn-color-black-5));
289
+ background: color-mix(in srgb, var(--odn-color-brand-6) 7%, var(--odn-color-bg-elevated));
290
+ }
291
+
292
+ /* 小票:比锁态底(brand 7%)更深一档的蓝,避免透明 black-2 透底发脏 */
293
+ [data-odn-approval][data-resolved=approve] [data-odn-approval-summary-surface] {
294
+ background: color-mix(in srgb, var(--odn-color-brand-6) 14%, var(--odn-color-bg-elevated));
295
+ }
296
+
297
+ [data-odn-approval][data-resolved=reject] {
298
+ border-color: var(--odn-color-black-5);
299
+ background: color-mix(in srgb, var(--odn-color-black-3) 45%, var(--odn-color-bg-elevated));
300
+ }
301
+
302
+ [data-odn-approval][data-resolved=approve] [data-odn-approval-icon] {
303
+ color: var(--odn-color-brand-6);
304
+ }
305
+
306
+ [data-odn-approval][data-resolved=reject] [data-odn-approval-icon] {
307
+ color: var(--odn-color-black-8);
308
+ }
309
+
310
+ [data-odn-approval-resolved-main] {
311
+ flex-shrink: 0;
312
+ font-weight: 500;
313
+ }
314
+
315
+ [data-odn-approval][data-resolved=approve] [data-odn-approval-resolved-main] {
316
+ color: var(--odn-color-brand-8);
317
+ }
318
+
319
+ [data-odn-approval][data-resolved=reject] [data-odn-approval-resolved-main] {
320
+ color: var(--odn-color-black-11);
321
+ }
@@ -0,0 +1,2 @@
1
+ import '../../style';
2
+ import './index.scss';
@@ -0,0 +1,2 @@
1
+ import "../../style";
2
+ import "./index.css";
package/dist/index.d.ts CHANGED
@@ -56,6 +56,7 @@ export { default as VirtualList, type VirtualListProps } from './virtual-list';
56
56
  export { default as ActionBar, type ActionBarProps } from './action-bar';
57
57
  export { default as AgentStep, type AgentStepProps, type AgentStepGroupProps } from './agent-step';
58
58
  export { default as AgentThink, type AgentThinkProps } from './agent-think';
59
+ export { default as Approval, type ApprovalProps, type ApprovalSpec, type ApprovalDecision, type ApprovalResolvePayload, type ApprovalSummaryItem, } from './approval';
59
60
  export { default as Artifact, type ArtifactProps } from './artifact';
60
61
  export { default as Attachments, type AttachmentsProps } from './attachments';
61
62
  export { default as CodeBlock, type CodeBlockProps } from './code-block';
@@ -78,4 +79,5 @@ export { default as UserBubble, type UserBubbleProps } from './user-bubble';
78
79
  export { default as Welcome, type WelcomeProps } from './welcome';
79
80
  export type { ToolCall, ToolStatus, Source, Attachment, PreviewTarget, PreviewTab, SendMeta, ComposerSegment, ComposerTextSegment, ComposerInvocationSegment, ComposerMentionSegment, TextData, InvocationData, MentionData, InlineRefState, SkillItem, SkillGroup, AgentEvent, Conversation, MessageSnapshot, ChatMessage } from './_genui-types';
80
81
  export { ComposerSegmentType } from './_genui-types';
82
+ export type { InterruptIntent, InterruptStatus, InterruptBase, } from './_interrupt-types';
81
83
  export { rawValueToSegments, segmentsToReadableText, segmentsHasContent, isTextSegment, isInvocationSegment, isMentionSegment, type SegmentsToReadableTextOptions, } from './composer/segments';
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ export { default as VirtualList } from "./virtual-list";
62
62
  export { default as ActionBar } from "./action-bar";
63
63
  export { default as AgentStep } from "./agent-step";
64
64
  export { default as AgentThink } from "./agent-think";
65
+ export { default as Approval } from "./approval";
65
66
  export { default as Artifact } from "./artifact";
66
67
  export { default as Attachments } from "./attachments";
67
68
  export { default as CodeBlock } from "./code-block";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one-design-next",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "description": "One Design Next from TAD@tencent.com",
5
5
  "packageManager": "pnpm@11.8.0",
6
6
  "module": "dist/index.js",