@activecollab/components 2.0.414 → 2.0.416

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 (45) hide show
  1. package/dist/cjs/components/Media/Media.js.map +1 -1
  2. package/dist/cjs/components/PortableText/Styles.js +20 -2
  3. package/dist/cjs/components/PortableText/Styles.js.map +1 -1
  4. package/dist/cjs/components/PortableText/renderers.js +20 -4
  5. package/dist/cjs/components/PortableText/renderers.js.map +1 -1
  6. package/dist/cjs/components/PortableText/types.js +39 -3
  7. package/dist/cjs/components/PortableText/types.js.map +1 -1
  8. package/dist/cjs/components/PortableText/types.test.js +137 -0
  9. package/dist/cjs/components/PortableText/types.test.js.map +1 -1
  10. package/dist/cjs/presentation/shared/FeatureAvailability.js +217 -0
  11. package/dist/cjs/presentation/shared/FeatureAvailability.js.map +1 -0
  12. package/dist/cjs/presentation/shared/MessageDialog.js.map +1 -1
  13. package/dist/cjs/presentation/shared/index.js +16 -1
  14. package/dist/cjs/presentation/shared/index.js.map +1 -1
  15. package/dist/esm/components/Media/Media.d.ts +3 -2
  16. package/dist/esm/components/Media/Media.d.ts.map +1 -1
  17. package/dist/esm/components/Media/Media.js.map +1 -1
  18. package/dist/esm/components/PortableText/Styles.d.ts +19 -1
  19. package/dist/esm/components/PortableText/Styles.d.ts.map +1 -1
  20. package/dist/esm/components/PortableText/Styles.js +20 -2
  21. package/dist/esm/components/PortableText/Styles.js.map +1 -1
  22. package/dist/esm/components/PortableText/renderers.d.ts.map +1 -1
  23. package/dist/esm/components/PortableText/renderers.js +20 -4
  24. package/dist/esm/components/PortableText/renderers.js.map +1 -1
  25. package/dist/esm/components/PortableText/types.d.ts +16 -2
  26. package/dist/esm/components/PortableText/types.d.ts.map +1 -1
  27. package/dist/esm/components/PortableText/types.js +32 -2
  28. package/dist/esm/components/PortableText/types.js.map +1 -1
  29. package/dist/esm/components/PortableText/types.test.js +138 -1
  30. package/dist/esm/components/PortableText/types.test.js.map +1 -1
  31. package/dist/esm/presentation/shared/FeatureAvailability.d.ts +52 -0
  32. package/dist/esm/presentation/shared/FeatureAvailability.d.ts.map +1 -0
  33. package/dist/esm/presentation/shared/FeatureAvailability.js +203 -0
  34. package/dist/esm/presentation/shared/FeatureAvailability.js.map +1 -0
  35. package/dist/esm/presentation/shared/MessageDialog.d.ts.map +1 -1
  36. package/dist/esm/presentation/shared/MessageDialog.js.map +1 -1
  37. package/dist/esm/presentation/shared/index.d.ts +2 -0
  38. package/dist/esm/presentation/shared/index.d.ts.map +1 -1
  39. package/dist/esm/presentation/shared/index.js +1 -0
  40. package/dist/esm/presentation/shared/index.js.map +1 -1
  41. package/dist/index.js +210 -140
  42. package/dist/index.js.map +1 -1
  43. package/dist/index.min.js +1 -1
  44. package/dist/index.min.js.map +1 -1
  45. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import React, { Fragment } from "react";
2
2
  import { StyledCode, StyledCodeBlock, StyledDivider, StyledLink, StyledList, StyledTableBlock } from "./Styles";
3
+ import { isPortableTextMediaImageVariant } from "./types";
3
4
  import { Media } from "../Media";
4
5
  import { Table, Tbody, Thead } from "../Tables";
5
6
  import { TitledText, titledTextHeadings } from "../TitledText";
@@ -90,10 +91,16 @@ export const portableTextDefaultBlockRenderers = {
90
91
  let block = _ref8.block,
91
92
  children = _ref8.children;
92
93
  const ordered = block.style === "number";
93
- return /*#__PURE__*/React.createElement(StyledList, {
94
- as: ordered ? "ol" : "ul",
95
- $ordered: ordered
96
- }, children);
94
+ return (
95
+ /*#__PURE__*/
96
+ // `data-portable-list` scopes the depth-marker rules in Styles.ts to
97
+ // design-system lists, and marks the ancestors those rules count.
98
+ React.createElement(StyledList, {
99
+ as: ordered ? "ol" : "ul",
100
+ $ordered: ordered,
101
+ "data-portable-list": ""
102
+ }, children)
103
+ );
97
104
  },
