@morlay/dsh-client-ui-primitives 0.0.4 → 0.0.5

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 (34) hide show
  1. package/README.md +18 -266
  2. package/dist/client.cjs +1 -611
  3. package/dist/client.d.cts +11 -658
  4. package/dist/client.d.mts +11 -658
  5. package/dist/index.mjs +1 -1
  6. package/dist/{reference-Dxy9uQYz.mjs → reference-Cjcn21uW.mjs} +0 -1
  7. package/locale/en.json +1 -1
  8. package/locale/zh.json +1 -1
  9. package/package.json +2 -2
  10. package/src/client/index.ts +7 -9
  11. package/src/client/schema-form/Editor.tsx +25 -38
  12. package/src/client/schema-form/SchemaForm.tsx +6 -12
  13. package/src/client/schema-form/controller.ts +65 -123
  14. package/src/client/schema-form/draft.ts +55 -138
  15. package/src/client/schema-form/fields.tsx +5 -14
  16. package/src/client/schema-form/hints.ts +31 -131
  17. package/src/client/schema-form/index.ts +15 -20
  18. package/src/client/schema-form/labels.ts +7 -9
  19. package/src/client/schema-form/lines.ts +36 -60
  20. package/src/client/schema-form/locales.ts +6 -8
  21. package/src/client/schema-form/rows.ts +22 -41
  22. package/src/client/schema-form/schema-node.ts +87 -150
  23. package/src/client/schema-form/slot-contract.ts +55 -76
  24. package/src/client/schema-form/styles.ts +39 -51
  25. package/src/client/schema-form/testing/fake-describe.ts +3 -9
  26. package/src/client/schema-form/testing/fake-scope.ts +8 -10
  27. package/src/client/schema-form/value.tsx +14 -26
  28. package/src/client/settings-form/SettingsForm.tsx +13 -17
  29. package/src/client/settings-form/fields.tsx +25 -35
  30. package/src/client/settings-form/form-model.ts +63 -145
  31. package/src/client/styling/styled.tsx +3 -5
  32. package/src/client/theme.generated.ts +6 -7
  33. package/src/reference-markdown.tsx +1 -1
  34. package/src/reference.ts +1 -1
@@ -21,7 +21,7 @@ const Input = styled("input")(styles.input);
21
21
  const Invalid = styled("p")(styles.invalid);
22
22
  const Hint = styled("p")(styles.hint);
23
23
 
