@wix/web5-core 1.58.0 → 1.59.0

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 (52) hide show
  1. package/dist/cjs/client/applyThemeOverrides.js +89 -0
  2. package/dist/cjs/client/applyThemeOverrides.js.map +1 -0
  3. package/dist/cjs/client/clientBundleUrl.js +43 -0
  4. package/dist/cjs/client/clientBundleUrl.js.map +1 -1
  5. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js +5 -2
  6. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  7. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js +4 -1
  8. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  9. package/dist/cjs/component/componentDefinitions/NextStepsSectionDefinition.js +35 -2
  10. package/dist/cjs/component/componentDefinitions/NextStepsSectionDefinition.js.map +1 -1
  11. package/dist/cjs/component/componentDefinitions/TextBlockSectionDefinition.js +27 -1
  12. package/dist/cjs/component/componentDefinitions/TextBlockSectionDefinition.js.map +1 -1
  13. package/dist/cjs/component/componentDefinitions/index.js +8 -1
  14. package/dist/cjs/component/componentDefinitions/index.js.map +1 -1
  15. package/dist/cjs/component/types.js.map +1 -1
  16. package/dist/cjs/hostScope.js.map +1 -1
  17. package/dist/cjs/index.js +11 -3
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/esm/client/applyThemeOverrides.js +85 -0
  20. package/dist/esm/client/applyThemeOverrides.js.map +1 -0
  21. package/dist/esm/client/clientBundleUrl.js +39 -0
  22. package/dist/esm/client/clientBundleUrl.js.map +1 -1
  23. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js +6 -3
  24. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  25. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js +5 -2
  26. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  27. package/dist/esm/component/componentDefinitions/NextStepsSectionDefinition.js +36 -3
  28. package/dist/esm/component/componentDefinitions/NextStepsSectionDefinition.js.map +1 -1
  29. package/dist/esm/component/componentDefinitions/TextBlockSectionDefinition.js +27 -1
  30. package/dist/esm/component/componentDefinitions/TextBlockSectionDefinition.js.map +1 -1
  31. package/dist/esm/component/componentDefinitions/index.js +8 -1
  32. package/dist/esm/component/componentDefinitions/index.js.map +1 -1
  33. package/dist/esm/component/types.js.map +1 -1
  34. package/dist/esm/hostScope.js.map +1 -1
  35. package/dist/esm/index.js +2 -1
  36. package/dist/esm/index.js.map +1 -1
  37. package/dist/types/client/applyThemeOverrides.d.ts +19 -0
  38. package/dist/types/client/applyThemeOverrides.d.ts.map +1 -0
  39. package/dist/types/client/clientBundleUrl.d.ts +22 -0
  40. package/dist/types/client/clientBundleUrl.d.ts.map +1 -1
  41. package/dist/types/component/componentDefinitions/HeroEntitySectionDefinition.d.ts.map +1 -1
  42. package/dist/types/component/componentDefinitions/HeroSectionDefinition.d.ts.map +1 -1
  43. package/dist/types/component/componentDefinitions/NextStepsSectionDefinition.d.ts.map +1 -1
  44. package/dist/types/component/componentDefinitions/TextBlockSectionDefinition.d.ts.map +1 -1
  45. package/dist/types/component/componentDefinitions/index.d.ts.map +1 -1
  46. package/dist/types/component/types.d.ts +7 -0
  47. package/dist/types/component/types.d.ts.map +1 -1
  48. package/dist/types/hostScope.d.ts +11 -0
  49. package/dist/types/hostScope.d.ts.map +1 -1
  50. package/dist/types/index.d.ts +2 -1
  51. package/dist/types/index.d.ts.map +1 -1
  52. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { headingText, bodyText, firstImageSrc, parseCalloutTag, extractEntityRefs } from './parse-utils.js';
2
+ import { headingText, headingMarkdown, bodyText, firstImageSrc, parseCalloutTag, extractEntityRefs } from './parse-utils.js';
3
3
  import { getPartsByType } from '../../parts/parts.js';
4
4
  import { DIAGNOSTIC_TYPES } from '../diagnosticTypes.js';
5
5
 
