@wildo-ai/presets-components 1.1.5 → 1.1.6

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 (189) hide show
  1. package/dist/esm/.native.tsbuildinfo +1 -0
  2. package/dist/esm/components/actions/action-bar.d.ts.map +1 -1
  3. package/dist/esm/components/actions/action-bar.js +5 -2
  4. package/dist/esm/components/actions/action-bar.js.map +1 -1
  5. package/dist/esm/components/ai-elements/chat/suggestion.d.ts.map +1 -1
  6. package/dist/esm/components/ai-elements/chat/suggestion.js +8 -1
  7. package/dist/esm/components/ai-elements/chat/suggestion.js.map +1 -1
  8. package/dist/esm/components/ai-elements/decision/approval.d.ts +108 -13
  9. package/dist/esm/components/ai-elements/decision/approval.d.ts.map +1 -1
  10. package/dist/esm/components/ai-elements/decision/approval.js +60 -10
  11. package/dist/esm/components/ai-elements/decision/approval.js.map +1 -1
  12. package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts +3 -1
  13. package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts.map +1 -1
  14. package/dist/esm/components/ai-elements/graph/graph-runtime.js +3 -1
  15. package/dist/esm/components/ai-elements/graph/graph-runtime.js.map +1 -1
  16. package/dist/esm/components/app/app-layout-main-container.d.ts +9 -0
  17. package/dist/esm/components/app/app-layout-main-container.d.ts.map +1 -1
  18. package/dist/esm/components/app/app-layout-main-container.js +17 -23
  19. package/dist/esm/components/app/app-layout-main-container.js.map +1 -1
  20. package/dist/esm/components/app/app-layout-main-container.labels.d.ts.map +1 -1
  21. package/dist/esm/components/app/app-layout-main-container.labels.js +27 -0
  22. package/dist/esm/components/app/app-layout-main-container.labels.js.map +1 -1
  23. package/dist/esm/components/billing/billing-plan-change-preview.d.ts.map +1 -1
  24. package/dist/esm/components/billing/billing-plan-change-preview.js +5 -2
  25. package/dist/esm/components/billing/billing-plan-change-preview.js.map +1 -1
  26. package/dist/esm/components/billing/billing-plan-change-preview.labels.d.ts.map +1 -1
  27. package/dist/esm/components/billing/billing-plan-change-preview.labels.js +3 -0
  28. package/dist/esm/components/billing/billing-plan-change-preview.labels.js.map +1 -1
  29. package/dist/esm/components/billing/billing-pricing-table.d.ts +1 -1
  30. package/dist/esm/components/billing/billing-pricing-table.d.ts.map +1 -1
  31. package/dist/esm/components/billing/billing-pricing-table.js +8 -4
  32. package/dist/esm/components/billing/billing-pricing-table.js.map +1 -1
  33. package/dist/esm/components/billing/billing-pricing-table.labels.d.ts.map +1 -1
  34. package/dist/esm/components/billing/billing-pricing-table.labels.js +7 -1
  35. package/dist/esm/components/billing/billing-pricing-table.labels.js.map +1 -1
  36. package/dist/esm/components/billing/billing-usage-dashboard.d.ts.map +1 -1
  37. package/dist/esm/components/billing/billing-usage-dashboard.js +6 -3
  38. package/dist/esm/components/billing/billing-usage-dashboard.js.map +1 -1
  39. package/dist/esm/components/billing/billing-usage-dashboard.labels.d.ts.map +1 -1
  40. package/dist/esm/components/billing/billing-usage-dashboard.labels.js +2 -1
  41. package/dist/esm/components/billing/billing-usage-dashboard.labels.js.map +1 -1
  42. package/dist/esm/components/data-display/formatters/display-field-enum.d.ts.map +1 -1
  43. package/dist/esm/components/data-display/formatters/display-field-enum.js +18 -4
  44. package/dist/esm/components/data-display/formatters/display-field-enum.js.map +1 -1
  45. package/dist/esm/components/data-display/formatters/display-field-file.d.ts.map +1 -1
  46. package/dist/esm/components/data-display/formatters/display-field-file.js +13 -14
  47. package/dist/esm/components/data-display/formatters/display-field-file.js.map +1 -1
  48. package/dist/esm/components/data-display/formatters/display-field-file.labels.d.ts.map +1 -1
  49. package/dist/esm/components/data-display/formatters/display-field-file.labels.js +1 -0
  50. package/dist/esm/components/data-display/formatters/display-field-file.labels.js.map +1 -1
  51. package/dist/esm/components/data-display/formatters/display-field-number.d.ts.map +1 -1
  52. package/dist/esm/components/data-display/formatters/display-field-number.js +6 -1
  53. package/dist/esm/components/data-display/formatters/display-field-number.js.map +1 -1
  54. package/dist/esm/components/data-display/formatters/display-field-number.labels.d.ts.map +1 -1
  55. package/dist/esm/components/data-display/formatters/display-field-number.labels.js +5 -2
  56. package/dist/esm/components/data-display/formatters/display-field-number.labels.js.map +1 -1
  57. package/dist/esm/components/data-display/formatters/display-field-string.d.ts +1 -1
  58. package/dist/esm/components/data-display/formatters/display-field-string.d.ts.map +1 -1
  59. package/dist/esm/components/data-display/formatters/display-field-string.js +51 -12
  60. package/dist/esm/components/data-display/formatters/display-field-string.js.map +1 -1
  61. package/dist/esm/components/data-display/untrusted-html-content.d.ts +55 -0
  62. package/dist/esm/components/data-display/untrusted-html-content.d.ts.map +1 -0
  63. package/dist/esm/components/data-display/untrusted-html-content.js +67 -0
  64. package/dist/esm/components/data-display/untrusted-html-content.js.map +1 -0
  65. package/dist/esm/components/form/chromes/form-primitive.labels.d.ts.map +1 -1
  66. package/dist/esm/components/form/chromes/form-primitive.labels.js +9 -0
  67. package/dist/esm/components/form/chromes/form-primitive.labels.js.map +1 -1
  68. package/dist/esm/components/form/combobox.d.ts.map +1 -1
  69. package/dist/esm/components/form/combobox.js +10 -10
  70. package/dist/esm/components/form/combobox.js.map +1 -1
  71. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts +42 -0
  72. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts.map +1 -0
  73. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js +120 -0
  74. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js.map +1 -0
  75. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts +16 -0
  76. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts.map +1 -0
  77. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js +8 -0
  78. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js.map +1 -0
  79. package/dist/esm/components/navigation/app-level/activity-bar.d.ts.map +1 -1
  80. package/dist/esm/components/navigation/app-level/activity-bar.js +2 -2
  81. package/dist/esm/components/navigation/app-level/activity-bar.js.map +1 -1
  82. package/dist/esm/components/navigation/app-level/menu-user-org.d.ts.map +1 -1
  83. package/dist/esm/components/navigation/app-level/menu-user-org.js +10 -4
  84. package/dist/esm/components/navigation/app-level/menu-user-org.js.map +1 -1
  85. package/dist/esm/components/navigation/app-level/menu-user-org.labels.d.ts.map +1 -1
  86. package/dist/esm/components/navigation/app-level/menu-user-org.labels.js +7 -0
  87. package/dist/esm/components/navigation/app-level/menu-user-org.labels.js.map +1 -1
  88. package/dist/esm/components/navigation/app-level/menubar.d.ts.map +1 -1
  89. package/dist/esm/components/navigation/app-level/menubar.js +6 -6
  90. package/dist/esm/components/navigation/app-level/menubar.js.map +1 -1
  91. package/dist/esm/components/navigation/app-level/navigation-back.d.ts.map +1 -1
  92. package/dist/esm/components/navigation/app-level/navigation-back.js +27 -9
  93. package/dist/esm/components/navigation/app-level/navigation-back.js.map +1 -1
  94. package/dist/esm/components/navigation/app-level/sidebar.js +3 -3
  95. package/dist/esm/components/navigation/app-level/sidebar.js.map +1 -1
  96. package/dist/esm/components/navigation/app-level/status-bar.js +2 -2
  97. package/dist/esm/components/navigation/app-level/status-bar.js.map +1 -1
  98. package/dist/esm/components/navigation/app-level/toolbar.d.ts.map +1 -1
  99. package/dist/esm/components/navigation/app-level/toolbar.js +2 -2
  100. package/dist/esm/components/navigation/app-level/toolbar.js.map +1 -1
  101. package/dist/esm/components/navigation/app-level/utility-panel.js +2 -2
  102. package/dist/esm/components/navigation/app-level/utility-panel.js.map +1 -1
  103. package/dist/esm/components/navigation/breadcrumb.js +1 -1
  104. package/dist/esm/components/navigation/breadcrumb.js.map +1 -1
  105. package/dist/esm/components/sections/stepper.d.ts.map +1 -1
  106. package/dist/esm/components/sections/stepper.js +5 -3
  107. package/dist/esm/components/sections/stepper.js.map +1 -1
  108. package/dist/esm/config/preset-navigation.d.ts.map +1 -1
  109. package/dist/esm/config/preset-navigation.js +23 -2
  110. package/dist/esm/config/preset-navigation.js.map +1 -1
  111. package/dist/esm/config/resources/agent-work.resource-presets.d.ts +4 -0
  112. package/dist/esm/config/resources/agent-work.resource-presets.d.ts.map +1 -0
  113. package/dist/esm/config/resources/agent-work.resource-presets.js +115 -0
  114. package/dist/esm/config/resources/agent-work.resource-presets.js.map +1 -0
  115. package/dist/esm/config/resources/api-key-rotation-window.d.ts +22 -0
  116. package/dist/esm/config/resources/api-key-rotation-window.d.ts.map +1 -0
  117. package/dist/esm/config/resources/api-key-rotation-window.js +45 -0
  118. package/dist/esm/config/resources/api-key-rotation-window.js.map +1 -0
  119. package/dist/esm/config/resources/application.resource-presets.d.ts.map +1 -1
  120. package/dist/esm/config/resources/application.resource-presets.js +147 -61
  121. package/dist/esm/config/resources/application.resource-presets.js.map +1 -1
  122. package/dist/esm/config/resources/billing.resource-presets.d.ts +4 -3
  123. package/dist/esm/config/resources/billing.resource-presets.d.ts.map +1 -1
  124. package/dist/esm/config/resources/billing.resource-presets.js +240 -111
  125. package/dist/esm/config/resources/billing.resource-presets.js.map +1 -1
  126. package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts +4 -0
  127. package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts.map +1 -0
  128. package/dist/esm/config/resources/conversation-threads.resource-presets.js +105 -0
  129. package/dist/esm/config/resources/conversation-threads.resource-presets.js.map +1 -0
  130. package/dist/esm/config/resources/guidance.resource-presets.d.ts.map +1 -1
  131. package/dist/esm/config/resources/guidance.resource-presets.js +18 -11
  132. package/dist/esm/config/resources/guidance.resource-presets.js.map +1 -1
  133. package/dist/esm/config/resources/identity.resource-presets.d.ts +0 -13
  134. package/dist/esm/config/resources/identity.resource-presets.d.ts.map +1 -1
  135. package/dist/esm/config/resources/identity.resource-presets.js +48 -16
  136. package/dist/esm/config/resources/identity.resource-presets.js.map +1 -1
  137. package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts +6 -0
  138. package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts.map +1 -0
  139. package/dist/esm/config/resources/inbound-deliveries.resource-presets.js +112 -0
  140. package/dist/esm/config/resources/inbound-deliveries.resource-presets.js.map +1 -0
  141. package/dist/esm/config/resources/inbound-email.resource-presets.d.ts +4 -0
  142. package/dist/esm/config/resources/inbound-email.resource-presets.d.ts.map +1 -0
  143. package/dist/esm/config/resources/inbound-email.resource-presets.js +182 -0
  144. package/dist/esm/config/resources/inbound-email.resource-presets.js.map +1 -0
  145. package/dist/esm/config/resources/index.d.ts.map +1 -1
  146. package/dist/esm/config/resources/index.js +9 -2
  147. package/dist/esm/config/resources/index.js.map +1 -1
  148. package/dist/esm/config/resources/legal-holds.resource-presets.d.ts +4 -0
  149. package/dist/esm/config/resources/legal-holds.resource-presets.d.ts.map +1 -0
  150. package/dist/esm/config/resources/legal-holds.resource-presets.js +76 -0
  151. package/dist/esm/config/resources/legal-holds.resource-presets.js.map +1 -0
  152. package/dist/esm/config/resources/organizations.resource-presets.d.ts.map +1 -1
  153. package/dist/esm/config/resources/organizations.resource-presets.js +139 -36
  154. package/dist/esm/config/resources/organizations.resource-presets.js.map +1 -1
  155. package/dist/esm/config/resources/resource.config.utils.d.ts +20 -0
  156. package/dist/esm/config/resources/resource.config.utils.d.ts.map +1 -1
  157. package/dist/esm/config/resources/resource.config.utils.js +20 -0
  158. package/dist/esm/config/resources/resource.config.utils.js.map +1 -1
  159. package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts +5 -0
  160. package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts.map +1 -0
  161. package/dist/esm/config/resources/retention-enforcement.resource-presets.js +74 -0
  162. package/dist/esm/config/resources/retention-enforcement.resource-presets.js.map +1 -0
  163. package/dist/esm/config/resources/security.resource-presets.d.ts +3 -1
  164. package/dist/esm/config/resources/security.resource-presets.d.ts.map +1 -1
  165. package/dist/esm/config/resources/security.resource-presets.js +563 -133
  166. package/dist/esm/config/resources/security.resource-presets.js.map +1 -1
  167. package/dist/esm/config/resources/service-providers.resource-presets.d.ts +4 -0
  168. package/dist/esm/config/resources/service-providers.resource-presets.d.ts.map +1 -0
  169. package/dist/esm/config/resources/service-providers.resource-presets.js +321 -0
  170. package/dist/esm/config/resources/service-providers.resource-presets.js.map +1 -0
  171. package/dist/esm/config/resources/webhooks.resource-presets.d.ts +4 -3
  172. package/dist/esm/config/resources/webhooks.resource-presets.d.ts.map +1 -1
  173. package/dist/esm/config/resources/webhooks.resource-presets.js +76 -25
  174. package/dist/esm/config/resources/webhooks.resource-presets.js.map +1 -1
  175. package/dist/esm/index.d.ts +1 -0
  176. package/dist/esm/index.d.ts.map +1 -1
  177. package/dist/esm/index.js +1 -0
  178. package/dist/esm/index.js.map +1 -1
  179. package/dist/esm/registration/register-common-enums.d.ts.map +1 -1
  180. package/dist/esm/registration/register-common-enums.js +15 -0
  181. package/dist/esm/registration/register-common-enums.js.map +1 -1
  182. package/dist/esm/registration/register-provider-components.d.ts.map +1 -1
  183. package/dist/esm/registration/register-provider-components.js +6 -0
  184. package/dist/esm/registration/register-provider-components.js.map +1 -1
  185. package/dist/esm/themes/dense.theme.d.ts.map +1 -1
  186. package/dist/esm/themes/dense.theme.js +22 -2
  187. package/dist/esm/themes/dense.theme.js.map +1 -1
  188. package/dist/tsconfig.build.tsbuildinfo +1 -1
  189. package/package.json +8 -6
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-enum.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-enum.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldEnum Component\n *\n * Displays an enum value based on the enum UI decorator.\n * Supports different display modes: text, badge, icon, card\n */\n\nimport * as React from \"react\"\n\nimport { useI18n, useIconRegistry, IconSize, ICON_SIZE_MAP, Text, Badge, Card, useContextualDisplayParams, resolveEnumDisplayConfig } from \"@wildo-ai/saas-frontend-lib\"\nimport { FrontendComponentType } from \"@wildo-ai/presets-components-models\"\nimport { EnumDisplayMode } from \"@wildo-ai/zod-decorators\"\nimport type { IconLike } from \"@wildo-ai/zod-decorators\"\nimport type { DisplayFieldEnumProps } from '@wildo-ai/saas-frontend-lib'\nimport type { BadgeVariants_Variant } from '@wildo-ai/saas-frontend-lib'\n\n/**\n * DisplayFieldEnum component\n *\n * Renders an enum value according to the display policy\n */\nfunction DisplayFieldEnum({\n schema,\n value,\n className,\n labels,\n}: DisplayFieldEnumProps): React.JSX.Element | null {\n const { tComponent, isReady } = useI18n({ component: FrontendComponentType.LOW_LEVEL_FORM_FIELD })\n const { renderIcon } = useIconRegistry()\n\n // The field's own metadata over the registered vocabulary's (#1321) — see `resolveEnumDisplayConfig`.\n const enumUI = resolveEnumDisplayConfig(schema)\n // SUMMARY surfaces (cards, FK previews) merge `summaryOverride` over\n // `display` — the {primitive}UI decorator contract. E.g. a priority enum can\n // render `BADGE` on the detail page but `summaryOverride: { displayMode: ICON }`\n // (icon-only) on list cards.\n const displayParams = useContextualDisplayParams(enumUI)\n const displayMode = displayParams?.displayMode ?? EnumDisplayMode.TEXT\n\n const resolveColor = (enumValue: string, fallback: BadgeVariants_Variant): BadgeVariants_Variant => {\n return (\n enumUI?.values?.[enumValue]?.color\n ?? enumUI?.defaultColor\n ?? fallback\n ) as BadgeVariants_Variant\n }\n\n const resolveIcon = (enumValue: string): IconLike | undefined => {\n return (\n enumUI?.values?.[enumValue]?.icon\n ?? enumUI?.defaultIcon\n )\n }\n\n // Get display label for the value\n const displayLabel = value ? (labels?.[value] ?? value) : null\n\n /**\n * Render an `IconLike` — dispatches between string refs (via icon registry)\n * and direct React component refs (via createElement).\n */\n const renderIconLike = (icon: IconLike, size: IconSize, className?: string): React.ReactNode => {\n if (typeof icon === 'string') {\n return renderIcon(icon, { size, className })\n }\n const sizeInPixels = ICON_SIZE_MAP[size]\n return React.createElement(icon, { size: sizeInPixels, className })\n }\n\n // Render the value content\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined || value === '' || displayLabel === null) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // Render based on display mode\n switch (displayMode) {\n case EnumDisplayMode.TEXT:\n return <Text>{displayLabel}</Text>\n\n case EnumDisplayMode.BADGE: {\n const variant = resolveColor(value, 'secondary')\n const icon = resolveIcon(value)\n /*\n * NO local layout class on the badge. `Badge` is already `inline-flex items-center` with\n * the glyph gap its own structure owns; restating it here was a second copy of the same\n * decision, and the copy carried the one-pixel gap long after the shared one could have\n * fixed it for every badge at once.\n */\n return (\n <Badge variant={variant}>\n {icon ? renderIconLike(icon, IconSize.SM) : null}\n {displayLabel}\n </Badge>\n )\n }\n\n // ICON — the COMPACT, icon-only representation: a colored badge carrying\n // just the value's icon; the label goes to assistive tech (sr-only) and\n // to sighted users on hover (native `title`). This is what summary\n // surfaces use via `summaryOverride: { displayMode: ICON }`. It is NOT a\n // \"badge with icon\" — that's BADGE with a per-value `icon` configured.\n case EnumDisplayMode.ICON: {\n const iconVariant = resolveColor(value, 'outline')\n const icon = resolveIcon(value)\n\n if (icon) {\n return (\n <Badge variant={iconVariant} className=\"px-1.5\" title={displayLabel}>\n {renderIconLike(icon, IconSize.SM)}\n <span className=\"sr-only\">{displayLabel}</span>\n </Badge>\n )\n }\n\n // No icon configured for this value — the color dot IS the icon.\n return (\n <Badge\n variant={iconVariant}\n className=\"h-2.5 w-2.5 rounded-full p-0\"\n title={displayLabel}\n >\n <span className=\"sr-only\">{displayLabel}</span>\n </Badge>\n )\n }\n\n case EnumDisplayMode.CARD:\n return (\n <Card className=\"inline-flex px-card-sm py-1.5\">\n <Text className=\"text-sm font-medium\">{displayLabel}</Text>\n </Card>\n )\n\n default:\n return <Text>{displayLabel}</Text>\n }\n }\n\n if (!isReady) return null\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return <div className={className}>{renderValue()}</div>\n}\n\n;(DisplayFieldEnum as typeof DisplayFieldEnum & { displayName: string }).displayName = \"DisplayFieldEnum\"\n\nexport { DisplayFieldEnum }\n"]}
1
+ {"version":3,"file":"display-field-enum.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-enum.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldEnum Component\n *\n * Displays an enum value based on the enum UI decorator.\n * Supports different display modes: text, badge, icon, card\n */\n\nimport * as React from \"react\"\n\nimport { useI18n, useIconRegistry, IconSize, ICON_SIZE_MAP, Text, Badge, Card, useContextualDisplayParams, resolveEnumDisplayConfig } from \"@wildo-ai/saas-frontend-lib\"\nimport { FrontendComponentType, resolveVocabularyWordKey } from \"@wildo-ai/presets-components-models\"\nimport { EnumDisplayMode, getSystemEnumName } from \"@wildo-ai/zod-decorators\"\nimport type { IconLike } from \"@wildo-ai/zod-decorators\"\nimport type { DisplayFieldEnumProps } from '@wildo-ai/saas-frontend-lib'\nimport type { BadgeVariants_Variant } from '@wildo-ai/saas-frontend-lib'\n\n/**\n * DisplayFieldEnum component\n *\n * Renders an enum value according to the display policy\n */\nfunction DisplayFieldEnum({\n schema,\n value,\n className,\n labels,\n}: DisplayFieldEnumProps): React.JSX.Element | null {\n const { tComponent, t, isReady } = useI18n({ component: FrontendComponentType.LOW_LEVEL_FORM_FIELD })\n const { renderIcon } = useIconRegistry()\n\n // The field's own metadata over the registered vocabulary's (#1321) — see `resolveEnumDisplayConfig`.\n const enumUI = resolveEnumDisplayConfig(schema)\n // SUMMARY surfaces (cards, FK previews) merge `summaryOverride` over\n // `display` — the {primitive}UI decorator contract. E.g. a priority enum can\n // render `BADGE` on the detail page but `summaryOverride: { displayMode: ICON }`\n // (icon-only) on list cards.\n const displayParams = useContextualDisplayParams(enumUI)\n const displayMode = displayParams?.displayMode ?? EnumDisplayMode.TEXT\n\n const resolveColor = (enumValue: string, fallback: BadgeVariants_Variant): BadgeVariants_Variant => {\n return (\n enumUI?.values?.[enumValue]?.color\n ?? enumUI?.defaultColor\n ?? fallback\n ) as BadgeVariants_Variant\n }\n\n const resolveIcon = (enumValue: string): IconLike | undefined => {\n return (\n enumUI?.values?.[enumValue]?.icon\n ?? enumUI?.defaultIcon\n )\n }\n\n /*\n * A value the resolved `labels` do not cover, on a field that names its vocabulary (#1851). The labels are built from\n * the enum's own MEMBERS, so a union such as a feature list (`z.enum(CoreFeature) | z.string()`) carries values no\n * member names — an application's own feature ids — and those read their word straight from the vocabulary, where\n * it keeps it (`resolveVocabularyWordKey`). A value with no word shows itself: a missing label that looks missing.\n */\n const vocabulary = schema ? getSystemEnumName(schema) : undefined\n const vocabularyWord = (enumValue: string): string | undefined => {\n if (!vocabulary) return undefined\n const key = resolveVocabularyWordKey(vocabulary, enumValue)\n const word = t(key)\n return word === key ? undefined : word\n }\n\n // Get display label for the value\n const displayLabel = value ? (labels?.[value] ?? vocabularyWord(value) ?? value) : null\n\n /**\n * Render an `IconLike` — dispatches between string refs (via icon registry)\n * and direct React component refs (via createElement).\n */\n const renderIconLike = (icon: IconLike, size: IconSize, className?: string): React.ReactNode => {\n if (typeof icon === 'string') {\n return renderIcon(icon, { size, className })\n }\n const sizeInPixels = ICON_SIZE_MAP[size]\n return React.createElement(icon, { size: sizeInPixels, className })\n }\n\n // Render the value content\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined || value === '' || displayLabel === null) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // Render based on display mode\n switch (displayMode) {\n case EnumDisplayMode.TEXT:\n return <Text>{displayLabel}</Text>\n\n case EnumDisplayMode.BADGE: {\n const variant = resolveColor(value, 'secondary')\n const icon = resolveIcon(value)\n /*\n * NO local layout class on the badge. `Badge` is already `inline-flex items-center` with\n * the glyph gap its own structure owns; restating it here was a second copy of the same\n * decision, and the copy carried the one-pixel gap long after the shared one could have\n * fixed it for every badge at once.\n */\n return (\n <Badge variant={variant}>\n {icon ? renderIconLike(icon, IconSize.SM) : null}\n {displayLabel}\n </Badge>\n )\n }\n\n // ICON — the COMPACT, icon-only representation: a colored badge carrying\n // just the value's icon; the label goes to assistive tech (sr-only) and\n // to sighted users on hover (native `title`). This is what summary\n // surfaces use via `summaryOverride: { displayMode: ICON }`. It is NOT a\n // \"badge with icon\" — that's BADGE with a per-value `icon` configured.\n case EnumDisplayMode.ICON: {\n const iconVariant = resolveColor(value, 'outline')\n const icon = resolveIcon(value)\n\n if (icon) {\n return (\n <Badge variant={iconVariant} className=\"px-1.5\" title={displayLabel}>\n {renderIconLike(icon, IconSize.SM)}\n <span className=\"sr-only\">{displayLabel}</span>\n </Badge>\n )\n }\n\n // No icon configured for this value — the color dot IS the icon.\n return (\n <Badge\n variant={iconVariant}\n className=\"h-2.5 w-2.5 rounded-full p-0\"\n title={displayLabel}\n >\n <span className=\"sr-only\">{displayLabel}</span>\n </Badge>\n )\n }\n\n case EnumDisplayMode.CARD:\n return (\n <Card className=\"inline-flex px-card-sm py-1.5\">\n <Text className=\"text-sm font-medium\">{displayLabel}</Text>\n </Card>\n )\n\n default:\n return <Text>{displayLabel}</Text>\n }\n }\n\n if (!isReady) return null\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return <div className={className}>{renderValue()}</div>\n}\n\n;(DisplayFieldEnum as typeof DisplayFieldEnum & { displayName: string }).displayName = \"DisplayFieldEnum\"\n\nexport { DisplayFieldEnum }\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-file.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAaL,qBAAqB,EAQtB,MAAM,6BAA6B,CAAC;AAgErC;;;;;;;;GAQG;AACH,iBAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAe,EACf,QAAe,EACf,YAAmB,EACnB,cAAc,GACf,EAAE,qBAAqB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAqZlD;AAyDD,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"display-field-file.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAaL,qBAAqB,EAQtB,MAAM,6BAA6B,CAAC;AA4DrC;;;;;;;;GAQG;AACH,iBAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAe,EACf,QAAe,EACf,YAAmB,EACnB,cAAc,GACf,EAAE,qBAAqB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAqZlD;AAyDD,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
@@ -32,17 +32,16 @@ function isSingleFileValue(value) {
32
32
  function isMultipleFileValue(value) {
33
33
  return value !== null && value !== undefined && 'fileIds' in value;
34
34
  }
35
- function getNeutralFileDisplayLabel(value, t) {
36
- if (isSingleFileValue(value)) {
37
- return t('File attached') ?? 'File attached';
38
- }
39
- const fileCount = value.fileIds.length;
40
- const translatedMultipleLabel = t('Files attached', { count: fileCount });
35
+ /**
36
+ * The neutral name shown for attached files whose details are unavailable. Every word comes from this
37
+ * component's labels (#1557): it used to look up English sentences through the plain `t`, with an
38
+ * English fallback and a count sentence built in code, none of which a translator could reach.
39
+ */
40
+ function getNeutralFileDisplayLabel(value, tComponent) {
41
+ const fileCount = isSingleFileValue(value) ? 1 : value.fileIds.length;
41
42
  return fileCount > 1
42
- ? (translatedMultipleLabel && translatedMultipleLabel !== 'Files attached'
43
- ? translatedMultipleLabel
44
- : `${fileCount} files attached`)
45
- : (t('File attached') ?? 'File attached');
43
+ ? tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'files_count', { count: fileCount })
44
+ : tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'file_attached');
46
45
  }
47
46
  function getFileValueRefreshKey(value) {
48
47
  if (!value || typeof value !== 'object' || !('updatedAt' in value)) {
@@ -62,7 +61,7 @@ function getFileValueRefreshKey(value) {
62
61
  */
63
62
  function DisplayFieldFile({ schema, value, className, fieldName, endpoints, showSize = true, showType = true, showDownload = true, httpOperations, }) {
64
63
  const { renderIcon } = useIconRegistry();
65
- const { t, tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_FORM_FIELD_FILE, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE] });
64
+ const { tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_FORM_FIELD_FILE, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE] });
66
65
  const fileSchemaMetadata = getFileSchemaMetadata(schema);
67
66
  const isMultiple = fileSchemaMetadata?.multiple ?? false;
68
67
  // State for loaded metadata (single file or array of files)
@@ -127,7 +126,7 @@ function DisplayFieldFile({ schema, value, className, fieldName, endpoints, show
127
126
  };
128
127
  fetchAllMetadata();
129
128
  return () => { cancelled = true; };
130
- }, [fileIdsKey, fileValueRefreshKey, endpoints.getMetadata, httpOperations, t, tComponent]);
129
+ }, [fileIdsKey, fileValueRefreshKey, endpoints.getMetadata, httpOperations, tComponent]);
131
130
  // =========================================================================
