@hubspot/ui-extensions-sdk-api-metadata 0.12.0 → 0.12.1

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.
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Wraps code as text in HTML code tags for HTML rendering. Special HTML characters are escaped.
3
+ *
4
+ * @param value - The code as text to wrap in HTML code tags
5
+ * @returns The code as text wrapped in HTML code tags
6
+ */
7
+ export declare const wrapCodeInHtmlCodeTags: (value: string) => string;
8
+ /**
9
+ * Converts HTML to XHTML (well-formed XML) by ensuring all void elements
10
+ * are self-closing and the output is valid XML.
11
+ *
12
+ * This is necessary because the generated HTML will be embedded in JSX
13
+ * fragments, which require valid XML syntax. For example, `<br>` must
14
+ * become `<br/>` and `<img src="...">` must become `<img src="..."/>`.
15
+ *
16
+ * Outermost `<p>` tags are stripped when the content is a single paragraph to allow
17
+ * for cleaner inline rendering. When multiple block elements exist (e.g., text followed
18
+ * by a list), the structure is preserved.
19
+ *
20
+ * @param html - The HTML string to convert
21
+ * @returns The HTML converted to XHTML format with self-closing tags
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * convertHtmlToJsx('<p>Hello<br>World</p>')
26
+ * // Returns: 'Hello<br/>World'
27
+ *
28
+ * convertHtmlToJsx('<img src="test.png">')
29
+ * // Returns: '<img src="test.png"/>'
30
+ * ```
31
+ */
32
+ export declare const convertHtmlToJsx: (html: string) => string;
@@ -0,0 +1,77 @@
1
+ import { parseDocument, DomUtils } from 'htmlparser2';
2
+ import serialize from 'dom-serializer';
3
+ const escapeJsxExpressions = (jsx) => {
4
+ return jsx.replaceAll('{', '&#123;').replaceAll('}', '&#125;');
5
+ };
6
+ const sanitizeHtmlTextForCodeBlock = (htmlText) => {
7
+ return escapeJsxExpressions(htmlText
8
+ .replaceAll('&', '&amp;')
9
+ .replaceAll('<', '&lt;')
10
+ .replaceAll('>', '&gt;'));
11
+ // NOTE: We are not putting HTML inside an HTML attribute so we don't need to escape quotes or apostrophes
12
+ };
13
+ /**
14
+ * Wraps code as text in HTML code tags for HTML rendering. Special HTML characters are escaped.
15
+ *
16
+ * @param value - The code as text to wrap in HTML code tags
17
+ * @returns The code as text wrapped in HTML code tags
18
+ */
19
+ export const wrapCodeInHtmlCodeTags = (value) => {
20
+ return `<code>${sanitizeHtmlTextForCodeBlock(value)}</code>`;
21
+ };
22
+ const stripOutermostParagraphNode = (dom) => {
23
+ // Check if there's exactly one root element and it's a <p> tag
24
+ const rootChildren = dom.children;
25
+ if (rootChildren.length !== 1) {
26
+ return;
27
+ }
28
+ const firstChild = rootChildren[0];
29
+ if (firstChild.type !== 'tag' || firstChild.name !== 'p') {
30
+ return;
31
+ }
32
+ // Move all of the children of the <p> element node to the root DOM node
33
+ const childrenToMove = [...firstChild.childNodes];
34
+ for (const child of childrenToMove) {
35
+ DomUtils.appendChild(dom, child);
36
+ }
37
+ // Now remove the <p> element node
38
+ DomUtils.removeElement(firstChild);
39
+ };
40
+ /**
41
+ * Converts HTML to XHTML (well-formed XML) by ensuring all void elements
42
+ * are self-closing and the output is valid XML.
43
+ *
44
+ * This is necessary because the generated HTML will be embedded in JSX
45
+ * fragments, which require valid XML syntax. For example, `<br>` must
46
+ * become `<br/>` and `<img src="...">` must become `<img src="..."/>`.
47
+ *
48
+ * Outermost `<p>` tags are stripped when the content is a single paragraph to allow
49
+ * for cleaner inline rendering. When multiple block elements exist (e.g., text followed
50
+ * by a list), the structure is preserved.
51
+ *
52
+ * @param html - The HTML string to convert
53
+ * @returns The HTML converted to XHTML format with self-closing tags
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * convertHtmlToJsx('<p>Hello<br>World</p>')
58
+ * // Returns: 'Hello<br/>World'
59
+ *
60
+ * convertHtmlToJsx('<img src="test.png">')
61
+ * // Returns: '<img src="test.png"/>'
62
+ * ```
63
+ */
64
+ export const convertHtmlToJsx = (html) => {
65
+ // Parse HTML into a DOM structure (parse as HTML to handle loose syntax)
66
+ const dom = parseDocument(html, {
67
+ xmlMode: false,
68
+ });
69
+ // Remove unnecessary outermost <p> tag
70
+ stripOutermostParagraphNode(dom);
71
+ // Serialize back to string with XML rules (self-closing tags, etc.)
72
+ const xhtml = serialize(dom, {
73
+ xmlMode: true, // Use XML/XHTML serialization rules
74
+ selfClosingTags: true, // Ensure void elements are self-closing
75
+ });
76
+ return `<>${escapeJsxExpressions(xhtml)}</>`;
77
+ };
@@ -1,7 +1,12 @@
1
1
  /**
2
- * Renders inline markdown text to HTML.
2
+ * Renders markdown text to JSX.
3
+ *
4
+ * Supports both inline elements (emphasis, code spans, links) and block-level
5
+ * elements (lists, paragraphs, headings). The output is converted to XHTML format
6
+ * to ensure it's valid XML/JSX, with all void elements properly self-closing
7
+ * (e.g., `<br/>` instead of `<br>`).
3
8
  *
4
9
  * @param markdownText - The markdown text to render to HTML
5
- * @returns The markdown text rendered to HTML
10
+ * @returns The markdown text rendered to XHTML
6
11
  */