98
105
  "list-item": _ref9 => {
99
106
  let children = _ref9.children;
@@ -109,6 +116,15 @@ export const portableTextDefaultBlockRenderers = {
109
116
  alt = _ref1.alt,
110
117
  variant = _ref1.variant,
111
118
  caption = _ref1.caption;
119
+
120
+ // Video (and future) variants carry service semantics, so their renderer
121
+ // is application-catalog territory — an injected `media` override. The
122
+ // universal set covers images only; anything else degrades and warns, per
123
+ // the contract's degradation rule.
124
+ if (variant !== undefined && !isPortableTextMediaImageVariant(variant)) {
125
+ console.warn("PortableText: no default renderer for media variant \"" + variant + "\".");
126
+ return null;
127
+ }
112
128
  return /*#__PURE__*/React.createElement(Media, {
113
129
  src: src,
114
130
  alt: alt,
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.js","names":["React","Fragment","StyledCode","StyledCodeBlock","StyledDivider","StyledLink","StyledList","StyledTableBlock","Media","Table","Tbody","Thead","TitledText","titledTextHeadings","Body1","Typography","portableTextDefaultMarkRenderers","strong","_ref","children","createElement","em","_ref2","code","_ref3","link","_ref4","mark","href","target","rel","HEADING_LEVEL_VARIANTS","DEFAULT_HEADING_LEVEL","headingVariantForLevel","level","undefined","variant","console","warn","HeadingBlock","_ref5","block","_ref6","Heading","portableTextDefaultBlockRenderers","paragraph","_ref7","heading","list","_ref8","ordered","style","as","$ordered","_ref9","media","_ref0","_ref1","src","alt","caption","_ref10","_ref11","title","_ref12","_ref13","language","table","_ref14","renderSpans","_ref15","header","rows","cell","spans","map","span","index","key","text","row","rowIndex","cellIndex","divider"],"sources":["../../../../src/components/PortableText/renderers.tsx"],"sourcesContent":["import React, { Fragment, ReactNode } from \"react\";\n\nimport {\n StyledCode,\n StyledCodeBlock,\n StyledDivider,\n StyledLink,\n StyledList,\n StyledTableBlock,\n} from \"./Styles\";\nimport {\n PortableTextBlockRenderer,\n PortableTextCodeBlock,\n PortableTextDefaultBlockType,\n PortableTextDefaultMark,\n PortableTextHeadingBlock,\n PortableTextHeadingLevel,\n PortableTextLinkMark,\n PortableTextListBlock,\n PortableTextMarkRenderer,\n PortableTextMediaBlock,\n PortableTextSpan,\n PortableTextTableBlock,\n PortableTextTitledTextBlock,\n} from \"./types\";\nimport { Media } from \"../Media\";\nimport { Table, Tbody, Thead } from \"../Tables\";\nimport {\n TitledText,\n TitledTextVariant,\n titledTextHeadings,\n} from \"../TitledText\";\nimport { Body1 } from \"../Typography\";\nimport { Typography } from \"../Typography/Typography\";\n\n/**\n * The default renderers for the universal set — everything a client renders\n * without injection, and nothing more: no product element ever lands here.\n * Injected {@link PortableTextComponents} maps take precedence entry by entry.\n */\n\nexport const portableTextDefaultMarkRenderers: Record<\n PortableTextDefaultMark,\n PortableTextMarkRenderer\n> = {\n strong: ({ children }) => <strong>{children}</strong>,\n em: ({ children }) => <em>{children}</em>,\n code: ({ children }) => <StyledCode>{children}</StyledCode>,\n link: ({ mark, children }) => {\n const href = (mark as PortableTextLinkMark | undefined)?.href;\n\n // A link mark without an href (authored as a plain string) has nowhere\n // to go — keep the text, skip the anchor.\n if (!href) {\n return <>{children}</>;\n }\n\n return (\n <StyledLink href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </StyledLink>\n );\n },\n};\n\n/** The semantic wire levels resolve to typography only here, in the renderer. */\nconst HEADING_LEVEL_VARIANTS: Record<\n PortableTextHeadingLevel,\n TitledTextVariant\n> = {\n 1: \"title1\",\n 2: \"title2\",\n 3: \"header2\",\n};\n\n/** The level `heading` and `titled-text` fall back to. */\nconst DEFAULT_HEADING_LEVEL: PortableTextHeadingLevel = 3;\n\n/**\n * Resolve a semantic wire level to its typography variant. An absent level is\n * the documented default; any other unrecognised level is a serializer bug on\n * a fixed 1–3 scale, so it falls back to the default and is logged, per the\n * contract's degradation rule.\n */\nconst headingVariantForLevel = (\n level: PortableTextHeadingLevel | undefined\n): TitledTextVariant => {\n if (level === undefined) {\n return HEADING_LEVEL_VARIANTS[DEFAULT_HEADING_LEVEL];\n }\n\n const variant = HEADING_LEVEL_VARIANTS[level];\n if (!variant) {\n console.warn(\n `PortableText: unknown heading level ${level}, falling back to ${DEFAULT_HEADING_LEVEL}.`\n );\n return HEADING_LEVEL_VARIANTS[DEFAULT_HEADING_LEVEL];\n }\n\n return variant;\n};\n\n/** Heading levels map to the same typography TitledText uses. */\nconst HeadingBlock: PortableTextBlockRenderer = ({ block, children }) => {\n const { level } = block as PortableTextHeadingBlock;\n const Heading = titledTextHeadings[headingVariantForLevel(level)];\n return <Heading>{children}</Heading>;\n};\n\nexport const portableTextDefaultBlockRenderers: Record<\n PortableTextDefaultBlockType,\n PortableTextBlockRenderer\n> = {\n paragraph: ({ children }) => <Body1>{children}</Body1>,\n heading: HeadingBlock,\n list: ({ block, children }) => {\n const ordered = (block as PortableTextListBlock).style === \"number\";\n return (\n <StyledList as={ordered ? \"ol\" : \"ul\"} $ordered={ordered}>\n {children}\n </StyledList>\n );\n },\n \"list-item\": ({ children }) => (\n <Typography variant=\"Body 1\" as=\"li\">\n {children}\n </Typography>\n ),\n media: ({ block }) => {\n const { src, alt, variant, caption } = block as PortableTextMediaBlock;\n return <Media src={src} alt={alt} variant={variant} caption={caption} />;\n },\n \"titled-text\": ({ block, children }) => {\n const { title, level } = block as PortableTextTitledTextBlock;\n return (\n <TitledText title={title} variant={headingVariantForLevel(level)}>\n {children}\n </TitledText>\n );\n },\n // No highlighter ships with the default set, so every language — known,\n // unknown or absent — is plain preformatted text; the hint travels on\n // data-language for surfaces that highlight.\n \"code-block\": ({ block }) => {\n const { code, language } = block as PortableTextCodeBlock;\n return (\n <StyledCodeBlock data-language={language || undefined}>\n <code>{code}</code>\n </StyledCodeBlock>\n );\n },\n table: ({ block, renderSpans }) => {\n const { header, rows } = block as PortableTextTableBlock;\n // Standalone (engine-less) use has no span renderer — keep the raw text.\n const cell = (spans: PortableTextSpan[]): ReactNode =>\n renderSpans\n ? renderSpans(spans)\n : spans.map((span, index) => (\n <Fragment key={index}>{span.text}</Fragment>\n ));\n\n return (\n <StyledTableBlock>\n <Table>\n <Thead>\n <tr>\n {header.map((spans, index) => (\n <th key={index}>{cell(spans)}</th>\n ))}\n </tr>\n </Thead>\n <Tbody>\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {row.map((spans, cellIndex) => (\n <td key={cellIndex}>{cell(spans)}</td>\n ))}\n </tr>\n ))}\n </Tbody>\n </Table>\n </StyledTableBlock>\n );\n },\n divider: () => <StyledDivider />,\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"renderers.js","names":["React","Fragment","StyledCode","StyledCodeBlock","StyledDivider","StyledLink","StyledList","StyledTableBlock","isPortableTextMediaImageVariant","Media","Table","Tbody","Thead","TitledText","titledTextHeadings","Body1","Typography","portableTextDefaultMarkRenderers","strong","_ref","children","createElement","em","_ref2","code","_ref3","link","_ref4","mark","href","target","rel","HEADING_LEVEL_VARIANTS","DEFAULT_HEADING_LEVEL","headingVariantForLevel","level","undefined","variant","console","warn","HeadingBlock","_ref5","block","_ref6","Heading","portableTextDefaultBlockRenderers","paragraph","_ref7","heading","list","_ref8","ordered","style","as","$ordered","_ref9","media","_ref0","_ref1","src","alt","caption","_ref10","_ref11","title","_ref12","_ref13","language","table","_ref14","renderSpans","_ref15","header","rows","cell","spans","map","span","index","key","text","row","rowIndex","cellIndex","divider"],"sources":["../../../../src/components/PortableText/renderers.tsx"],"sourcesContent":["import React, { Fragment, ReactNode } from \"react\";\n\nimport {\n StyledCode,\n StyledCodeBlock,\n StyledDivider,\n StyledLink,\n StyledList,\n StyledTableBlock,\n} from \"./Styles\";\nimport {\n isPortableTextMediaImageVariant,\n PortableTextBlockRenderer,\n PortableTextCodeBlock,\n PortableTextDefaultBlockType,\n PortableTextDefaultMark,\n PortableTextHeadingBlock,\n PortableTextHeadingLevel,\n PortableTextLinkMark,\n PortableTextListBlock,\n PortableTextMarkRenderer,\n PortableTextMediaBlock,\n PortableTextSpan,\n PortableTextTableBlock,\n PortableTextTitledTextBlock,\n} from \"./types\";\nimport { Media } from \"../Media\";\nimport { Table, Tbody, Thead } from \"../Tables\";\nimport {\n TitledText,\n TitledTextVariant,\n titledTextHeadings,\n} from \"../TitledText\";\nimport { Body1 } from \"../Typography\";\nimport { Typography } from \"../Typography/Typography\";\n\n/**\n * The default renderers for the universal set — everything a client renders\n * without injection, and nothing more: no product element ever lands here.\n * Injected {@link PortableTextComponents} maps take precedence entry by entry.\n */\n\nexport const portableTextDefaultMarkRenderers: Record<\n PortableTextDefaultMark,\n PortableTextMarkRenderer\n> = {\n strong: ({ children }) => <strong>{children}</strong>,\n em: ({ children }) => <em>{children}</em>,\n code: ({ children }) => <StyledCode>{children}</StyledCode>,\n link: ({ mark, children }) => {\n const href = (mark as PortableTextLinkMark | undefined)?.href;\n\n // A link mark without an href (authored as a plain string) has nowhere\n // to go — keep the text, skip the anchor.\n if (!href) {\n return <>{children}</>;\n }\n\n return (\n <StyledLink href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </StyledLink>\n );\n },\n};\n\n/** The semantic wire levels resolve to typography only here, in the renderer. */\nconst HEADING_LEVEL_VARIANTS: Record<\n PortableTextHeadingLevel,\n TitledTextVariant\n> = {\n 1: \"title1\",\n 2: \"title2\",\n 3: \"header2\",\n};\n\n/** The level `heading` and `titled-text` fall back to. */\nconst DEFAULT_HEADING_LEVEL: PortableTextHeadingLevel = 3;\n\n/**\n * Resolve a semantic wire level to its typography variant. An absent level is\n * the documented default; any other unrecognised level is a serializer bug on\n * a fixed 1–3 scale, so it falls back to the default and is logged, per the\n * contract's degradation rule.\n */\nconst headingVariantForLevel = (\n level: PortableTextHeadingLevel | undefined\n): TitledTextVariant => {\n if (level === undefined) {\n return HEADING_LEVEL_VARIANTS[DEFAULT_HEADING_LEVEL];\n }\n\n const variant = HEADING_LEVEL_VARIANTS[level];\n if (!variant) {\n console.warn(\n `PortableText: unknown heading level ${level}, falling back to ${DEFAULT_HEADING_LEVEL}.`\n );\n return HEADING_LEVEL_VARIANTS[DEFAULT_HEADING_LEVEL];\n }\n\n return variant;\n};\n\n/** Heading levels map to the same typography TitledText uses. */\nconst HeadingBlock: PortableTextBlockRenderer = ({ block, children }) => {\n const { level } = block as PortableTextHeadingBlock;\n const Heading = titledTextHeadings[headingVariantForLevel(level)];\n return <Heading>{children}</Heading>;\n};\n\nexport const portableTextDefaultBlockRenderers: Record<\n PortableTextDefaultBlockType,\n PortableTextBlockRenderer\n> = {\n paragraph: ({ children }) => <Body1>{children}</Body1>,\n heading: HeadingBlock,\n list: ({ block, children }) => {\n const ordered = (block as PortableTextListBlock).style === \"number\";\n return (\n // `data-portable-list` scopes the depth-marker rules in Styles.ts to\n // design-system lists, and marks the ancestors those rules count.\n <StyledList\n as={ordered ? \"ol\" : \"ul\"}\n $ordered={ordered}\n data-portable-list=\"\"\n >\n {children}\n </StyledList>\n );\n },\n \"list-item\": ({ children }) => (\n <Typography variant=\"Body 1\" as=\"li\">\n {children}\n </Typography>\n ),\n media: ({ block }) => {\n const { src, alt, variant, caption } = block as PortableTextMediaBlock;\n\n // Video (and future) variants carry service semantics, so their renderer\n // is application-catalog territory — an injected `media` override. The\n // universal set covers images only; anything else degrades and warns, per\n // the contract's degradation rule.\n if (variant !== undefined && !isPortableTextMediaImageVariant(variant)) {\n console.warn(\n `PortableText: no default renderer for media variant \"${variant}\".`\n );\n return null;\n }\n\n return <Media src={src} alt={alt} variant={variant} caption={caption} />;\n },\n \"titled-text\": ({ block, children }) => {\n const { title, level } = block as PortableTextTitledTextBlock;\n return (\n <TitledText title={title} variant={headingVariantForLevel(level)}>\n {children}\n </TitledText>\n );\n },\n // No highlighter ships with the default set, so every language — known,\n // unknown or absent — is plain preformatted text; the hint travels on\n // data-language for surfaces that highlight.\n \"code-block\": ({ block }) => {\n const { code, language } = block as PortableTextCodeBlock;\n return (\n <StyledCodeBlock data-language={language || undefined}>\n <code>{code}</code>\n </StyledCodeBlock>\n );\n },\n table: ({ block, renderSpans }) => {\n const { header, rows } = block as PortableTextTableBlock;\n // Standalone (engine-less) use has no span renderer — keep the raw text.\n const cell = (spans: PortableTextSpan[]): ReactNode =>\n renderSpans\n ? renderSpans(spans)\n : spans.map((span, index) => (\n <Fragment key={index}>{span.text}</Fragment>\n ));\n\n return (\n <StyledTableBlock>\n <Table>\n <Thead>\n <tr>\n {header.map((spans, index) => (\n <th key={index}>{cell(spans)}</th>\n ))}\n </tr>\n </Thead>\n <Tbody>\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {row.map((spans, cellIndex) => (\n <td key={cellIndex}>{cell(spans)}</td>\n ))}\n </tr>\n ))}\n </Tbody>\n </Table>\n </StyledTableBlock>\n );\n },\n divider: () => <StyledDivider />,\n};\n"],"mappings":"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","ignoreList":[]}
@@ -43,9 +43,14 @@ export interface PortableTextHeadingBlock {
43
43
  children: PortableTextSpan[];
44
44
  }
45
45
  export type PortableTextListStyle = "bullet" | "number";
46
+ /**
47
+ * A list item's children are its own spans first, then any nested `list`
48
+ * block(s) — the shape that carries multi-level lists. A spans-only item (no
49
+ * nested list) is the common, flat case and stays valid unchanged.
50
+ */
46
51
  export interface PortableTextListItemBlock {
47
52
  type: "list-item";
48
- children: PortableTextSpan[];
53
+ children: (PortableTextSpan | PortableTextListBlock)[];
49
54
  }
50
55
  export interface PortableTextListBlock {
51
56
  type: "list";
@@ -53,7 +58,16 @@ export interface PortableTextListBlock {
53
58
  children: PortableTextListItemBlock[];
54
59
  }
55
60
  /** Screenshots render framed (border, no shadow); illustrations render flat. */
56
- export type PortableTextMediaVariant = "screenshot" | "illustration";
61
+ export type PortableTextMediaImageVariant = "screenshot" | "illustration";
62
+ /**
63
+ * Video variants name the hosting service; `src` is the canonical video URL.
64
+ * Their rendering carries service semantics (URL parsing, embed derivation),
65
+ * so it belongs to the application catalog — injected as a `media` block
66
+ * override — never to the default set. The default renderer degrades them.
67
+ */
68
+ export type PortableTextMediaVideoVariant = "vimeo" | "youtube";
69
+ export type PortableTextMediaVariant = PortableTextMediaImageVariant | PortableTextMediaVideoVariant;
70
+ export declare const isPortableTextMediaImageVariant: (value: unknown) => value is PortableTextMediaImageVariant;
57
71
  export interface PortableTextMediaBlock {
58
72
  type: "media";
59
73
  src: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/PortableText/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/PortableText/types.ts"],"names":[],"mappings":"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"}
@@ -27,8 +27,29 @@ export const PORTABLE_TEXT_DEFAULT_MARKS = ["strong", "em", "code", "link"];
27
27
 
28
28
  /** 1 maps to Title1, 2 to Title2, 3 to Header2 typography. */
29
29
 
30
+ /**
31
+ * A list item's children are its own spans first, then any nested `list`
32
+ * block(s) — the shape that carries multi-level lists. A spans-only item (no
33
+ * nested list) is the common, flat case and stays valid unchanged.
34
+ */
35
+
30
36
  /** Screenshots render framed (border, no shadow); illustrations render flat. */
31
37
 
38
+ /**
39
+ * Video variants name the hosting service; `src` is the canonical video URL.
40
+ * Their rendering carries service semantics (URL parsing, embed derivation),
41
+ * so it belongs to the application catalog — injected as a `media` block
42
+ * override — never to the default set. The default renderer degrades them.
43
+ */
44
+
45
+ // A Record so the compiler checks the list against the union in both
46
+ // directions: a missing and a stray key each fail to build.
47
+ const MEDIA_IMAGE_VARIANTS = {
48
+ screenshot: true,
49
+ illustration: true
50
+ };
51
+ export const isPortableTextMediaImageVariant = value => typeof value === "string" && value in MEDIA_IMAGE_VARIANTS;
52
+
32
53
  /** A table cell is a span array, so inline marks work inside cells. */
33
54
 
34
55
  /** A themed horizontal rule between sections. Carries no data. */
@@ -98,10 +119,19 @@ export const isPortableTextBlock = value => {
98
119
  switch (value.type) {
99
120
  case "paragraph":
100
121
  case "heading":
101
- case "list-item":
102
122
  return Array.isArray(value.children) && value.children.every(isPortableTextSpan);
123
+ case "list-item":
124
+ // The item's spans, plus optional nested `list` block(s). Widened only
125
+ // for nested lists: any other block child (a stray paragraph, an object)
126
+ // still fails, so a serializer bug is caught here, not at render.
127
+ return Array.isArray(value.children) && value.children.every(child => isPortableTextSpan(child) || isPortableTextBlock(child) && child.type === "list");
103
128
  case "list":
104
- return Array.isArray(value.children) && value.children.every(isPortableTextBlock);
129
+ // A list holds `list-item`s only. A sublist emitted as a sibling of the
130
+ // items (the classic half-implemented-nesting bug) renders invalid HTML
131
+ // — <ul> with a direct <ul> child — so it fails here, not at render.
132
+ // `list-item` is validated but sits outside the PortableTextBlock union,
133
+ // so the discriminator is checked before isPortableTextBlock narrows it.
134
+ return Array.isArray(value.children) && value.children.every(child => isRecord(child) && child.type === "list-item" && isPortableTextBlock(child));
105
135
  case "media":
106
136
  return typeof value.src === "string";
107
137
  case "titled-text":
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":["PORTABLE_TEXT_DEFAULT_MARKS","DEFAULT_BLOCK_TYPES","paragraph","heading","list","media","table","divider","PORTABLE_TEXT_DEFAULT_BLOCKS","Object","keys","isRecord","value","isPortableTextSpan","text","isPortableTextTableRow","Array","isArray","every","cell","isPortableTextObjectNode","type","_type","isPortableTextBlock","children","src","title","content","undefined","isPortableTextContent","code","language","header","rows","node"],"sources":["../../../../src/components/PortableText/types.ts"],"sourcesContent":["import { ComponentType, ReactNode } from \"react\";\n\n/**\n * Portable Text envelope — the general content contract for structured,\n * renderer-independent content (in-app messages, help, changelogs).\n *\n * The design system owns this envelope and the universal default set below.\n * It never hardcodes a product element: concrete elements (callout,\n * button-reference, doc-link, …) are defined in the application catalog and\n * injected into the Portable Text engine through {@link PortableTextComponents}.\n * See README.md next to this file for the full contract.\n */\n\n/* ---- Spans and marks ------------------------------------------------- */\n\n/**\n * A mark with data. Parameterless marks travel as plain strings (\"strong\");\n * marks that need data travel as objects discriminated by `type`.\n */\nexport interface PortableTextMarkObject {\n type: string;\n [data: string]: unknown;\n}\n\n/** The one default mark that carries data. */\nexport interface PortableTextLinkMark extends PortableTextMarkObject {\n type: \"link\";\n href: string;\n}\n\nexport type PortableTextMark = string | PortableTextMarkObject;\n\n/** The leaf of every text run: a piece of text plus the marks wrapping it. */\nexport interface PortableTextSpan {\n text: string;\n marks?: PortableTextMark[];\n}\n\n/** Marks every client understands without injection. */\nexport const PORTABLE_TEXT_DEFAULT_MARKS = [\n \"strong\",\n \"em\",\n \"code\",\n \"link\",\n] as const;\n\nexport type PortableTextDefaultMark =\n (typeof PORTABLE_TEXT_DEFAULT_MARKS)[number];\n\n/* ---- Blocks ----------------------------------------------------------- */\n\nexport interface PortableTextParagraphBlock {\n type: \"paragraph\";\n children: PortableTextSpan[];\n}\n\n/** 1 maps to Title1, 2 to Title2, 3 to Header2 typography. */\nexport type PortableTextHeadingLevel = 1 | 2 | 3;\n\nexport interface PortableTextHeadingBlock {\n type: \"heading\";\n level: PortableTextHeadingLevel;\n children: PortableTextSpan[];\n}\n\nexport type PortableTextListStyle = \"bullet\" | \"number\";\n\nexport interface PortableTextListItemBlock {\n type: \"list-item\";\n children: PortableTextSpan[];\n}\n\nexport interface PortableTextListBlock {\n type: \"list\";\n style?: PortableTextListStyle;\n children: PortableTextListItemBlock[];\n}\n\n/** Screenshots render framed (border, no shadow); illustrations render flat. */\nexport type PortableTextMediaVariant = \"screenshot\" | \"illustration\";\n\nexport interface PortableTextMediaBlock {\n type: \"media\";\n src: string;\n alt?: string;\n variant?: PortableTextMediaVariant;\n caption?: string;\n}\n\nexport interface PortableTextTitledTextBlock {\n type: \"titled-text\";\n /**\n * Same semantic scale as `heading` — 1, 2 or 3 (the default) — so the wire\n * format never encodes a typography name. How a level looks is the\n * renderer's business.\n */\n level?: PortableTextHeadingLevel;\n title: string;\n content?: PortableTextNode[];\n}\n\nexport interface PortableTextCodeBlock {\n type: \"code-block\";\n /**\n * A language hint (e.g. \"php\", \"json\"). The default renderer does no\n * highlighting, so any value — known, unknown or absent — renders as plain\n * preformatted text; it travels as data for surfaces that highlight.\n */\n language?: string;\n code: string;\n}\n\n/** A table cell is a span array, so inline marks work inside cells. */\nexport type PortableTextTableCell = PortableTextSpan[];\nexport type PortableTextTableRow = PortableTextTableCell[];\n\nexport interface PortableTextTableBlock {\n type: \"table\";\n header: PortableTextTableRow;\n rows: PortableTextTableRow[];\n}\n\n/** A themed horizontal rule between sections. Carries no data. */\nexport interface PortableTextDividerBlock {\n type: \"divider\";\n}\n\nexport type PortableTextBlock =\n | PortableTextParagraphBlock\n | PortableTextHeadingBlock\n | PortableTextListBlock\n | PortableTextMediaBlock\n | PortableTextTitledTextBlock\n | PortableTextCodeBlock\n | PortableTextTableBlock\n | PortableTextDividerBlock;\n\n/**\n * Derived from the union's discriminators, so adding a block to the union\n * without a renderer entry is a compile error, never silent drift.\n */\nexport type PortableTextDefaultBlockType = (\n | PortableTextBlock\n | PortableTextListItemBlock\n)[\"type\"];\n\n// A Record so the compiler checks the list against the union in both\n// directions: a missing and a stray key each fail to build.\nconst DEFAULT_BLOCK_TYPES: Record<PortableTextDefaultBlockType, true> = {\n paragraph: true,\n heading: true,\n list: true,\n \"list-item\": true,\n media: true,\n \"titled-text\": true,\n \"code-block\": true,\n table: true,\n divider: true,\n};\n\n/** Blocks every client understands without injection. */\nexport const PORTABLE_TEXT_DEFAULT_BLOCKS = Object.keys(\n DEFAULT_BLOCK_TYPES\n) as readonly PortableTextDefaultBlockType[];\n\n/* ---- Objects ----------------------------------------------------------- */\n\n/**\n * An embedded component the envelope does not interpret: `_type` names an\n * application-catalog element, everything else is that element's data. An\n * object whose `_type` has no injected renderer renders nothing and is logged.\n */\nexport interface PortableTextObjectNode {\n type: \"object\";\n _type: string;\n [data: string]: unknown;\n}\n\nexport type PortableTextNode = PortableTextBlock | PortableTextObjectNode;\n\n/** The root of a message body: what an API returns under `content`. */\nexport type PortableTextContent = PortableTextNode[];\n\n/* ---- Injection contract ------------------------------------------------ */\n\nexport interface PortableTextMarkRendererProps<\n TMark extends PortableTextMarkObject = PortableTextMarkObject\n> {\n /** Present for object marks; absent when the mark is a plain string. */\n mark?: TMark;\n children: ReactNode;\n}\n\nexport type PortableTextMarkRenderer<\n TMark extends PortableTextMarkObject = PortableTextMarkObject\n> = ComponentType<PortableTextMarkRendererProps<TMark>>;\n\nexport interface PortableTextObjectRendererProps<\n TNode extends PortableTextObjectNode = PortableTextObjectNode\n> {\n node: TNode;\n /** The object's nested `content`, already rendered by the engine. */\n children?: ReactNode;\n}\n\nexport type PortableTextObjectRenderer<\n TNode extends PortableTextObjectNode = PortableTextObjectNode\n> = ComponentType<PortableTextObjectRendererProps<TNode>>;\n\nexport interface PortableTextBlockRendererProps<\n TBlock extends PortableTextBlock = PortableTextBlock\n> {\n block: TBlock;\n /** The block's rendered children/content, when it has any. */\n children?: ReactNode;\n /**\n * Engine-bound span renderer for blocks that carry spans outside `children`\n * (table cells). Resolves marks with the same precedence — injected first,\n * then defaults — as flowing text. Absent when a renderer is used without\n * the engine.\n */\n renderSpans?: (spans: PortableTextSpan[]) => ReactNode;\n}\n\nexport type PortableTextBlockRenderer<\n TBlock extends PortableTextBlock = PortableTextBlock\n> = ComponentType<PortableTextBlockRendererProps<TBlock>>;\n\nexport type PortableTextUnknownKind = \"block\" | \"mark\" | \"object\";\n\n/**\n * Called once per unknown type instead of rendering it, so content written\n * for newer clients degrades silently on older ones.\n */\nexport type PortableTextUnknownTypeHandler = (\n kind: PortableTextUnknownKind,\n type: string\n) => void;\n\n/**\n * What an application injects into the Portable Text engine: renderers for\n * its catalog marks and objects, optional overrides for the default blocks,\n * and the unknown-type hook.\n */\nexport interface PortableTextComponents {\n marks?: Record<string, PortableTextMarkRenderer>;\n objects?: Record<string, PortableTextObjectRenderer>;\n blocks?: Partial<\n Record<PortableTextDefaultBlockType, PortableTextBlockRenderer>\n >;\n onUnknownType?: PortableTextUnknownTypeHandler;\n}\n\n/* ---- Runtime guards ----------------------------------------------------- */\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nexport const isPortableTextSpan = (value: unknown): value is PortableTextSpan =>\n isRecord(value) && typeof value.text === \"string\";\n\nexport const isPortableTextTableRow = (\n value: unknown\n): value is PortableTextTableRow =>\n Array.isArray(value) &&\n value.every((cell) => Array.isArray(cell) && cell.every(isPortableTextSpan));\n\nexport const isPortableTextObjectNode = (\n value: unknown\n): value is PortableTextObjectNode =>\n isRecord(value) && value.type === \"object\" && typeof value._type === \"string\";\n\n/**\n * A block is any non-object node with a string `type`. Unknown block types\n * stay valid on purpose — they render nothing on clients that predate them.\n * Known types are held to their shape, so a serializer bug (a paragraph\n * without `children`, a list of non-nodes) fails here instead of at render.\n */\nexport const isPortableTextBlock = (\n value: unknown\n): value is PortableTextBlock => {\n if (\n !isRecord(value) ||\n typeof value.type !== \"string\" ||\n value.type === \"object\"\n ) {\n return false;\n }\n\n switch (value.type) {\n case \"paragraph\":\n case \"heading\":\n case \"list-item\":\n return (\n Array.isArray(value.children) &&\n value.children.every(isPortableTextSpan)\n );\n case \"list\":\n return (\n Array.isArray(value.children) &&\n value.children.every(isPortableTextBlock)\n );\n case \"media\":\n return typeof value.src === \"string\";\n case \"titled-text\":\n return (\n typeof value.title === \"string\" &&\n (value.content === undefined || isPortableTextContent(value.content))\n );\n case \"code-block\":\n return (\n typeof value.code === \"string\" &&\n (value.language === undefined || typeof value.language === \"string\")\n );\n case \"table\":\n return (\n isPortableTextTableRow(value.header) &&\n Array.isArray(value.rows) &&\n value.rows.every(isPortableTextTableRow)\n );\n case \"divider\":\n return true;\n default:\n return true;\n }\n};\n\nexport const isPortableTextContent = (\n value: unknown\n): value is PortableTextContent =>\n Array.isArray(value) &&\n value.every(\n (node) => isPortableTextBlock(node) || isPortableTextObjectNode(node)\n );\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":["PORTABLE_TEXT_DEFAULT_MARKS","MEDIA_IMAGE_VARIANTS","screenshot","illustration","isPortableTextMediaImageVariant","value","DEFAULT_BLOCK_TYPES","paragraph","heading","list","media","table","divider","PORTABLE_TEXT_DEFAULT_BLOCKS","Object","keys","isRecord","isPortableTextSpan","text","isPortableTextTableRow","Array","isArray","every","cell","isPortableTextObjectNode","type","_type","isPortableTextBlock","children","child","src","title","content","undefined","isPortableTextContent","code","language","header","rows","node"],"sources":["../../../../src/components/PortableText/types.ts"],"sourcesContent":["import { ComponentType, ReactNode } from \"react\";\n\n/**\n * Portable Text envelope — the general content contract for structured,\n * renderer-independent content (in-app messages, help, changelogs).\n *\n * The design system owns this envelope and the universal default set below.\n * It never hardcodes a product element: concrete elements (callout,\n * button-reference, doc-link, …) are defined in the application catalog and\n * injected into the Portable Text engine through {@link PortableTextComponents}.\n * See README.md next to this file for the full contract.\n */\n\n/* ---- Spans and marks ------------------------------------------------- */\n\n/**\n * A mark with data. Parameterless marks travel as plain strings (\"strong\");\n * marks that need data travel as objects discriminated by `type`.\n */\nexport interface PortableTextMarkObject {\n type: string;\n [data: string]: unknown;\n}\n\n/** The one default mark that carries data. */\nexport interface PortableTextLinkMark extends PortableTextMarkObject {\n type: \"link\";\n href: string;\n}\n\nexport type PortableTextMark = string | PortableTextMarkObject;\n\n/** The leaf of every text run: a piece of text plus the marks wrapping it. */\nexport interface PortableTextSpan {\n text: string;\n marks?: PortableTextMark[];\n}\n\n/** Marks every client understands without injection. */\nexport const PORTABLE_TEXT_DEFAULT_MARKS = [\n \"strong\",\n \"em\",\n \"code\",\n \"link\",\n] as const;\n\nexport type PortableTextDefaultMark =\n (typeof PORTABLE_TEXT_DEFAULT_MARKS)[number];\n\n/* ---- Blocks ----------------------------------------------------------- */\n\nexport interface PortableTextParagraphBlock {\n type: \"paragraph\";\n children: PortableTextSpan[];\n}\n\n/** 1 maps to Title1, 2 to Title2, 3 to Header2 typography. */\nexport type PortableTextHeadingLevel = 1 | 2 | 3;\n\nexport interface PortableTextHeadingBlock {\n type: \"heading\";\n level: PortableTextHeadingLevel;\n children: PortableTextSpan[];\n}\n\nexport type PortableTextListStyle = \"bullet\" | \"number\";\n\n/**\n * A list item's children are its own spans first, then any nested `list`\n * block(s) — the shape that carries multi-level lists. A spans-only item (no\n * nested list) is the common, flat case and stays valid unchanged.\n */\nexport interface PortableTextListItemBlock {\n type: \"list-item\";\n children: (PortableTextSpan | PortableTextListBlock)[];\n}\n\nexport interface PortableTextListBlock {\n type: \"list\";\n style?: PortableTextListStyle;\n children: PortableTextListItemBlock[];\n}\n\n/** Screenshots render framed (border, no shadow); illustrations render flat. */\nexport type PortableTextMediaImageVariant = \"screenshot\" | \"illustration\";\n\n/**\n * Video variants name the hosting service; `src` is the canonical video URL.\n * Their rendering carries service semantics (URL parsing, embed derivation),\n * so it belongs to the application catalog — injected as a `media` block\n * override — never to the default set. The default renderer degrades them.\n */\nexport type PortableTextMediaVideoVariant = \"vimeo\" | \"youtube\";\n\nexport type PortableTextMediaVariant =\n | PortableTextMediaImageVariant\n | PortableTextMediaVideoVariant;\n\n// A Record so the compiler checks the list against the union in both\n// directions: a missing and a stray key each fail to build.\nconst MEDIA_IMAGE_VARIANTS: Record<PortableTextMediaImageVariant, true> = {\n screenshot: true,\n illustration: true,\n};\n\nexport const isPortableTextMediaImageVariant = (\n value: unknown\n): value is PortableTextMediaImageVariant =>\n typeof value === \"string\" && value in MEDIA_IMAGE_VARIANTS;\n\nexport interface PortableTextMediaBlock {\n type: \"media\";\n src: string;\n alt?: string;\n variant?: PortableTextMediaVariant;\n caption?: string;\n}\n\nexport interface PortableTextTitledTextBlock {\n type: \"titled-text\";\n /**\n * Same semantic scale as `heading` — 1, 2 or 3 (the default) — so the wire\n * format never encodes a typography name. How a level looks is the\n * renderer's business.\n */\n level?: PortableTextHeadingLevel;\n title: string;\n content?: PortableTextNode[];\n}\n\nexport interface PortableTextCodeBlock {\n type: \"code-block\";\n /**\n * A language hint (e.g. \"php\", \"json\"). The default renderer does no\n * highlighting, so any value — known, unknown or absent — renders as plain\n * preformatted text; it travels as data for surfaces that highlight.\n */\n language?: string;\n code: string;\n}\n\n/** A table cell is a span array, so inline marks work inside cells. */\nexport type PortableTextTableCell = PortableTextSpan[];\nexport type PortableTextTableRow = PortableTextTableCell[];\n\nexport interface PortableTextTableBlock {\n type: \"table\";\n header: PortableTextTableRow;\n rows: PortableTextTableRow[];\n}\n\n/** A themed horizontal rule between sections. Carries no data. */\nexport interface PortableTextDividerBlock {\n type: \"divider\";\n}\n\nexport type PortableTextBlock =\n | PortableTextParagraphBlock\n | PortableTextHeadingBlock\n | PortableTextListBlock\n | PortableTextMediaBlock\n | PortableTextTitledTextBlock\n | PortableTextCodeBlock\n | PortableTextTableBlock\n | PortableTextDividerBlock;\n\n/**\n * Derived from the union's discriminators, so adding a block to the union\n * without a renderer entry is a compile error, never silent drift.\n */\nexport type PortableTextDefaultBlockType = (\n | PortableTextBlock\n | PortableTextListItemBlock\n)[\"type\"];\n\n// A Record so the compiler checks the list against the union in both\n// directions: a missing and a stray key each fail to build.\nconst DEFAULT_BLOCK_TYPES: Record<PortableTextDefaultBlockType, true> = {\n paragraph: true,\n heading: true,\n list: true,\n \"list-item\": true,\n media: true,\n \"titled-text\": true,\n \"code-block\": true,\n table: true,\n divider: true,\n};\n\n/** Blocks every client understands without injection. */\nexport const PORTABLE_TEXT_DEFAULT_BLOCKS = Object.keys(\n DEFAULT_BLOCK_TYPES\n) as readonly PortableTextDefaultBlockType[];\n\n/* ---- Objects ----------------------------------------------------------- */\n\n/**\n * An embedded component the envelope does not interpret: `_type` names an\n * application-catalog element, everything else is that element's data. An\n * object whose `_type` has no injected renderer renders nothing and is logged.\n */\nexport interface PortableTextObjectNode {\n type: \"object\";\n _type: string;\n [data: string]: unknown;\n}\n\nexport type PortableTextNode = PortableTextBlock | PortableTextObjectNode;\n\n/** The root of a message body: what an API returns under `content`. */\nexport type PortableTextContent = PortableTextNode[];\n\n/* ---- Injection contract ------------------------------------------------ */\n\nexport interface PortableTextMarkRendererProps<\n TMark extends PortableTextMarkObject = PortableTextMarkObject\n> {\n /** Present for object marks; absent when the mark is a plain string. */\n mark?: TMark;\n children: ReactNode;\n}\n\nexport type PortableTextMarkRenderer<\n TMark extends PortableTextMarkObject = PortableTextMarkObject\n> = ComponentType<PortableTextMarkRendererProps<TMark>>;\n\nexport interface PortableTextObjectRendererProps<\n TNode extends PortableTextObjectNode = PortableTextObjectNode\n> {\n node: TNode;\n /** The object's nested `content`, already rendered by the engine. */\n children?: ReactNode;\n}\n\nexport type PortableTextObjectRenderer<\n TNode extends PortableTextObjectNode = PortableTextObjectNode\n> = ComponentType<PortableTextObjectRendererProps<TNode>>;\n\nexport interface PortableTextBlockRendererProps<\n TBlock extends PortableTextBlock = PortableTextBlock\n> {\n block: TBlock;\n /** The block's rendered children/content, when it has any. */\n children?: ReactNode;\n /**\n * Engine-bound span renderer for blocks that carry spans outside `children`\n * (table cells). Resolves marks with the same precedence — injected first,\n * then defaults — as flowing text. Absent when a renderer is used without\n * the engine.\n */\n renderSpans?: (spans: PortableTextSpan[]) => ReactNode;\n}\n\nexport type PortableTextBlockRenderer<\n TBlock extends PortableTextBlock = PortableTextBlock\n> = ComponentType<PortableTextBlockRendererProps<TBlock>>;\n\nexport type PortableTextUnknownKind = \"block\" | \"mark\" | \"object\";\n\n/**\n * Called once per unknown type instead of rendering it, so content written\n * for newer clients degrades silently on older ones.\n */\nexport type PortableTextUnknownTypeHandler = (\n kind: PortableTextUnknownKind,\n type: string\n) => void;\n\n/**\n * What an application injects into the Portable Text engine: renderers for\n * its catalog marks and objects, optional overrides for the default blocks,\n * and the unknown-type hook.\n */\nexport interface PortableTextComponents {\n marks?: Record<string, PortableTextMarkRenderer>;\n objects?: Record<string, PortableTextObjectRenderer>;\n blocks?: Partial<\n Record<PortableTextDefaultBlockType, PortableTextBlockRenderer>\n >;\n onUnknownType?: PortableTextUnknownTypeHandler;\n}\n\n/* ---- Runtime guards ----------------------------------------------------- */\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nexport const isPortableTextSpan = (value: unknown): value is PortableTextSpan =>\n isRecord(value) && typeof value.text === \"string\";\n\nexport const isPortableTextTableRow = (\n value: unknown\n): value is PortableTextTableRow =>\n Array.isArray(value) &&\n value.every((cell) => Array.isArray(cell) && cell.every(isPortableTextSpan));\n\nexport const isPortableTextObjectNode = (\n value: unknown\n): value is PortableTextObjectNode =>\n isRecord(value) && value.type === \"object\" && typeof value._type === \"string\";\n\n/**\n * A block is any non-object node with a string `type`. Unknown block types\n * stay valid on purpose — they render nothing on clients that predate them.\n * Known types are held to their shape, so a serializer bug (a paragraph\n * without `children`, a list of non-nodes) fails here instead of at render.\n */\nexport const isPortableTextBlock = (\n value: unknown\n): value is PortableTextBlock => {\n if (\n !isRecord(value) ||\n typeof value.type !== \"string\" ||\n value.type === \"object\"\n ) {\n return false;\n }\n\n switch (value.type) {\n case \"paragraph\":\n case \"heading\":\n return (\n Array.isArray(value.children) &&\n value.children.every(isPortableTextSpan)\n );\n case \"list-item\":\n // The item's spans, plus optional nested `list` block(s). Widened only\n // for nested lists: any other block child (a stray paragraph, an object)\n // still fails, so a serializer bug is caught here, not at render.\n return (\n Array.isArray(value.children) &&\n value.children.every(\n (child) =>\n isPortableTextSpan(child) ||\n (isPortableTextBlock(child) && child.type === \"list\")\n )\n );\n case \"list\":\n // A list holds `list-item`s only. A sublist emitted as a sibling of the\n // items (the classic half-implemented-nesting bug) renders invalid HTML\n // — <ul> with a direct <ul> child — so it fails here, not at render.\n // `list-item` is validated but sits outside the PortableTextBlock union,\n // so the discriminator is checked before isPortableTextBlock narrows it.\n return (\n Array.isArray(value.children) &&\n value.children.every(\n (child) =>\n isRecord(child) &&\n child.type === \"list-item\" &&\n isPortableTextBlock(child)\n )\n );\n case \"media\":\n return typeof value.src === \"string\";\n case \"titled-text\":\n return (\n typeof value.title === \"string\" &&\n (value.content === undefined || isPortableTextContent(value.content))\n );\n case \"code-block\":\n return (\n typeof value.code === \"string\" &&\n (value.language === undefined || typeof value.language === \"string\")\n );\n case \"table\":\n return (\n isPortableTextTableRow(value.header) &&\n Array.isArray(value.rows) &&\n value.rows.every(isPortableTextTableRow)\n );\n case \"divider\":\n return true;\n default:\n return true;\n }\n};\n\nexport const isPortableTextContent = (\n value: unknown\n): value is PortableTextContent =>\n Array.isArray(value) &&\n value.every(\n (node) => isPortableTextBlock(node) || isPortableTextObjectNode(node)\n );\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import { createElement, Fragment } from "react";
2
- import { isPortableTextBlock, isPortableTextContent, isPortableTextObjectNode, isPortableTextSpan, PORTABLE_TEXT_DEFAULT_BLOCKS, PORTABLE_TEXT_DEFAULT_MARKS } from "./types";
2
+ import { isPortableTextBlock, isPortableTextContent, isPortableTextMediaImageVariant, isPortableTextObjectNode, isPortableTextSpan, PORTABLE_TEXT_DEFAULT_BLOCKS, PORTABLE_TEXT_DEFAULT_MARKS } from "./types";
3
3
  describe("PortableText envelope", () => {
4
4
  const sampleMessageContent = [{
5
5
  type: "heading",
@@ -197,6 +197,126 @@ describe("PortableText envelope", () => {
197
197
  rows: []
198
198
  }])).toBe(false);
199
199
  });
200
+ it("accepts a list-item whose children nest a list block after its spans", () => {
201
+ expect(isPortableTextContent([{
202
+ type: "list",
203
+ style: "bullet",
204
+ children: [{
205
+ type: "list-item",
206
+ children: [{
207
+ text: "Step 3:",
208
+ marks: ["strong"]
209
+ }, {
210
+ text: " Choose one of the following options:"
211
+ }, {
212
+ type: "list",
213
+ style: "bullet",
214
+ children: [{
215
+ type: "list-item",
216
+ children: [{
217
+ text: "Sign in via Email"
218
+ }]
219
+ }, {
220
+ type: "list-item",
221
+ children: [{
222
+ text: "Sign in via your Google account"
223
+ }]
224
+ }]
225
+ }]
226
+ }]
227
+ }])).toBe(true);
228
+ });
229
+ it("validates a list nested four levels deep with mixed styles per level", () => {
230
+ expect(isPortableTextContent([{
231
+ type: "list",
232
+ style: "number",
233
+ children: [{
234
+ type: "list-item",
235
+ children: [{
236
+ text: "Top level, ordered"
237
+ }, {
238
+ type: "list",
239
+ style: "bullet",
240
+ children: [{
241
+ type: "list-item",
242
+ children: [{
243
+ text: "Level 2, bullet"
244
+ }, {
245
+ type: "list",
246
+ style: "number",
247
+ children: [{
248
+ type: "list-item",
249
+ children: [{
250
+ text: "Level 3, ordered"
251
+ }, {
252
+ type: "list",
253
+ style: "bullet",
254
+ children: [{
255
+ type: "list-item",
256
+ children: [{
257
+ text: "Level 4, bullet"
258
+ }]
259
+ }]
260
+ }]
261
+ }]
262
+ }]
263
+ }]
264
+ }]
265
+ }]
266
+ }])).toBe(true);
267
+ });
268
+ it("rejects a list whose child is a sublist instead of a list-item", () => {
269
+ // The classic half-implemented-nesting bug: the sublist is emitted as a
270
+ // sibling of the items rather than inside one. It renders invalid HTML
271
+ // (<ul> with a direct <ul> child), so the guard must reject it.
272
+ expect(isPortableTextContent([{
273
+ type: "list",
274
+ style: "bullet",
275
+ children: [{
276
+ type: "list-item",
277
+ children: [{
278
+ text: "Parent"
279
+ }]
280
+ }, {
281
+ type: "list",
282
+ style: "bullet",
283
+ children: [{
284
+ type: "list-item",
285
+ children: [{
286
+ text: "Orphan sub"
287
+ }]
288
+ }]
289
+ }]
290
+ }])).toBe(false);
291
+ });
292
+ it("rejects a list-item child that is neither a span nor a nested list", () => {
293
+ // A stray paragraph child — the guard is widened for nested lists only.
294
+ expect(isPortableTextContent([{
295
+ type: "list",
296
+ children: [{
297
+ type: "list-item",
298
+ children: [{
299
+ text: "An item"
300
+ }, {
301
+ type: "paragraph",
302
+ children: [{
303
+ text: "not allowed here"
304
+ }]
305
+ }]
306
+ }]
307
+ }])).toBe(false);
308
+ // An embedded object child is rejected too.
309
+ expect(isPortableTextContent([{
310
+ type: "list",
311
+ children: [{
312
+ type: "list-item",
313
+ children: [{
314
+ type: "object",
315
+ _type: "callout"
316
+ }]
317
+ }]
318
+ }])).toBe(false);
319
+ });
200
320
  it("accepts a code-block without a language and a table without rows", () => {
201
321
  expect(isPortableTextContent([{
202
322
  type: "code-block",
@@ -241,6 +361,23 @@ describe("PortableText envelope", () => {
241
361
  expect(PORTABLE_TEXT_DEFAULT_BLOCKS).toEqual(["paragraph", "heading", "list", "list-item", "media", "titled-text", "code-block", "table", "divider"]);
242
362
  expect(PORTABLE_TEXT_DEFAULT_MARKS).toEqual(["strong", "em", "code", "link"]);
243
363
  });
364
+ it("keeps video media variants in the envelope but out of the image variant set", () => {
365
+ expect(isPortableTextContent([{
366
+ type: "media",
367
+ variant: "vimeo",
368
+ src: "https://vimeo.com/1131696931",
369
+ caption: "Duplicating a project"
370
+ }, {
371
+ type: "media",
372
+ variant: "youtube",
373
+ src: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
374
+ }])).toBe(true);
375
+ expect(isPortableTextMediaImageVariant("screenshot")).toBe(true);
376
+ expect(isPortableTextMediaImageVariant("illustration")).toBe(true);
377
+ expect(isPortableTextMediaImageVariant("vimeo")).toBe(false);
378
+ expect(isPortableTextMediaImageVariant("youtube")).toBe(false);
379
+ expect(isPortableTextMediaImageVariant(undefined)).toBe(false);
380
+ });
244
381
  it("accepts an application components map through the injection contract", () => {
245
382
  var _components$marks;
246
383
  const seen = [];
@@ -1 +1 @@
1
- {"version":3,"file":"types.test.js","names":["createElement","Fragment","isPortableTextBlock","isPortableTextContent","isPortableTextObjectNode","isPortableTextSpan","PORTABLE_TEXT_DEFAULT_BLOCKS","PORTABLE_TEXT_DEFAULT_MARKS","describe","sampleMessageContent","type","level","children","text","marks","article","style","src","variant","caption","title","content","_type","tone","label","language","code","header","rows","it","expect","toBe","payload","data","heading","paragraph","callout","toEqual","_components$marks","seen","components","_ref","objects","_ref2","onUnknownType","kind","push","Object","keys"],"sources":["../../../../src/components/PortableText/types.test.ts"],"sourcesContent":["import { createElement, Fragment } from \"react\";\n\nimport {\n isPortableTextBlock,\n isPortableTextContent,\n isPortableTextObjectNode,\n isPortableTextSpan,\n PORTABLE_TEXT_DEFAULT_BLOCKS,\n PORTABLE_TEXT_DEFAULT_MARKS,\n PortableTextComponents,\n PortableTextContent,\n} from \"./types\";\n\ndescribe(\"PortableText envelope\", () => {\n const sampleMessageContent: PortableTextContent = [\n { type: \"heading\", level: 2, children: [{ text: \"IP Firewall\" }] },\n {\n type: \"paragraph\",\n children: [\n { text: \"Open the \" },\n { text: \"Security page\", marks: [\"interface-name\"] },\n { text: \" and press \" },\n { text: \"Enter\", marks: [\"keyboard-key\"] },\n { text: \". Read more in \" },\n {\n text: \"the help article\",\n marks: [{ type: \"doc-link\", article: \"ip-firewall\" }],\n },\n { text: \".\" },\n ],\n },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [{ text: \"Allowlist the IPs you trust\" }],\n },\n {\n type: \"list-item\",\n children: [{ text: \"immediately\", marks: [\"strong\"] }],\n },\n ],\n },\n {\n type: \"media\",\n src: \"/screenshots/firewall.png\",\n variant: \"screenshot\",\n caption: \"The firewall settings\",\n },\n {\n type: \"titled-text\",\n title: \"Allowlist the IPs you trust\",\n level: 3,\n content: [\n { type: \"paragraph\", children: [{ text: \"Add one range per line.\" }] },\n ],\n },\n {\n type: \"object\",\n _type: \"callout\",\n tone: \"note\",\n content: [\n {\n type: \"paragraph\",\n children: [{ text: \"Takes effect immediately.\" }],\n },\n ],\n },\n {\n type: \"object\",\n _type: \"button-reference\",\n label: \"Save Changes\",\n variant: \"primary\",\n },\n { type: \"divider\" },\n {\n type: \"code-block\",\n language: \"json\",\n code: '{ \"allowlist\": [\"203.0.113.0/24\"] }',\n },\n {\n type: \"table\",\n header: [[{ text: \"Range\" }], [{ text: \"Purpose\" }]],\n rows: [\n [\n [{ text: \"203.0.113.0/24\", marks: [\"code\"] }],\n [{ text: \"Office\", marks: [\"strong\"] }],\n ],\n [[{ text: \"198.51.100.0/24\", marks: [\"code\"] }], [{ text: \"VPN\" }]],\n ],\n },\n ];\n\n it(\"validates a sample message that mixes default blocks and catalog objects\", () => {\n expect(isPortableTextContent(sampleMessageContent)).toBe(true);\n });\n\n it(\"keeps unknown block and object types valid so older clients degrade instead of break\", () => {\n expect(\n isPortableTextContent([\n { type: \"some-future-block\", payload: 1 },\n { type: \"object\", _type: \"some-future-element\", data: true },\n ])\n ).toBe(true);\n });\n\n it(\"rejects nodes without a type discriminator and objects without _type\", () => {\n expect(isPortableTextContent([{ children: [] }])).toBe(false);\n expect(isPortableTextContent([{ type: \"object\" }])).toBe(false);\n expect(isPortableTextContent([\"paragraph\"])).toBe(false);\n expect(isPortableTextContent({ content: [] })).toBe(false);\n });\n\n it(\"rejects known blocks whose shape a serializer bug has broken\", () => {\n expect(isPortableTextContent([{ type: \"paragraph\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"heading\", level: 2, children: \"oops\" }])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"paragraph\", children: [{ marks: [\"strong\"] }] },\n ])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"list\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"list\", children: [\"not a node\"] }])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"media\" }])).toBe(false);\n expect(isPortableTextContent([{ type: \"titled-text\", content: [] }])).toBe(\n false\n );\n expect(\n isPortableTextContent([\n { type: \"titled-text\", title: \"Ranges\", content: \"oops\" },\n ])\n ).toBe(false);\n });\n\n it(\"rejects malformed code-block, table and divider-adjacent shapes\", () => {\n expect(isPortableTextContent([{ type: \"code-block\" }])).toBe(false);\n expect(isPortableTextContent([{ type: \"code-block\", code: 42 }])).toBe(\n false\n );\n expect(\n isPortableTextContent([{ type: \"code-block\", code: \"x\", language: 1 }])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"table\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"table\", header: [], rows: \"oops\" }])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [[{ text: \"A\" }]], rows: [[\"not a cell\"]] },\n ])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [{ text: \"not a cell\" }], rows: [] },\n ])\n ).toBe(false);\n });\n\n it(\"accepts a code-block without a language and a table without rows\", () => {\n expect(\n isPortableTextContent([{ type: \"code-block\", code: \"npm install\" }])\n ).toBe(true);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [[{ text: \"A\" }]], rows: [] },\n ])\n ).toBe(true);\n expect(isPortableTextContent([{ type: \"divider\" }])).toBe(true);\n });\n\n it(\"accepts a titled-text with only a title, with or without content\", () => {\n expect(\n isPortableTextContent([{ type: \"titled-text\", title: \"Ranges\" }])\n ).toBe(true);\n expect(\n isPortableTextContent([\n { type: \"titled-text\", title: \"Ranges\", content: [] },\n ])\n ).toBe(true);\n });\n\n it(\"tells blocks, objects and spans apart\", () => {\n const [heading, paragraph] = sampleMessageContent;\n const callout = sampleMessageContent[5];\n\n expect(isPortableTextBlock(heading)).toBe(true);\n expect(isPortableTextBlock(callout)).toBe(false);\n expect(isPortableTextObjectNode(callout)).toBe(true);\n expect(isPortableTextObjectNode(heading)).toBe(false);\n expect(isPortableTextSpan({ text: \"plain\" })).toBe(true);\n expect(isPortableTextSpan(paragraph)).toBe(false);\n });\n\n it(\"ships a universal default set free of product elements\", () => {\n expect(PORTABLE_TEXT_DEFAULT_BLOCKS).toEqual([\n \"paragraph\",\n \"heading\",\n \"list\",\n \"list-item\",\n \"media\",\n \"titled-text\",\n \"code-block\",\n \"table\",\n \"divider\",\n ]);\n expect(PORTABLE_TEXT_DEFAULT_MARKS).toEqual([\n \"strong\",\n \"em\",\n \"code\",\n \"link\",\n ]);\n });\n\n it(\"accepts an application components map through the injection contract\", () => {\n const seen: string[] = [];\n const components: PortableTextComponents = {\n marks: {\n \"interface-name\": ({ children }) =>\n createElement(Fragment, null, children),\n },\n objects: {\n callout: ({ children }) => createElement(Fragment, null, children),\n },\n onUnknownType: (kind, type) => {\n seen.push(`${kind}:${type}`);\n },\n };\n\n components.onUnknownType?.(\"object\", \"some-future-element\");\n\n expect(Object.keys(components.marks ?? {})).toEqual([\"interface-name\"]);\n expect(seen).toEqual([\"object:some-future-element\"]);\n });\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"types.test.js","names":["createElement","Fragment","isPortableTextBlock","isPortableTextContent","isPortableTextMediaImageVariant","isPortableTextObjectNode","isPortableTextSpan","PORTABLE_TEXT_DEFAULT_BLOCKS","PORTABLE_TEXT_DEFAULT_MARKS","describe","sampleMessageContent","type","level","children","text","marks","article","style","src","variant","caption","title","content","_type","tone","label","language","code","header","rows","it","expect","toBe","payload","data","heading","paragraph","callout","toEqual","undefined","_components$marks","seen","components","_ref","objects","_ref2","onUnknownType","kind","push","Object","keys"],"sources":["../../../../src/components/PortableText/types.test.ts"],"sourcesContent":["import { createElement, Fragment } from \"react\";\n\nimport {\n isPortableTextBlock,\n isPortableTextContent,\n isPortableTextMediaImageVariant,\n isPortableTextObjectNode,\n isPortableTextSpan,\n PORTABLE_TEXT_DEFAULT_BLOCKS,\n PORTABLE_TEXT_DEFAULT_MARKS,\n PortableTextComponents,\n PortableTextContent,\n} from \"./types\";\n\ndescribe(\"PortableText envelope\", () => {\n const sampleMessageContent: PortableTextContent = [\n { type: \"heading\", level: 2, children: [{ text: \"IP Firewall\" }] },\n {\n type: \"paragraph\",\n children: [\n { text: \"Open the \" },\n { text: \"Security page\", marks: [\"interface-name\"] },\n { text: \" and press \" },\n { text: \"Enter\", marks: [\"keyboard-key\"] },\n { text: \". Read more in \" },\n {\n text: \"the help article\",\n marks: [{ type: \"doc-link\", article: \"ip-firewall\" }],\n },\n { text: \".\" },\n ],\n },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [{ text: \"Allowlist the IPs you trust\" }],\n },\n {\n type: \"list-item\",\n children: [{ text: \"immediately\", marks: [\"strong\"] }],\n },\n ],\n },\n {\n type: \"media\",\n src: \"/screenshots/firewall.png\",\n variant: \"screenshot\",\n caption: \"The firewall settings\",\n },\n {\n type: \"titled-text\",\n title: \"Allowlist the IPs you trust\",\n level: 3,\n content: [\n { type: \"paragraph\", children: [{ text: \"Add one range per line.\" }] },\n ],\n },\n {\n type: \"object\",\n _type: \"callout\",\n tone: \"note\",\n content: [\n {\n type: \"paragraph\",\n children: [{ text: \"Takes effect immediately.\" }],\n },\n ],\n },\n {\n type: \"object\",\n _type: \"button-reference\",\n label: \"Save Changes\",\n variant: \"primary\",\n },\n { type: \"divider\" },\n {\n type: \"code-block\",\n language: \"json\",\n code: '{ \"allowlist\": [\"203.0.113.0/24\"] }',\n },\n {\n type: \"table\",\n header: [[{ text: \"Range\" }], [{ text: \"Purpose\" }]],\n rows: [\n [\n [{ text: \"203.0.113.0/24\", marks: [\"code\"] }],\n [{ text: \"Office\", marks: [\"strong\"] }],\n ],\n [[{ text: \"198.51.100.0/24\", marks: [\"code\"] }], [{ text: \"VPN\" }]],\n ],\n },\n ];\n\n it(\"validates a sample message that mixes default blocks and catalog objects\", () => {\n expect(isPortableTextContent(sampleMessageContent)).toBe(true);\n });\n\n it(\"keeps unknown block and object types valid so older clients degrade instead of break\", () => {\n expect(\n isPortableTextContent([\n { type: \"some-future-block\", payload: 1 },\n { type: \"object\", _type: \"some-future-element\", data: true },\n ])\n ).toBe(true);\n });\n\n it(\"rejects nodes without a type discriminator and objects without _type\", () => {\n expect(isPortableTextContent([{ children: [] }])).toBe(false);\n expect(isPortableTextContent([{ type: \"object\" }])).toBe(false);\n expect(isPortableTextContent([\"paragraph\"])).toBe(false);\n expect(isPortableTextContent({ content: [] })).toBe(false);\n });\n\n it(\"rejects known blocks whose shape a serializer bug has broken\", () => {\n expect(isPortableTextContent([{ type: \"paragraph\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"heading\", level: 2, children: \"oops\" }])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"paragraph\", children: [{ marks: [\"strong\"] }] },\n ])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"list\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"list\", children: [\"not a node\"] }])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"media\" }])).toBe(false);\n expect(isPortableTextContent([{ type: \"titled-text\", content: [] }])).toBe(\n false\n );\n expect(\n isPortableTextContent([\n { type: \"titled-text\", title: \"Ranges\", content: \"oops\" },\n ])\n ).toBe(false);\n });\n\n it(\"rejects malformed code-block, table and divider-adjacent shapes\", () => {\n expect(isPortableTextContent([{ type: \"code-block\" }])).toBe(false);\n expect(isPortableTextContent([{ type: \"code-block\", code: 42 }])).toBe(\n false\n );\n expect(\n isPortableTextContent([{ type: \"code-block\", code: \"x\", language: 1 }])\n ).toBe(false);\n expect(isPortableTextContent([{ type: \"table\" }])).toBe(false);\n expect(\n isPortableTextContent([{ type: \"table\", header: [], rows: \"oops\" }])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [[{ text: \"A\" }]], rows: [[\"not a cell\"]] },\n ])\n ).toBe(false);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [{ text: \"not a cell\" }], rows: [] },\n ])\n ).toBe(false);\n });\n\n it(\"accepts a list-item whose children nest a list block after its spans\", () => {\n expect(\n isPortableTextContent([\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [\n { text: \"Step 3:\", marks: [\"strong\"] },\n { text: \" Choose one of the following options:\" },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [{ text: \"Sign in via Email\" }],\n },\n {\n type: \"list-item\",\n children: [{ text: \"Sign in via your Google account\" }],\n },\n ],\n },\n ],\n },\n ],\n },\n ])\n ).toBe(true);\n });\n\n it(\"validates a list nested four levels deep with mixed styles per level\", () => {\n expect(\n isPortableTextContent([\n {\n type: \"list\",\n style: \"number\",\n children: [\n {\n type: \"list-item\",\n children: [\n { text: \"Top level, ordered\" },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [\n { text: \"Level 2, bullet\" },\n {\n type: \"list\",\n style: \"number\",\n children: [\n {\n type: \"list-item\",\n children: [\n { text: \"Level 3, ordered\" },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n {\n type: \"list-item\",\n children: [{ text: \"Level 4, bullet\" }],\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ])\n ).toBe(true);\n });\n\n it(\"rejects a list whose child is a sublist instead of a list-item\", () => {\n // The classic half-implemented-nesting bug: the sublist is emitted as a\n // sibling of the items rather than inside one. It renders invalid HTML\n // (<ul> with a direct <ul> child), so the guard must reject it.\n expect(\n isPortableTextContent([\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n { type: \"list-item\", children: [{ text: \"Parent\" }] },\n {\n type: \"list\",\n style: \"bullet\",\n children: [\n { type: \"list-item\", children: [{ text: \"Orphan sub\" }] },\n ],\n },\n ],\n },\n ])\n ).toBe(false);\n });\n\n it(\"rejects a list-item child that is neither a span nor a nested list\", () => {\n // A stray paragraph child — the guard is widened for nested lists only.\n expect(\n isPortableTextContent([\n {\n type: \"list\",\n children: [\n {\n type: \"list-item\",\n children: [\n { text: \"An item\" },\n { type: \"paragraph\", children: [{ text: \"not allowed here\" }] },\n ],\n },\n ],\n },\n ])\n ).toBe(false);\n // An embedded object child is rejected too.\n expect(\n isPortableTextContent([\n {\n type: \"list\",\n children: [\n {\n type: \"list-item\",\n children: [{ type: \"object\", _type: \"callout\" }],\n },\n ],\n },\n ])\n ).toBe(false);\n });\n\n it(\"accepts a code-block without a language and a table without rows\", () => {\n expect(\n isPortableTextContent([{ type: \"code-block\", code: \"npm install\" }])\n ).toBe(true);\n expect(\n isPortableTextContent([\n { type: \"table\", header: [[{ text: \"A\" }]], rows: [] },\n ])\n ).toBe(true);\n expect(isPortableTextContent([{ type: \"divider\" }])).toBe(true);\n });\n\n it(\"accepts a titled-text with only a title, with or without content\", () => {\n expect(\n isPortableTextContent([{ type: \"titled-text\", title: \"Ranges\" }])\n ).toBe(true);\n expect(\n isPortableTextContent([\n { type: \"titled-text\", title: \"Ranges\", content: [] },\n ])\n ).toBe(true);\n });\n\n it(\"tells blocks, objects and spans apart\", () => {\n const [heading, paragraph] = sampleMessageContent;\n const callout = sampleMessageContent[5];\n\n expect(isPortableTextBlock(heading)).toBe(true);\n expect(isPortableTextBlock(callout)).toBe(false);\n expect(isPortableTextObjectNode(callout)).toBe(true);\n expect(isPortableTextObjectNode(heading)).toBe(false);\n expect(isPortableTextSpan({ text: \"plain\" })).toBe(true);\n expect(isPortableTextSpan(paragraph)).toBe(false);\n });\n\n it(\"ships a universal default set free of product elements\", () => {\n expect(PORTABLE_TEXT_DEFAULT_BLOCKS).toEqual([\n \"paragraph\",\n \"heading\",\n \"list\",\n \"list-item\",\n \"media\",\n \"titled-text\",\n \"code-block\",\n \"table\",\n \"divider\",\n ]);\n expect(PORTABLE_TEXT_DEFAULT_MARKS).toEqual([\n \"strong\",\n \"em\",\n \"code\",\n \"link\",\n ]);\n });\n\n it(\"keeps video media variants in the envelope but out of the image variant set\", () => {\n expect(\n isPortableTextContent([\n {\n type: \"media\",\n variant: \"vimeo\",\n src: \"https://vimeo.com/1131696931\",\n caption: \"Duplicating a project\",\n },\n {\n type: \"media\",\n variant: \"youtube\",\n src: \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\",\n },\n ])\n ).toBe(true);\n\n expect(isPortableTextMediaImageVariant(\"screenshot\")).toBe(true);\n expect(isPortableTextMediaImageVariant(\"illustration\")).toBe(true);\n expect(isPortableTextMediaImageVariant(\"vimeo\")).toBe(false);\n expect(isPortableTextMediaImageVariant(\"youtube\")).toBe(false);\n expect(isPortableTextMediaImageVariant(undefined)).toBe(false);\n });\n\n it(\"accepts an application components map through the injection contract\", () => {\n const seen: string[] = [];\n const components: PortableTextComponents = {\n marks: {\n \"interface-name\": ({ children }) =>\n createElement(Fragment, null, children),\n },\n objects: {\n callout: ({ children }) => createElement(Fragment, null, children),\n },\n onUnknownType: (kind, type) => {\n seen.push(`${kind}:${type}`);\n },\n };\n\n components.onUnknownType?.(\"object\", \"some-future-element\");\n\n expect(Object.keys(components.marks ?? {})).toEqual([\"interface-name\"]);\n expect(seen).toEqual([\"object:some-future-element\"]);\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,52 @@
1
+ import { ReactElement } from "react";
2
+ /**
3
+ * FeatureAvailability — a compact, data-driven block that states where a
4
+ * feature is available: on which hosting, on which plans and to which roles.
5
+ *
6
+ * It is the reusable version of the availability panel used in the Help Docs
7
+ * example articles, extracted so several stories (and, later, the real
8
+ * PortableText renderer) can share one implementation and one visual language:
9
+ *
10
+ * • green check → available
11
+ * • analog clock → decided but not shipped yet ("to be determined")
12
+ * • strikethrough → not included
13
+ *
14
+ * The component is theme-agnostic (all colors come from `--color-*` tokens) and
15
+ * self-contained (it carries its own typography, so it renders correctly
16
+ * outside the article body as well).
17
+ */
18
+ export type AvailabilityStatus = "available" | "pending" | "excluded";
19
+ export interface AvailabilityMark {
20
+ label: string;
21
+ status: AvailabilityStatus;
22
+ /** Muted parenthetical, e.g. "(stable, since Jun 17 2026)". Include the parens. */
23
+ note?: string;
24
+ /** Italic muted trailing text for the pending state, e.g. "to be determined". */
25
+ pending?: string;
26
+ /**
27
+ * Nested marks rendered in parentheses, e.g. Member+ (PM ✓ / FM ✓). When a
28
+ * mark has children it does not render its own status icon — the children
29
+ * carry the marks.
30
+ */
31
+ children?: AvailabilityMark[];
32
+ }
33
+ export interface AvailabilityRow {
34
+ label: string;
35
+ items: AvailabilityMark[];
36
+ /** Icon before the label (Availability row) or after it (Plans / Roles). Default "after". */
37
+ iconPosition?: "before" | "after";
38
+ /** Separate items with a middot (used on the Availability row). Default false. */
39
+ separated?: boolean;
40
+ }
41
+ export interface FeatureAvailabilityProps {
42
+ rows: AvailabilityRow[];
43
+ className?: string;
44
+ }
45
+ export declare const FeatureAvailability: ({ rows, className, }: FeatureAvailabilityProps) => ReactElement;
46
+ /**
47
+ * A realistic GA feature: shipped on Cloud, self-hosted still to be scheduled,
48
+ * on every plan, for internal roles but not for clients. Exercises all three
49
+ * marks (check / clock / strikethrough) out of the box.
50
+ */
51
+ export declare const DEFAULT_FEATURE_AVAILABILITY: FeatureAvailabilityProps;
52
+ //# sourceMappingURL=FeatureAvailability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureAvailability.d.ts","sourceRoot":"","sources":["../../../../src/presentation/shared/FeatureAvailability.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI5C;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;IAC3B,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsMD,eAAO,MAAM,mBAAmB,GAAI,sBAGjC,wBAAwB,KAAG,YAsB7B,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,wBA8C1C,CAAC"}