132
131
  // NATURE DETECTION (via shared utility from zod-decorators)
133
132
  // =========================================================================
@@ -251,7 +250,7 @@ function DisplayFieldFile({ schema, value, className, fieldName, endpoints, show
251
250
  }
252
251
  // Loading state
253
252
  if (loading) {
254
- const loadingLabel = t('Loading file metadata') ?? 'Loading file metadata';
253
+ const loadingLabel = tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'loading_metadata');
255
254
  return (_jsx(Surface, { asChild: true, emitPolicyVars: false, variant: SurfaceVariant.INSET, children: _jsxs("div", { className: "flex items-center gap-group p-card-sm rounded-md border bg-muted/30", role: "status", "aria-label": loadingLabel, children: [_jsx(Skeleton, { className: "h-6 w-6 rounded" }), _jsxs("div", { className: "flex-1 min-w-0 space-y-1.5", children: [_jsx(Skeleton, { className: "h-4 w-36" }), _jsx(Skeleton, { className: "h-3 w-20" })] })] }) }));
256
255
  }
257
256
  // Error state
@@ -261,7 +260,7 @@ function DisplayFieldFile({ schema, value, className, fieldName, endpoints, show
261
260
  // No metadata available yet — keep the UI neutral instead of exposing
262
261
  // internal file identifiers while metadata is loading or unavailable.
263
262
  if (metadataEntries.length === 0) {
264
- return (_jsxs("div", { className: "flex items-center gap-element text-muted-foreground", children: [_jsx("span", { "aria-hidden": "true", children: renderIcon(StandardIconReference.FILE, { size: IconSize.SM }) }), _jsx(Text, { className: "text-sm", children: getNeutralFileDisplayLabel(value, t) })] }));
263
+ return (_jsxs("div", { className: "flex items-center gap-element text-muted-foreground", children: [_jsx("span", { "aria-hidden": "true", children: renderIcon(StandardIconReference.FILE, { size: IconSize.SM }) }), _jsx(Text, { className: "text-sm", children: getNeutralFileDisplayLabel(value, tComponent) })] }));
265
264
  }
266
265
  // Multiple files — gallery or individual cards
267
266
  if (isMultiple || metadataEntries.length > 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-file.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldFile Component\n *\n * Root display component for file fields. Acts as both:\n * 1. Metadata fetcher — loads file metadata from server via authenticated httpOperations\n * 2. Nature router — delegates rendering to nature-specific display components\n *\n * Nature routing priority:\n * 1. Schema metadata `fileConfig.nature` (explicit, from z_file({ nature: FileNature.IMAGE }))\n * 2. Fetched metadata MIME type detection (from server response)\n * 3. Generic file card (fallback for unknown types / archives)\n *\n * For multiple images → gallery display. For mixed multiple → individual cards.\n *\n * Nature-specific sub-components are imported directly within this preset.\n * Custom apps can override the entire file display by registering a new preset\n * for LOW_LEVEL_DISPLAY_FIELD_FILE, or override individual nature renderers\n * by registering for LOW_LEVEL_DISPLAY_FIELD_FILE_IMAGE etc. at the wrapper level.\n */\n\nimport * as React from \"react\"\nimport {\n Text,\n Skeleton,\n DisplayFieldFileImage,\n DisplayFieldFileVideo,\n DisplayFieldFileAudio,\n DisplayFieldFileDocument,\n DisplayFieldFileGallery,\n useIconRegistry,\n StandardIconReference,\n IconSize,\n useI18n,\n Surface,\n DisplayFieldFileProps,\n useFileActivation,\n envLoader,\n useOptionalDisplayTemplateContext,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from '@wildo-ai/saas-frontend-lib';\n\nimport { FrontendComponentType, SurfaceVariant } from \"@wildo-ai/presets-components-models\"\nimport { resolveInvalidLabel } from \"./display-field-i18n.utils\"\nimport {\n FileValue,\n SingleFileValue,\n MultipleFileValue,\n FileMetadata,\n FileFieldEndpoints,\n FileDisplayNature,\n FileDisplayPresentation,\n resolveFileDisplayNature,\n resolveFileDisplayPolicy,\n getFileMetadata as getFileSchemaMetadata,\n getFieldUIDisplayConfig,\n type FileUIDisplayParams,\n formatFileSize,\n} from \"@wildo-ai/zod-decorators\"\n\ntype FileMetadataEntry = {\n fileId: string\n refreshKey: string\n metadata: FileMetadata\n}\n\n/** Type guard to check if value is a single file */\nfunction isSingleFileValue(value: FileValue | null | undefined): value is SingleFileValue {\n return value !== null && value !== undefined && 'fileId' in value;\n}\n\n/** Type guard to check if value is multiple files */\nfunction isMultipleFileValue(value: FileValue | null | undefined): value is MultipleFileValue {\n return value !== null && value !== undefined && 'fileIds' in value;\n}\n\nfunction getNeutralFileDisplayLabel(\n value: FileValue,\n t: (key: string, params?: Record<string, unknown>) => string | undefined,\n): string {\n if (isSingleFileValue(value)) {\n return t('File attached') ?? 'File attached'\n }\n\n const fileCount = value.fileIds.length\n const translatedMultipleLabel = t('Files attached', { count: fileCount })\n return fileCount > 1\n ? (\n translatedMultipleLabel && translatedMultipleLabel !== 'Files attached'\n ? translatedMultipleLabel\n : `${fileCount} files attached`\n )\n : (t('File attached') ?? 'File attached')\n}\n\nfunction getFileValueRefreshKey(value: FileValue | null | undefined): string {\n if (!value || typeof value !== 'object' || !('updatedAt' in value)) {\n return ''\n }\n\n const updatedAt = value.updatedAt\n return updatedAt instanceof Date ? updatedAt.toISOString() : String(updatedAt)\n}\n\n/**\n * DisplayFieldFile component\n *\n * Renders a file reference with:\n * - Filename with link\n * - File size\n * - File type icon/badge\n * - Download option\n */\nfunction DisplayFieldFile({\n schema,\n value,\n className,\n fieldName,\n endpoints,\n showSize = true,\n showType = true,\n showDownload = true,\n httpOperations,\n}: DisplayFieldFileProps): React.JSX.Element | null {\n const { renderIcon } = useIconRegistry()\n const { t, tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_FORM_FIELD_FILE, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE] })\n const fileSchemaMetadata = getFileSchemaMetadata(schema)\n const isMultiple = fileSchemaMetadata?.multiple ?? false\n\n // State for loaded metadata (single file or array of files)\n const [metadataEntries, setMetadataEntries] = React.useState<FileMetadataEntry[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n\n // Get file IDs from value (handles both single and multiple)\n const fileIds = React.useMemo(() => {\n if (isSingleFileValue(value)) {\n return [value.fileId];\n }\n if (isMultipleFileValue(value)) {\n return value.fileIds;\n }\n return [];\n }, [value]);\n\n // Stable key for dependency tracking (avoids inline .join() in useEffect deps)\n const fileIdsKey = React.useMemo(() => fileIds.join(','), [fileIds]);\n const fileValueRefreshKey = React.useMemo(() => getFileValueRefreshKey(value), [value]);\n\n // Fetch metadata when value changes\n React.useEffect(() => {\n // Derive IDs from the key to keep closure and dependency in sync\n const currentFileIds = fileIdsKey ? fileIdsKey.split(',') : []\n\n if (currentFileIds.length === 0 || !endpoints.getMetadata) {\n setMetadataEntries([])\n return\n }\n\n let cancelled = false\n setLoading(true)\n setError(null)\n\n const fetchAllMetadata = async () => {\n try {\n const settledResults = await Promise.allSettled(\n currentFileIds.map(async (fileId) => {\n const metadataUrl = `${endpoints.getMetadata}/${encodeURIComponent(fileId)}/metadata`\n\n // Use authenticated HTTP operations when available (injected by engine wrapper).\n // Falls back to raw fetch for standalone usage without resource context.\n if (httpOperations) {\n return httpOperations.get<FileMetadata>(metadataUrl)\n }\n\n // Fallback: raw fetch with cookie credentials (standalone usage)\n const response = await fetch(metadataUrl, { credentials: 'include' })\n if (!response.ok) {\n throw new Error('Failed to fetch file metadata')\n }\n return response.json() as Promise<FileMetadata>\n })\n )\n\n const successfulEntries: FileMetadataEntry[] = settledResults.flatMap((result, index) => (\n result.status === 'fulfilled'\n ? [{ fileId: currentFileIds[index]!, refreshKey: fileValueRefreshKey, metadata: result.value }]\n : []\n ))\n\n if (!cancelled) {\n setMetadataEntries(successfulEntries)\n setError(\n successfulEntries.length === 0 && settledResults.some(result => result.status === 'rejected')\n ? tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'metadataLoadFailed')\n : null\n )\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n fetchAllMetadata()\n return () => { cancelled = true }\n }, [fileIdsKey, fileValueRefreshKey, endpoints.getMetadata, httpOperations, t, tComponent])\n\n // =========================================================================\n // NATURE DETECTION (via shared utility from zod-decorators)\n // =========================================================================\n\n const schemaNature = fileSchemaMetadata?.nature\n\n // The authored file display policy: `presentation` (resting: card / thumbnail /\n // full) x `activation` (click: none / overlay / download / new tab / custom).\n // Resolution is per FILE, not per field, because the runtime guard tier needs the\n // actual MIME: a field declaring the open `FileNature.ALL` can hold something no\n // displayer can render, and the policy then degrades deterministically rather\n // than rendering a blank frame or a dead click.\n const displayConfig = getFieldUIDisplayConfig(schema) as FileUIDisplayParams | undefined\n\n // CUSTOM activation targets an OPERATION on the owning resource; only the\n // resource-aware host can dispatch it, so it arrives opaquely through the display\n // template context (same ownership split as `hiddenFieldNames`).\n const displayTemplateCtx = useOptionalDisplayTemplateContext()\n const onFileActivationOperation = displayTemplateCtx?.onFileActivationOperation\n\n // Overlay host for `FileActivationPolicy.OVERLAY` — one host for every nature,\n // replacing the old image-only lightbox.\n const [overlayFileId, setOverlayFileId] = React.useState<string | null>(null)\n\n // =========================================================================\n // FILE ICON MAPPING (for generic card fallback)\n // =========================================================================\n\n const getFileIconRef = (mimeType?: string): StandardIconReference => {\n if (!mimeType) return StandardIconReference.FILE\n if (mimeType.startsWith('image/')) return StandardIconReference.FILE_IMAGE\n if (mimeType.startsWith('video/')) return StandardIconReference.FILE_VIDEO\n if (mimeType.startsWith('audio/')) return StandardIconReference.FILE_AUDIO\n if (mimeType === 'application/pdf') return StandardIconReference.FILE_TEXT\n if (mimeType.includes('spreadsheet') || mimeType.includes('excel')) return StandardIconReference.FILE_SPREADSHEET\n if (mimeType.includes('presentation') || mimeType.includes('powerpoint')) return StandardIconReference.FILE_PRESENTATION\n if (mimeType.includes('document') || mimeType.includes('word')) return StandardIconReference.FILE_TEXT\n if (mimeType.includes('zip') || mimeType.includes('rar') || mimeType.includes('7z')) return StandardIconReference.FILE_ARCHIVE\n return StandardIconReference.FILE\n }\n\n // =========================================================================\n // NATURE-AWARE RENDERING\n // =========================================================================\n\n /**\n * Render a single file with nature-aware component selection.\n * Delegates to the appropriate nature-specific display preset,\n * falling back to the generic file card for unknown/archive types.\n */\n const renderNatureAwareFile = (metadata: FileMetadata, fileId: string, refreshKey: string): React.ReactNode => {\n const policy = resolveFileDisplayPolicy({ schemaNature, mimeType: metadata.mimeType, authored: displayConfig })\n\n if (policy.degraded && envLoader.isDevelopment()) {\n // Loud in dev, silent in prod: the authored policy was unsatisfiable for THIS\n // file. Only reachable under an open declared nature — a narrow one that cannot\n // display is refused at registry build.\n console.warn(\n `[DisplayFieldFile] \"${fieldName ?? \"(unnamed field)\"}\": authored file display policy degraded — ${policy.degradationReason}.`,\n )\n }\n\n // CARD presentation short-circuits every nature: the neutral card IS the resting\n // render, and the media (if any) is reachable through the activation policy.\n const body = policy.presentation === FileDisplayPresentation.CARD\n ? renderGenericFileItem(metadata, fileId)\n : renderNatureMedia(metadata, fileId, refreshKey, policy.presentation, policy.displayNature)\n\n return (\n <FileActivationBoundary\n key={`${fileId}:${refreshKey}`}\n activation={policy.activation}\n metadata={metadata}\n fileId={fileId}\n fieldName={fieldName ?? ''}\n getBlob={httpOperations?.getBlob}\n onOperationRequested={onFileActivationOperation}\n onOverlayRequested={() => setOverlayFileId(fileId)}\n activateLabel={metadata.filename}\n >\n {body}\n </FileActivationBoundary>\n )\n }\n\n /**\n * Render the media itself for a THUMBNAIL / FULL presentation. Nature displayers\n * own how their medium looks; the presentation tier tells them how large a claim\n * on the layout they may make.\n */\n const renderNatureMedia = (\n metadata: FileMetadata,\n fileId: string,\n refreshKey: string,\n presentation: FileDisplayPresentation,\n nature: FileDisplayNature,\n ): React.ReactNode => {\n switch (nature) {\n case FileDisplayNature.IMAGE:\n return (\n <DisplayFieldFileImage\n metadata={metadata}\n fileId={fileId}\n serveUrl={endpoints.serve ? `${endpoints.serve}/${encodeURIComponent(fileId)}` : undefined}\n getBlob={httpOperations?.getBlob}\n previewOptions={displayConfig?.preview}\n presentation={presentation}\n showDownload={showDownload}\n showSize={showSize}\n />\n )\n\n case FileDisplayNature.VIDEO:\n return <DisplayFieldFileVideo metadata={metadata} fileId={fileId} showDownload={showDownload} showSize={showSize} />\n\n case FileDisplayNature.AUDIO:\n return <DisplayFieldFileAudio metadata={metadata} fileId={fileId} showDownload={showDownload} showSize={showSize} />\n\n case FileDisplayNature.DOCUMENT:\n return (\n <DisplayFieldFileDocument\n metadata={metadata}\n fileId={fileId}\n refreshKey={refreshKey}\n presentation={presentation}\n serveUrl={endpoints.serve ? `${endpoints.serve}/${encodeURIComponent(fileId)}` : undefined}\n getBlob={httpOperations?.getBlob}\n showDownload={showDownload}\n showSize={showSize}\n />\n )\n\n default:\n return renderGenericFileItem(metadata, fileId)\n }\n }\n\n /** Render a generic file card (used for archives, unknown types, and as fallback) */\n const renderGenericFileItem = (metadata: FileMetadata, fileId: string): React.ReactNode => {\n const fileIconRef = getFileIconRef(metadata.mimeType)\n\n return (\n <Surface key={fileId} asChild emitPolicyVars={false} variant={SurfaceVariant.INSET}>\n <div className=\"flex items-center gap-group p-card-sm rounded-md border bg-muted/30\">\n {/* File icon (decorative — filename provides the meaningful content) */}\n <span aria-hidden=\"true\">{renderIcon(fileIconRef, { size: IconSize.LG, className: \"text-muted-foreground\" })}</span>\n\n {/* File info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-element\">\n {metadata.url && showDownload ? (\n <a\n href={metadata.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-primary hover:underline truncate\"\n >\n {metadata.filename}\n </a>\n ) : (\n <Text className=\"font-medium truncate\">{metadata.filename}</Text>\n )}\n </div>\n\n {/* Meta info */}\n <div className=\"flex items-center gap-group text-xs text-muted-foreground mt-0.5\">\n {showSize && metadata.size !== undefined && (\n <span>{formatFileSize(metadata.size)}</span>\n )}\n {showType && metadata.mimeType && (\n <span className=\"uppercase\">{metadata.extension || metadata.mimeType.split('/').pop()}</span>\n )}\n </div>\n </div>\n\n {/* Thumbnail for images (in generic mode — for mixed content lists) */}\n {metadata.thumbnailUrl && metadata.mimeType?.startsWith('image/') && (\n <img\n src={metadata.thumbnailUrl}\n alt={metadata.filename}\n className=\"h-12 w-12 rounded object-cover\"\n />\n )}\n </div>\n </Surface>\n )\n }\n\n // =========================================================================\n // MULTI-FILE GALLERY DETECTION\n // =========================================================================\n\n /**\n * Check if multiple files should be rendered as a gallery.\n * Conditions: multiple mode + all files are images (by schema nature or MIME detection).\n */\n const shouldRenderGallery = React.useMemo(() => {\n if (metadataEntries.length <= 1) return false\n\n // Schema declares IMAGE nature — always gallery for multiple\n if (resolveFileDisplayNature(schemaNature) === FileDisplayNature.IMAGE) return true\n\n // All fetched files are images — auto-gallery\n return metadataEntries.every(({ metadata }) => metadata.mimeType?.startsWith('image/'))\n }, [metadataEntries, schemaNature])\n\n const invalidLabel = React.useMemo(\n () => resolveInvalidLabel(tComponent, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE),\n [tComponent]\n )\n\n // =========================================================================\n // RENDER\n // =========================================================================\n\n if (!isReady) return null\n\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // Handle invalid value\n if (typeof value !== 'object' || (!('fileId' in value) && !('fileIds' in value))) {\n return <Text className=\"text-muted-foreground italic\">{invalidLabel}</Text>\n }\n\n // Loading state\n if (loading) {\n const loadingLabel = t('Loading file metadata') ?? 'Loading file metadata'\n return (\n <Surface asChild emitPolicyVars={false} variant={SurfaceVariant.INSET}>\n <div className=\"flex items-center gap-group p-card-sm rounded-md border bg-muted/30\" role=\"status\" aria-label={loadingLabel}>\n <Skeleton className=\"h-6 w-6 rounded\" />\n <div className=\"flex-1 min-w-0 space-y-1.5\">\n <Skeleton className=\"h-4 w-36\" />\n <Skeleton className=\"h-3 w-20\" />\n </div>\n </div>\n </Surface>\n )\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center gap-element text-destructive\" role=\"alert\">\n <span aria-hidden=\"true\">{renderIcon(StandardIconReference.WARNING, { size: IconSize.SM })}</span>\n <Text className=\"text-sm\">{error}</Text>\n </div>\n )\n }\n\n // No metadata available yet — keep the UI neutral instead of exposing\n // internal file identifiers while metadata is loading or unavailable.\n if (metadataEntries.length === 0) {\n return (\n <div className=\"flex items-center gap-element text-muted-foreground\">\n <span aria-hidden=\"true\">{renderIcon(StandardIconReference.FILE, { size: IconSize.SM })}</span>\n <Text className=\"text-sm\">{getNeutralFileDisplayLabel(value, t)}</Text>\n </div>\n )\n }\n\n // Multiple files — gallery or individual cards\n if (isMultiple || metadataEntries.length > 1) {\n // Gallery for all-image collections\n if (shouldRenderGallery) {\n return (\n <DisplayFieldFileGallery\n metadataList={metadataEntries.map(({ metadata }) => metadata)}\n fileIds={metadataEntries.map(({ fileId }) => fileId)}\n showDownload={showDownload}\n />\n )\n }\n\n // Mixed content or non-image multiple — individual nature-aware cards\n return (\n <div className=\"space-y-item\">\n {metadataEntries.map(({ metadata, fileId, refreshKey }) => renderNatureAwareFile(metadata, fileId, refreshKey))}\n </div>\n )\n }\n\n // Single file — nature-aware rendering\n return renderNatureAwareFile(metadataEntries[0]!.metadata, metadataEntries[0]!.fileId, metadataEntries[0]!.refreshKey)\n }\n\n // Overlay host for OVERLAY activation — ONE host for every nature (it replaces the\n // old image-only lightbox). It renders the file at FULL presentation, which is what\n // \"display it\" means for each medium: a full image, a player, a paginated PDF.\n const overlayEntry = overlayFileId\n ? metadataEntries.find(entry => entry.fileId === overlayFileId)\n : undefined\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return (\n <div className={className}>\n {renderValue()}\n {overlayEntry && (\n <Dialog open onOpenChange={(open) => { if (!open) setOverlayFileId(null) }}>\n <DialogContent className=\"max-w-5xl\">\n <DialogHeader>\n <DialogTitle>{overlayEntry.metadata.filename}</DialogTitle>\n </DialogHeader>\n {renderNatureMedia(\n overlayEntry.metadata,\n overlayEntry.fileId,\n overlayEntry.refreshKey,\n FileDisplayPresentation.FULL,\n resolveFileDisplayNature(schemaNature, overlayEntry.metadata.mimeType),\n )}\n </DialogContent>\n </Dialog>\n )}\n </div>\n )\n}\n\n/**\n * Binds a file's activation policy onto its rendered body.\n *\n * A thin boundary rather than a prop on each nature displayer: every nature gets\n * identical click/keyboard semantics, and a displayer stays free to be purely\n * presentational. When the policy is inert (NONE, or means unavailable) the body is\n * returned untouched — no affordance, no focus stop, no lie about interactivity.\n */\nfunction FileActivationBoundary({\n activation,\n metadata,\n fileId,\n fieldName,\n getBlob,\n onOperationRequested,\n onOverlayRequested,\n activateLabel,\n children,\n}: {\n activation: React.ComponentProps<typeof DisplayFieldFile> extends never ? never : Parameters<typeof useFileActivation>[0]['activation']\n metadata: FileMetadata\n fileId: string\n fieldName: string\n getBlob?: (url: string) => Promise<Blob>\n onOperationRequested?: Parameters<typeof useFileActivation>[0]['onOperationRequested']\n onOverlayRequested?: () => void\n activateLabel?: string\n children: React.ReactNode\n}): React.JSX.Element {\n const { interactive, activationProps } = useFileActivation({\n activation,\n metadata,\n fileId,\n fieldName,\n getBlob,\n onOperationRequested,\n onOverlayRequested,\n ariaLabel: activateLabel,\n })\n\n if (!interactive) return <>{children}</>\n\n return (\n <div\n {...activationProps}\n data-slot=\"file-activation\"\n className=\"cursor-pointer rounded-md focus-ring-offset outline-none\"\n >\n {children}\n </div>\n )\n}\n\n;(DisplayFieldFile as typeof DisplayFieldFile & { displayName: string }).displayName = \"DisplayFieldFile\"\n\nexport { DisplayFieldFile }\n\n"]}
1
+ {"version":3,"file":"display-field-file.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldFile Component\n *\n * Root display component for file fields. Acts as both:\n * 1. Metadata fetcher — loads file metadata from server via authenticated httpOperations\n * 2. Nature router — delegates rendering to nature-specific display components\n *\n * Nature routing priority:\n * 1. Schema metadata `fileConfig.nature` (explicit, from z_file({ nature: FileNature.IMAGE }))\n * 2. Fetched metadata MIME type detection (from server response)\n * 3. Generic file card (fallback for unknown types / archives)\n *\n * For multiple images → gallery display. For mixed multiple → individual cards.\n *\n * Nature-specific sub-components are imported directly within this preset.\n * Custom apps can override the entire file display by registering a new preset\n * for LOW_LEVEL_DISPLAY_FIELD_FILE, or override individual nature renderers\n * by registering for LOW_LEVEL_DISPLAY_FIELD_FILE_IMAGE etc. at the wrapper level.\n */\n\nimport * as React from \"react\"\nimport {\n Text,\n Skeleton,\n DisplayFieldFileImage,\n DisplayFieldFileVideo,\n DisplayFieldFileAudio,\n DisplayFieldFileDocument,\n DisplayFieldFileGallery,\n useIconRegistry,\n StandardIconReference,\n IconSize,\n useI18n,\n Surface,\n DisplayFieldFileProps,\n useFileActivation,\n envLoader,\n useOptionalDisplayTemplateContext,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from '@wildo-ai/saas-frontend-lib';\n\nimport { FrontendComponentType, SurfaceVariant } from \"@wildo-ai/presets-components-models\"\nimport { resolveInvalidLabel } from \"./display-field-i18n.utils\"\nimport {\n FileValue,\n SingleFileValue,\n MultipleFileValue,\n FileMetadata,\n FileFieldEndpoints,\n FileDisplayNature,\n FileDisplayPresentation,\n resolveFileDisplayNature,\n resolveFileDisplayPolicy,\n getFileMetadata as getFileSchemaMetadata,\n getFieldUIDisplayConfig,\n type FileUIDisplayParams,\n formatFileSize,\n} from \"@wildo-ai/zod-decorators\"\n\ntype FileMetadataEntry = {\n fileId: string\n refreshKey: string\n metadata: FileMetadata\n}\n\n/** Type guard to check if value is a single file */\nfunction isSingleFileValue(value: FileValue | null | undefined): value is SingleFileValue {\n return value !== null && value !== undefined && 'fileId' in value;\n}\n\n/** Type guard to check if value is multiple files */\nfunction isMultipleFileValue(value: FileValue | null | undefined): value is MultipleFileValue {\n return value !== null && value !== undefined && 'fileIds' in value;\n}\n\n/**\n * The neutral name shown for attached files whose details are unavailable. Every word comes from this\n * component's labels (#1557): it used to look up English sentences through the plain `t`, with an\n * English fallback and a count sentence built in code, none of which a translator could reach.\n */\nfunction getNeutralFileDisplayLabel(\n value: FileValue,\n tComponent: (componentType: FrontendComponentType, key: string, params?: Record<string, string | number>) => string,\n): string {\n const fileCount = isSingleFileValue(value) ? 1 : value.fileIds.length\n return fileCount > 1\n ? tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'files_count', { count: fileCount })\n : tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'file_attached')\n}\n\nfunction getFileValueRefreshKey(value: FileValue | null | undefined): string {\n if (!value || typeof value !== 'object' || !('updatedAt' in value)) {\n return ''\n }\n\n const updatedAt = value.updatedAt\n return updatedAt instanceof Date ? updatedAt.toISOString() : String(updatedAt)\n}\n\n/**\n * DisplayFieldFile component\n *\n * Renders a file reference with:\n * - Filename with link\n * - File size\n * - File type icon/badge\n * - Download option\n */\nfunction DisplayFieldFile({\n schema,\n value,\n className,\n fieldName,\n endpoints,\n showSize = true,\n showType = true,\n showDownload = true,\n httpOperations,\n}: DisplayFieldFileProps): React.JSX.Element | null {\n const { renderIcon } = useIconRegistry()\n const { tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_FORM_FIELD_FILE, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE] })\n const fileSchemaMetadata = getFileSchemaMetadata(schema)\n const isMultiple = fileSchemaMetadata?.multiple ?? false\n\n // State for loaded metadata (single file or array of files)\n const [metadataEntries, setMetadataEntries] = React.useState<FileMetadataEntry[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n\n // Get file IDs from value (handles both single and multiple)\n const fileIds = React.useMemo(() => {\n if (isSingleFileValue(value)) {\n return [value.fileId];\n }\n if (isMultipleFileValue(value)) {\n return value.fileIds;\n }\n return [];\n }, [value]);\n\n // Stable key for dependency tracking (avoids inline .join() in useEffect deps)\n const fileIdsKey = React.useMemo(() => fileIds.join(','), [fileIds]);\n const fileValueRefreshKey = React.useMemo(() => getFileValueRefreshKey(value), [value]);\n\n // Fetch metadata when value changes\n React.useEffect(() => {\n // Derive IDs from the key to keep closure and dependency in sync\n const currentFileIds = fileIdsKey ? fileIdsKey.split(',') : []\n\n if (currentFileIds.length === 0 || !endpoints.getMetadata) {\n setMetadataEntries([])\n return\n }\n\n let cancelled = false\n setLoading(true)\n setError(null)\n\n const fetchAllMetadata = async () => {\n try {\n const settledResults = await Promise.allSettled(\n currentFileIds.map(async (fileId) => {\n const metadataUrl = `${endpoints.getMetadata}/${encodeURIComponent(fileId)}/metadata`\n\n // Use authenticated HTTP operations when available (injected by engine wrapper).\n // Falls back to raw fetch for standalone usage without resource context.\n if (httpOperations) {\n return httpOperations.get<FileMetadata>(metadataUrl)\n }\n\n // Fallback: raw fetch with cookie credentials (standalone usage)\n const response = await fetch(metadataUrl, { credentials: 'include' })\n if (!response.ok) {\n throw new Error('Failed to fetch file metadata')\n }\n return response.json() as Promise<FileMetadata>\n })\n )\n\n const successfulEntries: FileMetadataEntry[] = settledResults.flatMap((result, index) => (\n result.status === 'fulfilled'\n ? [{ fileId: currentFileIds[index]!, refreshKey: fileValueRefreshKey, metadata: result.value }]\n : []\n ))\n\n if (!cancelled) {\n setMetadataEntries(successfulEntries)\n setError(\n successfulEntries.length === 0 && settledResults.some(result => result.status === 'rejected')\n ? tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'metadataLoadFailed')\n : null\n )\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n fetchAllMetadata()\n return () => { cancelled = true }\n }, [fileIdsKey, fileValueRefreshKey, endpoints.getMetadata, httpOperations, tComponent])\n\n // =========================================================================\n // NATURE DETECTION (via shared utility from zod-decorators)\n // =========================================================================\n\n const schemaNature = fileSchemaMetadata?.nature\n\n // The authored file display policy: `presentation` (resting: card / thumbnail /\n // full) x `activation` (click: none / overlay / download / new tab / custom).\n // Resolution is per FILE, not per field, because the runtime guard tier needs the\n // actual MIME: a field declaring the open `FileNature.ALL` can hold something no\n // displayer can render, and the policy then degrades deterministically rather\n // than rendering a blank frame or a dead click.\n const displayConfig = getFieldUIDisplayConfig(schema) as FileUIDisplayParams | undefined\n\n // CUSTOM activation targets an OPERATION on the owning resource; only the\n // resource-aware host can dispatch it, so it arrives opaquely through the display\n // template context (same ownership split as `hiddenFieldNames`).\n const displayTemplateCtx = useOptionalDisplayTemplateContext()\n const onFileActivationOperation = displayTemplateCtx?.onFileActivationOperation\n\n // Overlay host for `FileActivationPolicy.OVERLAY` — one host for every nature,\n // replacing the old image-only lightbox.\n const [overlayFileId, setOverlayFileId] = React.useState<string | null>(null)\n\n // =========================================================================\n // FILE ICON MAPPING (for generic card fallback)\n // =========================================================================\n\n const getFileIconRef = (mimeType?: string): StandardIconReference => {\n if (!mimeType) return StandardIconReference.FILE\n if (mimeType.startsWith('image/')) return StandardIconReference.FILE_IMAGE\n if (mimeType.startsWith('video/')) return StandardIconReference.FILE_VIDEO\n if (mimeType.startsWith('audio/')) return StandardIconReference.FILE_AUDIO\n if (mimeType === 'application/pdf') return StandardIconReference.FILE_TEXT\n if (mimeType.includes('spreadsheet') || mimeType.includes('excel')) return StandardIconReference.FILE_SPREADSHEET\n if (mimeType.includes('presentation') || mimeType.includes('powerpoint')) return StandardIconReference.FILE_PRESENTATION\n if (mimeType.includes('document') || mimeType.includes('word')) return StandardIconReference.FILE_TEXT\n if (mimeType.includes('zip') || mimeType.includes('rar') || mimeType.includes('7z')) return StandardIconReference.FILE_ARCHIVE\n return StandardIconReference.FILE\n }\n\n // =========================================================================\n // NATURE-AWARE RENDERING\n // =========================================================================\n\n /**\n * Render a single file with nature-aware component selection.\n * Delegates to the appropriate nature-specific display preset,\n * falling back to the generic file card for unknown/archive types.\n */\n const renderNatureAwareFile = (metadata: FileMetadata, fileId: string, refreshKey: string): React.ReactNode => {\n const policy = resolveFileDisplayPolicy({ schemaNature, mimeType: metadata.mimeType, authored: displayConfig })\n\n if (policy.degraded && envLoader.isDevelopment()) {\n // Loud in dev, silent in prod: the authored policy was unsatisfiable for THIS\n // file. Only reachable under an open declared nature — a narrow one that cannot\n // display is refused at registry build.\n console.warn(\n `[DisplayFieldFile] \"${fieldName ?? \"(unnamed field)\"}\": authored file display policy degraded — ${policy.degradationReason}.`,\n )\n }\n\n // CARD presentation short-circuits every nature: the neutral card IS the resting\n // render, and the media (if any) is reachable through the activation policy.\n const body = policy.presentation === FileDisplayPresentation.CARD\n ? renderGenericFileItem(metadata, fileId)\n : renderNatureMedia(metadata, fileId, refreshKey, policy.presentation, policy.displayNature)\n\n return (\n <FileActivationBoundary\n key={`${fileId}:${refreshKey}`}\n activation={policy.activation}\n metadata={metadata}\n fileId={fileId}\n fieldName={fieldName ?? ''}\n getBlob={httpOperations?.getBlob}\n onOperationRequested={onFileActivationOperation}\n onOverlayRequested={() => setOverlayFileId(fileId)}\n activateLabel={metadata.filename}\n >\n {body}\n </FileActivationBoundary>\n )\n }\n\n /**\n * Render the media itself for a THUMBNAIL / FULL presentation. Nature displayers\n * own how their medium looks; the presentation tier tells them how large a claim\n * on the layout they may make.\n */\n const renderNatureMedia = (\n metadata: FileMetadata,\n fileId: string,\n refreshKey: string,\n presentation: FileDisplayPresentation,\n nature: FileDisplayNature,\n ): React.ReactNode => {\n switch (nature) {\n case FileDisplayNature.IMAGE:\n return (\n <DisplayFieldFileImage\n metadata={metadata}\n fileId={fileId}\n serveUrl={endpoints.serve ? `${endpoints.serve}/${encodeURIComponent(fileId)}` : undefined}\n getBlob={httpOperations?.getBlob}\n previewOptions={displayConfig?.preview}\n presentation={presentation}\n showDownload={showDownload}\n showSize={showSize}\n />\n )\n\n case FileDisplayNature.VIDEO:\n return <DisplayFieldFileVideo metadata={metadata} fileId={fileId} showDownload={showDownload} showSize={showSize} />\n\n case FileDisplayNature.AUDIO:\n return <DisplayFieldFileAudio metadata={metadata} fileId={fileId} showDownload={showDownload} showSize={showSize} />\n\n case FileDisplayNature.DOCUMENT:\n return (\n <DisplayFieldFileDocument\n metadata={metadata}\n fileId={fileId}\n refreshKey={refreshKey}\n presentation={presentation}\n serveUrl={endpoints.serve ? `${endpoints.serve}/${encodeURIComponent(fileId)}` : undefined}\n getBlob={httpOperations?.getBlob}\n showDownload={showDownload}\n showSize={showSize}\n />\n )\n\n default:\n return renderGenericFileItem(metadata, fileId)\n }\n }\n\n /** Render a generic file card (used for archives, unknown types, and as fallback) */\n const renderGenericFileItem = (metadata: FileMetadata, fileId: string): React.ReactNode => {\n const fileIconRef = getFileIconRef(metadata.mimeType)\n\n return (\n <Surface key={fileId} asChild emitPolicyVars={false} variant={SurfaceVariant.INSET}>\n <div className=\"flex items-center gap-group p-card-sm rounded-md border bg-muted/30\">\n {/* File icon (decorative — filename provides the meaningful content) */}\n <span aria-hidden=\"true\">{renderIcon(fileIconRef, { size: IconSize.LG, className: \"text-muted-foreground\" })}</span>\n\n {/* File info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-element\">\n {metadata.url && showDownload ? (\n <a\n href={metadata.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-primary hover:underline truncate\"\n >\n {metadata.filename}\n </a>\n ) : (\n <Text className=\"font-medium truncate\">{metadata.filename}</Text>\n )}\n </div>\n\n {/* Meta info */}\n <div className=\"flex items-center gap-group text-xs text-muted-foreground mt-0.5\">\n {showSize && metadata.size !== undefined && (\n <span>{formatFileSize(metadata.size)}</span>\n )}\n {showType && metadata.mimeType && (\n <span className=\"uppercase\">{metadata.extension || metadata.mimeType.split('/').pop()}</span>\n )}\n </div>\n </div>\n\n {/* Thumbnail for images (in generic mode — for mixed content lists) */}\n {metadata.thumbnailUrl && metadata.mimeType?.startsWith('image/') && (\n <img\n src={metadata.thumbnailUrl}\n alt={metadata.filename}\n className=\"h-12 w-12 rounded object-cover\"\n />\n )}\n </div>\n </Surface>\n )\n }\n\n // =========================================================================\n // MULTI-FILE GALLERY DETECTION\n // =========================================================================\n\n /**\n * Check if multiple files should be rendered as a gallery.\n * Conditions: multiple mode + all files are images (by schema nature or MIME detection).\n */\n const shouldRenderGallery = React.useMemo(() => {\n if (metadataEntries.length <= 1) return false\n\n // Schema declares IMAGE nature — always gallery for multiple\n if (resolveFileDisplayNature(schemaNature) === FileDisplayNature.IMAGE) return true\n\n // All fetched files are images — auto-gallery\n return metadataEntries.every(({ metadata }) => metadata.mimeType?.startsWith('image/'))\n }, [metadataEntries, schemaNature])\n\n const invalidLabel = React.useMemo(\n () => resolveInvalidLabel(tComponent, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE),\n [tComponent]\n )\n\n // =========================================================================\n // RENDER\n // =========================================================================\n\n if (!isReady) return null\n\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // Handle invalid value\n if (typeof value !== 'object' || (!('fileId' in value) && !('fileIds' in value))) {\n return <Text className=\"text-muted-foreground italic\">{invalidLabel}</Text>\n }\n\n // Loading state\n if (loading) {\n const loadingLabel = tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, 'loading_metadata')\n return (\n <Surface asChild emitPolicyVars={false} variant={SurfaceVariant.INSET}>\n <div className=\"flex items-center gap-group p-card-sm rounded-md border bg-muted/30\" role=\"status\" aria-label={loadingLabel}>\n <Skeleton className=\"h-6 w-6 rounded\" />\n <div className=\"flex-1 min-w-0 space-y-1.5\">\n <Skeleton className=\"h-4 w-36\" />\n <Skeleton className=\"h-3 w-20\" />\n </div>\n </div>\n </Surface>\n )\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center gap-element text-destructive\" role=\"alert\">\n <span aria-hidden=\"true\">{renderIcon(StandardIconReference.WARNING, { size: IconSize.SM })}</span>\n <Text className=\"text-sm\">{error}</Text>\n </div>\n )\n }\n\n // No metadata available yet — keep the UI neutral instead of exposing\n // internal file identifiers while metadata is loading or unavailable.\n if (metadataEntries.length === 0) {\n return (\n <div className=\"flex items-center gap-element text-muted-foreground\">\n <span aria-hidden=\"true\">{renderIcon(StandardIconReference.FILE, { size: IconSize.SM })}</span>\n <Text className=\"text-sm\">{getNeutralFileDisplayLabel(value, tComponent)}</Text>\n </div>\n )\n }\n\n // Multiple files — gallery or individual cards\n if (isMultiple || metadataEntries.length > 1) {\n // Gallery for all-image collections\n if (shouldRenderGallery) {\n return (\n <DisplayFieldFileGallery\n metadataList={metadataEntries.map(({ metadata }) => metadata)}\n fileIds={metadataEntries.map(({ fileId }) => fileId)}\n showDownload={showDownload}\n />\n )\n }\n\n // Mixed content or non-image multiple — individual nature-aware cards\n return (\n <div className=\"space-y-item\">\n {metadataEntries.map(({ metadata, fileId, refreshKey }) => renderNatureAwareFile(metadata, fileId, refreshKey))}\n </div>\n )\n }\n\n // Single file — nature-aware rendering\n return renderNatureAwareFile(metadataEntries[0]!.metadata, metadataEntries[0]!.fileId, metadataEntries[0]!.refreshKey)\n }\n\n // Overlay host for OVERLAY activation — ONE host for every nature (it replaces the\n // old image-only lightbox). It renders the file at FULL presentation, which is what\n // \"display it\" means for each medium: a full image, a player, a paginated PDF.\n const overlayEntry = overlayFileId\n ? metadataEntries.find(entry => entry.fileId === overlayFileId)\n : undefined\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return (\n <div className={className}>\n {renderValue()}\n {overlayEntry && (\n <Dialog open onOpenChange={(open) => { if (!open) setOverlayFileId(null) }}>\n <DialogContent className=\"max-w-5xl\">\n <DialogHeader>\n <DialogTitle>{overlayEntry.metadata.filename}</DialogTitle>\n </DialogHeader>\n {renderNatureMedia(\n overlayEntry.metadata,\n overlayEntry.fileId,\n overlayEntry.refreshKey,\n FileDisplayPresentation.FULL,\n resolveFileDisplayNature(schemaNature, overlayEntry.metadata.mimeType),\n )}\n </DialogContent>\n </Dialog>\n )}\n </div>\n )\n}\n\n/**\n * Binds a file's activation policy onto its rendered body.\n *\n * A thin boundary rather than a prop on each nature displayer: every nature gets\n * identical click/keyboard semantics, and a displayer stays free to be purely\n * presentational. When the policy is inert (NONE, or means unavailable) the body is\n * returned untouched — no affordance, no focus stop, no lie about interactivity.\n */\nfunction FileActivationBoundary({\n activation,\n metadata,\n fileId,\n fieldName,\n getBlob,\n onOperationRequested,\n onOverlayRequested,\n activateLabel,\n children,\n}: {\n activation: React.ComponentProps<typeof DisplayFieldFile> extends never ? never : Parameters<typeof useFileActivation>[0]['activation']\n metadata: FileMetadata\n fileId: string\n fieldName: string\n getBlob?: (url: string) => Promise<Blob>\n onOperationRequested?: Parameters<typeof useFileActivation>[0]['onOperationRequested']\n onOverlayRequested?: () => void\n activateLabel?: string\n children: React.ReactNode\n}): React.JSX.Element {\n const { interactive, activationProps } = useFileActivation({\n activation,\n metadata,\n fileId,\n fieldName,\n getBlob,\n onOperationRequested,\n onOverlayRequested,\n ariaLabel: activateLabel,\n })\n\n if (!interactive) return <>{children}</>\n\n return (\n <div\n {...activationProps}\n data-slot=\"file-activation\"\n className=\"cursor-pointer rounded-md focus-ring-offset outline-none\"\n >\n {children}\n </div>\n )\n}\n\n;(DisplayFieldFile as typeof DisplayFieldFile & { displayName: string }).displayName = \"DisplayFieldFile\"\n\nexport { DisplayFieldFile }\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-file.labels.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,mBAAmB,EAA2B,MAAM,qCAAqC,CAAC;AAM1I,eAAO,MAAM,uBAAuB,EAAE,mBAAmB,EAiBxD,CAAC"}
1
+ {"version":3,"file":"display-field-file.labels.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,mBAAmB,EAA2B,MAAM,qCAAqC,CAAC;AAM1I,eAAO,MAAM,uBAAuB,EAAE,mBAAmB,EAkBxD,CAAC"}
@@ -15,6 +15,7 @@ export const DisplayFieldFile_Labels = [
15
15
  params: [{ key: 'count', meaning: 'number of attached files' }],
16
16
  },
17
17
  { ref: 'no_file', kind: LabelKind.EMPTY_STATE, purpose: 'Shown when the file field has no attachment' },
18
+ { ref: 'file_attached', kind: LabelKind.LABEL, purpose: 'Neutral name shown for one attached file whose details (such as its file name) could not be loaded' },
18
19
  { ref: 'loading_metadata', kind: LabelKind.MESSAGE, purpose: 'Shown while the file metadata is being fetched' },
19
20
  { ref: 'metadata_error', kind: LabelKind.MESSAGE, purpose: 'Shown when the file metadata could not be loaded' },
20
21
  { ref: 'invalid', kind: LabelKind.MESSAGE, purpose: 'Fallback shown in place of a file value that cannot be interpreted as a file reference' },
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-file.labels.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAA4B,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE1I,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,uBAAuB,GAA0B;IAC5D,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,2DAA2D,EAAE;IACzH,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,0DAA0D,EAAE;IACxH,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,wDAAwD,EAAE;IACtH,EAAE,GAAG,EAAE,sBAAsB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,6DAA6D,EAAE;IAC9H,EAAE,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,2EAA2E,EAAE;IAC3I;QACE,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,OAAO,EAAE,qEAAqE;QAC9E,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;KAChE;IACD,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,EAAE,OAAO,EAAE,6CAA6C,EAAE;IACvG,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,gDAAgD,EAAE;IAC/G,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,kDAAkD,EAAE;IAC/G,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,wFAAwF,EAAE;IAC9I,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,qGAAqG,EAAE;CACvK,CAAC;AACF,uBAAuB,CAAC,qBAAqB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { FrontendComponentType, LabelKind, type LabellingUnitaryDef, registerComponentLabels } from '@wildo-ai/presets-components-models';\n\n// Companion-only label metadata for this component: keys + params + (where\n// authored) per-key purpose / kind / variable meaning. Statically scanned by\n// the dev companion; NOT imported at runtime, so it never ships in the bundle.\n\nexport const DisplayFieldFile_Labels: LabellingUnitaryDef[] = [\n { ref: 'file_nature_image', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be an image' },\n { ref: 'file_nature_video', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be a video' },\n { ref: 'file_nature_audio', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be audio' },\n { ref: 'file_nature_document', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be a document' },\n { ref: 'file_nature_generic', kind: LabelKind.LABEL, purpose: 'Kind label shown for any file whose nature is not specifically recognised' },\n {\n ref: 'files_count',\n kind: LabelKind.LABEL,\n purpose: 'Summary of how many files the field holds when several are attached',\n params: [{ key: 'count', meaning: 'number of attached files' }],\n },\n { ref: 'no_file', kind: LabelKind.EMPTY_STATE, purpose: 'Shown when the file field has no attachment' },\n { ref: 'loading_metadata', kind: LabelKind.MESSAGE, purpose: 'Shown while the file metadata is being fetched' },\n { ref: 'metadata_error', kind: LabelKind.MESSAGE, purpose: 'Shown when the file metadata could not be loaded' },\n { ref: 'invalid', kind: LabelKind.MESSAGE, purpose: 'Fallback shown in place of a file value that cannot be interpreted as a file reference' },\n { ref: 'metadataLoadFailed', kind: LabelKind.MESSAGE, purpose: 'Shown on a file field when the details of its attached files (name, size, type) could not be loaded' },\n];\nregisterComponentLabels(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, DisplayFieldFile_Labels);\n"]}
1
+ {"version":3,"file":"display-field-file.labels.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-file.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAA4B,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE1I,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,uBAAuB,GAA0B;IAC5D,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,2DAA2D,EAAE;IACzH,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,0DAA0D,EAAE;IACxH,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,wDAAwD,EAAE;IACtH,EAAE,GAAG,EAAE,sBAAsB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,6DAA6D,EAAE;IAC9H,EAAE,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,2EAA2E,EAAE;IAC3I;QACE,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,OAAO,EAAE,qEAAqE;QAC9E,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;KAChE;IACD,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,EAAE,OAAO,EAAE,6CAA6C,EAAE;IACvG,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,oGAAoG,EAAE;IAC9J,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,gDAAgD,EAAE;IAC/G,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,kDAAkD,EAAE;IAC/G,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,wFAAwF,EAAE;IAC9I,EAAE,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,qGAAqG,EAAE;CACvK,CAAC;AACF,uBAAuB,CAAC,qBAAqB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { FrontendComponentType, LabelKind, type LabellingUnitaryDef, registerComponentLabels } from '@wildo-ai/presets-components-models';\n\n// Companion-only label metadata for this component: keys + params + (where\n// authored) per-key purpose / kind / variable meaning. Statically scanned by\n// the dev companion; NOT imported at runtime, so it never ships in the bundle.\n\nexport const DisplayFieldFile_Labels: LabellingUnitaryDef[] = [\n { ref: 'file_nature_image', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be an image' },\n { ref: 'file_nature_video', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be a video' },\n { ref: 'file_nature_audio', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be audio' },\n { ref: 'file_nature_document', kind: LabelKind.LABEL, purpose: 'Kind label shown when the file is detected to be a document' },\n { ref: 'file_nature_generic', kind: LabelKind.LABEL, purpose: 'Kind label shown for any file whose nature is not specifically recognised' },\n {\n ref: 'files_count',\n kind: LabelKind.LABEL,\n purpose: 'Summary of how many files the field holds when several are attached',\n params: [{ key: 'count', meaning: 'number of attached files' }],\n },\n { ref: 'no_file', kind: LabelKind.EMPTY_STATE, purpose: 'Shown when the file field has no attachment' },\n { ref: 'file_attached', kind: LabelKind.LABEL, purpose: 'Neutral name shown for one attached file whose details (such as its file name) could not be loaded' },\n { ref: 'loading_metadata', kind: LabelKind.MESSAGE, purpose: 'Shown while the file metadata is being fetched' },\n { ref: 'metadata_error', kind: LabelKind.MESSAGE, purpose: 'Shown when the file metadata could not be loaded' },\n { ref: 'invalid', kind: LabelKind.MESSAGE, purpose: 'Fallback shown in place of a file value that cannot be interpreted as a file reference' },\n { ref: 'metadataLoadFailed', kind: LabelKind.MESSAGE, purpose: 'Shown on a file field when the details of its attached files (name, size, type) could not be loaded' },\n];\nregisterComponentLabels(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_FILE, DisplayFieldFile_Labels);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-number.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAG1E;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAM,GACP,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CA6FpD;AAID,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"display-field-number.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAG1E;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAM,GACP,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAmGpD;AAID,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -11,7 +11,8 @@ import { DisplayFieldFormatUtils } from "./display-field-format.utils.js";
11
11
  * Renders a number value according to the number UI decorator
12
12
  */
13
13
  function DisplayFieldNumber({ schema, value, className, locale, }) {
14
- const { regionalPreferences, tComponent, isReady } = useI18n({ component: FrontendComponentType.LOW_LEVEL_FORM_FIELD });
14
+ // The shared field words (`noValue`) and this display's own (`unlimited`, #1851).
15
+ const { regionalPreferences, tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER] });
15
16
  const numberUI = getNumberUI(schema);
16
17
  const displayMode = useContextualDisplayParams(numberUI)?.displayMode ?? NumberDisplayMode.RAW;
17
18
  const decimalPlaces = numberUI?.decimalPlaces;
@@ -33,6 +34,10 @@ function DisplayFieldNumber({ schema, value, className, locale, }) {
33
34
  if (value === null || value === undefined) {
34
35
  return _jsxs(_Fragment, { children: [_jsx(Text, { className: "text-muted-foreground italic", "aria-hidden": "true", children: "\u2014" }), _jsx("span", { className: "sr-only", children: tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue') })] });
35
36
  }
37
+ // A value that means NO LIMIT (`numberUI({ unlimitedAt })`, #1851) is a word, not a quantity: `-1` read as a count.
38
+ if (numberUI?.unlimitedAt !== undefined && value === numberUI.unlimitedAt) {
39
+ return _jsx(Text, { children: tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER, 'unlimited') });
40
+ }
36
41
  // Format the number based on display mode
37
42
  let formattedValue;
38
43
  switch (displayMode) {
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-number.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldNumber Component\n *\n * Displays a number value based on the number UI decorator.\n * Supports different display modes: raw, formatted, percentage, compact, ordinal, bytes\n */\n\nimport * as React from \"react\"\n\nimport { Text, useContextualDisplayParams} from \"@wildo-ai/saas-frontend-lib\"\nimport { useI18n } from \"@wildo-ai/saas-frontend-lib\"\nimport { FrontendComponentType } from \"@wildo-ai/presets-components-models\"\nimport { getNumberUI, NumberDisplayMode, PercentageScale } from \"@wildo-ai/zod-decorators\"\nimport type { DisplayFieldNumberProps } from '@wildo-ai/saas-frontend-lib'\nimport { DisplayFieldFormatUtils } from \"./display-field-format.utils\"\n\n/**\n * DisplayFieldNumber component\n *\n * Renders a number value according to the number UI decorator\n */\nfunction DisplayFieldNumber({\n schema,\n value,\n className,\n locale,\n}: DisplayFieldNumberProps): React.JSX.Element | null {\n const { regionalPreferences, tComponent, isReady } = useI18n({ component: FrontendComponentType.LOW_LEVEL_FORM_FIELD })\n\n const numberUI = getNumberUI(schema)\n const displayMode = useContextualDisplayParams(numberUI)?.displayMode ?? NumberDisplayMode.RAW\n const decimalPlaces = numberUI?.decimalPlaces\n const trailingZeros = numberUI?.trailingZeros ?? false\n const prefix = numberUI?.prefix ?? ''\n const suffix = numberUI?.suffix ?? ''\n const percentageScale = numberUI?.percentageScale ?? PercentageScale.NORMALIZED\n\n // Locale priority: explicit prop > regional preferences > browser locale > fallback.\n // `regionalPreferences` is null until the i18n bundle resolves (`isReady`), and this\n // read runs in the render body BEFORE the `!isReady` gate below — so optional-chain it.\n // Without the `?.`, the first render throws `Cannot read properties of null (reading\n // 'locale')`, the DisplayFieldErrorBoundary catches it, and every number field shows an\n // error box until i18n hydrates. On that first beat the browser-locale fallback applies;\n // the real preference takes over on the next render.\n const effectiveLocale = locale ?? regionalPreferences?.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en')\n\n // Render the value content\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // Format the number based on display mode\n let formattedValue: string\n\n switch (displayMode) {\n case NumberDisplayMode.RAW:\n if (decimalPlaces !== undefined) {\n formattedValue = trailingZeros\n ? value.toFixed(decimalPlaces)\n : parseFloat(value.toFixed(decimalPlaces)).toString()\n } else {\n formattedValue = value.toString()\n }\n break\n\n case NumberDisplayMode.FORMATTED:\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: trailingZeros ? decimalPlaces : undefined,\n maximumFractionDigits: decimalPlaces,\n }).format(value)\n break\n\n case NumberDisplayMode.PERCENTAGE: {\n // Intl.NumberFormat style:'percent' expects a 0–1 value and multiplies by 100.\n // If scale is 'normalized' (default), value is already 0–1 → pass directly.\n // If scale is 'percent', value is 0–100 → divide by 100 first.\n const percentValue = percentageScale === PercentageScale.PERCENT ? value / 100 : value\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n style: 'percent',\n minimumFractionDigits: trailingZeros ? decimalPlaces : undefined,\n maximumFractionDigits: decimalPlaces ?? 0,\n }).format(percentValue)\n break\n }\n\n case NumberDisplayMode.COMPACT:\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: decimalPlaces ?? 1,\n }).format(value)\n break\n\n case NumberDisplayMode.ORDINAL:\n formattedValue = DisplayFieldFormatUtils.formatOrdinal(value, effectiveLocale)\n break\n\n case NumberDisplayMode.BYTES:\n formattedValue = DisplayFieldFormatUtils.formatBytes(value, decimalPlaces ?? 2)\n break\n\n default:\n formattedValue = value.toString()\n }\n\n // Add prefix and suffix\n const displayValue = `${prefix}${formattedValue}${suffix}`\n\n // `tabular-nums` gives fixed-width digits so numeric columns/rows align\n // (matches the money + bigdecimal formatters).\n return <Text className=\"tabular-nums\">{displayValue}</Text>\n }\n\n if (!isReady) return null\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return <div className={className}>{renderValue()}</div>\n}\n\n;(DisplayFieldNumber as typeof DisplayFieldNumber & { displayName: string }).displayName = \"DisplayFieldNumber\"\n\nexport { DisplayFieldNumber }\n"]}
1
+ {"version":3,"file":"display-field-number.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\n/**\n * DisplayFieldNumber Component\n *\n * Displays a number value based on the number UI decorator.\n * Supports different display modes: raw, formatted, percentage, compact, ordinal, bytes\n */\n\nimport * as React from \"react\"\n\nimport { Text, useContextualDisplayParams} from \"@wildo-ai/saas-frontend-lib\"\nimport { useI18n } from \"@wildo-ai/saas-frontend-lib\"\nimport { FrontendComponentType } from \"@wildo-ai/presets-components-models\"\nimport { getNumberUI, NumberDisplayMode, PercentageScale } from \"@wildo-ai/zod-decorators\"\nimport type { DisplayFieldNumberProps } from '@wildo-ai/saas-frontend-lib'\nimport { DisplayFieldFormatUtils } from \"./display-field-format.utils\"\n\n/**\n * DisplayFieldNumber component\n *\n * Renders a number value according to the number UI decorator\n */\nfunction DisplayFieldNumber({\n schema,\n value,\n className,\n locale,\n}: DisplayFieldNumberProps): React.JSX.Element | null {\n // The shared field words (`noValue`) and this display's own (`unlimited`, #1851).\n const { regionalPreferences, tComponent, isReady } = useI18n({ component: [FrontendComponentType.LOW_LEVEL_FORM_FIELD, FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER] })\n\n const numberUI = getNumberUI(schema)\n const displayMode = useContextualDisplayParams(numberUI)?.displayMode ?? NumberDisplayMode.RAW\n const decimalPlaces = numberUI?.decimalPlaces\n const trailingZeros = numberUI?.trailingZeros ?? false\n const prefix = numberUI?.prefix ?? ''\n const suffix = numberUI?.suffix ?? ''\n const percentageScale = numberUI?.percentageScale ?? PercentageScale.NORMALIZED\n\n // Locale priority: explicit prop > regional preferences > browser locale > fallback.\n // `regionalPreferences` is null until the i18n bundle resolves (`isReady`), and this\n // read runs in the render body BEFORE the `!isReady` gate below — so optional-chain it.\n // Without the `?.`, the first render throws `Cannot read properties of null (reading\n // 'locale')`, the DisplayFieldErrorBoundary catches it, and every number field shows an\n // error box until i18n hydrates. On that first beat the browser-locale fallback applies;\n // the real preference takes over on the next render.\n const effectiveLocale = locale ?? regionalPreferences?.locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en')\n\n // Render the value content\n const renderValue = () => {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return <><Text className=\"text-muted-foreground italic\" aria-hidden=\"true\">—</Text><span className=\"sr-only\">{tComponent(FrontendComponentType.LOW_LEVEL_FORM_FIELD, 'noValue')}</span></>\n }\n\n // A value that means NO LIMIT (`numberUI({ unlimitedAt })`, #1851) is a word, not a quantity: `-1` read as a count.\n if (numberUI?.unlimitedAt !== undefined && value === numberUI.unlimitedAt) {\n return <Text>{tComponent(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER, 'unlimited')}</Text>\n }\n\n // Format the number based on display mode\n let formattedValue: string\n\n switch (displayMode) {\n case NumberDisplayMode.RAW:\n if (decimalPlaces !== undefined) {\n formattedValue = trailingZeros\n ? value.toFixed(decimalPlaces)\n : parseFloat(value.toFixed(decimalPlaces)).toString()\n } else {\n formattedValue = value.toString()\n }\n break\n\n case NumberDisplayMode.FORMATTED:\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: trailingZeros ? decimalPlaces : undefined,\n maximumFractionDigits: decimalPlaces,\n }).format(value)\n break\n\n case NumberDisplayMode.PERCENTAGE: {\n // Intl.NumberFormat style:'percent' expects a 0–1 value and multiplies by 100.\n // If scale is 'normalized' (default), value is already 0–1 → pass directly.\n // If scale is 'percent', value is 0–100 → divide by 100 first.\n const percentValue = percentageScale === PercentageScale.PERCENT ? value / 100 : value\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n style: 'percent',\n minimumFractionDigits: trailingZeros ? decimalPlaces : undefined,\n maximumFractionDigits: decimalPlaces ?? 0,\n }).format(percentValue)\n break\n }\n\n case NumberDisplayMode.COMPACT:\n formattedValue = new Intl.NumberFormat(effectiveLocale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: decimalPlaces ?? 1,\n }).format(value)\n break\n\n case NumberDisplayMode.ORDINAL:\n formattedValue = DisplayFieldFormatUtils.formatOrdinal(value, effectiveLocale)\n break\n\n case NumberDisplayMode.BYTES:\n formattedValue = DisplayFieldFormatUtils.formatBytes(value, decimalPlaces ?? 2)\n break\n\n default:\n formattedValue = value.toString()\n }\n\n // Add prefix and suffix\n const displayValue = `${prefix}${formattedValue}${suffix}`\n\n // `tabular-nums` gives fixed-width digits so numeric columns/rows align\n // (matches the money + bigdecimal formatters).\n return <Text className=\"tabular-nums\">{displayValue}</Text>\n }\n\n if (!isReady) return null\n\n // Label/description rendering is handled by the parent DisplayField (FIELD-01)\n return <div className={className}>{renderValue()}</div>\n}\n\n;(DisplayFieldNumber as typeof DisplayFieldNumber & { displayName: string }).displayName = \"DisplayFieldNumber\"\n\nexport { DisplayFieldNumber }\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-number.labels.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,mBAAmB,EAA2B,MAAM,qCAAqC,CAAC;AAM/H,eAAO,MAAM,gCAAgC,EAAE,mBAAmB,EAAO,CAAC"}
1
+ {"version":3,"file":"display-field-number.labels.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,mBAAmB,EAA2B,MAAM,qCAAqC,CAAC;AAM1I,eAAO,MAAM,gCAAgC,EAAE,mBAAmB,EAGjE,CAAC"}
@@ -1,7 +1,10 @@
1
- import { FrontendComponentType, registerComponentLabels } from '@wildo-ai/presets-components-models';
1
+ import { FrontendComponentType, LabelKind, registerComponentLabels } from '@wildo-ai/presets-components-models';
2
2
  // Companion-only label metadata for this component: keys + params + (where
3
3
  // authored) per-key purpose / kind / variable meaning. Statically scanned by
4
4
  // the dev companion; NOT imported at runtime, so it never ships in the bundle.
5
- export const LowLevelDisplayFieldNumberLabels = [];
5
+ export const LowLevelDisplayFieldNumberLabels = [
6
+ // #1851 — a number declaring `numberUI({ unlimitedAt })` shows this word for that value (a feature limit's -1).
7
+ { ref: 'unlimited', kind: LabelKind.LABEL, purpose: 'Shown in place of a number when the value means there is no limit, for example a plan\'s feature limit set to unlimited' },
8
+ ];
6
9
  registerComponentLabels(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER, LowLevelDisplayFieldNumberLabels);
7
10
  //# sourceMappingURL=display-field-number.labels.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-number.labels.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAA4B,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE/H,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,gCAAgC,GAA0B,EAAE,CAAC;AAC1E,uBAAuB,CAAC,qBAAqB,CAAC,8BAA8B,EAAE,gCAAgC,CAAC,CAAC","sourcesContent":["import { FrontendComponentType, type LabellingUnitaryDef, registerComponentLabels } from '@wildo-ai/presets-components-models';\n\n// Companion-only label metadata for this component: keys + params + (where\n// authored) per-key purpose / kind / variable meaning. Statically scanned by\n// the dev companion; NOT imported at runtime, so it never ships in the bundle.\n\nexport const LowLevelDisplayFieldNumberLabels: LabellingUnitaryDef[] = [];\nregisterComponentLabels(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER, LowLevelDisplayFieldNumberLabels);\n"]}
1
+ {"version":3,"file":"display-field-number.labels.js","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-number.labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAA4B,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE1I,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,gCAAgC,GAA0B;IACrE,gHAAgH;IAChH,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,yHAAyH,EAAE;CAChL,CAAC;AACF,uBAAuB,CAAC,qBAAqB,CAAC,8BAA8B,EAAE,gCAAgC,CAAC,CAAC","sourcesContent":["import { FrontendComponentType, LabelKind, type LabellingUnitaryDef, registerComponentLabels } from '@wildo-ai/presets-components-models';\n\n// Companion-only label metadata for this component: keys + params + (where\n// authored) per-key purpose / kind / variable meaning. Statically scanned by\n// the dev companion; NOT imported at runtime, so it never ships in the bundle.\n\nexport const LowLevelDisplayFieldNumberLabels: LabellingUnitaryDef[] = [\n // #1851 — a number declaring `numberUI({ unlimitedAt })` shows this word for that value (a feature limit's -1).\n { ref: 'unlimited', kind: LabelKind.LABEL, purpose: 'Shown in place of a number when the value means there is no limit, for example a plan\\'s feature limit set to unlimited' },\n];\nregisterComponentLabels(FrontendComponentType.LOW_LEVEL_DISPLAY_FIELD_NUMBER, LowLevelDisplayFieldNumberLabels);\n"]}
@@ -2,7 +2,7 @@
2
2
  * DisplayFieldString Component
3
3
  *
4
4
  * Displays a string value based on the string UI decorator.
5
- * Supports different display modes: text, truncate, multiline, markdown, color, link, email, badge, copy, secret
5
+ * Supports different display modes: text, truncate, multiline, markdown, untrusted_html, color, link, email, badge, copy, secret
6
6
  */
7
7
  import * as React from "react";
8
8
  import type { DisplayFieldStringProps } from '@wildo-ai/saas-frontend-lib';
@@ -1 +1 @@
1
- {"version":3,"file":"display-field-string.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-string.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAsB1E;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,SAAS,GACV,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAsOpD;AAID,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"display-field-string.d.ts","sourceRoot":"","sources":["../../../../../../src/components/data-display/formatters/display-field-string.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AA+B1E;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,SAAS,GACV,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAuQpD;AAID,OAAO,EAAE,kBAAkB,EAAE,CAAA"}