@skopon-cool/form-sdk 0.6.7 → 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.
@@ -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[] | boolean;
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":"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"}
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,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;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,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,OAAO,CAAA;IAClE,2CAA2C;IAC3C,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,4BAA4B;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,0BAA0B;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+CAA+C;IAC/C,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAAA;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,mCAAmC;IACnC,YAAY,CAAC,EAAE,gBAAgB,CAAA;IAC/B,mCAAmC;IACnC,aAAa,CAAC,EAAE,iBAAiB,CAAA;IACjC,qBAAqB;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,UAAU,EAAE,cAAc,CAAA;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE7D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE3D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE7D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE/D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE/D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAOjE;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,WAAW,CAAC,EAAE,cAAc,CAAA;IAC5B,UAAU,CAAC,EAAE,cAAc,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,UAAU,CAAA;IAC3B,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.6.7",
6
+ "version": "0.6.8",
7
7
  "description": "Skopon form rendering SDK (A2UI + form_definition) with submit helpers",
8
8
  "type": "module",
9
9
  "sideEffects": [
@@ -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: { type: 'string' },
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) return fileItemFromUrl(entry.url, `external-${externalUidRef.current++}`)
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(fileItemFromUrl(entry.url, `external-${externalUidRef.current++}`))
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 = fileAcceptTypes?.includes('image/*') ?? placeholderIcon === 'image'
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
- {children}
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'
@@ -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[] | boolean
211
+ defaultValue?: string | Array<string | FormFileValueRef> | boolean
202
212
  /** 派生 JSON Schema 时写入 property.$comment */
203
213
  jsonSchemaDescription?: string
204
214
  /** 是否隐藏(仅 text 块;隐藏时仍提交) */