7
- export declare const renderInlineMarkdownToHtml: (markdownText: string) => string;
12
+ export declare const renderMarkdownToJsx: (markdownText: string) => string;
@@ -1,14 +1,21 @@
1
1
  import { Marked } from 'marked';
2
+ import { convertHtmlToJsx } from "./jsx-utils.js";
2
3
  const markedInstance = new Marked({
3
4
  breaks: true,
4
5
  gfm: true,
5
6
  });
6
7
  /**
7
- * Renders inline markdown text to HTML.
8
+ * Renders markdown text to JSX.
9
+ *
10
+ * Supports both inline elements (emphasis, code spans, links) and block-level
11
+ * elements (lists, paragraphs, headings). The output is converted to XHTML format
12
+ * to ensure it's valid XML/JSX, with all void elements properly self-closing
13
+ * (e.g., `<br/>` instead of `<br>`).
8
14
  *
9
15
  * @param markdownText - The markdown text to render to HTML
10
- * @returns The markdown text rendered to HTML
16
+ * @returns The markdown text rendered to XHTML
11
17
  */
12
- export const renderInlineMarkdownToHtml = (markdownText) => {
13
- return markedInstance.parseInline(markdownText).toString().trim();
18
+ export const renderMarkdownToJsx = (markdownText) => {
19
+ const html = markedInstance.parse(markdownText).toString().trim();
20
+ return convertHtmlToJsx(html);
14
21
  };
package/dist/types.d.ts CHANGED
@@ -35,5 +35,98 @@ export interface ComponentPropDocumentation {
35
35
  * FUTURE: We should use code generation to generate this enum.
36
36
  */
37
37
  export declare enum ComponentName {
38
- Accordion = "Accordion"
38
+ Accordion = "Accordion",
39
+ Alert = "Alert",
40
+ AutoGrid = "AutoGrid",
41
+ BarChart = "BarChart",
42
+ Box = "Box",
43
+ Button = "Button",
44
+ ButtonRow = "ButtonRow",
45
+ Card = "Card",
46
+ Center = "Center",
47
+ Checkbox = "Checkbox",
48
+ CrmActionButton = "CrmActionButton",
49
+ CrmActionLink = "CrmActionLink",
50
+ CrmAssociationPivot = "CrmAssociationPivot",
51
+ CrmAssociationPropertyList = "CrmAssociationPropertyList",
52
+ CrmAssociationStageTracker = "CrmAssociationStageTracker",
53
+ CrmAssociationTable = "CrmAssociationTable",
54
+ CrmCardActions = "CrmCardActions",
55
+ CrmDataHighlight = "CrmDataHighlight",
56
+ CrmPropertyList = "CrmPropertyList",
57
+ CrmReport = "CrmReport",
58
+ CrmSimpleDeadline = "CrmSimpleDeadline",
59
+ CrmStageTracker = "CrmStageTracker",
60
+ CrmStatistics = "CrmStatistics",
61
+ CurrencyInput = "CurrencyInput",
62
+ DateInput = "DateInput",
63
+ DescriptionList = "DescriptionList",
64
+ DescriptionListItem = "DescriptionListItem",
65
+ Divider = "Divider",
66
+ Dropdown = "Dropdown",
67
+ DropdownButtonItem = "DropdownButtonItem",
68
+ EmptyState = "EmptyState",
69
+ ErrorState = "ErrorState",
70
+ ExpandableText = "ExpandableText",
71
+ FileInput = "FileInput",
72
+ Flex = "Flex",
73
+ Form = "Form",
74
+ Grid = "Grid",
75
+ GridItem = "GridItem",
76
+ HeaderActions = "HeaderActions",
77
+ Heading = "Heading",
78
+ Icon = "Icon",
79
+ Iframe = "Iframe",
80
+ Illustration = "Illustration",
81
+ Image = "Image",
82
+ Inline = "Inline",
83
+ Input = "Input",
84
+ LineChart = "LineChart",
85
+ Link = "Link",
86
+ List = "List",
87
+ LoadingButton = "LoadingButton",
88
+ LoadingSpinner = "LoadingSpinner",
89
+ MediaObject = "MediaObject",
90
+ Modal = "Modal",
91
+ ModalBody = "ModalBody",
92
+ ModalFooter = "ModalFooter",
93
+ MultiSelect = "MultiSelect",
94
+ NumberInput = "NumberInput",
95
+ Panel = "Panel",
96
+ PanelBody = "PanelBody",
97
+ PanelFooter = "PanelFooter",
98
+ PanelSection = "PanelSection",
99
+ Popover = "Popover",
100
+ PrimaryHeaderActionButton = "PrimaryHeaderActionButton",
101
+ ProgressBar = "ProgressBar",
102
+ RadioButton = "RadioButton",
103
+ ScoreCircle = "ScoreCircle",
104
+ SearchInput = "SearchInput",
105
+ SecondaryHeaderActionButton = "SecondaryHeaderActionButton",
106
+ Select = "Select",
107
+ SettingsView = "SettingsView",
108
+ Stack2 = "Stack2",
109
+ Statistics = "Statistics",
110
+ StatisticsItem = "StatisticsItem",
111
+ StatisticsTrend = "StatisticsTrend",
112
+ StatusTag = "StatusTag",
113
+ StepIndicator = "StepIndicator",
114
+ StepperInput = "StepperInput",
115
+ Tab = "Tab",
116
+ Table = "Table",
117
+ TableBody = "TableBody",
118
+ TableCell = "TableCell",
119
+ TableFooter = "TableFooter",
120
+ TableHead = "TableHead",
121
+ TableHeader = "TableHeader",
122
+ TableRow = "TableRow",
123
+ Tabs = "Tabs",
124
+ Tag = "Tag",
125
+ Text = "Text",
126
+ TextArea = "TextArea",
127
+ Tile = "Tile",
128
+ TimeInput = "TimeInput",
129
+ Toggle = "Toggle",
130
+ ToggleGroup = "ToggleGroup",
131
+ Tooltip = "Tooltip"
39
132
  }
package/dist/types.js CHANGED
@@ -6,4 +6,97 @@
6
6
  export var ComponentName;
7
7
  (function (ComponentName) {
8
8
  ComponentName["Accordion"] = "Accordion";
9
+ ComponentName["Alert"] = "Alert";
10
+ ComponentName["AutoGrid"] = "AutoGrid";
11
+ ComponentName["BarChart"] = "BarChart";
12
+ ComponentName["Box"] = "Box";
13
+ ComponentName["Button"] = "Button";
14
+ ComponentName["ButtonRow"] = "ButtonRow";
15
+ ComponentName["Card"] = "Card";
16
+ ComponentName["Center"] = "Center";
17
+ ComponentName["Checkbox"] = "Checkbox";
18
+ ComponentName["CrmActionButton"] = "CrmActionButton";
19
+ ComponentName["CrmActionLink"] = "CrmActionLink";
20
+ ComponentName["CrmAssociationPivot"] = "CrmAssociationPivot";
21
+ ComponentName["CrmAssociationPropertyList"] = "CrmAssociationPropertyList";
22
+ ComponentName["CrmAssociationStageTracker"] = "CrmAssociationStageTracker";
23
+ ComponentName["CrmAssociationTable"] = "CrmAssociationTable";
24
+ ComponentName["CrmCardActions"] = "CrmCardActions";
25
+ ComponentName["CrmDataHighlight"] = "CrmDataHighlight";
26
+ ComponentName["CrmPropertyList"] = "CrmPropertyList";
27
+ ComponentName["CrmReport"] = "CrmReport";
28
+ ComponentName["CrmSimpleDeadline"] = "CrmSimpleDeadline";
29
+ ComponentName["CrmStageTracker"] = "CrmStageTracker";
30
+ ComponentName["CrmStatistics"] = "CrmStatistics";
31
+ ComponentName["CurrencyInput"] = "CurrencyInput";
32
+ ComponentName["DateInput"] = "DateInput";
33
+ ComponentName["DescriptionList"] = "DescriptionList";
34
+ ComponentName["DescriptionListItem"] = "DescriptionListItem";
35
+ ComponentName["Divider"] = "Divider";
36
+ ComponentName["Dropdown"] = "Dropdown";
37
+ ComponentName["DropdownButtonItem"] = "DropdownButtonItem";
38
+ ComponentName["EmptyState"] = "EmptyState";
39
+ ComponentName["ErrorState"] = "ErrorState";
40
+ ComponentName["ExpandableText"] = "ExpandableText";
41
+ ComponentName["FileInput"] = "FileInput";
42
+ ComponentName["Flex"] = "Flex";
43
+ ComponentName["Form"] = "Form";
44
+ ComponentName["Grid"] = "Grid";
45
+ ComponentName["GridItem"] = "GridItem";
46
+ ComponentName["HeaderActions"] = "HeaderActions";
47
+ ComponentName["Heading"] = "Heading";
48
+ ComponentName["Icon"] = "Icon";
49
+ ComponentName["Iframe"] = "Iframe";
50
+ ComponentName["Illustration"] = "Illustration";
51
+ ComponentName["Image"] = "Image";
52
+ ComponentName["Inline"] = "Inline";
53
+ ComponentName["Input"] = "Input";
54
+ ComponentName["LineChart"] = "LineChart";
55
+ ComponentName["Link"] = "Link";
56
+ ComponentName["List"] = "List";
57
+ ComponentName["LoadingButton"] = "LoadingButton";
58
+ ComponentName["LoadingSpinner"] = "LoadingSpinner";
59
+ ComponentName["MediaObject"] = "MediaObject";
60
+ ComponentName["Modal"] = "Modal";
61
+ ComponentName["ModalBody"] = "ModalBody";
62
+ ComponentName["ModalFooter"] = "ModalFooter";
63
+ ComponentName["MultiSelect"] = "MultiSelect";
64
+ ComponentName["NumberInput"] = "NumberInput";
65
+ ComponentName["Panel"] = "Panel";
66
+ ComponentName["PanelBody"] = "PanelBody";
67
+ ComponentName["PanelFooter"] = "PanelFooter";
68
+ ComponentName["PanelSection"] = "PanelSection";
69
+ ComponentName["Popover"] = "Popover";
70
+ ComponentName["PrimaryHeaderActionButton"] = "PrimaryHeaderActionButton";
71
+ ComponentName["ProgressBar"] = "ProgressBar";
72
+ ComponentName["RadioButton"] = "RadioButton";
73
+ ComponentName["ScoreCircle"] = "ScoreCircle";
74
+ ComponentName["SearchInput"] = "SearchInput";
75
+ ComponentName["SecondaryHeaderActionButton"] = "SecondaryHeaderActionButton";
76
+ ComponentName["Select"] = "Select";
77
+ ComponentName["SettingsView"] = "SettingsView";
78
+ ComponentName["Stack2"] = "Stack2";
79
+ ComponentName["Statistics"] = "Statistics";
80
+ ComponentName["StatisticsItem"] = "StatisticsItem";
81
+ ComponentName["StatisticsTrend"] = "StatisticsTrend";
82
+ ComponentName["StatusTag"] = "StatusTag";
83
+ ComponentName["StepIndicator"] = "StepIndicator";
84
+ ComponentName["StepperInput"] = "StepperInput";
85
+ ComponentName["Tab"] = "Tab";
86
+ ComponentName["Table"] = "Table";
87
+ ComponentName["TableBody"] = "TableBody";
88
+ ComponentName["TableCell"] = "TableCell";
89
+ ComponentName["TableFooter"] = "TableFooter";
90
+ ComponentName["TableHead"] = "TableHead";
91
+ ComponentName["TableHeader"] = "TableHeader";
92
+ ComponentName["TableRow"] = "TableRow";
93
+ ComponentName["Tabs"] = "Tabs";
94
+ ComponentName["Tag"] = "Tag";
95
+ ComponentName["Text"] = "Text";
96
+ ComponentName["TextArea"] = "TextArea";
97
+ ComponentName["Tile"] = "Tile";
98
+ ComponentName["TimeInput"] = "TimeInput";
99
+ ComponentName["Toggle"] = "Toggle";
100
+ ComponentName["ToggleGroup"] = "ToggleGroup";
101
+ ComponentName["Tooltip"] = "Tooltip";
9
102
  })(ComponentName || (ComponentName = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions-sdk-api-metadata",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "UI Extensions SDK API Metadata",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -25,17 +25,18 @@
25
25
  },
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "@hubspot/ts-export-types-reader": "0.1.2",
28
+ "@hubspot/ts-export-types-reader": "1.1.0",
29
+ "dom-serializer": "^2.0.0",
30
+ "htmlparser2": "^9.1.0",
29
31
  "marked": "17.0.1"
30
32
  },
31
33
  "devDependencies": {
32
- "@hubspot/ts-export-types": "0.1.2",
34
+ "@hubspot/ts-export-types": "1.1.0",
33
35
  "@vitest/coverage-v8": "2.1.8",
34
36
  "typescript": "5.9.3",
35
37
  "vitest": "2.1.9"
36
38
  },
37
39
  "engines": {
38
40
  "node": ">=16"
39
- },
40
- "gitHead": "c5b66da065a341df3afd98ce6641bb3e6317aeb4"
41
+ }
41
42
  }
@@ -1,7 +0,0 @@
1
- /**
2
- * Wraps code as text in HTML code tags for HTML rendering. Special HTML characters are escaped.
3
- *
4
- * @param value - The code as text to wrap in HTML code tags
5
- * @returns The code as text wrapped in HTML code tags
6
- */
7
- export declare const wrapCodeInHtmlCodeTags: (value: string) => string;
@@ -1,18 +0,0 @@
1
- const sanitizeHtmlText = (htmlText) => {
2
- return (htmlText
3
- .replaceAll('&', '&amp;')
4
- .replaceAll('<', '&lt;')
5
- .replaceAll('>', '&gt;')
6
- .replaceAll('"', '&quot;')
7
- // Use double quotes for consistency with other entity references
8
- .replaceAll("'", '&#x27;'));
9
- };
10
- /**
11
- * Wraps code as text in HTML code tags for HTML rendering. Special HTML characters are escaped.
12
- *
13
- * @param value - The code as text to wrap in HTML code tags
14
- * @returns The code as text wrapped in HTML code tags
15
- */
16
- export const wrapCodeInHtmlCodeTags = (value) => {
17
- return `<code>${sanitizeHtmlText(value)}</code>`;
18
- };