24
- /** 上游 icons 里的 IconInfoOutlineRegular(fill-only 几何,整份图标表不搬)。 */
24
+ // 上游 icons 里的 IconInfoOutlineRegular(fill-only 几何,整份图标表不搬)。
25
25
  function InfoGlyph({ size }: { size: number }) {
26
26
  return (
27
27
  <svg
@@ -42,50 +42,45 @@ function InfoGlyph({ size }: { size: number }) {
42
42
  );
43
43
  }
44
44
 
45
- /** What every settings field control needs regardless of its value type. */
45
+ // What every settings field control needs regardless of its value type.
46
46
  export interface SettingsFieldProps {
47
- /** Stable id associating the label with its control. */
47
+ // Stable id associating the label with its control.
48
48
  id: string;
49
- /** Visible label. */
49
+ // Visible label.
50
50
  label: string;
51
- /** One-line explanation rendered under the control. */
51
+ // One-line explanation rendered under the control.
52
52
  hint: string;
53
- /** Draft text this control renders. */
53
+ // Draft text this control renders.
54
54
  text: string;
55
- /** True when saving would leave a user-layer entry for this field. */
55
+ // True when saving would leave a user-layer entry for this field.
56
56
  overridden: boolean;
57
- /** True when the draft is not a value this field accepts. */
57
+ // True when the draft is not a value this field accepts.
58
58
  invalid: boolean;
59
- /** Copy for the overridden badge. */
59
+ // Copy for the overridden badge.
60
60
  overriddenLabel: string;
61
- /** Copy for the reset control. */
61
+ // Copy for the reset control.
62
62
  resetLabel: string;
63
- /** Copy shown in place of the hint while the draft is invalid. */
63
+ // Copy shown in place of the hint while the draft is invalid.
64
64
  invalidLabel: string;
65
- /** Disables every control (read-only document, or an unavailable namespace). */
65
+ // Disables every control (read-only document, or an unavailable namespace).
66
66
  disabled: boolean;
67
- /** Stage draft text. */
67
+ // Stage draft text.
68
68
  onEdit: (text: string) => void;
69
- /** Stage a clear so the field re-inherits the composition layer. */
69
+ // Stage a clear so the field re-inherits the composition layer.
70
70
  onReset: () => void;
71
71
  }
72
72
 
73
- /**
74
- * A staged value field. `numeric` only hints the keypad: which drafts a field
75
- * accepts is decided by its spec, so the control never silently rewrites what
76
- * the user typed.
77
- * @param props - the field's copy, its staged text, and the edit actions.
78
- * @returns the labelled control.
79
- */
73
+ // A staged value field. `numeric` only hints the keypad: which drafts a field accepts is decided by its spec, so the
74
+ // control never silently rewrites what the user typed.
80
75
  export function SettingsValueField(
81
76
  props: Omit<SettingsFieldProps, "hint"> & {
82
- /** Optional explanation shown below the input. */
77
+ // Optional explanation shown below the input.
83
78
  hint?: string;
84
- /** Rules disclosed by the information button beside the label. */
79
+ // Rules disclosed by the information button beside the label.
85
80
  help?: { label: string; content: ReactNode };
86
- /** Hints a numeric keypad without narrowing what the control accepts. */
81
+ // Hints a numeric keypad without narrowing what the control accepts.
87
82
  numeric?: boolean;
88
- /** Placeholder shown while the draft is empty. */
83
+ // Placeholder shown while the draft is empty.
89
84
  placeholder?: string;
90
85
  },
91
86
  ) {
@@ -153,19 +148,14 @@ export function SettingsValueField(
153
148
  );
154
149
  }
155
150
 
156
- /**
157
- * A write-only credential control. The value never rides a response, so the
158
- * control reports only whether one is configured and starts blank; a blank
159
- * draft writes nothing, which keeps the stored key rather than clearing it.
160
- * 控件要求浏览器不要把已存的登录密码自动填进来(上游 11c0511271)。
161
- * @param props - the field's copy, its staged text, and the configured state.
162
- * @returns the labelled control.
163
- */
151
+ // A write-only credential control. The value never rides a response, so the control reports only whether one is
152
+ // configured and starts blank; a blank draft writes nothing, which keeps the stored key rather than clearing it.
153
+ // 控件要求浏览器不要把已存的登录密码自动填进来(上游 11c0511271)。
164
154
  export function SettingsSecretField(
165
155
  props: Pick<SettingsFieldProps, "id" | "label" | "hint" | "text" | "disabled" | "onEdit"> & {
166
- /** Whether the Host reports a configured credential for this reference. */
156
+ // Whether the Host reports a configured credential for this reference.
167
157
  configured: boolean;
168
- /** Copy describing the configured state. */
158
+ // Copy describing the configured state.
169
159
  stateLabel: string;
170
160
  },
171
161
  ) {
@@ -1,165 +1,123 @@
1
- // 搬自 vendor/deepseek-harness/packages/client/ui-primitives/src/settings-form/form-model.ts
2
- // (上游 `@deepseek-ai/dsh-client-ui-primitives`,见本包 .agents/adrs 里的搬迁记录);逻辑未改,
3
- // 只有 catch 的未用参数按 lint 口径写成可选绑定。改这里之前先看上游是否也改了同一处。
4
-
5
- /**
6
- * The staged form model behind a plugin's settings page.
7
- *
8
- * A card stages what the user types and writes it only when they save. Each
9
- * settings write is a durable, revision-fenced document mutation, so a control
10
- * that committed as it settled turned one edit into a write the user never
11
- * asked for and could not preview; staged text makes what is on screen exactly
12
- * what a save would store.
13
- *
14
- * A field shows its effective value — the user layer over the composition
15
- * layer over the schema default — and whether the user layer carries it. That
16
- * presence, not a value comparison, is what marks a field overridden: an
17
- * override equal to the composition default is still an override.
18
- */
1
+ // 与 vendor/deepseek-harness/packages/client/ui-primitives/src/settings-form/form-model.ts 逐行对应;
2
+ // 改这里之前先看上游是否也改了同一处(上游只读)。
3
+
4
+ // The staged form model behind a plugin's settings page: a card stages what the user types and writes it only on
5
+ // save, and a field is marked overridden by its user-layer presence rather than by a value comparison.
19
6
 
20
7
  import { createSnapshotStore, type SnapshotStore } from "@deepseek-ai/dsh-client-store";
21
8
 
22
- /** What the model reads of one Host entry's form. */
9
+ // What the model reads of one Host entry's form.
23
10
  export interface SettingsFormScopeSnapshot<T> {
24
- /** `ready` while the Host serves the entry to this client; the form renders nothing otherwise. */
11
+ // `ready` while the Host serves the entry to this client; the form renders nothing otherwise.
25
12
  status: "loading" | "ready" | "unavailable";
26
- /** Last accepted schema-resolved section; undefined before the first acceptance. */
13
+ // Last accepted schema-resolved section; undefined before the first acceptance.
27
14
  value: T | undefined;
28
- /** Composition layer the value resolves over: what a field reverts to once cleared. */
15
+ // Composition layer the value resolves over: what a field reverts to once cleared.
29
16
  base: unknown;
30
- /** Raw user layer as stored; a field's PRESENCE here is what marks it overridden. */
17
+ // Raw user layer as stored; a field's PRESENCE here is what marks it overridden.
31
18
  user: unknown;
32
- /** Whether the Host document accepts writes. */
19
+ // Whether the Host document accepts writes.
33
20
  writable: boolean;
34
- /** Revision the snapshot was read at; a save fences its mutation with the revision its drafts started from. */
21
+ // Revision the snapshot was read at; a save fences its mutation with the revision its drafts started from.
35
22
  revision: number | undefined;
36
23
  }
37
24
 
38
- /** One path edit a save sends, as the shared configuration form's `mutate` accepts it. */
25
+ // One path edit a save sends, as the shared configuration form's `mutate` accepts it.
39
26
  export type SettingsFormPathOp =
40
27
  | { op: "set"; path: readonly string[]; value: unknown }
41
28
  | { op: "unset"; path: readonly string[] };
42
29
 
43
- /** The entry form the model stages over: the reads and the atomic write of the form `ui-settings` shares per Host entry. */
30
+ // The entry form the model stages over: the reads and the atomic write of the form `ui-settings` shares per Host entry.
44
31
  export interface SettingsFormScope<T> {
45
- /** @returns the current sync snapshot. */
46
32
  getSnapshot(): SettingsFormScopeSnapshot<T>;
47
- /**
48
- * Observe snapshot replacements.
49
- * @param listener - invoked after each snapshot change.
50
- * @returns the disposer removing this listener.
51
- */
33
+ // Observe snapshot replacements.
52
34
  subscribe(listener: () => void): () => void;
53
- /**
54
- * Apply ordered field edits in one revision-fenced write.
55
- * @param ops - the edits, in staging order.
56
- * @param expectedRevision - the revision the drafts were staged against, when known.
57
- * @returns true for Host acceptance, false for refusal, after any recovery read.
58
- */
35
+ // Apply ordered field edits in one revision-fenced write; resolves after any recovery read.
59
36
  mutate(ops: readonly SettingsFormPathOp[], expectedRevision?: number): Promise<boolean>;
60
37
  }
61
38
 
62
- /** The write one field's staged text performs when the card is saved. */
39
+ // The write one field's staged text performs when the card is saved.
63
40
  export type SettingsFieldWrite = { kind: "set"; value: unknown } | { kind: "clear" };
64
41
 
65
- /** How one section field converts between its stored value and its draft text. */
42
+ // How one section field converts between its stored value and its draft text.
66
43
  export interface SettingsFieldSpec {
67
- /** Field name inside the namespace section. */
44
+ // Field name inside the namespace section.
68
45
  field: string;
69
- /** Render a stored value as draft text; the empty string when the section carries none. */
46
+ // Render a stored value as draft text; the empty string when the section carries none.
70
47
  format: (value: unknown) => string;
71
- /**
72
- * The write this draft text stages, or undefined when the text is not a
73
- * value this field accepts — which blocks the save rather than discarding it.
74
- */
48
+ // The write this draft text stages, or undefined when the text is not a value this field accepts (blocks the save).
75
49
  parse: (text: string) => SettingsFieldWrite | undefined;
76
50
  }
77
51
 
78
- /**
79
- * A control whose value is written outside the settings section. A credential
80
- * literal never rides a response, so its draft has nothing to seed from: it is
81
- * blank until typed, and a blank draft writes nothing.
82
- */
52
+ // A control whose value is written outside the settings section: a credential literal never rides a response, so its
53
+ // draft is blank until typed and a blank draft writes nothing.
83
54
  export interface SettingsSecretSpec {
84
- /** Field name addressing this control inside the card's form. */
55
+ // Field name addressing this control inside the card's form.
85
56
  field: string;
86
- /** Write the staged text; resolves to whether the Host accepted it. */
57
+ // Write the staged text; resolves to whether the Host accepted it.
87
58
  write: (text: string) => Promise<boolean>;
88
59
  }
89
60
 
90
- /** One field as a card's control renders it. */
61
+ // One field as a card's control renders it.
91
62
  export interface SettingsFieldState {
92
- /** Draft text the control renders. */
63
+ // Draft text the control renders.
93
64
  text: string;
94
- /**
95
- * Whether saving would leave a user-layer entry for this field. A staged
96
- * edit answers for itself, so the badge previews the save rather than
97
- * reporting a state the pending edit already contradicts.
98
- */
65
+ // Whether saving would leave a user-layer entry for this field; a staged edit answers for itself.
99
66
  overridden: boolean;
100
- /** Whether the draft is not a value this field accepts, which blocks saving. */
67
+ // Whether the draft is not a value this field accepts, which blocks saving.
101
68
  invalid: boolean;
102
69
  }
103
70
 
104
- /** Form state every plugin card shares. */
71
+ // Form state every plugin card shares.
105
72
  export interface SettingsFormShell {
106
- /** False while the namespace is not served to this client; the card renders nothing. */
73
+ // False while the namespace is not served to this client; the card renders nothing.
107
74
  available: boolean;
108
- /** Whether the Host document accepts writes. */
75
+ // Whether the Host document accepts writes.
109
76
  writable: boolean;
110
- /** Whether the form holds edits that a save would write. */
77
+ // Whether the form holds edits that a save would write.
111
78
  dirty: boolean;
112
- /** Whether any staged draft is invalid, which blocks the save. */
79
+ // Whether any staged draft is invalid, which blocks the save.
113
80
  invalid: boolean;
114
- /** Whether a save is crossing the wire. */
81
+ // Whether a save is crossing the wire.
115
82
  saving: boolean;
116
- /** Whether the last save did not land as staged; cleared by the next edit or save. */
83
+ // Whether the last save did not land as staged; cleared by the next edit or save.
117
84
  failed: boolean;
118
85
  }
119
86
 
120
- /** The write actions every plugin card's slot entry injects. */
87
+ // The write actions every plugin card's slot entry injects.
121
88
  export interface SettingsFormActions {
122
- /** Stage draft text for one field. */
89
+ // Stage draft text for one field.
123
90
  edit: (field: string, text: string) => void;
124
- /** Stage a clear, so saving lets the field re-inherit the composition layer. */
91
+ // Stage a clear, so saving lets the field re-inherit the composition layer.
125
92
  resetField: (field: string) => void;
126
- /** Write every staged edit, then re-seed from what the Host accepted. */
93
+ // Write every staged edit, then re-seed from what the Host accepted.
127
94
  save: () => void;
128
- /** Drop every staged edit. */
95
+ // Drop every staged edit.
129
96
  discard: () => void;
130
97
  }
131
98
 
132
- /** One field's staged edit. */
99
+ // One field's staged edit.
133
100
  interface StagedEdit {
134
- /** Draft text the control renders. */
101
+ // Draft text the control renders.
135
102
  text: string;
136
- /** True when this edit clears the field whatever text it shows. */
103
+ // True when this edit clears the field whatever text it shows.
137
104
  clear: boolean;
138
105
  }
139
106
 
140
- /** One staged edit resolved into the write a save performs. */
107
+ // One staged edit resolved into the write a save performs.
141
108
  interface PlannedWrite {
142
- /** Field this entry writes. */
109
+ // Field this entry writes.
143
110
  field: string;
144
- /**
145
- * Perform the write and report whether the Host holds the staged value
146
- * afterwards; undefined when the draft is not a value the field accepts.
147
- */
111
+ // Perform the write and report whether the Host holds the staged value afterwards.
148
112
  run?: () => Promise<boolean>;
149
113
  op?: SettingsFormPathOp;
150
114
  }
151
115
 
152
- /**
153
- * A whole-number field. An empty draft clears the field; any other draft that
154
- * is not a finite number blocks the save.
155
- * @param field - field name inside the namespace section.
156
- * @returns the field's conversion spec.
157
- */
116
+ // A whole-number field: an empty draft clears the field, any other draft that is not a finite number blocks the save.
158
117
  export function settingsNumberField(field: string): SettingsFieldSpec {
159
118
  return {
160
119
  field,
161
- // A section that carries no number for this field renders empty rather
162
- // than as a value nobody chose.
120
+ // A section that carries no number for this field renders empty rather than as a value nobody chose.
163
121
  format: (value) => (typeof value === "number" ? String(value) : ""),
164
122
  parse: (text) => {
165
123
  const trimmed = text.trim();
@@ -170,12 +128,7 @@ export function settingsNumberField(field: string): SettingsFieldSpec {
170
128
  };
171
129
  }
172
130
 
173
- /**
174
- * A free-text field. An empty draft clears the field, so emptying the control
175
- * and saving is the same gesture as resetting it.
176
- * @param field - field name inside the namespace section.
177
- * @returns the field's conversion spec.
178
- */
131
+ // A free-text field: an empty draft clears the field, so emptying the control and saving is the same as resetting it.
179
132
  export function settingsTextField(field: string): SettingsFieldSpec {
180
133
  return {
181
134
  field,
@@ -187,13 +140,8 @@ export function settingsTextField(field: string): SettingsFieldSpec {
187
140
  };
188
141
  }
189
142
 
190
- /**
191
- * Stages one card's edits over one settings namespace and writes them on save.
192
- *
193
- * The form publishes through a snapshot store because slot components read
194
- * through a snapshot selector, while both the scope and the local drafts
195
- * change underneath; every projection is rebuilt from the two together.
196
- */
143
+ // Stages one card's edits over one settings namespace and writes them on save. The form publishes through a snapshot
144
+ // store because slot components read through a snapshot selector while both the scope and the drafts change underneath.
197
145
  export class SettingsFormModel<T> {
198
146
  private readonly specs: Map<string, SettingsFieldSpec>;
199
147
  private readonly secretSpecs: Map<string, SettingsSecretSpec>;
@@ -204,11 +152,6 @@ export class SettingsFormModel<T> {
204
152
  private saving = false;
205
153
  private failed = false;
206
154
 
207
- /**
208
- * @param scope - the shared configuration form for this card's namespace.
209
- * @param specs - the section fields this card edits.
210
- * @param secrets - the card's write-only controls, written outside the section.
211
- */
212
155
  constructor(
213
156
  private readonly scope: SettingsFormScope<T>,
214
157
  specs: SettingsFieldSpec[],
@@ -221,11 +164,7 @@ export class SettingsFormModel<T> {
221
164
  });
222
165
  }
223
166
 
224
- /**
225
- * Publish a projection of this form, rebuilt whenever the scope or a draft changes.
226
- * @param project - build the card's state from the form's current reads.
227
- * @returns the store the card's component reads through its bound selector.
228
- */
167
+ // Publish a projection of this form, rebuilt whenever the scope or a draft changes.
229
168
  bind<S>(project: () => S): SnapshotStore<S> {
230
169
  const store = createSnapshotStore(project());
231
170
  this.listeners.add(() => {
@@ -234,10 +173,7 @@ export class SettingsFormModel<T> {
234
173
  return store;
235
174
  }
236
175
 
237
- /**
238
- * Read the card-level state: what the Host serves, and what a save would do.
239
- * @returns the form state every card shares.
240
- */
176
+ // Read the card-level state: what the Host serves, and what a save would do.
241
177
  shell(): SettingsFormShell {
242
178
  const snapshot = this.scope.getSnapshot();
243
179
  const plan = this.plan();
@@ -251,11 +187,7 @@ export class SettingsFormModel<T> {
251
187
  };
252
188
  }
253
189
 
254
- /**
255
- * Read one control's state.
256
- * @param field - field name of a section field or of a write-only control.
257
- * @returns the draft text, whether a save would leave an override, and whether it is invalid.
258
- */
190
+ // Read one control's state: draft text, whether a save would leave an override, and whether it is invalid.
259
191
  field(field: string): SettingsFieldState {
260
192
  const staged = this.staged.get(field);
261
193
  if (this.secretSpecs.has(field)) {
@@ -277,10 +209,7 @@ export class SettingsFormModel<T> {
277
209
  };
278
210
  }
279
211
 
280
- /**
281
- * Build the edit, reset, save, and discard actions bound to this form.
282
- * @returns the actions a card's slot entry injects.
283
- */
212
+ // Build the edit, reset, save, and discard actions bound to this form.
284
213
  actions(): SettingsFormActions {
285
214
  return {
286
215
  edit: (field, text) => {
@@ -302,15 +231,8 @@ export class SettingsFormModel<T> {
302
231
  };
303
232
  }
304
233
 
305
- /**
306
- * Write every staged edit, then re-seed from what the Host accepted.
307
- *
308
- * The Host is the only authority on whether a value was accepted — its
309
- * validators own the constraints no schema can express — so the outcome is
310
- * read back from the section rather than predicted here. A save that did not
311
- * land keeps its drafts, so the user can correct them instead of retyping.
312
- * @returns settlement after every write and the read-back.
313
- */
234
+ // Write every staged edit, then re-seed from what the Host accepted: the outcome is read back rather than predicted
235
+ // (the Host is the only authority), and a save that did not land keeps its drafts so the user can correct them.
314
236
  async save(): Promise<void> {
315
237
  const plan = this.plan();
316
238
  if (
@@ -344,18 +266,14 @@ export class SettingsFormModel<T> {
344
266
  }
345
267
  }
346
268
 
347
- /** Release the form's accepted-value subscription. */
269
+ // Release the form's accepted-value subscription.
348
270
  dispose(): void {
349
271
  this.unsubscribe();
350
272
  this.listeners.clear();
351
273
  }
352
274
 
353
- /**
354
- * Every staged edit a save would write. An entry whose draft is not a value
355
- * its field accepts carries no write: the form is still dirty, and the save
356
- * refuses rather than dropping the edit.
357
- * @returns the planned writes, in the order the fields were staged.
358
- */
275
+ // Every staged edit a save would write; an entry whose draft its field rejects carries no write (the form stays
276
+ // dirty, and the save refuses rather than dropping the edit).
359
277
  private plan(): PlannedWrite[] {
360
278
  const plan: PlannedWrite[] = [];
361
279
  for (const [field, staged] of this.staged) {
@@ -388,8 +306,8 @@ export class SettingsFormModel<T> {
388
306
 
389
307
  private spec(field: string): SettingsFieldSpec {
390
308
  const spec = this.specs.get(field);
391
- // Every call site names a field this card declared; a missing one is a
392
- // wiring mistake that must not degrade into a silently inert control.
309
+ // Every call site names a field this card declared; a missing one is a wiring mistake that must not become a
310
+ // silently inert control.
393
311
  if (spec === undefined) throw new Error(`plugin card has no field ${field}`);
394
312
  return spec;
395
313
  }
@@ -24,10 +24,8 @@ export type StyledComponent<T extends ElementType> = ForwardRefExoticComponent<
24
24
  StyledProps<T> & RefAttributes<StyledRef<T>>
25
25
  > & { readonly [sxSymbol]: CSSProps };
26
26
 
27
- /**
28
- * `styled('div')({ padding: '4px' }, { '&:hover': { … } })` → 带 `data-css-*` 的组件。
29
- * 多个样式对象按顺序深合并(后者覆盖前者),便于把变体叠在基样式上。
30
- */
27
+ // `styled('div')({ padding: '4px' }, { '&:hover': { … } })` → 带 `data-css-*` 的组件。
28
+ // 多个样式对象按顺序深合并(后者覆盖前者),便于把变体叠在基样式上。
31
29
  export function styled<T extends ElementType>(
32
30
  Component: T,
33
31
  defaultProps: Partial<ComponentProps<T>> = {},
@@ -50,7 +48,7 @@ export function styled<T extends ElementType>(
50
48
  };
51
49
  }
52
50
 
53
- /** 取回 styled 组件携带的样式对象(需要在其之上继续组合时用)。 */
51
+ // 取回 styled 组件携带的样式对象(需要在其之上继续组合时用)。
54
52
  export function styleOf(component: StyledComponent<ElementType>): CSSProps {
55
53
  return component[sxSymbol];
56
54
  }
@@ -1,10 +1,9 @@
1
- /**
2
- * 官方主题的 `--dsw-*` token 全集(400 个),由 packages/client/ui-primitives/scripts/gen-design-tokens.mts 生成,勿手改。
3
- *
4
- * 叶子是该变量的**默认值**(官方 light 主题里首次出现的定义):既是类型推导的来源,也可作 fallback。
5
- * `"$"` 键出现在「自身也是 token 的分支」上(命名体系里有 40 个短名同时是长名前缀的 token)。
6
- * 消费时只需树形状——`Token.vars()` 生成 `var(--dsw-…)`,不重新定义变量。
7
- * 漂移、往返与默认值完整性由 src/__tests__/design-tokens.spec.ts 守卫。 */
1
+ // 官方主题的 `--dsw-*` token 全集(400 个),由 packages/client/ui-primitives/scripts/gen-design-tokens.mts 生成,勿手改。
2
+ //
3
+ // 叶子是该变量的**默认值**(官方 light 主题里首次出现的定义):既是类型推导的来源,也可作 fallback。
4
+ // `"$"` 键出现在「自身也是 token 的分支」上(命名体系里有 40 个短名同时是长名前缀的 token)。
5
+ // 消费时只需树形状——`Token.vars()` 生成 `var(--dsw-…)`,不重新定义变量。
6
+ // 漂移、往返与默认值完整性由 src/__tests__/design-tokens.spec.ts 守卫。
8
7
  export const designTokens = {
9
8
  alias: {
10
9
  bg: {
@@ -106,7 +106,7 @@ function rangeOf(reference: Reference): string {
106
106
  // 本地引用的原文切片 → inline code;外部地址原样留下。引用不会嵌套(解析器保证),
107
107
  // 这里仍按 offset 顺序跳过被前一个切片覆盖的引用。
108
108
  // 边界:引用紧贴相邻 inline code 的反引号(`` `x`file:y ``)时两个 code span 会并成一个,
109
- // 这种写法退化成普通 code——与上一版包反引号的行为一致。
109
+ // 这种写法退化成普通 code。
110
110
  function tokenizeReferences(text: string): {
111
111
  readonly source: string;
112
112
  readonly tokens: Map<string, Reference>;
package/src/reference.ts CHANGED
@@ -522,7 +522,7 @@ function parseBareReference(raw: string): Reference | undefined {
522
522
  };
523
523
  }
524
524
 
525
- /** 引号 mention 的起手字符:`@"path with spaces"`。 */
525
+ // 引号 mention 的起手字符:`@"path with spaces"`。
526
526
  const QUOTED_PATH = '"';
527
527
 
528
528
  function parseQuotedReference(body: string): Reference | undefined {