@@ -49,7 +49,7 @@ Nike offerings span performance and lifestyle lines.
49
49
  * [Nike Life Cable Knit Turtleneck Sweater](web5://entity/product/ZDvHxsa3IJA8CyGX8BNpdw)
50
50
  * [Nike x Jacquemus NRG HE Swoosh Hoodie](web5://entity/product/qH2lqINGneHWYVZzzGnXTA)`,
51
51
  expected: {
52
- headline: 'Nike collections',
52
+ headline: '**Nike** collections',
53
53
  content: 'Nike offerings span performance and lifestyle lines.',
54
54
  image: 'web5://image/Nike+Life+collection',
55
55
  items: [{
@@ -112,7 +112,10 @@ Nike offerings span performance and lifestyle lines.
112
112
  leadingQuote = parseCalloutTag(raw).text || undefined;
113
113
  }
114
114
  return {
115
- headline: headingText(parts, 1),
115
+ // Markdown-preserving (not headingText): the hero title now carries the
116
+ // bold+italic hook the ECHO callout used to own, so the FE needs the
117
+ // formatting, not just the plain text. See FeatureHeroEntity.tsx.
118
+ headline: headingMarkdown(parts, 1),
116
119
  badge: headingText(parts, 3) || undefined,
117
120
  content: bodyText(parts) || undefined,
118
121
  image: firstImageSrc(parts),
@@ -1 +1 @@
1
- {"version":3,"names":["headingText","bodyText","firstImageSrc","parseCalloutTag","extractEntityRefs","getPartsByType","DIAGNOSTIC_TYPES","HeroEntitySectionDefinition","constructor","_defineProperty","headline","content","items","entityId","entityType","entityUrl","linkText","markdown","expected","image","parse","parts","context","entityRefs","length","reportDiagnostic","SECTION_REJECTED","map","e","undefined","description","imageUrl","markdownImageUrl","callout","h1Index","findIndex","p","_p$meta","type","meta","level","blockquotes","leadingQuote","bq","_bq$meta","_bq$content","bqIndex","indexOf","raw","trim","text","badge"],"sources":["../../../../src/component/componentDefinitions/HeroEntitySectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n bodyText,\n firstImageSrc,\n parseCalloutTag,\n extractEntityRefs,\n} from './parse-utils';\nimport type { Part } from '../../parts/parts';\nimport { getPartsByType } from '../../parts/parts';\nimport type {\n EntityItem,\n HeroEntityCompProps,\n HeroEntitySectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\n/**\n * Hero section whose body carries one or more web5 entity links\n * (`web5://entity/...`). It mirrors the framing of {@link HeroSectionDefinition}\n * (leading callout, h1, image, intro text) but, instead of turning the links\n * into CTA buttons, surfaces them as resolvable entities.\n *\n * Registered ahead of `HeroSectionDefinition` so an entity-bearing hero is\n * claimed here first. The pattern requires at least one `link[entityType]`, and\n * `parse()` returns `null` when no entity refs are found, letting a plain hero\n * fall through to `HeroSectionDefinition`.\n */\nexport class HeroEntitySectionDefinition\n implements SectionDefinition<HeroEntitySectionComponent>\n{\n sectionType = 'hero-entity' as const;\n singleInstance = true;\n patterns = [\n // Leading slots mirror HeroSectionDefinition: section descriptor, then the\n // optional leading ECHO callout, then an optional h3 badge, then the h1.\n // Callout and badge are independent; the second `html_comment?` preserves the\n // legacy callout-before-descriptor ordering for pages saved before this change.\n // Entity links carried as list items (the canonical shape).\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t | link)* > list{item[1-]:link[entityType] > image? > (t | callout)*}',\n // Entity links sitting at the top level of the hero body.\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t)* > (link[entityType] > image? > (t | callout)*)[1-] > list?',\n ];\n\n defaults: HeroEntityCompProps = {\n headline: 'Featured collection',\n content: 'Explore the highlights from this collection.',\n items: [\n {\n entityId: 'example-1',\n entityType: 'product',\n entityUrl: 'web5://entity/product/example-1',\n linkText: 'Example product',\n },\n ],\n };\n\n fixtures: SectionFixture<HeroEntityCompProps>[] = [\n {\n markdown: `<!-- section:hero, id:hero, semantic:hero -->\n\n# **Nike** collections\n\n![Nike Life collection](web5://image/Nike+Life+collection)\nNike offerings span performance and lifestyle lines.\n\n* [Nike Throwback Future Collection](web5://entity/article/WAyuiC63OSjwpvnOyZcblQ)\n* [Nike Life Cable Knit Turtleneck Sweater](web5://entity/product/ZDvHxsa3IJA8CyGX8BNpdw)\n* [Nike x Jacquemus NRG HE Swoosh Hoodie](web5://entity/product/qH2lqINGneHWYVZzzGnXTA)`,\n expected: {\n headline: 'Nike collections',\n content: 'Nike offerings span performance and lifestyle lines.',\n image: 'web5://image/Nike+Life+collection',\n items: [\n {\n entityId: 'WAyuiC63OSjwpvnOyZcblQ',\n entityType: 'article',\n entityUrl:\n 'web5://entity/article/WAyuiC63OSjwpvnOyZcblQ',\n linkText: 'Nike Throwback Future Collection',\n },\n {\n entityId: 'ZDvHxsa3IJA8CyGX8BNpdw',\n entityType: 'product',\n entityUrl:\n 'web5://entity/product/ZDvHxsa3IJA8CyGX8BNpdw',\n linkText: 'Nike Life Cable Knit Turtleneck Sweater',\n },\n {\n entityId: 'qH2lqINGneHWYVZzzGnXTA',\n entityType: 'product',\n entityUrl:\n 'web5://entity/product/qH2lqINGneHWYVZzzGnXTA',\n linkText: 'Nike x Jacquemus NRG HE Swoosh Hoodie',\n },\n ],\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): HeroEntityCompProps | null {\n const entityRefs = extractEntityRefs(parts);\n\n if (entityRefs.length === 0) {\n // Not an entity hero — let HeroSectionDefinition claim it.\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'hero-entity: no entity links found',\n );\n return null;\n }\n\n const items: EntityItem[] = entityRefs.map((e) => ({\n entityId: e.entityId,\n entityType: e.entityType,\n entityUrl: e.entityUrl,\n linkText: e.linkText || undefined,\n description: e.description || undefined,\n imageUrl: e.markdownImageUrl,\n callout: e.callout,\n }));\n\n // The leading callout before the h1 — the ECHO the orchestrator emits as the\n // hero's opening line, right after the section descriptor — is part of the\n // hero, mirroring HeroSectionDefinition. A trailing callout falls through to a\n // downstream callout section. (Per-item callouts inside the entity list are\n // handled by extractEntityRefs above and are unaffected.)\n const h1Index = parts.findIndex(\n (p) =>\n p.type === 'heading' && (p.meta as { level?: number })?.level === 1,\n );\n const blockquotes = getPartsByType<Part>(parts, 'callout');\n let leadingQuote: string | undefined;\n\n for (const bq of blockquotes) {\n const bqIndex = parts.indexOf(bq);\n if (h1Index >= 0 && bqIndex > h1Index) {\n continue;\n }\n const raw = (bq.meta?.markdown as string)?.trim() || bq.content?.trim();\n if (!raw) {\n continue;\n }\n leadingQuote = parseCalloutTag(raw).text || undefined;\n }\n\n return {\n headline: headingText(parts, 1),\n badge: headingText(parts, 3) || undefined,\n content: bodyText(parts) || undefined,\n image: firstImageSrc(parts),\n leadingQuote,\n items,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["headingText","headingMarkdown","bodyText","firstImageSrc","parseCalloutTag","extractEntityRefs","getPartsByType","DIAGNOSTIC_TYPES","HeroEntitySectionDefinition","constructor","_defineProperty","headline","content","items","entityId","entityType","entityUrl","linkText","markdown","expected","image","parse","parts","context","entityRefs","length","reportDiagnostic","SECTION_REJECTED","map","e","undefined","description","imageUrl","markdownImageUrl","callout","h1Index","findIndex","p","_p$meta","type","meta","level","blockquotes","leadingQuote","bq","_bq$meta","_bq$content","bqIndex","indexOf","raw","trim","text","badge"],"sources":["../../../../src/component/componentDefinitions/HeroEntitySectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n headingMarkdown,\n bodyText,\n firstImageSrc,\n parseCalloutTag,\n extractEntityRefs,\n} from './parse-utils';\nimport type { Part } from '../../parts/parts';\nimport { getPartsByType } from '../../parts/parts';\nimport type {\n EntityItem,\n HeroEntityCompProps,\n HeroEntitySectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\n/**\n * Hero section whose body carries one or more web5 entity links\n * (`web5://entity/...`). It mirrors the framing of {@link HeroSectionDefinition}\n * (leading callout, h1, image, intro text) but, instead of turning the links\n * into CTA buttons, surfaces them as resolvable entities.\n *\n * Registered ahead of `HeroSectionDefinition` so an entity-bearing hero is\n * claimed here first. The pattern requires at least one `link[entityType]`, and\n * `parse()` returns `null` when no entity refs are found, letting a plain hero\n * fall through to `HeroSectionDefinition`.\n */\nexport class HeroEntitySectionDefinition\n implements SectionDefinition<HeroEntitySectionComponent>\n{\n sectionType = 'hero-entity' as const;\n singleInstance = true;\n patterns = [\n // Leading slots mirror HeroSectionDefinition: section descriptor, then the\n // optional leading ECHO callout, then an optional h3 badge, then the h1.\n // Callout and badge are independent; the second `html_comment?` preserves the\n // legacy callout-before-descriptor ordering for pages saved before this change.\n // Entity links carried as list items (the canonical shape).\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t | link)* > list{item[1-]:link[entityType] > image? > (t | callout)*}',\n // Entity links sitting at the top level of the hero body.\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t)* > (link[entityType] > image? > (t | callout)*)[1-] > list?',\n ];\n\n defaults: HeroEntityCompProps = {\n headline: 'Featured collection',\n content: 'Explore the highlights from this collection.',\n items: [\n {\n entityId: 'example-1',\n entityType: 'product',\n entityUrl: 'web5://entity/product/example-1',\n linkText: 'Example product',\n },\n ],\n };\n\n fixtures: SectionFixture<HeroEntityCompProps>[] = [\n {\n markdown: `<!-- section:hero, id:hero, semantic:hero -->\n\n# **Nike** collections\n\n![Nike Life collection](web5://image/Nike+Life+collection)\nNike offerings span performance and lifestyle lines.\n\n* [Nike Throwback Future Collection](web5://entity/article/WAyuiC63OSjwpvnOyZcblQ)\n* [Nike Life Cable Knit Turtleneck Sweater](web5://entity/product/ZDvHxsa3IJA8CyGX8BNpdw)\n* [Nike x Jacquemus NRG HE Swoosh Hoodie](web5://entity/product/qH2lqINGneHWYVZzzGnXTA)`,\n expected: {\n headline: '**Nike** collections',\n content: 'Nike offerings span performance and lifestyle lines.',\n image: 'web5://image/Nike+Life+collection',\n items: [\n {\n entityId: 'WAyuiC63OSjwpvnOyZcblQ',\n entityType: 'article',\n entityUrl:\n 'web5://entity/article/WAyuiC63OSjwpvnOyZcblQ',\n linkText: 'Nike Throwback Future Collection',\n },\n {\n entityId: 'ZDvHxsa3IJA8CyGX8BNpdw',\n entityType: 'product',\n entityUrl:\n 'web5://entity/product/ZDvHxsa3IJA8CyGX8BNpdw',\n linkText: 'Nike Life Cable Knit Turtleneck Sweater',\n },\n {\n entityId: 'qH2lqINGneHWYVZzzGnXTA',\n entityType: 'product',\n entityUrl:\n 'web5://entity/product/qH2lqINGneHWYVZzzGnXTA',\n linkText: 'Nike x Jacquemus NRG HE Swoosh Hoodie',\n },\n ],\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): HeroEntityCompProps | null {\n const entityRefs = extractEntityRefs(parts);\n\n if (entityRefs.length === 0) {\n // Not an entity hero — let HeroSectionDefinition claim it.\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'hero-entity: no entity links found',\n );\n return null;\n }\n\n const items: EntityItem[] = entityRefs.map((e) => ({\n entityId: e.entityId,\n entityType: e.entityType,\n entityUrl: e.entityUrl,\n linkText: e.linkText || undefined,\n description: e.description || undefined,\n imageUrl: e.markdownImageUrl,\n callout: e.callout,\n }));\n\n // The leading callout before the h1 — the ECHO the orchestrator emits as the\n // hero's opening line, right after the section descriptor — is part of the\n // hero, mirroring HeroSectionDefinition. A trailing callout falls through to a\n // downstream callout section. (Per-item callouts inside the entity list are\n // handled by extractEntityRefs above and are unaffected.)\n const h1Index = parts.findIndex(\n (p) =>\n p.type === 'heading' && (p.meta as { level?: number })?.level === 1,\n );\n const blockquotes = getPartsByType<Part>(parts, 'callout');\n let leadingQuote: string | undefined;\n\n for (const bq of blockquotes) {\n const bqIndex = parts.indexOf(bq);\n if (h1Index >= 0 && bqIndex > h1Index) {\n continue;\n }\n const raw = (bq.meta?.markdown as string)?.trim() || bq.content?.trim();\n if (!raw) {\n continue;\n }\n leadingQuote = parseCalloutTag(raw).text || undefined;\n }\n\n return {\n // Markdown-preserving (not headingText): the hero title now carries the\n // bold+italic hook the ECHO callout used to own, so the FE needs the\n // formatting, not just the plain text. See FeatureHeroEntity.tsx.\n headline: headingMarkdown(parts, 1),\n badge: headingText(parts, 3) || undefined,\n content: bodyText(parts) || undefined,\n image: firstImageSrc(parts),\n leadingQuote,\n items,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { headingText, bodyText, firstImageSrc, parseCalloutTag, extractListItemText } from './parse-utils.js';
2
+ import { headingText, headingMarkdown, bodyText, firstImageSrc, parseCalloutTag, extractListItemText } from './parse-utils.js';
3
3
  import { getPartsByType, getLinks } from '../../parts/parts.js';
4
4
  export class HeroSectionDefinition {
5
5
  constructor() {
@@ -198,7 +198,10 @@ Get started today with our amazing features.
198
198
  leadingQuote = parseCalloutTag(raw).text || undefined;
199
199
  }
200
200
  return {
201
- headline: headingText(parts, 1),
201
+ // Markdown-preserving (not headingText): the hero title now carries the
202
+ // bold+italic hook the ECHO callout used to own, so the FE needs the
203
+ // formatting, not just the plain text. See FeatureComparisonHero.tsx.
204
+ headline: headingMarkdown(parts, 1),
202
205
  badge: headingText(parts, 3) || undefined,
203
206
  content: bodyText(parts) || undefined,
204
207
  buttons: buttons.length > 0 ? buttons : undefined,
@@ -1 +1 @@
1
- {"version":3,"names":["headingText","bodyText","firstImageSrc","parseCalloutTag","extractListItemText","getPartsByType","getLinks","HeroSectionDefinition","constructor","_defineProperty","headline","content","buttons","id","text","variant","markdown","expected","onClick","image","parse","parts","lists","list","item","_list$meta","meta","items","_item$meta","itemParts","nestedImage","buttonIndex","map","l","i","_l$content","trim","href","length","trailingList","filteredItems","_list$meta2","_item$meta2","hasImage","some","p","type","push","allItemsAreLinks","listLinks","_item$meta3","_itemLinkParts$0$cont","itemLinkParts","filter","allText","linkTexts","_l$content2","join","link","isFirstButton","lines","_item$meta4","h1Index","findIndex","_p$meta","level","blockquotes","leadingQuote","bq","_bq$meta","_bq$content","bqIndex","indexOf","raw","undefined","badge"],"sources":["../../../../src/component/componentDefinitions/HeroSectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n bodyText,\n firstImageSrc,\n parseCalloutTag,\n extractListItemText,\n} from './parse-utils';\nimport type { Part, ListPart, LinkPart, ListItemPart } from '../../parts/parts';\nimport { getPartsByType, getLinks } from '../../parts/parts';\nimport type {\n HeroButton,\n HeroCompProps,\n HeroSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition } from '../section-definition';\n\nexport class HeroSectionDefinition\n implements SectionDefinition<HeroSectionComponent>\n{\n sectionType = 'hero' as const;\n singleInstance = true;\n patterns = [\n // Canonical hero shape: section descriptor, then the leading ECHO callout\n // (optional in the grammar — the orchestrator always emits it, but a missing\n // ECHO must not stop the hero from rendering), then an optional h3 badge,\n // then the h1. The callout and badge are independent slots so a hero can\n // carry both. The second `html_comment?` keeps the legacy ordering\n // (callout before the descriptor) matching for pages saved before this change.\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t | link)* > list?',\n ];\n\n defaults: HeroCompProps = {\n headline: 'Build something amazing',\n content: 'Your platform for data-driven decisions.',\n buttons: [{ id: 'btn-0', text: 'Get started', variant: 'primary' }],\n };\n\n fixtures: SectionFixture<HeroCompProps>[] = [\n {\n markdown:\n '# Welcome\\n\\nBuild amazing things.\\n\\n[Get Started](/) [Learn More](/about)',\n expected: {\n headline: 'Welcome',\n content: 'Build amazing things.',\n buttons: [\n {\n id: 'btn-0',\n text: 'Get Started',\n variant: 'primary',\n onClick: '/',\n },\n {\n id: 'btn-1',\n text: 'Learn More',\n variant: 'secondary',\n onClick: '/about',\n },\n ],\n },\n },\n {\n markdown: `<!-- Hero Section -->\n\n# Welcome to Our Platform\n\n![Hero Image](hero.jpg)\n\nGet started today with our amazing features.\n\n[Get Started](/signup) [Learn More](/about)`,\n expected: {\n headline: 'Welcome to Our Platform',\n content: 'Get started today with our amazing features.',\n buttons: [\n {\n id: 'btn-0',\n text: 'Get Started',\n variant: 'primary',\n onClick: '/signup',\n },\n {\n id: 'btn-1',\n text: 'Learn More',\n variant: 'secondary',\n onClick: '/about',\n },\n ],\n image: 'hero.jpg',\n },\n },\n ];\n\n parse(parts: Part[]): HeroCompProps {\n let image = firstImageSrc(parts);\n const lists = getPartsByType<ListPart>(parts, 'list');\n\n if (!image) {\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const nestedImage = firstImageSrc(itemParts);\n if (nestedImage) {\n image = nestedImage;\n break;\n }\n }\n if (image) {\n break;\n }\n }\n }\n\n // Start with top-level links as buttons\n let buttonIndex = 0;\n const buttons: HeroButton[] = getLinks(parts).map(\n (l, i): HeroButton => ({\n id: `btn-${i}`,\n text: l.content?.trim() || 'Learn more',\n variant: i === 0 ? 'primary' : 'secondary',\n onClick: l.meta.href,\n }),\n );\n buttonIndex = buttons.length;\n\n // Process lists: filter out image-only items, then check if remaining\n // items are all link-only. If so, convert to buttons; otherwise keep as trailingList.\n let trailingList: string | undefined;\n if (lists.length > 0) {\n for (const list of lists) {\n // Filter out image-only items\n const filteredItems: ListItemPart[] = [];\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const hasImage = itemParts.some((p) => p.type === 'image');\n if (hasImage) {\n continue;\n }\n filteredItems.push(item);\n }\n\n if (filteredItems.length === 0) {\n continue;\n }\n\n // Check if ALL remaining items contain only links (no other text)\n let allItemsAreLinks = true;\n const listLinks: { text: string; href: string }[] = [];\n\n for (const item of filteredItems) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const itemLinkParts = itemParts.filter(\n (p): p is LinkPart => p.type === 'link',\n );\n\n if (itemLinkParts.length === 0) {\n allItemsAreLinks = false;\n break;\n }\n\n // Check if the item text is entirely link text (no extra content)\n const allText = extractListItemText(item).trim();\n const linkTexts = itemLinkParts\n .map((l) => l.content?.trim() || '')\n .join(' ')\n .trim();\n\n if (allText !== linkTexts) {\n allItemsAreLinks = false;\n break;\n }\n\n listLinks.push({\n text: itemLinkParts[0].content?.trim() || 'Learn more',\n href: itemLinkParts[0].meta.href,\n });\n }\n\n if (allItemsAreLinks && listLinks.length > 0) {\n // Convert link-only list items to buttons\n for (const link of listLinks) {\n const isFirstButton = buttons.length === 0;\n buttons.push({\n id: `btn-${buttonIndex++}`,\n text: link.text,\n variant: isFirstButton ? 'primary' : 'secondary',\n onClick: link.href,\n });\n }\n } else {\n // Keep as trailing list markdown\n const lines: string[] = [];\n for (const item of filteredItems) {\n const text =\n (item.meta?.markdown as string) || extractListItemText(item);\n if (text) {\n lines.push(`- ${text}`);\n }\n }\n if (lines.length > 0) {\n trailingList = lines.join('\\n');\n }\n }\n }\n }\n\n // The hero claims the leading callout before the h1 — the ECHO the\n // orchestrator emits as the hero's opening line, right after the section\n // descriptor. A trailing blockquote is not part of the hero pattern, so it\n // falls through to a downstream callout section instead.\n const h1Index = parts.findIndex(\n (p) => p.type === 'heading' && (p.meta as { level: number })?.level === 1,\n );\n const blockquotes = getPartsByType<Part>(parts, 'callout');\n let leadingQuote: string | undefined;\n\n for (const bq of blockquotes) {\n const bqIndex = parts.indexOf(bq);\n if (h1Index >= 0 && bqIndex > h1Index) {\n continue;\n }\n const raw = (bq.meta?.markdown as string)?.trim() || bq.content?.trim();\n if (!raw) {\n continue;\n }\n leadingQuote = parseCalloutTag(raw).text || undefined;\n }\n\n return {\n headline: headingText(parts, 1),\n badge: headingText(parts, 3) || undefined,\n content: bodyText(parts) || undefined,\n buttons: buttons.length > 0 ? buttons : undefined,\n image,\n trailingList,\n leadingQuote,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["headingText","headingMarkdown","bodyText","firstImageSrc","parseCalloutTag","extractListItemText","getPartsByType","getLinks","HeroSectionDefinition","constructor","_defineProperty","headline","content","buttons","id","text","variant","markdown","expected","onClick","image","parse","parts","lists","list","item","_list$meta","meta","items","_item$meta","itemParts","nestedImage","buttonIndex","map","l","i","_l$content","trim","href","length","trailingList","filteredItems","_list$meta2","_item$meta2","hasImage","some","p","type","push","allItemsAreLinks","listLinks","_item$meta3","_itemLinkParts$0$cont","itemLinkParts","filter","allText","linkTexts","_l$content2","join","link","isFirstButton","lines","_item$meta4","h1Index","findIndex","_p$meta","level","blockquotes","leadingQuote","bq","_bq$meta","_bq$content","bqIndex","indexOf","raw","undefined","badge"],"sources":["../../../../src/component/componentDefinitions/HeroSectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n headingMarkdown,\n bodyText,\n firstImageSrc,\n parseCalloutTag,\n extractListItemText,\n} from './parse-utils';\nimport type { Part, ListPart, LinkPart, ListItemPart } from '../../parts/parts';\nimport { getPartsByType, getLinks } from '../../parts/parts';\nimport type {\n HeroButton,\n HeroCompProps,\n HeroSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition } from '../section-definition';\n\nexport class HeroSectionDefinition\n implements SectionDefinition<HeroSectionComponent>\n{\n sectionType = 'hero' as const;\n singleInstance = true;\n patterns = [\n // Canonical hero shape: section descriptor, then the leading ECHO callout\n // (optional in the grammar — the orchestrator always emits it, but a missing\n // ECHO must not stop the hero from rendering), then an optional h3 badge,\n // then the h1. The callout and badge are independent slots so a hero can\n // carry both. The second `html_comment?` keeps the legacy ordering\n // (callout before the descriptor) matching for pages saved before this change.\n 'html_comment? > callout? > html_comment? > h3? > h1 > (image | t | link)* > list?',\n ];\n\n defaults: HeroCompProps = {\n headline: 'Build something amazing',\n content: 'Your platform for data-driven decisions.',\n buttons: [{ id: 'btn-0', text: 'Get started', variant: 'primary' }],\n };\n\n fixtures: SectionFixture<HeroCompProps>[] = [\n {\n markdown:\n '# Welcome\\n\\nBuild amazing things.\\n\\n[Get Started](/) [Learn More](/about)',\n expected: {\n headline: 'Welcome',\n content: 'Build amazing things.',\n buttons: [\n {\n id: 'btn-0',\n text: 'Get Started',\n variant: 'primary',\n onClick: '/',\n },\n {\n id: 'btn-1',\n text: 'Learn More',\n variant: 'secondary',\n onClick: '/about',\n },\n ],\n },\n },\n {\n markdown: `<!-- Hero Section -->\n\n# Welcome to Our Platform\n\n![Hero Image](hero.jpg)\n\nGet started today with our amazing features.\n\n[Get Started](/signup) [Learn More](/about)`,\n expected: {\n headline: 'Welcome to Our Platform',\n content: 'Get started today with our amazing features.',\n buttons: [\n {\n id: 'btn-0',\n text: 'Get Started',\n variant: 'primary',\n onClick: '/signup',\n },\n {\n id: 'btn-1',\n text: 'Learn More',\n variant: 'secondary',\n onClick: '/about',\n },\n ],\n image: 'hero.jpg',\n },\n },\n ];\n\n parse(parts: Part[]): HeroCompProps {\n let image = firstImageSrc(parts);\n const lists = getPartsByType<ListPart>(parts, 'list');\n\n if (!image) {\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const nestedImage = firstImageSrc(itemParts);\n if (nestedImage) {\n image = nestedImage;\n break;\n }\n }\n if (image) {\n break;\n }\n }\n }\n\n // Start with top-level links as buttons\n let buttonIndex = 0;\n const buttons: HeroButton[] = getLinks(parts).map(\n (l, i): HeroButton => ({\n id: `btn-${i}`,\n text: l.content?.trim() || 'Learn more',\n variant: i === 0 ? 'primary' : 'secondary',\n onClick: l.meta.href,\n }),\n );\n buttonIndex = buttons.length;\n\n // Process lists: filter out image-only items, then check if remaining\n // items are all link-only. If so, convert to buttons; otherwise keep as trailingList.\n let trailingList: string | undefined;\n if (lists.length > 0) {\n for (const list of lists) {\n // Filter out image-only items\n const filteredItems: ListItemPart[] = [];\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const hasImage = itemParts.some((p) => p.type === 'image');\n if (hasImage) {\n continue;\n }\n filteredItems.push(item);\n }\n\n if (filteredItems.length === 0) {\n continue;\n }\n\n // Check if ALL remaining items contain only links (no other text)\n let allItemsAreLinks = true;\n const listLinks: { text: string; href: string }[] = [];\n\n for (const item of filteredItems) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const itemLinkParts = itemParts.filter(\n (p): p is LinkPart => p.type === 'link',\n );\n\n if (itemLinkParts.length === 0) {\n allItemsAreLinks = false;\n break;\n }\n\n // Check if the item text is entirely link text (no extra content)\n const allText = extractListItemText(item).trim();\n const linkTexts = itemLinkParts\n .map((l) => l.content?.trim() || '')\n .join(' ')\n .trim();\n\n if (allText !== linkTexts) {\n allItemsAreLinks = false;\n break;\n }\n\n listLinks.push({\n text: itemLinkParts[0].content?.trim() || 'Learn more',\n href: itemLinkParts[0].meta.href,\n });\n }\n\n if (allItemsAreLinks && listLinks.length > 0) {\n // Convert link-only list items to buttons\n for (const link of listLinks) {\n const isFirstButton = buttons.length === 0;\n buttons.push({\n id: `btn-${buttonIndex++}`,\n text: link.text,\n variant: isFirstButton ? 'primary' : 'secondary',\n onClick: link.href,\n });\n }\n } else {\n // Keep as trailing list markdown\n const lines: string[] = [];\n for (const item of filteredItems) {\n const text =\n (item.meta?.markdown as string) || extractListItemText(item);\n if (text) {\n lines.push(`- ${text}`);\n }\n }\n if (lines.length > 0) {\n trailingList = lines.join('\\n');\n }\n }\n }\n }\n\n // The hero claims the leading callout before the h1 — the ECHO the\n // orchestrator emits as the hero's opening line, right after the section\n // descriptor. A trailing blockquote is not part of the hero pattern, so it\n // falls through to a downstream callout section instead.\n const h1Index = parts.findIndex(\n (p) => p.type === 'heading' && (p.meta as { level: number })?.level === 1,\n );\n const blockquotes = getPartsByType<Part>(parts, 'callout');\n let leadingQuote: string | undefined;\n\n for (const bq of blockquotes) {\n const bqIndex = parts.indexOf(bq);\n if (h1Index >= 0 && bqIndex > h1Index) {\n continue;\n }\n const raw = (bq.meta?.markdown as string)?.trim() || bq.content?.trim();\n if (!raw) {\n continue;\n }\n leadingQuote = parseCalloutTag(raw).text || undefined;\n }\n\n return {\n // Markdown-preserving (not headingText): the hero title now carries the\n // bold+italic hook the ECHO callout used to own, so the FE needs the\n // formatting, not just the plain text. See FeatureComparisonHero.tsx.\n headline: headingMarkdown(parts, 1),\n badge: headingText(parts, 3) || undefined,\n content: bodyText(parts) || undefined,\n buttons: buttons.length > 0 ? buttons : undefined,\n image,\n trailingList,\n leadingQuote,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { headingText, extractListItemText, firstImageSrc } from './parse-utils.js';
2
+ import { headingText, bodyText, extractListItemText, firstImageSrc } from './parse-utils.js';
3
3
  import { getPartsByType, getLinks } from '../../parts/parts.js';
4
4
  function linkToMarkdown(link) {
5
5
  var _link$content, _link$meta;
@@ -35,16 +35,39 @@ function inlineBodyMarkdown(parts) {
35
35
  export class NextStepsSectionDefinition {
36
36
  constructor() {
37
37
  _defineProperty(this, "sectionType", 'nextSteps');
38
- _defineProperty(this, "patterns", ['(html_comment[section^="next"] | html_comment[semantic^="next"]) > h2 > image? > list{item[1-]:(icon | t)* > (t? > link)+}', '(html_comment[section^="next"] | html_comment[semantic^="next"]) > h2 > image? > (t | link)+']);
38
+ _defineProperty(this, "patterns", [
39
+ // Framing sentence (`t?`) then one chip per bullet — the authored shape.
40
+ '(html_comment[section^="next"] | html_comment[semantic^="next"]) > h2 > image? > t? > list{item[1-]:(icon | t)* > (t? > link)+}',
41
+ // Legacy inline shape: chips embedded in the prose. Still arrives from
42
+ // sites whose next-steps prompt has not moved to the list shape.
43
+ '(html_comment[section^="next"] | html_comment[semantic^="next"]) > h2 > image? > (t | link)+']);
39
44
  _defineProperty(this, "defaults", {
40
45
  title: 'Next Steps',
41
- body: '[Get started](/start)',
46
+ body: 'Where would you like to go next?',
42
47
  backgroundImage: undefined,
43
48
  steps: [{
44
49
  content: '[Get started](/start)'
45
50
  }]
46
51
  });
47
52
  _defineProperty(this, "fixtures", [{
53
+ markdown: `<!-- section:next-steps, semantic:next_steps -->
54
+
55
+ ## Find the right care for mature, sensitive skin
56
+
57
+ Want to focus on rich hydrators and barrier builders?
58
+
59
+ - [hydrating creams →](web5://ask/hydrating+creams+for+mature+skin)
60
+ - [gentle resurfacing serums →](web5://ask/gentle+resurfacing+serums)`,
61
+ expected: {
62
+ title: 'Find the right care for mature, sensitive skin',
63
+ body: 'Want to focus on rich hydrators and barrier builders?',
64
+ steps: [{
65
+ content: '[hydrating creams →](web5://ask/hydrating+creams+for+mature+skin)'
66
+ }, {
67
+ content: '[gentle resurfacing serums →](web5://ask/gentle+resurfacing+serums)'
68
+ }]
69
+ }
70
+ }, {
48
71
  markdown: `<!-- section: next_steps -->
49
72
 
50
73
  ## Next Steps
@@ -66,10 +89,14 @@ export class NextStepsSectionDefinition {
66
89
  const backgroundImage = firstImageSrc(parts);
67
90
  const steps = [];
68
91
  let body;
92
+ let chipsInlineInBody = false;
69
93
 
70
94
  // Try list-based pattern first
71
95
  const lists = getPartsByType(parts, 'list');
72
96
  if (lists.length > 0) {
97
+ // The framing sentence is the only top-level prose — list items live
98
+ // under each list's meta.items, so bodyText never picks up a chip.
99
+ body = bodyText(parts) || undefined;
73
100
  for (const list of lists) {
74
101
  for (const item of ((_list$meta = list.meta) == null ? void 0 : _list$meta.items) ?? []) {
75
102
  var _list$meta, _item$meta, _iconPart$meta;
@@ -99,6 +126,9 @@ export class NextStepsSectionDefinition {
99
126
  }
100
127
  } else {
101
128
  body = inlineBodyMarkdown(parts);
129
+ // body carries the chips as inline links — flag it so renderers show the
130
+ // prose alone instead of repeating every chip as a row beneath it.
131
+ chipsInlineInBody = Boolean(body);
102
132
  }
103
133
 
104
134
  // Fallback: inline links pattern
@@ -120,6 +150,9 @@ export class NextStepsSectionDefinition {
120
150
  ...(body ? {
121
151
  body
122
152
  } : {}),
153
+ ...(chipsInlineInBody ? {
154
+ chipsInlineInBody
155
+ } : {}),
123
156
  ...(backgroundImage ? {
124
157
  backgroundImage
125
158
  } : {}),
@@ -1 +1 @@
1
- {"version":3,"names":["headingText","extractListItemText","firstImageSrc","getPartsByType","getLinks","linkToMarkdown","link","_link$content","_link$meta","content","trim","meta","href","appendInlineToken","current","token","trimmed","test","inlineBodyMarkdown","parts","body","reduce","part","type","_part$meta","markdown","undefined","NextStepsSectionDefinition","constructor","_defineProperty","title","backgroundImage","steps","expected","parse","lists","length","list","item","_list$meta","items","_item$meta","_iconPart$meta","itemParts","iconPart","find","p","iconHint","contentFragments","push","_p$content","filter","Boolean","join","links","_link$content2","_link$meta2","text"],"sources":["../../../../src/component/componentDefinitions/NextStepsSectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n extractListItemText,\n firstImageSrc,\n} from './parse-utils';\nimport {\n getPartsByType,\n getLinks,\n type Part,\n type ListPart,\n type LinkPart,\n type IconPart,\n} from '../../parts/parts';\nimport type {\n NextStepsCompProps,\n NextStepsSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition } from '../section-definition';\n\nfunction linkToMarkdown(link: LinkPart): string {\n return `[${link.content?.trim() || ''}](${link.meta?.href || ''})`;\n}\n\nfunction appendInlineToken(current: string, token: string): string {\n const trimmed = token.trim();\n if (!trimmed) {\n return current;\n }\n if (!current) {\n return trimmed;\n }\n if (/^[,.;:!?)]/.test(trimmed)) {\n return `${current}${trimmed}`;\n }\n return `${current} ${trimmed}`;\n}\n\nfunction inlineBodyMarkdown(parts: Part[]): string | undefined {\n const body = parts.reduce((current, part) => {\n if (part.type === 'link') {\n return appendInlineToken(current, linkToMarkdown(part as LinkPart));\n }\n if (part.type === 'text' || part.type === 'richText') {\n const markdown = (part.meta?.markdown as string | undefined)?.trim();\n return appendInlineToken(current, markdown || part.content || '');\n }\n return current;\n }, '');\n\n return body || undefined;\n}\n\nexport class NextStepsSectionDefinition\n implements SectionDefinition<NextStepsSectionComponent>\n{\n sectionType = 'nextSteps' as const;\n patterns = [\n '(html_comment[section^=\"next\"] | html_comment[semantic^=\"next\"]) > h2 > image? > list{item[1-]:(icon | t)* > (t? > link)+}',\n '(html_comment[section^=\"next\"] | html_comment[semantic^=\"next\"]) > h2 > image? > (t | link)+',\n ];\n\n defaults: NextStepsCompProps = {\n title: 'Next Steps',\n body: '[Get started](/start)',\n backgroundImage: undefined,\n steps: [{ content: '[Get started](/start)' }],\n };\n\n fixtures: SectionFixture<NextStepsCompProps>[] = [\n {\n markdown: `<!-- section: next_steps -->\n\n## Next Steps\n\n- Check out [Documentation](/docs)\n- Try [Examples](/examples)`,\n expected: {\n title: 'Next Steps',\n steps: [\n { content: 'Check out [Documentation](/docs)' },\n { content: 'Try [Examples](/examples)' },\n ],\n },\n },\n ];\n\n parse(parts: Part[]): NextStepsCompProps {\n const title = headingText(parts, 2) || 'Next Steps';\n const backgroundImage = firstImageSrc(parts);\n const steps: { content: string; iconHint?: string }[] = [];\n let body: string | undefined;\n\n // Try list-based pattern first\n const lists = getPartsByType<ListPart>(parts, 'list');\n if (lists.length > 0) {\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n\n const iconPart = itemParts.find((p) => p.type === 'icon') as\n | IconPart\n | undefined;\n const iconHint = (iconPart?.meta as { iconHint?: string })?.iconHint;\n\n const contentFragments: string[] = [];\n for (const p of itemParts) {\n if (p.type === 'link') {\n const link = p as LinkPart;\n contentFragments.push(linkToMarkdown(link));\n } else if (p.type === 'text' || p.type === 'richText') {\n contentFragments.push(p.content?.trim() || '');\n }\n }\n const content =\n contentFragments.filter(Boolean).join(' ') ||\n extractListItemText(item);\n if (content.trim()) {\n steps.push({\n content: content.trim(),\n ...(iconHint ? { iconHint } : {}),\n });\n }\n }\n }\n } else {\n body = inlineBodyMarkdown(parts);\n }\n\n // Fallback: inline links pattern\n if (steps.length === 0) {\n const links = getLinks(parts);\n for (const link of links) {\n const text = link.content?.trim();\n const href = link.meta?.href;\n if (text && href) {\n steps.push({ content: linkToMarkdown(link) });\n }\n }\n }\n\n return {\n title,\n ...(body ? { body } : {}),\n ...(backgroundImage ? { backgroundImage } : {}),\n steps,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["headingText","bodyText","extractListItemText","firstImageSrc","getPartsByType","getLinks","linkToMarkdown","link","_link$content","_link$meta","content","trim","meta","href","appendInlineToken","current","token","trimmed","test","inlineBodyMarkdown","parts","body","reduce","part","type","_part$meta","markdown","undefined","NextStepsSectionDefinition","constructor","_defineProperty","title","backgroundImage","steps","expected","parse","chipsInlineInBody","lists","length","list","item","_list$meta","items","_item$meta","_iconPart$meta","itemParts","iconPart","find","p","iconHint","contentFragments","push","_p$content","filter","Boolean","join","links","_link$content2","_link$meta2","text"],"sources":["../../../../src/component/componentDefinitions/NextStepsSectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n bodyText,\n extractListItemText,\n firstImageSrc,\n} from './parse-utils';\nimport {\n getPartsByType,\n getLinks,\n type Part,\n type ListPart,\n type LinkPart,\n type IconPart,\n} from '../../parts/parts';\nimport type {\n NextStepsCompProps,\n NextStepsSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition } from '../section-definition';\n\nfunction linkToMarkdown(link: LinkPart): string {\n return `[${link.content?.trim() || ''}](${link.meta?.href || ''})`;\n}\n\nfunction appendInlineToken(current: string, token: string): string {\n const trimmed = token.trim();\n if (!trimmed) {\n return current;\n }\n if (!current) {\n return trimmed;\n }\n if (/^[,.;:!?)]/.test(trimmed)) {\n return `${current}${trimmed}`;\n }\n return `${current} ${trimmed}`;\n}\n\nfunction inlineBodyMarkdown(parts: Part[]): string | undefined {\n const body = parts.reduce((current, part) => {\n if (part.type === 'link') {\n return appendInlineToken(current, linkToMarkdown(part as LinkPart));\n }\n if (part.type === 'text' || part.type === 'richText') {\n const markdown = (part.meta?.markdown as string | undefined)?.trim();\n return appendInlineToken(current, markdown || part.content || '');\n }\n return current;\n }, '');\n\n return body || undefined;\n}\n\nexport class NextStepsSectionDefinition\n implements SectionDefinition<NextStepsSectionComponent>\n{\n sectionType = 'nextSteps' as const;\n patterns = [\n // Framing sentence (`t?`) then one chip per bullet — the authored shape.\n '(html_comment[section^=\"next\"] | html_comment[semantic^=\"next\"]) > h2 > image? > t? > list{item[1-]:(icon | t)* > (t? > link)+}',\n // Legacy inline shape: chips embedded in the prose. Still arrives from\n // sites whose next-steps prompt has not moved to the list shape.\n '(html_comment[section^=\"next\"] | html_comment[semantic^=\"next\"]) > h2 > image? > (t | link)+',\n ];\n\n defaults: NextStepsCompProps = {\n title: 'Next Steps',\n body: 'Where would you like to go next?',\n backgroundImage: undefined,\n steps: [{ content: '[Get started](/start)' }],\n };\n\n fixtures: SectionFixture<NextStepsCompProps>[] = [\n {\n markdown: `<!-- section:next-steps, semantic:next_steps -->\n\n## Find the right care for mature, sensitive skin\n\nWant to focus on rich hydrators and barrier builders?\n\n- [hydrating creams →](web5://ask/hydrating+creams+for+mature+skin)\n- [gentle resurfacing serums →](web5://ask/gentle+resurfacing+serums)`,\n expected: {\n title: 'Find the right care for mature, sensitive skin',\n body: 'Want to focus on rich hydrators and barrier builders?',\n steps: [\n {\n content:\n '[hydrating creams →](web5://ask/hydrating+creams+for+mature+skin)',\n },\n {\n content:\n '[gentle resurfacing serums →](web5://ask/gentle+resurfacing+serums)',\n },\n ],\n },\n },\n {\n markdown: `<!-- section: next_steps -->\n\n## Next Steps\n\n- Check out [Documentation](/docs)\n- Try [Examples](/examples)`,\n expected: {\n title: 'Next Steps',\n steps: [\n { content: 'Check out [Documentation](/docs)' },\n { content: 'Try [Examples](/examples)' },\n ],\n },\n },\n ];\n\n parse(parts: Part[]): NextStepsCompProps {\n const title = headingText(parts, 2) || 'Next Steps';\n const backgroundImage = firstImageSrc(parts);\n const steps: { content: string; iconHint?: string }[] = [];\n let body: string | undefined;\n let chipsInlineInBody = false;\n\n // Try list-based pattern first\n const lists = getPartsByType<ListPart>(parts, 'list');\n if (lists.length > 0) {\n // The framing sentence is the only top-level prose — list items live\n // under each list's meta.items, so bodyText never picks up a chip.\n body = bodyText(parts) || undefined;\n\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n\n const iconPart = itemParts.find((p) => p.type === 'icon') as\n | IconPart\n | undefined;\n const iconHint = (iconPart?.meta as { iconHint?: string })?.iconHint;\n\n const contentFragments: string[] = [];\n for (const p of itemParts) {\n if (p.type === 'link') {\n const link = p as LinkPart;\n contentFragments.push(linkToMarkdown(link));\n } else if (p.type === 'text' || p.type === 'richText') {\n contentFragments.push(p.content?.trim() || '');\n }\n }\n const content =\n contentFragments.filter(Boolean).join(' ') ||\n extractListItemText(item);\n if (content.trim()) {\n steps.push({\n content: content.trim(),\n ...(iconHint ? { iconHint } : {}),\n });\n }\n }\n }\n } else {\n body = inlineBodyMarkdown(parts);\n // body carries the chips as inline links — flag it so renderers show the\n // prose alone instead of repeating every chip as a row beneath it.\n chipsInlineInBody = Boolean(body);\n }\n\n // Fallback: inline links pattern\n if (steps.length === 0) {\n const links = getLinks(parts);\n for (const link of links) {\n const text = link.content?.trim();\n const href = link.meta?.href;\n if (text && href) {\n steps.push({ content: linkToMarkdown(link) });\n }\n }\n }\n\n return {\n title,\n ...(body ? { body } : {}),\n ...(chipsInlineInBody ? { chipsInlineInBody } : {}),\n ...(backgroundImage ? { backgroundImage } : {}),\n steps,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -4,7 +4,24 @@ import { DIAGNOSTIC_TYPES } from '../diagnosticTypes.js';
4
4
  export class TextBlockSectionDefinition {
5
5
  constructor() {
6
6
  _defineProperty(this, "sectionType", 'textBlock');
7
- _defineProperty(this, "patterns", ['html_comment? > h2 > t > callout']);
7
+ // The trailing callout is OPTIONAL. A heading plus running copy is the shape
8
+ // stores emit constantly for explainer content, and requiring the blockquote
9
+ // meant those blocks matched no definition at all and fell through to
10
+ // `FallbackSectionDefinition` — rendered as undifferentiated prose with no
11
+ // section treatment. `parse()` already tolerates a missing callout (it only
12
+ // rejects when title AND description are empty).
13
+ //
14
+ // NOTE for registry authors: with the callout optional this also matches a
15
+ // bare `h2 > t`, and a pattern matches a PREFIX of the block. Register
16
+ // `textBlock` BELOW every definition whose block opens `h2 > t` — entity,
17
+ // entityCollection, listItemsSection, featureCards, ctaBanner, comparison,
18
+ // kpi, nextSteps. Above them it claims the heading + intro paragraph off the
19
+ // front of the block and strands the list / links / table that follow
20
+ // (`EntitySectionDefinition` allows `h2 > (t | callout)* > links…`, and
21
+ // `listItemsSection` / `ctaBanner` are the same shape). `createSdkRegistry`
22
+ // and the client registries in this repo order it that way; a client
23
+ // registry living outside this repo has to do the same.
24
+ _defineProperty(this, "patterns", ['html_comment? > h2 > t > callout?']);
8
25
  _defineProperty(this, "defaults", {
9
26
  title: 'Text Block Title',
10
27
  description: 'Description text.',
@@ -39,6 +56,15 @@ The platform scales with your needs.
39
56
  text: 'Start small with Go, then expand to the full suite as your data maturity grows.'
40
57
  }
41
58
  }
59
+ }, {
60
+ markdown: `## How to choose between a clinical serum and a nourishing dry oil
61
+
62
+ Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.`,
63
+ expected: {
64
+ title: 'How to choose between a clinical serum and a nourishing dry oil',
65
+ description: 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.',
66
+ callout: undefined
67
+ }
42
68
  }]);
43
69
  }
44
70
  parse(parts, context) {
@@ -1 +1 @@
1
- {"version":3,"names":["headingMarkdown","bodyText","calloutFromParts","DIAGNOSTIC_TYPES","TextBlockSectionDefinition","constructor","_defineProperty","title","description","callout","text","markdown","expected","parse","parts","context","reportDiagnostic","SECTION_REJECTED"],"sources":["../../../../src/component/componentDefinitions/TextBlockSectionDefinition.ts"],"sourcesContent":["import type { Part } from '../../parts/parts';\nimport { headingMarkdown, bodyText, calloutFromParts } from './parse-utils';\nimport type {\n TextBlockCompProps,\n TextBlockSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\nexport class TextBlockSectionDefinition\n implements SectionDefinition<TextBlockSectionComponent>\n{\n sectionType = 'textBlock' as const;\n patterns = ['html_comment? > h2 > t > callout'];\n\n defaults: TextBlockCompProps = {\n title: 'Text Block Title',\n description: 'Description text.',\n callout: { text: 'A key insight or quote.' },\n };\n\n fixtures: SectionFixture<TextBlockCompProps>[] = [\n {\n markdown: `## Choosing the Right Liquid Data Option\n\nLiquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.\n\n> If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.`,\n expected: {\n title: 'Choosing the Right Liquid Data Option',\n description:\n 'Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.',\n callout: {\n text: 'If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.',\n },\n },\n },\n {\n markdown: `<!-- section: textBlock -->\n## Key Takeaway\n\nThe platform scales with your needs.\n\n> Start small with Go, then expand to the full suite as your data maturity grows.`,\n expected: {\n title: 'Key Takeaway',\n description: 'The platform scales with your needs.',\n callout: {\n text: 'Start small with Go, then expand to the full suite as your data maturity grows.',\n },\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): TextBlockCompProps | null {\n const title = headingMarkdown(parts, 2) || '';\n const description = bodyText(parts) || '';\n const callout = calloutFromParts(parts);\n\n if (!title && !description) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'textBlock: both title and description are empty',\n );\n return null;\n }\n\n return { title, description, callout };\n }\n}\n"],"mappings":";AACA,SAASA,eAAe,EAAEC,QAAQ,EAAEC,gBAAgB,QAAQ,eAAe;AAO3E,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,OAAO,MAAMC,0BAA0B,CAEvC;EAAAC,YAAA;IAAAC,eAAA,sBACgB,WAAW;IAAAA,eAAA,mBACd,CAAC,kCAAkC,CAAC;IAAAA,eAAA,mBAEhB;MAC7BC,KAAK,EAAE,kBAAkB;MACzBC,WAAW,EAAE,mBAAmB;MAChCC,OAAO,EAAE;QAAEC,IAAI,EAAE;MAA0B;IAC7C,CAAC;IAAAJ,eAAA,mBAEgD,CAC/C;MACEK,QAAQ,EAAE;AAChB;AACA;AACA;AACA,kQAAkQ;MAC5PC,QAAQ,EAAE;QACRL,KAAK,EAAE,uCAAuC;QAC9CC,WAAW,EACT,iLAAiL;QACnLC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA;AACA;AACA;AACA,kFAAkF;MAC5EC,QAAQ,EAAE;QACRL,KAAK,EAAE,cAAc;QACrBC,WAAW,EAAE,sCAAsC;QACnDC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,CACF;EAAA;EAEDG,KAAKA,CAACC,KAAa,EAAEC,OAAsB,EAA6B;IACtE,MAAMR,KAAK,GAAGP,eAAe,CAACc,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE;IAC7C,MAAMN,WAAW,GAAGP,QAAQ,CAACa,KAAK,CAAC,IAAI,EAAE;IACzC,MAAML,OAAO,GAAGP,gBAAgB,CAACY,KAAK,CAAC;IAEvC,IAAI,CAACP,KAAK,IAAI,CAACC,WAAW,EAAE;MAC1BO,OAAO,YAAPA,OAAO,CAAEC,gBAAgB,YAAzBD,OAAO,CAAEC,gBAAgB,CACvBb,gBAAgB,CAACc,gBAAgB,EACjC,iDACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,OAAO;MAAEV,KAAK;MAAEC,WAAW;MAAEC;IAAQ,CAAC;EACxC;AACF","ignoreList":[]}
1
+ {"version":3,"names":["headingMarkdown","bodyText","calloutFromParts","DIAGNOSTIC_TYPES","TextBlockSectionDefinition","constructor","_defineProperty","title","description","callout","text","markdown","expected","undefined","parse","parts","context","reportDiagnostic","SECTION_REJECTED"],"sources":["../../../../src/component/componentDefinitions/TextBlockSectionDefinition.ts"],"sourcesContent":["import type { Part } from '../../parts/parts';\nimport { headingMarkdown, bodyText, calloutFromParts } from './parse-utils';\nimport type {\n TextBlockCompProps,\n TextBlockSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\nexport class TextBlockSectionDefinition\n implements SectionDefinition<TextBlockSectionComponent>\n{\n sectionType = 'textBlock' as const;\n // The trailing callout is OPTIONAL. A heading plus running copy is the shape\n // stores emit constantly for explainer content, and requiring the blockquote\n // meant those blocks matched no definition at all and fell through to\n // `FallbackSectionDefinition` — rendered as undifferentiated prose with no\n // section treatment. `parse()` already tolerates a missing callout (it only\n // rejects when title AND description are empty).\n //\n // NOTE for registry authors: with the callout optional this also matches a\n // bare `h2 > t`, and a pattern matches a PREFIX of the block. Register\n // `textBlock` BELOW every definition whose block opens `h2 > t` — entity,\n // entityCollection, listItemsSection, featureCards, ctaBanner, comparison,\n // kpi, nextSteps. Above them it claims the heading + intro paragraph off the\n // front of the block and strands the list / links / table that follow\n // (`EntitySectionDefinition` allows `h2 > (t | callout)* > links…`, and\n // `listItemsSection` / `ctaBanner` are the same shape). `createSdkRegistry`\n // and the client registries in this repo order it that way; a client\n // registry living outside this repo has to do the same.\n patterns = ['html_comment? > h2 > t > callout?'];\n\n defaults: TextBlockCompProps = {\n title: 'Text Block Title',\n description: 'Description text.',\n callout: { text: 'A key insight or quote.' },\n };\n\n fixtures: SectionFixture<TextBlockCompProps>[] = [\n {\n markdown: `## Choosing the Right Liquid Data Option\n\nLiquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.\n\n> If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.`,\n expected: {\n title: 'Choosing the Right Liquid Data Option',\n description:\n 'Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.',\n callout: {\n text: 'If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.',\n },\n },\n },\n {\n markdown: `<!-- section: textBlock -->\n## Key Takeaway\n\nThe platform scales with your needs.\n\n> Start small with Go, then expand to the full suite as your data maturity grows.`,\n expected: {\n title: 'Key Takeaway',\n description: 'The platform scales with your needs.',\n callout: {\n text: 'Start small with Go, then expand to the full suite as your data maturity grows.',\n },\n },\n },\n {\n markdown: `## How to choose between a clinical serum and a nourishing dry oil\n\nClinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.`,\n expected: {\n title: 'How to choose between a clinical serum and a nourishing dry oil',\n description:\n 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.',\n callout: undefined,\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): TextBlockCompProps | null {\n const title = headingMarkdown(parts, 2) || '';\n const description = bodyText(parts) || '';\n const callout = calloutFromParts(parts);\n\n if (!title && !description) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'textBlock: both title and description are empty',\n );\n return null;\n }\n\n return { title, description, callout };\n }\n}\n"],"mappings":";AACA,SAASA,eAAe,EAAEC,QAAQ,EAAEC,gBAAgB,QAAQ,eAAe;AAO3E,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,OAAO,MAAMC,0BAA0B,CAEvC;EAAAC,YAAA;IAAAC,eAAA,sBACgB,WAAW;IACzB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAAAA,eAAA,mBACW,CAAC,mCAAmC,CAAC;IAAAA,eAAA,mBAEjB;MAC7BC,KAAK,EAAE,kBAAkB;MACzBC,WAAW,EAAE,mBAAmB;MAChCC,OAAO,EAAE;QAAEC,IAAI,EAAE;MAA0B;IAC7C,CAAC;IAAAJ,eAAA,mBAEgD,CAC/C;MACEK,QAAQ,EAAE;AAChB;AACA;AACA;AACA,kQAAkQ;MAC5PC,QAAQ,EAAE;QACRL,KAAK,EAAE,uCAAuC;QAC9CC,WAAW,EACT,iLAAiL;QACnLC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA;AACA;AACA;AACA,kFAAkF;MAC5EC,QAAQ,EAAE;QACRL,KAAK,EAAE,cAAc;QACrBC,WAAW,EAAE,sCAAsC;QACnDC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA,gKAAgK;MAC1JC,QAAQ,EAAE;QACRL,KAAK,EAAE,iEAAiE;QACxEC,WAAW,EACT,iKAAiK;QACnKC,OAAO,EAAEI;MACX;IACF,CAAC,CACF;EAAA;EAEDC,KAAKA,CAACC,KAAa,EAAEC,OAAsB,EAA6B;IACtE,MAAMT,KAAK,GAAGP,eAAe,CAACe,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE;IAC7C,MAAMP,WAAW,GAAGP,QAAQ,CAACc,KAAK,CAAC,IAAI,EAAE;IACzC,MAAMN,OAAO,GAAGP,gBAAgB,CAACa,KAAK,CAAC;IAEvC,IAAI,CAACR,KAAK,IAAI,CAACC,WAAW,EAAE;MAC1BQ,OAAO,YAAPA,OAAO,CAAEC,gBAAgB,YAAzBD,OAAO,CAAEC,gBAAgB,CACvBd,gBAAgB,CAACe,gBAAgB,EACjC,iDACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,OAAO;MAAEX,KAAK;MAAEC,WAAW;MAAEC;IAAQ,CAAC;EACxC;AACF","ignoreList":[]}
@@ -46,6 +46,13 @@ export function createSdkRegistry() {
46
46
  // Collection entities are claimed by their own definition first — it is a
47
47
  // strictly narrower match than EntitySectionDefinition, which would
48
48
  // otherwise swallow collection, product and article blocks alike.
49
- .register(new EntityCollectionSectionDefinition()).register(new EntitySectionDefinition()).register(new HeroEntitySectionDefinition()).register(new HeroSectionDefinition()).register(new FeatureCardsSectionDefinition()).register(new TextBlockSectionDefinition()).register(new ListItemsSectionDefinition()).register(new FeatureSection9PlusDefinition()).register(new ComparisonSectionDefinition()).register(new HtmlCommentSectionDefinition()).register(new CtaBannerSectionDefinition()).register(new CalloutSectionDefinition()).register(new FallbackSectionDefinition()).register(new ErrorSectionDefinition());
49
+ .register(new EntityCollectionSectionDefinition()).register(new EntitySectionDefinition()).register(new HeroEntitySectionDefinition()).register(new HeroSectionDefinition()).register(new FeatureCardsSectionDefinition()).register(new ListItemsSectionDefinition()).register(new FeatureSection9PlusDefinition()).register(new ComparisonSectionDefinition()).register(new HtmlCommentSectionDefinition()).register(new CtaBannerSectionDefinition())
50
+ // textBlock comes after every definition whose block opens `h2 > t`
51
+ // (entity, listItems, featureCards, ctaBanner, comparison, …). Its
52
+ // trailing callout is optional, so its pattern also matches a bare
53
+ // `h2 > t`, and a pattern matches a PREFIX of the block — registered
54
+ // above those it would claim the heading + intro paragraph and strand
55
+ // the list / links / table that follow in a separate section.
56
+ .register(new TextBlockSectionDefinition()).register(new CalloutSectionDefinition()).register(new FallbackSectionDefinition()).register(new ErrorSectionDefinition());
50
57
  }
51
58
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ComparisonSectionDefinition","TextBlockSectionDefinition","HeroSectionDefinition","HeroEntitySectionDefinition","KpiSectionDefinition","FeatureCardsSectionDefinition","EntitySectionDefinition","EntityCollectionSectionDefinition","CtaBannerSectionDefinition","CalloutSectionDefinition","NextStepsSectionDefinition","FeatureSection9PlusDefinition","ListItemsSectionDefinition","SkipNodesSectionDefinition","HtmlCommentSectionDefinition","SearchSectionDefinition","ErrorSectionDefinition","FallbackSectionDefinition","ComponentRegistry","createSdkRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return (\n new ComponentRegistry<null>(null)\n .register(new SkipNodesSectionDefinition())\n .register(new SearchSectionDefinition())\n .register(new KpiSectionDefinition())\n .register(new NextStepsSectionDefinition())\n // Collection entities are claimed by their own definition first — it is a\n // strictly narrower match than EntitySectionDefinition, which would\n // otherwise swallow collection, product and article blocks alike.\n .register(new EntityCollectionSectionDefinition())\n .register(new EntitySectionDefinition())\n .register(new HeroEntitySectionDefinition())\n .register(new HeroSectionDefinition())\n .register(new FeatureCardsSectionDefinition())\n .register(new TextBlockSectionDefinition())\n .register(new ListItemsSectionDefinition())\n .register(new FeatureSection9PlusDefinition())\n .register(new ComparisonSectionDefinition())\n .register(new HtmlCommentSectionDefinition())\n .register(new CtaBannerSectionDefinition())\n .register(new CalloutSectionDefinition())\n .register(new FallbackSectionDefinition())\n .register(new ErrorSectionDefinition())\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["ComparisonSectionDefinition","TextBlockSectionDefinition","HeroSectionDefinition","HeroEntitySectionDefinition","KpiSectionDefinition","FeatureCardsSectionDefinition","EntitySectionDefinition","EntityCollectionSectionDefinition","CtaBannerSectionDefinition","CalloutSectionDefinition","NextStepsSectionDefinition","FeatureSection9PlusDefinition","ListItemsSectionDefinition","SkipNodesSectionDefinition","HtmlCommentSectionDefinition","SearchSectionDefinition","ErrorSectionDefinition","FallbackSectionDefinition","ComponentRegistry","createSdkRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return (\n new ComponentRegistry<null>(null)\n .register(new SkipNodesSectionDefinition())\n .register(new SearchSectionDefinition())\n .register(new KpiSectionDefinition())\n .register(new NextStepsSectionDefinition())\n // Collection entities are claimed by their own definition first — it is a\n // strictly narrower match than EntitySectionDefinition, which would\n // otherwise swallow collection, product and article blocks alike.\n .register(new EntityCollectionSectionDefinition())\n .register(new EntitySectionDefinition())\n .register(new HeroEntitySectionDefinition())\n .register(new HeroSectionDefinition())\n .register(new FeatureCardsSectionDefinition())\n .register(new ListItemsSectionDefinition())\n .register(new FeatureSection9PlusDefinition())\n .register(new ComparisonSectionDefinition())\n .register(new HtmlCommentSectionDefinition())\n .register(new CtaBannerSectionDefinition())\n // textBlock comes after every definition whose block opens `h2 > t`\n // (entity, listItems, featureCards, ctaBanner, comparison, …). Its\n // trailing callout is optional, so its pattern also matches a bare\n // `h2 > t`, and a pattern matches a PREFIX of the block — registered\n // above those it would claim the heading + intro paragraph and strand\n // the list / links / table that follow in a separate section.\n .register(new TextBlockSectionDefinition())\n .register(new CalloutSectionDefinition())\n .register(new FallbackSectionDefinition())\n .register(new ErrorSectionDefinition())\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../../src/component/types.ts"],"sourcesContent":["import type { FC } from 'react';\nimport type { Callout } from '../types/callout';\n\n/** Props extracted from markdown (base layer). */\nexport interface BaseCompProps {}\nexport interface SlotCompProps extends BaseCompProps {\n callout?: Callout;\n}\n\nexport interface SectionCompProps extends BaseCompProps {\n callout?: Callout;\n}\n\n/** Section props with a slot. TSlot enforces which slot component this section accepts. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface SectionCompPropsWithSlot<TSlot extends FC<any> = FC<any>>\n extends SectionCompProps {\n slot?: TSlot;\n}\n\n// ----------------------\n// Base Components\n// ----------------------\n\nexport interface TextCompProps extends BaseCompProps {\n content: string;\n variant?: 'h1' | 'h2' | 'body' | 'caption';\n}\n\nexport interface ButtonCompProps extends BaseCompProps {\n label: string;\n variant?: 'primary' | 'secondary' | 'ghost';\n onClick?: string;\n}\n\nexport interface ImageCompProps extends BaseCompProps {\n src: string;\n alt: string;\n ratio?: '16:9' | '4:3' | '1:1' | '9:16' | '3:4';\n}\n\nexport interface BadgeCompProps extends BaseCompProps {\n label: string;\n color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error';\n}\n\n// ----------------------\n// Hero Button (aligned to HeroSection1Button)\n// ----------------------\n\nexport interface HeroButton {\n id: string;\n text: string;\n variant?: 'primary' | 'secondary';\n onClick?: string;\n}\n\n// ----------------------\n// Slot Components\n// ----------------------\n\nexport interface KpiItemCompProps extends SlotCompProps {\n title: string;\n description: string;\n icon?: string;\n}\n\n/** Feature item — aligned to web50-server-ui Feature interface */\nexport interface FeatureItemCompProps extends SlotCompProps {\n title?: string;\n description?: string;\n icon?: string;\n}\n\n/** Feature card — aligned to web50-server-ui FeatureCard */\nexport interface FeatureCardCompProps extends SlotCompProps {\n title: string;\n description: string;\n imageUrl?: string;\n imageFromText?: boolean;\n linkText?: string;\n linkHref?: string;\n callout?: Callout;\n}\n\n/** Resolved entity data (populated at runtime via useResolveGenericEntityData) */\nexport interface EntityItemData {\n url: string;\n title: string;\n type: string;\n description?: string;\n excerpt?: string;\n imageUrl?: string;\n date?: string;\n publishDate?: string;\n author?: string;\n cmsItemId?: string;\n usage?: number;\n tags?: string[];\n /** Product vendor / brand name (e.g. \"HOKA\") */\n vendor?: string;\n /** Formatted price string (e.g. \"542.00 NIS\") */\n price?: string;\n /** Secondary product image URL — shown on hover */\n secondaryImageUrl?: string;\n /** Available sizes for the product */\n sizes?: string[];\n /** Original price before discount (formatted, e.g. \"494.00 NIS\") — shown with strikethrough */\n compareAtPrice?: string;\n /** Discount percentage (e.g. \"30% OFF\") */\n discountPercent?: string;\n /** Product variants with IDs and availability — used for add-to-cart and size display */\n variants?: {\n label: string;\n variantId: string;\n available: boolean;\n selectedOptions?: { name: string; value: string }[];\n price?: string;\n compareAtPrice?: string;\n }[];\n /** All product image URLs (not just featured + secondary) */\n allImages?: string[];\n /** Product option groups (e.g. Size, Color) with their available values */\n options?: { name: string; values: string[] }[];\n}\n\n/** Single entity item within an entity section */\nexport interface EntityItem {\n entityId: string;\n linkText?: string;\n entityType: string;\n entityUrl: string;\n description?: string;\n imageUrl?: string;\n /** Per-item callout from a blockquote inside the list item */\n callout?: Callout;\n /** Resolved at runtime via useResolveGenericEntityData hook; not produced by parse() */\n data?: EntityItemData;\n}\n\n// ---------------------------------------------------------------------------\n// Deprecated aliases — kept for seed-components compilation\n// ---------------------------------------------------------------------------\n/** @deprecated Use EntityItemData */\nexport type GenericEntityData = EntityItemData;\n/** @deprecated Use EntityItemData */\nexport type SolutionEntityData = EntityItemData;\n/** @deprecated Use EntityItemData */\nexport type BlogEntityData = EntityItemData;\n/** @deprecated Use EntityItem */\nexport type GenericEntityCompProps = EntityItem;\n\n/** Comparison row — aligned to web50-server-ui ComparisonRow */\nexport interface ComparisonRow {\n feature: string;\n iconHint?: string;\n values: (boolean | string)[];\n}\n\nexport interface ComparisonColumn {\n label: string;\n href?: string;\n entityId?: string;\n entityType?: string;\n}\n\n/** @deprecated Use Callout from types/callout instead */\nexport interface AiNarrativeCompProps extends SlotCompProps {\n content: string;\n}\n\n// ----------------------\n// Section Components\n// ----------------------\n\n/** Hero — aligned to HeroSection1Props */\nexport interface HeroCompProps extends SectionCompProps {\n headline: string;\n badge?: string | { text: string; showIndicator?: boolean };\n content?: string;\n buttons?: HeroButton[];\n image?: string;\n trailingList?: string;\n leadingQuote?: string;\n}\n\n/**\n * Entity hero — a hero section whose body carries one or more web5 entity\n * links (`web5://entity/...`). Shares the hero framing fields with\n * {@link HeroCompProps} but, instead of CTA buttons, surfaces the entities as\n * resolvable {@link EntityItem}s for rich rendering.\n */\nexport interface HeroEntityCompProps extends SectionCompProps {\n headline: string;\n badge?: string | { text: string; showIndicator?: boolean };\n content?: string;\n image?: string;\n leadingQuote?: string;\n items: EntityItem[];\n}\n\n/** KPI — aligned to KpiSectionProps */\nexport interface KpiCompProps\n extends SectionCompPropsWithSlot<KpiItemComponent> {\n title: string;\n items: KpiItemCompProps[];\n}\n\n/** Feature cards — aligned to FeatureCardsSectionProps */\nexport interface FeatureCardsCompProps extends SectionCompProps {\n cards: FeatureCardCompProps[];\n}\n\n/** Unified entity section — replaces EntityCompProps, SolutionEntityCompProps, BlogEntityCompProps */\nexport interface EntityCompProps extends SectionCompProps {\n title: string;\n description?: string;\n items: EntityItem[];\n}\n\n/** Comparison — aligned to ComparisonSection1Props */\nexport interface ComparisonCompProps extends SectionCompProps {\n title: string;\n description?: string;\n columnLabels: string[];\n columns?: ComparisonColumn[];\n rows: ComparisonRow[];\n featureColumnLabel?: string;\n ctaText?: string;\n ctaHref?: string;\n}\n\n/** General text — aligned to GeneralTextSectionProps (used by Fallback) */\nexport interface GeneralTextCompProps extends SectionCompProps {\n markdown: string;\n}\n\n/** Callout — aligned to CalloutSectionProps */\nexport interface CalloutCompProps extends SectionCompProps {\n callouts: Callout[];\n title?: string;\n relatedLinks?: { text: string; url: string }[];\n}\n\n/** Next steps — aligned to NextStepsSectionProps */\nexport interface NextStepsCompProps extends SectionCompProps {\n title: string;\n body?: string;\n backgroundImage?: string;\n steps: { content: string; iconHint?: string }[];\n}\n\n/** Feature section 9+ — aligned to FeatureSection9PlusProps */\nexport interface FeatureSection9PlusCompProps extends SectionCompProps {\n title: string;\n description?: string;\n features: { title?: string; description: string; iconHint?: string }[];\n}\n\n/** List items section — title + a list of feature items. */\nexport interface ListItemsSectionCompProps extends SectionCompProps {\n title: string;\n features: { title?: string; description: string }[];\n}\n\nexport type ListItemsSectionComponent = FC<ListItemsSectionCompProps>;\n\n/** Error — aligned to ErrorSection */\nexport interface ErrorCompProps extends SectionCompProps {\n type: import('../errors/conversationErrorTypes').ConversationErrorType;\n}\n\n/** Skip/HTML/Search — null-component parsers */\nexport interface NullCompProps extends SectionCompProps {}\n\n/** @deprecated Use EntityCompProps */\nexport type SolutionEntityCompProps = EntityCompProps;\n/** @deprecated Use EntityCompProps */\nexport type BlogEntityCompProps = EntityCompProps;\n\n/** CTA Banner — dark purple gradient card with headline, description, and pill link buttons */\nexport interface CtaBannerCompProps extends SectionCompProps {\n headline: string;\n description?: string;\n links: { text: string; href: string }[];\n /** Contextual background image — resolved from allowed keywords during parse() */\n imageUrl?: string;\n imageFromText?: boolean;\n}\n\nexport type CtaBannerSectionComponent = FC<CtaBannerCompProps>;\n\n/** Text block — heading + body with an optional pullquote callout on the side */\nexport interface TextBlockCompProps extends SectionCompProps {\n title: string;\n description: string;\n}\n\n/** Personalized narrative — standalone section with no parse() definition */\nexport interface PersonalizedNarrativeCompProps extends SectionCompProps {\n title: string;\n content?: string;\n}\n\n// --------------------------------\n// Types of component - all components\n// --------------------------------\n\nexport type Component = BaseComponent | SlotComponent | SectionComponent;\n\nexport type BaseComponent = FC<BaseCompProps>;\nexport type SlotComponent = FC<SlotCompProps>;\nexport type SectionComponent = FC<SectionCompProps>;\n\n// Base Components\nexport type TextComponent = FC<TextCompProps>;\nexport type ButtonComponent = FC<ButtonCompProps>;\nexport type ImageComponent = FC<ImageCompProps>;\nexport type BadgeComponent = FC<BadgeCompProps>;\n\n// Slot Components\nexport type KpiItemComponent = FC<KpiItemCompProps>;\nexport type FeatureItemComponent = FC<FeatureItemCompProps>;\nexport type FeatureCardComponent = FC<FeatureCardCompProps>;\n/** @deprecated Use FC<EntityItem> */\nexport type GenericEntityComponent = FC<EntityItem>;\nexport type AiNarrativeComponent = FC<AiNarrativeCompProps>;\n\n// Section Components\nexport type ComparisonSectionComponent = FC<ComparisonCompProps>;\nexport type GeneralTextSectionComponent = FC<GeneralTextCompProps>;\nexport type TextBlockSectionComponent = FC<TextBlockCompProps>;\nexport type HeroSectionComponent = FC<HeroCompProps>;\nexport type HeroEntitySectionComponent = FC<HeroEntityCompProps>;\n\n// section components with slots\nexport type KpiSectionComponent = FC<KpiCompProps>;\nexport type FeatureCardsSectionComponent = FC<FeatureCardsCompProps>;\nexport type EntitySectionComponent = FC<EntityCompProps>;\n\n// New section component types for Phase 4\nexport type CalloutSectionComponent = FC<CalloutCompProps>;\nexport type NextStepsSectionComponent = FC<NextStepsCompProps>;\nexport type FeatureSection9PlusSectionComponent =\n FC<FeatureSection9PlusCompProps>;\nexport type NullSectionComponent = FC<NullCompProps>;\nexport type ErrorSectionComponent = FC<ErrorCompProps>;\nexport type SolutionEntitySectionComponent = FC<SolutionEntityCompProps>;\nexport type BlogEntitySectionComponent = FC<BlogEntityCompProps>;\nexport type PersonalizedNarrativeSectionComponent =\n FC<PersonalizedNarrativeCompProps>;\n\nexport type PropsOf<T> = T extends (props: infer P) => unknown ? P : never;\n\nexport interface SectionFixture<TProps> {\n markdown: string;\n expected: Partial<TProps>;\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["../../../src/component/types.ts"],"sourcesContent":["import type { FC } from 'react';\nimport type { Callout } from '../types/callout';\n\n/** Props extracted from markdown (base layer). */\nexport interface BaseCompProps {}\nexport interface SlotCompProps extends BaseCompProps {\n callout?: Callout;\n}\n\nexport interface SectionCompProps extends BaseCompProps {\n callout?: Callout;\n}\n\n/** Section props with a slot. TSlot enforces which slot component this section accepts. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface SectionCompPropsWithSlot<TSlot extends FC<any> = FC<any>>\n extends SectionCompProps {\n slot?: TSlot;\n}\n\n// ----------------------\n// Base Components\n// ----------------------\n\nexport interface TextCompProps extends BaseCompProps {\n content: string;\n variant?: 'h1' | 'h2' | 'body' | 'caption';\n}\n\nexport interface ButtonCompProps extends BaseCompProps {\n label: string;\n variant?: 'primary' | 'secondary' | 'ghost';\n onClick?: string;\n}\n\nexport interface ImageCompProps extends BaseCompProps {\n src: string;\n alt: string;\n ratio?: '16:9' | '4:3' | '1:1' | '9:16' | '3:4';\n}\n\nexport interface BadgeCompProps extends BaseCompProps {\n label: string;\n color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error';\n}\n\n// ----------------------\n// Hero Button (aligned to HeroSection1Button)\n// ----------------------\n\nexport interface HeroButton {\n id: string;\n text: string;\n variant?: 'primary' | 'secondary';\n onClick?: string;\n}\n\n// ----------------------\n// Slot Components\n// ----------------------\n\nexport interface KpiItemCompProps extends SlotCompProps {\n title: string;\n description: string;\n icon?: string;\n}\n\n/** Feature item — aligned to web50-server-ui Feature interface */\nexport interface FeatureItemCompProps extends SlotCompProps {\n title?: string;\n description?: string;\n icon?: string;\n}\n\n/** Feature card — aligned to web50-server-ui FeatureCard */\nexport interface FeatureCardCompProps extends SlotCompProps {\n title: string;\n description: string;\n imageUrl?: string;\n imageFromText?: boolean;\n linkText?: string;\n linkHref?: string;\n callout?: Callout;\n}\n\n/** Resolved entity data (populated at runtime via useResolveGenericEntityData) */\nexport interface EntityItemData {\n url: string;\n title: string;\n type: string;\n description?: string;\n excerpt?: string;\n imageUrl?: string;\n date?: string;\n publishDate?: string;\n author?: string;\n cmsItemId?: string;\n usage?: number;\n tags?: string[];\n /** Product vendor / brand name (e.g. \"HOKA\") */\n vendor?: string;\n /** Formatted price string (e.g. \"542.00 NIS\") */\n price?: string;\n /** Secondary product image URL — shown on hover */\n secondaryImageUrl?: string;\n /** Available sizes for the product */\n sizes?: string[];\n /** Original price before discount (formatted, e.g. \"494.00 NIS\") — shown with strikethrough */\n compareAtPrice?: string;\n /** Discount percentage (e.g. \"30% OFF\") */\n discountPercent?: string;\n /** Product variants with IDs and availability — used for add-to-cart and size display */\n variants?: {\n label: string;\n variantId: string;\n available: boolean;\n selectedOptions?: { name: string; value: string }[];\n price?: string;\n compareAtPrice?: string;\n }[];\n /** All product image URLs (not just featured + secondary) */\n allImages?: string[];\n /** Product option groups (e.g. Size, Color) with their available values */\n options?: { name: string; values: string[] }[];\n}\n\n/** Single entity item within an entity section */\nexport interface EntityItem {\n entityId: string;\n linkText?: string;\n entityType: string;\n entityUrl: string;\n description?: string;\n imageUrl?: string;\n /** Per-item callout from a blockquote inside the list item */\n callout?: Callout;\n /** Resolved at runtime via useResolveGenericEntityData hook; not produced by parse() */\n data?: EntityItemData;\n}\n\n// ---------------------------------------------------------------------------\n// Deprecated aliases — kept for seed-components compilation\n// ---------------------------------------------------------------------------\n/** @deprecated Use EntityItemData */\nexport type GenericEntityData = EntityItemData;\n/** @deprecated Use EntityItemData */\nexport type SolutionEntityData = EntityItemData;\n/** @deprecated Use EntityItemData */\nexport type BlogEntityData = EntityItemData;\n/** @deprecated Use EntityItem */\nexport type GenericEntityCompProps = EntityItem;\n\n/** Comparison row — aligned to web50-server-ui ComparisonRow */\nexport interface ComparisonRow {\n feature: string;\n iconHint?: string;\n values: (boolean | string)[];\n}\n\nexport interface ComparisonColumn {\n label: string;\n href?: string;\n entityId?: string;\n entityType?: string;\n}\n\n/** @deprecated Use Callout from types/callout instead */\nexport interface AiNarrativeCompProps extends SlotCompProps {\n content: string;\n}\n\n// ----------------------\n// Section Components\n// ----------------------\n\n/** Hero — aligned to HeroSection1Props */\nexport interface HeroCompProps extends SectionCompProps {\n headline: string;\n badge?: string | { text: string; showIndicator?: boolean };\n content?: string;\n buttons?: HeroButton[];\n image?: string;\n trailingList?: string;\n leadingQuote?: string;\n}\n\n/**\n * Entity hero — a hero section whose body carries one or more web5 entity\n * links (`web5://entity/...`). Shares the hero framing fields with\n * {@link HeroCompProps} but, instead of CTA buttons, surfaces the entities as\n * resolvable {@link EntityItem}s for rich rendering.\n */\nexport interface HeroEntityCompProps extends SectionCompProps {\n headline: string;\n badge?: string | { text: string; showIndicator?: boolean };\n content?: string;\n image?: string;\n leadingQuote?: string;\n items: EntityItem[];\n}\n\n/** KPI — aligned to KpiSectionProps */\nexport interface KpiCompProps\n extends SectionCompPropsWithSlot<KpiItemComponent> {\n title: string;\n items: KpiItemCompProps[];\n}\n\n/** Feature cards — aligned to FeatureCardsSectionProps */\nexport interface FeatureCardsCompProps extends SectionCompProps {\n cards: FeatureCardCompProps[];\n}\n\n/** Unified entity section — replaces EntityCompProps, SolutionEntityCompProps, BlogEntityCompProps */\nexport interface EntityCompProps extends SectionCompProps {\n title: string;\n description?: string;\n items: EntityItem[];\n}\n\n/** Comparison — aligned to ComparisonSection1Props */\nexport interface ComparisonCompProps extends SectionCompProps {\n title: string;\n description?: string;\n columnLabels: string[];\n columns?: ComparisonColumn[];\n rows: ComparisonRow[];\n featureColumnLabel?: string;\n ctaText?: string;\n ctaHref?: string;\n}\n\n/** General text — aligned to GeneralTextSectionProps (used by Fallback) */\nexport interface GeneralTextCompProps extends SectionCompProps {\n markdown: string;\n}\n\n/** Callout — aligned to CalloutSectionProps */\nexport interface CalloutCompProps extends SectionCompProps {\n callouts: Callout[];\n title?: string;\n relatedLinks?: { text: string; url: string }[];\n}\n\n/** Next steps — aligned to NextStepsSectionProps */\nexport interface NextStepsCompProps extends SectionCompProps {\n title: string;\n body?: string;\n /**\n * True when the chips are already rendered inline inside `body`. Renderers\n * must show `body` alone in that case — listing `steps` as well repeats every\n * chip. `steps` stays populated either way; it is the machine-readable chip\n * list (the scroll chips under the answer are built from it).\n */\n chipsInlineInBody?: boolean;\n backgroundImage?: string;\n steps: { content: string; iconHint?: string }[];\n}\n\n/** Feature section 9+ — aligned to FeatureSection9PlusProps */\nexport interface FeatureSection9PlusCompProps extends SectionCompProps {\n title: string;\n description?: string;\n features: { title?: string; description: string; iconHint?: string }[];\n}\n\n/** List items section — title + a list of feature items. */\nexport interface ListItemsSectionCompProps extends SectionCompProps {\n title: string;\n features: { title?: string; description: string }[];\n}\n\nexport type ListItemsSectionComponent = FC<ListItemsSectionCompProps>;\n\n/** Error — aligned to ErrorSection */\nexport interface ErrorCompProps extends SectionCompProps {\n type: import('../errors/conversationErrorTypes').ConversationErrorType;\n}\n\n/** Skip/HTML/Search — null-component parsers */\nexport interface NullCompProps extends SectionCompProps {}\n\n/** @deprecated Use EntityCompProps */\nexport type SolutionEntityCompProps = EntityCompProps;\n/** @deprecated Use EntityCompProps */\nexport type BlogEntityCompProps = EntityCompProps;\n\n/** CTA Banner — dark purple gradient card with headline, description, and pill link buttons */\nexport interface CtaBannerCompProps extends SectionCompProps {\n headline: string;\n description?: string;\n links: { text: string; href: string }[];\n /** Contextual background image — resolved from allowed keywords during parse() */\n imageUrl?: string;\n imageFromText?: boolean;\n}\n\nexport type CtaBannerSectionComponent = FC<CtaBannerCompProps>;\n\n/** Text block — heading + body with an optional pullquote callout on the side */\nexport interface TextBlockCompProps extends SectionCompProps {\n title: string;\n description: string;\n}\n\n/** Personalized narrative — standalone section with no parse() definition */\nexport interface PersonalizedNarrativeCompProps extends SectionCompProps {\n title: string;\n content?: string;\n}\n\n// --------------------------------\n// Types of component - all components\n// --------------------------------\n\nexport type Component = BaseComponent | SlotComponent | SectionComponent;\n\nexport type BaseComponent = FC<BaseCompProps>;\nexport type SlotComponent = FC<SlotCompProps>;\nexport type SectionComponent = FC<SectionCompProps>;\n\n// Base Components\nexport type TextComponent = FC<TextCompProps>;\nexport type ButtonComponent = FC<ButtonCompProps>;\nexport type ImageComponent = FC<ImageCompProps>;\nexport type BadgeComponent = FC<BadgeCompProps>;\n\n// Slot Components\nexport type KpiItemComponent = FC<KpiItemCompProps>;\nexport type FeatureItemComponent = FC<FeatureItemCompProps>;\nexport type FeatureCardComponent = FC<FeatureCardCompProps>;\n/** @deprecated Use FC<EntityItem> */\nexport type GenericEntityComponent = FC<EntityItem>;\nexport type AiNarrativeComponent = FC<AiNarrativeCompProps>;\n\n// Section Components\nexport type ComparisonSectionComponent = FC<ComparisonCompProps>;\nexport type GeneralTextSectionComponent = FC<GeneralTextCompProps>;\nexport type TextBlockSectionComponent = FC<TextBlockCompProps>;\nexport type HeroSectionComponent = FC<HeroCompProps>;\nexport type HeroEntitySectionComponent = FC<HeroEntityCompProps>;\n\n// section components with slots\nexport type KpiSectionComponent = FC<KpiCompProps>;\nexport type FeatureCardsSectionComponent = FC<FeatureCardsCompProps>;\nexport type EntitySectionComponent = FC<EntityCompProps>;\n\n// New section component types for Phase 4\nexport type CalloutSectionComponent = FC<CalloutCompProps>;\nexport type NextStepsSectionComponent = FC<NextStepsCompProps>;\nexport type FeatureSection9PlusSectionComponent =\n FC<FeatureSection9PlusCompProps>;\nexport type NullSectionComponent = FC<NullCompProps>;\nexport type ErrorSectionComponent = FC<ErrorCompProps>;\nexport type SolutionEntitySectionComponent = FC<SolutionEntityCompProps>;\nexport type BlogEntitySectionComponent = FC<BlogEntityCompProps>;\nexport type PersonalizedNarrativeSectionComponent =\n FC<PersonalizedNarrativeCompProps>;\n\nexport type PropsOf<T> = T extends (props: infer P) => unknown ? P : never;\n\nexport interface SectionFixture<TProps> {\n markdown: string;\n expected: Partial<TProps>;\n}\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["WEB5_ROOT_ID","WEB5_ROOT_CLASS","WEB5_SCOPES","WEB5_SCOPE","join","WEB5_GLOBAL_TOKENS"],"sources":["../../src/hostScope.ts"],"sourcesContent":["/**\n * The mount-scope contract.\n *\n * Several packages have to agree on where Web5 content begins in a host\n * document:\n *\n * - **web5-core** scopes its own CSS to it (`base-utilities.css` already\n * targets `#root`).\n * - **the client build** compiles every selector against it (`scopeCss` in\n * `web5-core/scripts/scope-css.ts`).\n * - **web50-server-ui** stamps `WEB5_ROOT_CLASS` on the element it mounts\n * into, and renders the debug panel into `.debug-view`.\n * - **embed-placement** mounts the *same* client bundle into\n * `[data-web5-placement]` slots on host pages.\n *\n * One home for the list, so those cannot drift.\n *\n * ## Why it is a list and not just `#root`\n *\n * A placement renders client components **outside** `#root`, on the merchant's\n * own PDP. A stylesheet scoped to `#root` alone leaves every placement — and the\n * debug panel — completely unstyled. `w5-client-circana` and\n * `w5-client-feature-com` each discovered this and each hardcoded their own\n * list; this constant is what replaces both.\n */\nexport const WEB5_ROOT_ID = 'root';\n\nexport const WEB5_ROOT_CLASS = 'w5-root';\n\n/**\n * Every place Web5 content can be mounted.\n *\n * `#root` is the id the host runtime has always created, kept so the compiled\n * stylesheet matches before any script runs. `.w5-root` is stamped at mount and\n * keeps the contract working if the host ever renames the element.\n */\nexport const WEB5_SCOPES = [\n `#${WEB5_ROOT_ID}`,\n `.${WEB5_ROOT_CLASS}`,\n '[data-web5-placement]',\n '.debug-view',\n] as const;\n\n/**\n * `:is()` takes the specificity of its most specific argument, so this is worth\n * (1,0,0) whichever branch matches — enough to outrank the (0,1,1) descendant\n * selectors host themes use for rich-text typography.\n */\nexport const WEB5_SCOPE = `:is(${WEB5_SCOPES.join(',')})`;\n\n/**\n * Custom properties the **host** sets on `:root` at runtime. Their declarations\n * must stay global: moved into the scope they would shadow the host's value for\n * our own subtree, which is precisely where it is needed.\n *\n * Kept in sync with what `web50-server-ui` and the host offset injectors write.\n */\nexport const WEB5_GLOBAL_TOKENS: readonly RegExp[] = [\n /^--web5-host-left-offset$/,\n /^--web5-host-right-offset$/,\n /^--web5-window-scroll-top-offset$/,\n];\n\n/**\n * Per-client overrides for the host adaptation web50-server-ui performs at\n * mount. Shared behaviour, client values — a client package supplies this on\n * `clientConfig.hostFit` and never forks the implementation.\n */\nexport interface HostFitConfig {\n /** Master switch. Default `true`. */\n enabled?: boolean;\n /**\n * What \"the full available width\" means on this site. Default\n * `'main, [role=\"main\"]'`; falls back to `<body>` when nothing matches.\n */\n containerSelector?: string;\n /**\n * Widen the page's content container to the host container's content box.\n * Default **`false`** — opt in per client.\n *\n * Off by default because widening changes the layout of hosts that are\n * already sized correctly; only a client whose host constrains it (a theme\n * that drops the mount into a narrow reading column) needs this.\n */\n bleed?: boolean;\n /**\n * Sticky-header height. `'auto'` (default) measures it; a number pins it.\n *\n * Prefer pinning where the host chrome is known. Circana's\n * `inject-host-nav-offset` measured side rails at runtime, hit false\n * positives in production (host layout containers and full-height nav panels\n * matched the filter), and was changed to static values — the same trap\n * applies to any measured host geometry.\n */\n topInset?: number | 'auto';\n /**\n * Hide the host's own page-title heading where it sits above the mount.\n * Default **`false`** — opt in per client.\n *\n * A Web5 page opens with its own hero `h1`, so on a host that also prints the\n * CMS page title the visitor reads the page name twice and the document ends\n * up with two `h1`s. Every standard Shopify theme does this on `/pages/*` —\n * Dawn as `h1.main-page-title` before the `.rte`, Horizon as a `text-block`\n * before the block we mount into — hence a shared switch and not a per-theme\n * fork.\n *\n * Off by default because a heading above us is only reliably *ours to remove*\n * when the mount owns the page. A placement, or a host that puts Web5 beside\n * real editorial content, must keep it.\n */\n hideHostTitle?: boolean;\n /**\n * Collapse the host's padding and margin above the mount. Default\n * **`false`** — opt in per client.\n *\n * Only dead space goes: the walk stops at the first ancestor with anything\n * visible rendering above us, so a host that does put content over the mount\n * keeps its separation. Pairs with {@link hideHostTitle}, which is what takes\n * the title's own row out of that walk.\n */\n flushTop?: boolean;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,YAAY,GAAG,MAAM;AAElC,OAAO,MAAMC,eAAe,GAAG,SAAS;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG,CACzB,IAAIF,YAAY,EAAE,EAClB,IAAIC,eAAe,EAAE,EACrB,uBAAuB,EACvB,aAAa,CACL;;AAEV;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,UAAU,GAAG,OAAOD,WAAW,CAACE,IAAI,CAAC,GAAG,CAAC,GAAG;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAqC,GAAG,CACnD,2BAA2B,EAC3B,4BAA4B,EAC5B,mCAAmC,CACpC;;AAED;AACA;AACA;AACA;AACA","ignoreList":[]}
1
+ {"version":3,"names":["WEB5_ROOT_ID","WEB5_ROOT_CLASS","WEB5_SCOPES","WEB5_SCOPE","join","WEB5_GLOBAL_TOKENS"],"sources":["../../src/hostScope.ts"],"sourcesContent":["/**\n * The mount-scope contract.\n *\n * Several packages have to agree on where Web5 content begins in a host\n * document:\n *\n * - **web5-core** scopes its own CSS to it (`base-utilities.css` already\n * targets `#root`).\n * - **the client build** compiles every selector against it (`scopeCss` in\n * `web5-core/scripts/scope-css.ts`).\n * - **web50-server-ui** stamps `WEB5_ROOT_CLASS` on the element it mounts\n * into, and renders the debug panel into `.debug-view`.\n * - **embed-placement** mounts the *same* client bundle into\n * `[data-web5-placement]` slots on host pages.\n *\n * One home for the list, so those cannot drift.\n *\n * ## Why it is a list and not just `#root`\n *\n * A placement renders client components **outside** `#root`, on the merchant's\n * own PDP. A stylesheet scoped to `#root` alone leaves every placement — and the\n * debug panel — completely unstyled. `w5-client-circana` and\n * `w5-client-feature-com` each discovered this and each hardcoded their own\n * list; this constant is what replaces both.\n */\nexport const WEB5_ROOT_ID = 'root';\n\nexport const WEB5_ROOT_CLASS = 'w5-root';\n\n/**\n * Every place Web5 content can be mounted.\n *\n * `#root` is the id the host runtime has always created, kept so the compiled\n * stylesheet matches before any script runs. `.w5-root` is stamped at mount and\n * keeps the contract working if the host ever renames the element.\n */\nexport const WEB5_SCOPES = [\n `#${WEB5_ROOT_ID}`,\n `.${WEB5_ROOT_CLASS}`,\n '[data-web5-placement]',\n '.debug-view',\n] as const;\n\n/**\n * `:is()` takes the specificity of its most specific argument, so this is worth\n * (1,0,0) whichever branch matches — enough to outrank the (0,1,1) descendant\n * selectors host themes use for rich-text typography.\n */\nexport const WEB5_SCOPE = `:is(${WEB5_SCOPES.join(',')})`;\n\n/**\n * Custom properties the **host** sets on `:root` at runtime. Their declarations\n * must stay global: moved into the scope they would shadow the host's value for\n * our own subtree, which is precisely where it is needed.\n *\n * Kept in sync with what `web50-server-ui` and the host offset injectors write.\n */\nexport const WEB5_GLOBAL_TOKENS: readonly RegExp[] = [\n /^--web5-host-left-offset$/,\n /^--web5-host-right-offset$/,\n /^--web5-window-scroll-top-offset$/,\n];\n\n/**\n * Per-client overrides for the host adaptation web50-server-ui performs at\n * mount. Shared behaviour, client values — a client package supplies this on\n * `clientConfig.hostFit` and never forks the implementation.\n */\nexport interface HostFitConfig {\n /** Master switch. Default `true`. */\n enabled?: boolean;\n /**\n * What \"the full available width\" means on this site. Default\n * `'main, [role=\"main\"]'`; falls back to `<body>` when nothing matches.\n */\n containerSelector?: string;\n /**\n * Widen the page's content container to the host container's content box.\n * Default **`false`** — opt in per client.\n *\n * Off by default because widening changes the layout of hosts that are\n * already sized correctly; only a client whose host constrains it (a theme\n * that drops the mount into a narrow reading column) needs this.\n */\n bleed?: boolean;\n /**\n * Sticky-header height. `'auto'` (default) measures it; a number pins it.\n *\n * Prefer pinning where the host chrome is known. Circana's\n * `inject-host-nav-offset` measured side rails at runtime, hit false\n * positives in production (host layout containers and full-height nav panels\n * matched the filter), and was changed to static values — the same trap\n * applies to any measured host geometry.\n */\n topInset?: number | 'auto';\n /**\n * Height of the chrome the host pins to the *bottom* of the viewport — a\n * cookie bar, a sticky add-to-cart bar, Shopify's storefront preview bar.\n * `'auto'` (default) measures it; a number pins it.\n *\n * The mirror of {@link topInset}, and it exists for the same reason: the\n * prompt input is `position: fixed; bottom: 0`, so anything the host pins\n * down there covers it. Same trap, too — prefer pinning where the host\n * chrome is known and constant.\n */\n bottomInset?: number | 'auto';\n /**\n * Hide the host's own page-title heading where it sits above the mount.\n * Default **`false`** — opt in per client.\n *\n * A Web5 page opens with its own hero `h1`, so on a host that also prints the\n * CMS page title the visitor reads the page name twice and the document ends\n * up with two `h1`s. Every standard Shopify theme does this on `/pages/*` —\n * Dawn as `h1.main-page-title` before the `.rte`, Horizon as a `text-block`\n * before the block we mount into — hence a shared switch and not a per-theme\n * fork.\n *\n * Off by default because a heading above us is only reliably *ours to remove*\n * when the mount owns the page. A placement, or a host that puts Web5 beside\n * real editorial content, must keep it.\n */\n hideHostTitle?: boolean;\n /**\n * Collapse the host's padding and margin above the mount. Default\n * **`false`** — opt in per client.\n *\n * Only dead space goes: the walk stops at the first ancestor with anything\n * visible rendering above us, so a host that does put content over the mount\n * keeps its separation. Pairs with {@link hideHostTitle}, which is what takes\n * the title's own row out of that walk.\n */\n flushTop?: boolean;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,YAAY,GAAG,MAAM;AAElC,OAAO,MAAMC,eAAe,GAAG,SAAS;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG,CACzB,IAAIF,YAAY,EAAE,EAClB,IAAIC,eAAe,EAAE,EACrB,uBAAuB,EACvB,aAAa,CACL;;AAEV;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,UAAU,GAAG,OAAOD,WAAW,CAACE,IAAI,CAAC,GAAG,CAAC,GAAG;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAqC,GAAG,CACnD,2BAA2B,EAC3B,4BAA4B,EAC5B,mCAAmC,CACpC;;AAED;AACA;AACA;AACA;AACA","ignoreList":[]}
package/dist/esm/index.js CHANGED
@@ -137,8 +137,9 @@ export { getClientBundleOverride, isTrustedBundleHost } from './client/clientBun
137
137
  // Client-UMD URL resolution (DL #094 per-msid, DL #129 per-template) and the
138
138
  // universal bundle←backend config merge (DL #129 Q3/Q7) — shared by
139
139
  // `web50-server-ui` and `embed-placement`, the two client-bundle load sites.
140
- export { resolveClientBundleUrl } from './client/clientBundleUrl.js';
140
+ export { TEMPLATES_CDN_BASE, TEMPLATES_MANIFEST_URL, getTemplateOverride, isTemplatePickerRequested, isValidTemplateId, resolveClientBundleUrl } from './client/clientBundleUrl.js';
141
141
  export { mergeClientConfig } from './client/mergeClientConfig.js';
142
+ export { applyThemeOverrides, THEME_OVERRIDE_TOKENS } from './client/applyThemeOverrides.js';
142
143
 
143
144
  // Placement renderer + DI helper (DL #088 D3.2, D3.4)
144
145
  export { PlacementResponseRenderer, PlacementSmoothHeight } from './components/placement/PlacementResponseRenderer.js';