@skopon-cool/form-sdk 0.6.6 → 0.6.8
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.
- package/README.md +2 -0
- package/dist/adapter/formSchema.d.ts.map +1 -1
- package/dist/catalog/a2uiCustomCatalog.d.ts.map +1 -1
- package/dist/catalog/materialUploadContext.d.ts +5 -1
- package/dist/catalog/materialUploadContext.d.ts.map +1 -1
- package/dist/components/AskUserFormCard.d.ts +3 -1
- package/dist/components/AskUserFormCard.d.ts.map +1 -1
- package/dist/components/SkoponFormRenderer.d.ts +3 -1
- package/dist/components/SkoponFormRenderer.d.ts.map +1 -1
- package/dist/form-sdk.css +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2024 -1875
- package/dist/types/index.d.ts +10 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapter/formSchema.ts +39 -5
- package/src/catalog/a2uiCustomCatalog.tsx +159 -5
- package/src/catalog/materialUploadContext.tsx +13 -1
- package/src/components/AskUserFormCard.tsx +5 -1
- package/src/components/SkoponFormRenderer.tsx +5 -2
- package/src/index.ts +2 -0
- package/src/styles/index.css +69 -0
- package/src/types/index.ts +11 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -52,6 +52,15 @@ export interface FormBlockCondition {
|
|
|
52
52
|
operator: FormConditionOperator;
|
|
53
53
|
value?: string;
|
|
54
54
|
}
|
|
55
|
+
/** Durable file reference saved in a file field's answer. */
|
|
56
|
+
export interface FormFileValueRef {
|
|
57
|
+
asset_id: string;
|
|
58
|
+
source?: 'upload' | 'library_select';
|
|
59
|
+
url?: string;
|
|
60
|
+
expires_at?: number;
|
|
61
|
+
footage_asset_id?: string;
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
}
|
|
55
64
|
/** 简历多选组件:渲染时用于 /univ/resume/search 的筛选条件 */
|
|
56
65
|
export interface FormResumeFilter {
|
|
57
66
|
names?: string[];
|
|
@@ -133,7 +142,7 @@ export interface FormBlock {
|
|
|
133
142
|
fileReviewMessage?: string;
|
|
134
143
|
/** 审核未通过的历史文件,仅作错误态回显,不计入有效提交。 */
|
|
135
144
|
fileRejectedUrls?: string[];
|
|
136
|
-
defaultValue?: string | string
|
|
145
|
+
defaultValue?: string | Array<string | FormFileValueRef> | boolean;
|
|
137
146
|
/** 派生 JSON Schema 时写入 property.$comment */
|
|
138
147
|
jsonSchemaDescription?: string;
|
|
139
148
|
/** 是否隐藏(仅 text 块;隐藏时仍提交) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjD,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,KAAK,GACL,MAAM,GACN,OAAO,GACP,OAAO,GACP,aAAa,GACb,WAAW,GACX,UAAU,GACV,cAAc,GACd,eAAe,GACf,YAAY,GACZ,aAAa,GACb,WAAW,GACX,cAAc,GACd,oBAAoB,GACpB,kBAAkB,GAClB,mBAAmB,CAAA;AAEvB,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAC1E;AAED,eAAO,MAAM,qBAAqB,EAAG,MAAe,CAAA;AAEpD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEpD,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,WAAW,GACX,MAAM,GACN,UAAU,GACV,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,aAAa,GACb,OAAO,GACP,UAAU,GACV,QAAQ,GACR,KAAK,GACL,KAAK,GACL,UAAU,GACV,MAAM,GACN,MAAM,GACN,oBAAoB,GACpB,kBAAkB;AACpB,4CAA4C;GAC1C,mBAAmB,GACnB,OAAO,GACP,OAAO,GACP,OAAO,GACP,KAAK,CAAA;AAET,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAE1E,MAAM,MAAM,uBAAuB,GAC/B,OAAO,GACP,OAAO,GACP,OAAO,GACP,MAAM,GACN,aAAa,GACb,UAAU,CAAA;AAEd,eAAO,MAAM,gBAAgB,EAAE,aAAa,EAM3C,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,qBAAqB,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,UAAU,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;IACxB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uCAAuC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/B,mBAAmB,CAAC,EAAE,uBAAuB,CAAA;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0BAA0B;IAC1B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,qCAAqC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,mCAAmC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,oCAAoC;IACpC,cAAc,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,YAAY,CAAA;IACrE,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAA;IACpC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;IAChD,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACtC,kCAAkC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
FormBlock,
|
|
3
3
|
FormBlockType,
|
|
4
|
+
FormFileValueRef,
|
|
4
5
|
FormCaseFilter,
|
|
5
6
|
FormContentFilter,
|
|
6
7
|
FormResumeFilter,
|
|
@@ -63,10 +64,31 @@ function normalizeDefaultValue(
|
|
|
63
64
|
if (type === 'toggle') {
|
|
64
65
|
return coerceToggleValue(raw)
|
|
65
66
|
}
|
|
67
|
+
if (type === 'file') {
|
|
68
|
+
const values: unknown[] = Array.isArray(raw) ? raw : [raw]
|
|
69
|
+
const normalizedValues: Array<string | FormFileValueRef> = []
|
|
70
|
+
for (const value of values) {
|
|
71
|
+
if (typeof value === 'string') {
|
|
72
|
+
if (value.trim()) normalizedValues.push(value.trim())
|
|
73
|
+
continue
|
|
74
|
+
}
|
|
75
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) continue
|
|
76
|
+
const ref = value as Record<string, unknown>
|
|
77
|
+
const assetId = String(ref.asset_id ?? ref.assetId ?? '').trim()
|
|
78
|
+
if (!assetId) continue
|
|
79
|
+
const normalized: FormFileValueRef = { ...ref, asset_id: assetId }
|
|
80
|
+
delete normalized.assetId
|
|
81
|
+
if (normalized.source !== 'library_select') normalized.source = 'upload'
|
|
82
|
+
if (typeof normalized.url !== 'string' || !/^https?:\/\//i.test(normalized.url)) delete normalized.url
|
|
83
|
+
if (typeof normalized.expires_at !== 'number' || !Number.isFinite(normalized.expires_at)) delete normalized.expires_at
|
|
84
|
+
if (normalized.footage_asset_id != null) normalized.footage_asset_id = String(normalized.footage_asset_id)
|
|
85
|
+
normalizedValues.push(normalized)
|
|
86
|
+
}
|
|
87
|
+
return normalizedValues
|
|
88
|
+
}
|
|
66
89
|
if (
|
|
67
90
|
type === 'multiselect' ||
|
|
68
91
|
type === 'checkbox' ||
|
|
69
|
-
type === 'file' ||
|
|
70
92
|
type === 'resume_multiselect' ||
|
|
71
93
|
type === 'case_multiselect'
|
|
72
94
|
) {
|
|
@@ -342,9 +364,7 @@ export function resolveSchemaDefaultValue(block: FormBlock): unknown | undefined
|
|
|
342
364
|
return values.length > 0 ? values : undefined
|
|
343
365
|
}
|
|
344
366
|
case 'file': {
|
|
345
|
-
const values = Array.isArray(normalized)
|
|
346
|
-
? (normalized as string[]).map(String).map((item) => item.trim()).filter(Boolean)
|
|
347
|
-
: []
|
|
367
|
+
const values = Array.isArray(normalized) ? normalized : []
|
|
348
368
|
return values.length > 0 ? values : undefined
|
|
349
369
|
}
|
|
350
370
|
default:
|
|
@@ -389,7 +409,21 @@ function blockToJsonSchemaProperty(block: FormBlock): Record<string, unknown> |
|
|
|
389
409
|
const maxCount = normalizeFileUploadCount(block.fileMaxCount, 1)
|
|
390
410
|
property = {
|
|
391
411
|
type: 'array',
|
|
392
|
-
items: {
|
|
412
|
+
items: {
|
|
413
|
+
anyOf: [
|
|
414
|
+
{ type: 'string' },
|
|
415
|
+
{
|
|
416
|
+
type: 'object',
|
|
417
|
+
required: ['asset_id'],
|
|
418
|
+
properties: {
|
|
419
|
+
asset_id: { type: 'string' },
|
|
420
|
+
source: { type: 'string' },
|
|
421
|
+
url: { type: 'string' },
|
|
422
|
+
},
|
|
423
|
+
additionalProperties: true,
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
},
|
|
393
427
|
minItems: minCount,
|
|
394
428
|
...(maxCount > 0 ? { maxItems: maxCount } : {}),
|
|
395
429
|
}
|
|
@@ -41,7 +41,7 @@ import FilePlaceholderIcon from '../icons/FilePlaceholderIcon'
|
|
|
41
41
|
import { isUploadCancelledError } from '../client/uploadClient'
|
|
42
42
|
import { useA2uiPreviewMode } from './a2uiPreviewContext'
|
|
43
43
|
import { useFileUploadStatus } from './fileUploadStatusContext'
|
|
44
|
-
import { useMaterialUpload } from './materialUploadContext'
|
|
44
|
+
import { useMaterialResolveUrls, useMaterialUpload } from './materialUploadContext'
|
|
45
45
|
import {
|
|
46
46
|
asOptionalString,
|
|
47
47
|
asStringArray,
|
|
@@ -59,6 +59,7 @@ const SKOPON_COMPONENT_NAMES = new Set([
|
|
|
59
59
|
'SkoponMedia',
|
|
60
60
|
'SkoponSelect',
|
|
61
61
|
'SkoponModulePanel',
|
|
62
|
+
'Tabs',
|
|
62
63
|
'Image',
|
|
63
64
|
'Video',
|
|
64
65
|
'AudioPlayer',
|
|
@@ -334,6 +335,86 @@ const SkoponModulePanelImpl = createBinderlessComponentImplementation(
|
|
|
334
335
|
},
|
|
335
336
|
)
|
|
336
337
|
|
|
338
|
+
/** Keep visited module panels mounted so file previews and in-progress fields survive tab changes. */
|
|
339
|
+
const TabsImpl = createBinderlessComponentImplementation(
|
|
340
|
+
{ name: 'Tabs', schema: getBasicSchema('Tabs') },
|
|
341
|
+
({ context, buildChild }) => {
|
|
342
|
+
const props = context.componentModel.properties as Record<string, unknown>
|
|
343
|
+
const tabs = Array.isArray(props.tabs)
|
|
344
|
+
? props.tabs.filter((tab): tab is Record<string, unknown> => !!tab && typeof tab === 'object')
|
|
345
|
+
: []
|
|
346
|
+
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
347
|
+
const [visitedIndices, setVisitedIndices] = useState<Set<number>>(() => new Set([0]))
|
|
348
|
+
const selected = Math.min(selectedIndex, Math.max(0, tabs.length - 1))
|
|
349
|
+
const tabHeadersStyle = {
|
|
350
|
+
display: 'flex',
|
|
351
|
+
gap: 'var(--a2ui-spacing-xs, 0.25rem)',
|
|
352
|
+
borderBottom: 'var(--a2ui-tabs-border, var(--a2ui-border-width, 1px) solid var(--a2ui-color-border, #ccc))',
|
|
353
|
+
marginBottom: 'var(--a2ui-spacing-m, 0.5rem)',
|
|
354
|
+
}
|
|
355
|
+
const tabHeaderBaseStyle = {
|
|
356
|
+
padding: 'var(--a2ui-spacing-m, 0.5rem) var(--a2ui-spacing-l, 1rem)',
|
|
357
|
+
background: 'var(--a2ui-tabs-header-background, transparent)',
|
|
358
|
+
color: 'var(--a2ui-tabs-header-color, var(--a2ui-color-on-surface))',
|
|
359
|
+
border: 'none',
|
|
360
|
+
borderRadius: 'var(--a2ui-border-radius, 0.25rem) var(--a2ui-border-radius, 0.25rem) 0 0',
|
|
361
|
+
cursor: 'pointer',
|
|
362
|
+
fontFamily: 'inherit',
|
|
363
|
+
}
|
|
364
|
+
const tabHeaderActiveStyle = {
|
|
365
|
+
background: 'var(--a2ui-tabs-header-background-active, var(--a2ui-color-secondary, #eee))',
|
|
366
|
+
color: 'var(--a2ui-tabs-header-color-active, var(--a2ui-color-on-secondary, #333))',
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<div className="skopon-module-tabs">
|
|
371
|
+
<div className="skopon-module-tabs__header" role="tablist" aria-label="表单分组" style={tabHeadersStyle}>
|
|
372
|
+
{tabs.map((tab, index) => {
|
|
373
|
+
const active = selected === index
|
|
374
|
+
const rawTitle = tab.title as Parameters<typeof context.dataContext.resolveDynamicValue>[0]
|
|
375
|
+
const title = context.dataContext.resolveDynamicValue<string>(rawTitle) || ''
|
|
376
|
+
return (
|
|
377
|
+
<button
|
|
378
|
+
key={index}
|
|
379
|
+
type="button"
|
|
380
|
+
role="tab"
|
|
381
|
+
id={`skopon-module-tab-${context.componentModel.id}-${index}`}
|
|
382
|
+
aria-selected={active}
|
|
383
|
+
aria-controls={`skopon-module-panel-${context.componentModel.id}-${index}`}
|
|
384
|
+
className={`a2ui-tabs-header a2ui-tab-button ${active ? 'active' : ''}`}
|
|
385
|
+
style={{ ...tabHeaderBaseStyle, ...(active ? tabHeaderActiveStyle : {}) }}
|
|
386
|
+
onClick={() => {
|
|
387
|
+
setSelectedIndex(index)
|
|
388
|
+
setVisitedIndices(current => current.has(index) ? current : new Set(current).add(index))
|
|
389
|
+
}}
|
|
390
|
+
>
|
|
391
|
+
{title}
|
|
392
|
+
</button>
|
|
393
|
+
)
|
|
394
|
+
})}
|
|
395
|
+
</div>
|
|
396
|
+
<div className="skopon-module-tabs__content">
|
|
397
|
+
{tabs.map((tab, index) => {
|
|
398
|
+
const child = typeof tab.child === 'string' ? tab.child : ''
|
|
399
|
+
return (
|
|
400
|
+
<div
|
|
401
|
+
key={index}
|
|
402
|
+
id={`skopon-module-panel-${context.componentModel.id}-${index}`}
|
|
403
|
+
role="tabpanel"
|
|
404
|
+
aria-labelledby={`skopon-module-tab-${context.componentModel.id}-${index}`}
|
|
405
|
+
hidden={selected !== index}
|
|
406
|
+
style={{ padding: 'var(--a2ui-tabs-content-padding, 0 var(--a2ui-spacing-m, 0.5rem))' }}
|
|
407
|
+
>
|
|
408
|
+
{visitedIndices.has(index) && child ? buildChild(child) : null}
|
|
409
|
+
</div>
|
|
410
|
+
)
|
|
411
|
+
})}
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
)
|
|
415
|
+
},
|
|
416
|
+
)
|
|
417
|
+
|
|
337
418
|
function ChoicePickerPreview({ context }: { context: ComponentContext }) {
|
|
338
419
|
const { interactive } = useA2uiPreviewMode()
|
|
339
420
|
const { value, setValue, setValueSilent, fieldName } = useSkoponBoundField(context, 'value', {
|
|
@@ -596,6 +677,7 @@ function normalizeFileValues(value: unknown): FileValueRef[] {
|
|
|
596
677
|
result.push({
|
|
597
678
|
assetId,
|
|
598
679
|
source: obj.source === 'library_select' ? 'library_select' as const : 'upload' as const,
|
|
680
|
+
url: typeof obj.url === 'string' && /^https?:\/\//i.test(obj.url) ? obj.url : undefined,
|
|
599
681
|
})
|
|
600
682
|
return result
|
|
601
683
|
}, [])
|
|
@@ -619,6 +701,7 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
619
701
|
const { interactive } = useA2uiPreviewMode()
|
|
620
702
|
const { beginUpload } = useFileUploadStatus()
|
|
621
703
|
const uploadMaterial = useMaterialUpload()
|
|
704
|
+
const resolveMaterialUrls = useMaterialResolveUrls()
|
|
622
705
|
const { value, setValue, setValueSilent, fieldName } = useSkoponBoundField(context, 'value', {
|
|
623
706
|
component: 'FileUpload',
|
|
624
707
|
changeAction: 'change',
|
|
@@ -663,14 +746,22 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
663
746
|
? '物料或素材'
|
|
664
747
|
: '物料 · 仅上传'
|
|
665
748
|
const initialValues = normalizeFileValues(value)
|
|
749
|
+
const initialAssetIds = [...new Set(initialValues.flatMap((entry) => entry.assetId ? [entry.assetId] : []))]
|
|
666
750
|
const externalUidRef = useRef(0)
|
|
667
751
|
const mountedRef = useRef(true)
|
|
668
752
|
const controllersRef = useRef(new Map<string, AbortController>())
|
|
753
|
+
const previewRefreshAttemptedRef = useRef(new Set<string>())
|
|
669
754
|
const setValueRef = useRef(setValue)
|
|
670
755
|
setValueRef.current = setValue
|
|
671
756
|
const [items, setItems] = useState<FileUploadListItem[]>(() => [
|
|
672
757
|
...initialValues.map((entry) => {
|
|
673
|
-
if (entry.url)
|
|
758
|
+
if (entry.url) {
|
|
759
|
+
return {
|
|
760
|
+
...fileItemFromUrl(entry.url, `external-${externalUidRef.current++}`),
|
|
761
|
+
assetId: entry.assetId,
|
|
762
|
+
source: entry.source,
|
|
763
|
+
}
|
|
764
|
+
}
|
|
674
765
|
const option = assetOptions.find((item) => item.assetId === entry.assetId)
|
|
675
766
|
return {
|
|
676
767
|
uid: `asset-${entry.assetId}-${externalUidRef.current++}`,
|
|
@@ -689,6 +780,35 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
689
780
|
])
|
|
690
781
|
const itemsRef = useRef(items)
|
|
691
782
|
itemsRef.current = items
|
|
783
|
+
const unresolvedAssetIds = initialAssetIds.filter((assetId) => {
|
|
784
|
+
const itemUrl = itemsRef.current.find((item) => item.assetId === assetId)?.url
|
|
785
|
+
const option = assetOptions.find((item) => item.assetId === assetId)
|
|
786
|
+
return !(itemUrl || option?.previewUrl || option?.url)
|
|
787
|
+
})
|
|
788
|
+
const unresolvedAssetKey = unresolvedAssetIds.join('\u0000')
|
|
789
|
+
|
|
790
|
+
useEffect(() => {
|
|
791
|
+
const assetIds = unresolvedAssetKey ? unresolvedAssetKey.split('\u0000') : []
|
|
792
|
+
if (!resolveMaterialUrls || !assetIds.length) return
|
|
793
|
+
let cancelled = false
|
|
794
|
+
void resolveMaterialUrls(assetIds).then((urls) => {
|
|
795
|
+
if (cancelled) return
|
|
796
|
+
const validUrls = Object.fromEntries(Object.entries(urls).filter(([assetId, url]) =>
|
|
797
|
+
assetIds.includes(assetId) && /^https?:\/\//i.test(url),
|
|
798
|
+
))
|
|
799
|
+
if (!Object.keys(validUrls).length) return
|
|
800
|
+
setItems((current) => {
|
|
801
|
+
const next = current.map((item) => item.assetId && validUrls[item.assetId]
|
|
802
|
+
? { ...item, url: validUrls[item.assetId] }
|
|
803
|
+
: item)
|
|
804
|
+
itemsRef.current = next
|
|
805
|
+
return next
|
|
806
|
+
})
|
|
807
|
+
}).catch((error: unknown) => {
|
|
808
|
+
console.warn('[Form material preview] Unable to resolve saved asset previews', error)
|
|
809
|
+
})
|
|
810
|
+
return () => { cancelled = true }
|
|
811
|
+
}, [unresolvedAssetKey, resolveMaterialUrls])
|
|
692
812
|
|
|
693
813
|
const commitItems = useCallback(
|
|
694
814
|
(
|
|
@@ -738,7 +858,11 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
738
858
|
const key = entry.assetId ? `asset:${entry.assetId}` : `url:${entry.url}`
|
|
739
859
|
if (present.has(key)) return
|
|
740
860
|
if (entry.url) {
|
|
741
|
-
next.push(
|
|
861
|
+
next.push({
|
|
862
|
+
...fileItemFromUrl(entry.url, `external-${externalUidRef.current++}`),
|
|
863
|
+
assetId: entry.assetId,
|
|
864
|
+
source: entry.source,
|
|
865
|
+
})
|
|
742
866
|
return
|
|
743
867
|
}
|
|
744
868
|
const option = assetOptions.find((item) => item.assetId === entry.assetId)
|
|
@@ -830,6 +954,35 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
830
954
|
[commitItems],
|
|
831
955
|
)
|
|
832
956
|
|
|
957
|
+
const handlePreviewError = useCallback((uid: string) => {
|
|
958
|
+
const item = itemsRef.current.find((candidate) => candidate.uid === uid)
|
|
959
|
+
if (!item?.url) return
|
|
960
|
+
|
|
961
|
+
// Signed preview URLs can expire while a form is open. Clear the failed URL
|
|
962
|
+
// immediately so the browser does not leave a broken-image icon, then ask
|
|
963
|
+
// the host to resolve the stable asset ID once more.
|
|
964
|
+
const failedUrl = item.url
|
|
965
|
+
const next = itemsRef.current.map((candidate) =>
|
|
966
|
+
candidate.uid === uid ? { ...candidate, url: undefined } : candidate,
|
|
967
|
+
)
|
|
968
|
+
itemsRef.current = next
|
|
969
|
+
setItems(next)
|
|
970
|
+
|
|
971
|
+
if (!item.assetId || !resolveMaterialUrls || previewRefreshAttemptedRef.current.has(uid)) return
|
|
972
|
+
previewRefreshAttemptedRef.current.add(uid)
|
|
973
|
+
void resolveMaterialUrls([item.assetId]).then((urls) => {
|
|
974
|
+
const freshUrl = urls[item.assetId!]
|
|
975
|
+
if (!mountedRef.current || !freshUrl || freshUrl === failedUrl || !/^https?:\/\//i.test(freshUrl)) return
|
|
976
|
+
const refreshed = itemsRef.current.map((candidate) =>
|
|
977
|
+
candidate.uid === uid ? { ...candidate, url: freshUrl } : candidate,
|
|
978
|
+
)
|
|
979
|
+
itemsRef.current = refreshed
|
|
980
|
+
setItems(refreshed)
|
|
981
|
+
}).catch((error: unknown) => {
|
|
982
|
+
console.warn('[Form material preview] Unable to refresh a failed asset preview', error)
|
|
983
|
+
})
|
|
984
|
+
}, [resolveMaterialUrls])
|
|
985
|
+
|
|
833
986
|
const uploadedCount = items.filter((item) => item.status === 'done').length
|
|
834
987
|
const atMaxLimit = hasMaxLimit && items.filter((item) => item.status !== 'error').length >= maxCount
|
|
835
988
|
const belowMinCount = uploadedCount < minCount
|
|
@@ -881,7 +1034,7 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
881
1034
|
if (compact) {
|
|
882
1035
|
const displayItem = items.find((item) => item.status === 'error') ?? items[0]
|
|
883
1036
|
const displayUrl = displayItem?.url
|
|
884
|
-
const isImage =
|
|
1037
|
+
const isImage = placeholderIcon === 'image' || Boolean(fileAcceptTypes?.some((type) => type.toLowerCase().startsWith('image/')))
|
|
885
1038
|
const state = reviewStatus === 'passed'
|
|
886
1039
|
? 'passed'
|
|
887
1040
|
: reviewStatus === 'failed'
|
|
@@ -906,7 +1059,7 @@ function FileUploadPreview({ context }: { context: ComponentContext }) {
|
|
|
906
1059
|
<><article className={`skopon-compact-upload skopon-compact-upload--${state}`} data-skopon-field={fieldName || undefined}>
|
|
907
1060
|
<div className="skopon-compact-upload__thumb">
|
|
908
1061
|
{displayUrl && isImage ? (
|
|
909
|
-
<img src={displayUrl} alt={label || '已上传素材'} />
|
|
1062
|
+
<img src={displayUrl} alt={label || '已上传素材'} onError={() => displayItem && handlePreviewError(displayItem.uid)} />
|
|
910
1063
|
) : (
|
|
911
1064
|
<FilePlaceholderIcon type={placeholderIcon} size={30} />
|
|
912
1065
|
)}
|
|
@@ -1175,6 +1328,7 @@ export function buildSkoponCatalog(): Catalog<ReactComponentImplementation> {
|
|
|
1175
1328
|
SkoponMediaImpl,
|
|
1176
1329
|
SkoponSelectImpl,
|
|
1177
1330
|
SkoponModulePanelImpl,
|
|
1331
|
+
TabsImpl,
|
|
1178
1332
|
ImageImpl,
|
|
1179
1333
|
VideoImpl,
|
|
1180
1334
|
AudioPlayerImpl,
|
|
@@ -22,18 +22,26 @@ export type MaterialUploadFn = (
|
|
|
22
22
|
options?: { signal?: AbortSignal },
|
|
23
23
|
) => Promise<MaterialUploadResult>
|
|
24
24
|
|
|
25
|
+
/** Resolve durable private asset IDs to short-lived preview URLs for rendering. */
|
|
26
|
+
export type MaterialResolveUrlsFn = (assetIds: string[]) => Promise<Record<string, string>>
|
|
27
|
+
|
|
25
28
|
const MaterialUploadContext = createContext<MaterialUploadFn | null>(null)
|
|
29
|
+
const MaterialResolveUrlsContext = createContext<MaterialResolveUrlsFn | null>(null)
|
|
26
30
|
|
|
27
31
|
export function MaterialUploadProvider({
|
|
28
32
|
uploadMaterial,
|
|
33
|
+
resolveMaterialUrls,
|
|
29
34
|
children,
|
|
30
35
|
}: {
|
|
31
36
|
uploadMaterial?: MaterialUploadFn | null
|
|
37
|
+
resolveMaterialUrls?: MaterialResolveUrlsFn | null
|
|
32
38
|
children: ReactNode
|
|
33
39
|
}) {
|
|
34
40
|
return (
|
|
35
41
|
<MaterialUploadContext.Provider value={uploadMaterial ?? null}>
|
|
36
|
-
{
|
|
42
|
+
<MaterialResolveUrlsContext.Provider value={resolveMaterialUrls ?? null}>
|
|
43
|
+
{children}
|
|
44
|
+
</MaterialResolveUrlsContext.Provider>
|
|
37
45
|
</MaterialUploadContext.Provider>
|
|
38
46
|
)
|
|
39
47
|
}
|
|
@@ -41,3 +49,7 @@ export function MaterialUploadProvider({
|
|
|
41
49
|
export function useMaterialUpload(): MaterialUploadFn | null {
|
|
42
50
|
return useContext(MaterialUploadContext)
|
|
43
51
|
}
|
|
52
|
+
|
|
53
|
+
export function useMaterialResolveUrls(): MaterialResolveUrlsFn | null {
|
|
54
|
+
return useContext(MaterialResolveUrlsContext)
|
|
55
|
+
}
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
import SkoponFormRenderer, { type SkoponFormRendererRef } from './SkoponFormRenderer'
|
|
42
42
|
import CurlSubmitBlock from './CurlSubmitBlock'
|
|
43
43
|
import SkoponFormProvider from './SkoponFormProvider'
|
|
44
|
-
import type { MaterialUploadFn } from '../catalog/materialUploadContext'
|
|
44
|
+
import type { MaterialResolveUrlsFn, MaterialUploadFn } from '../catalog/materialUploadContext'
|
|
45
45
|
|
|
46
46
|
const REFRESH_REPORT_DEBOUNCE_MS = 80
|
|
47
47
|
|
|
@@ -85,6 +85,8 @@ export interface AskUserFormCardProps {
|
|
|
85
85
|
caseSearch?: CaseSearchFn | null
|
|
86
86
|
/** 用户私有物料上传函数,由宿主负责浏览器直传及上下文。 */
|
|
87
87
|
uploadMaterial?: MaterialUploadFn | null
|
|
88
|
+
/** 用户私有素材 URL 解析函数,由宿主提供 API,SDK 负责用它回显 asset_id。 */
|
|
89
|
+
resolveMaterialUrls?: MaterialResolveUrlsFn | null
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
interface AskUserFormCardBodyProps extends AskUserFormCardProps {
|
|
@@ -107,6 +109,7 @@ function AskUserFormCardBody({
|
|
|
107
109
|
contentSearch = null,
|
|
108
110
|
caseSearch = null,
|
|
109
111
|
uploadMaterial = null,
|
|
112
|
+
resolveMaterialUrls = null,
|
|
110
113
|
onSurfaceReadyChange,
|
|
111
114
|
onAutoControlReady,
|
|
112
115
|
}: AskUserFormCardBodyProps) {
|
|
@@ -521,6 +524,7 @@ function AskUserFormCardBody({
|
|
|
521
524
|
contentSearch={contentSearch}
|
|
522
525
|
caseSearch={caseSearch}
|
|
523
526
|
uploadMaterial={uploadMaterial}
|
|
527
|
+
resolveMaterialUrls={resolveMaterialUrls}
|
|
524
528
|
onUploadingChange={setUploading}
|
|
525
529
|
/>
|
|
526
530
|
|
|
@@ -16,7 +16,7 @@ import { isA2uiSurfaceEmpty, surfaceDocToMessages } from '../adapter/a2uiAdapter
|
|
|
16
16
|
import { SKOPON_CATALOG_ID, buildSkoponCatalog } from '../catalog/a2uiCustomCatalog'
|
|
17
17
|
import { A2uiPreviewModeProvider } from '../catalog/a2uiPreviewContext'
|
|
18
18
|
import { FileUploadStatusProvider } from '../catalog/fileUploadStatusContext'
|
|
19
|
-
import { MaterialUploadProvider, type MaterialUploadFn } from '../catalog/materialUploadContext'
|
|
19
|
+
import { MaterialUploadProvider, type MaterialResolveUrlsFn, type MaterialUploadFn } from '../catalog/materialUploadContext'
|
|
20
20
|
import { CaseSearchProvider, type CaseSearchFn } from '../catalog/caseSearchContext'
|
|
21
21
|
import { ContentSearchProvider, type ContentSearchFn } from '../catalog/contentSearchContext'
|
|
22
22
|
import { ResumeSearchProvider, type ResumeSearchFn } from '../catalog/resumeSearchContext'
|
|
@@ -44,6 +44,8 @@ export interface SkoponFormRendererProps {
|
|
|
44
44
|
onUploadingChange?: (uploading: boolean) => void
|
|
45
45
|
/** 宿主注入的用户私有物料直传;未注入时上传会失败并提示配置。 */
|
|
46
46
|
uploadMaterial?: MaterialUploadFn | null
|
|
47
|
+
/** 宿主注入的私有素材 URL 解析器;用于回显已保存的 asset_id。 */
|
|
48
|
+
resolveMaterialUrls?: MaterialResolveUrlsFn | null
|
|
47
49
|
/** 外层已包裹 SkoponFormProvider 时可设为 false,避免重复 ConfigProvider */
|
|
48
50
|
wrapProvider?: boolean
|
|
49
51
|
}
|
|
@@ -61,6 +63,7 @@ const SkoponFormRenderer = forwardRef<SkoponFormRendererRef, SkoponFormRendererP
|
|
|
61
63
|
caseSearch = null,
|
|
62
64
|
onUploadingChange,
|
|
63
65
|
uploadMaterial = null,
|
|
66
|
+
resolveMaterialUrls = null,
|
|
64
67
|
wrapProvider = true,
|
|
65
68
|
},
|
|
66
69
|
ref,
|
|
@@ -148,7 +151,7 @@ const SkoponFormRenderer = forwardRef<SkoponFormRendererRef, SkoponFormRendererP
|
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
const content = (
|
|
151
|
-
<MaterialUploadProvider uploadMaterial={uploadMaterial}>
|
|
154
|
+
<MaterialUploadProvider uploadMaterial={uploadMaterial} resolveMaterialUrls={resolveMaterialUrls}>
|
|
152
155
|
<FileUploadStatusProvider onUploadingChange={onUploadingChange}>
|
|
153
156
|
<ResumeSearchProvider resumeSearch={resumeSearch}>
|
|
154
157
|
<ContentSearchProvider contentSearch={contentSearch}>
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type {
|
|
|
14
14
|
FormDefinitionPayload,
|
|
15
15
|
FormDetailResult,
|
|
16
16
|
FormFilePlaceholderIcon,
|
|
17
|
+
FormFileValueRef,
|
|
17
18
|
FormJsonSchema,
|
|
18
19
|
FormMediaSize,
|
|
19
20
|
FormModule,
|
|
@@ -153,6 +154,7 @@ export type { SkoponA2uiStreamRendererProps } from './components/SkoponA2uiStrea
|
|
|
153
154
|
|
|
154
155
|
export { default as AskUserFormCard } from './components/AskUserFormCard'
|
|
155
156
|
export type { AskUserFormCardProps } from './components/AskUserFormCard'
|
|
157
|
+
export type { MaterialResolveUrlsFn, MaterialUploadFn, MaterialUploadResult } from './catalog/materialUploadContext'
|
|
156
158
|
|
|
157
159
|
export { default as CurlSubmitBlock } from './components/CurlSubmitBlock'
|
|
158
160
|
export type { CurlSubmitBlockProps } from './components/CurlSubmitBlock'
|
package/src/styles/index.css
CHANGED
|
@@ -825,10 +825,79 @@
|
|
|
825
825
|
.skopon-file-source-actions {
|
|
826
826
|
display: flex;
|
|
827
827
|
flex-wrap: wrap;
|
|
828
|
+
align-items: center;
|
|
828
829
|
gap: 8px;
|
|
829
830
|
margin: 8px 0;
|
|
830
831
|
}
|
|
831
832
|
|
|
833
|
+
.skopon-file-source-actions > .ant-upload-wrapper,
|
|
834
|
+
.skopon-file-source-actions > .ant-upload-wrapper > .ant-upload,
|
|
835
|
+
.skopon-card-form .skopon-file-source-actions > .ant-upload-wrapper,
|
|
836
|
+
.skopon-card-form .skopon-file-source-actions > .ant-upload-wrapper > .ant-upload {
|
|
837
|
+
display: inline-flex;
|
|
838
|
+
width: auto;
|
|
839
|
+
flex: 0 0 auto;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/* Keep the three form actions consistent across hosts with different CSS resets. */
|
|
843
|
+
.skopon-resume-select-actions .ant-btn,
|
|
844
|
+
.skopon-file-source-actions .ant-btn,
|
|
845
|
+
.skopon-card-form .skopon-resume-select-actions .ant-btn,
|
|
846
|
+
.skopon-card-form .skopon-file-source-actions .ant-btn {
|
|
847
|
+
box-sizing: border-box;
|
|
848
|
+
display: inline-flex;
|
|
849
|
+
min-width: 0;
|
|
850
|
+
min-height: 32px;
|
|
851
|
+
height: 32px;
|
|
852
|
+
align-items: center;
|
|
853
|
+
justify-content: center;
|
|
854
|
+
gap: 6px;
|
|
855
|
+
padding: 0 13px;
|
|
856
|
+
border: 1px solid var(--color-border-strong, #cbd5d1);
|
|
857
|
+
border-radius: var(--radius-button, 9999px);
|
|
858
|
+
background: var(--color-surface, #fff);
|
|
859
|
+
color: var(--color-primary, #208368);
|
|
860
|
+
font-family: var(--font-sans, sans-serif);
|
|
861
|
+
font-size: 13px;
|
|
862
|
+
font-weight: var(--font-weight-medium, 500);
|
|
863
|
+
line-height: 18px;
|
|
864
|
+
box-shadow: none !important;
|
|
865
|
+
filter: none !important;
|
|
866
|
+
white-space: nowrap;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
.skopon-resume-select-actions .ant-btn:hover:not(:disabled),
|
|
870
|
+
.skopon-file-source-actions .ant-btn:hover:not(:disabled),
|
|
871
|
+
.skopon-card-form .skopon-resume-select-actions .ant-btn:hover:not(:disabled),
|
|
872
|
+
.skopon-card-form .skopon-file-source-actions .ant-btn:hover:not(:disabled) {
|
|
873
|
+
border-color: var(--color-primary, #208368);
|
|
874
|
+
background: var(--color-primary-subtle, #e6f7ed);
|
|
875
|
+
color: var(--color-primary, #208368);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.skopon-resume-select-actions .ant-btn:focus:not(:focus-visible),
|
|
879
|
+
.skopon-file-source-actions .ant-btn:focus:not(:focus-visible),
|
|
880
|
+
.skopon-card-form .skopon-resume-select-actions .ant-btn:focus:not(:focus-visible),
|
|
881
|
+
.skopon-card-form .skopon-file-source-actions .ant-btn:focus:not(:focus-visible) {
|
|
882
|
+
outline: none;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
.skopon-resume-select-actions .ant-btn:focus-visible,
|
|
886
|
+
.skopon-file-source-actions .ant-btn:focus-visible,
|
|
887
|
+
.skopon-card-form .skopon-resume-select-actions .ant-btn:focus-visible,
|
|
888
|
+
.skopon-card-form .skopon-file-source-actions .ant-btn:focus-visible {
|
|
889
|
+
outline: 2px solid var(--color-focus-ring, color-mix(in srgb, var(--color-primary, #208368) 35%, transparent));
|
|
890
|
+
outline-offset: 2px;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
.skopon-resume-select-actions .ant-btn::before,
|
|
894
|
+
.skopon-file-source-actions .ant-btn::before,
|
|
895
|
+
.skopon-card-form .skopon-resume-select-actions .ant-btn::before,
|
|
896
|
+
.skopon-card-form .skopon-file-source-actions .ant-btn::before {
|
|
897
|
+
box-shadow: none !important;
|
|
898
|
+
filter: none !important;
|
|
899
|
+
}
|
|
900
|
+
|
|
832
901
|
.skopon-asset-picker {
|
|
833
902
|
display: grid;
|
|
834
903
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
package/src/types/index.ts
CHANGED
|
@@ -114,6 +114,16 @@ export interface FormBlockCondition {
|
|
|
114
114
|
value?: string
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/** Durable file reference saved in a file field's answer. */
|
|
118
|
+
export interface FormFileValueRef {
|
|
119
|
+
asset_id: string
|
|
120
|
+
source?: 'upload' | 'library_select'
|
|
121
|
+
url?: string
|
|
122
|
+
expires_at?: number
|
|
123
|
+
footage_asset_id?: string
|
|
124
|
+
[key: string]: unknown
|
|
125
|
+
}
|
|
126
|
+
|
|
117
127
|
/** 简历多选组件:渲染时用于 /univ/resume/search 的筛选条件 */
|
|
118
128
|
export interface FormResumeFilter {
|
|
119
129
|
names?: string[]
|
|
@@ -198,7 +208,7 @@ export interface FormBlock {
|
|
|
198
208
|
fileReviewMessage?: string
|
|
199
209
|
/** 审核未通过的历史文件,仅作错误态回显,不计入有效提交。 */
|
|
200
210
|
fileRejectedUrls?: string[]
|
|
201
|
-
defaultValue?: string | string
|
|
211
|
+
defaultValue?: string | Array<string | FormFileValueRef> | boolean
|
|
202
212
|
/** 派生 JSON Schema 时写入 property.$comment */
|
|
203
213
|
jsonSchemaDescription?: string
|
|
204
214
|
/** 是否隐藏(仅 text 块;隐藏时仍提交) */
|