@multiplatform.one/markdown 7.4.1 → 7.6.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 (285) hide show
  1. package/dist/cjs/Aside/index.cjs +6 -4
  2. package/dist/cjs/Aside/index.native.js +6 -4
  3. package/dist/cjs/Aside/index.native.js.map +1 -1
  4. package/dist/cjs/Hr/index.cjs +2 -3
  5. package/dist/cjs/Hr/index.native.js +2 -3
  6. package/dist/cjs/Hr/index.native.js.map +1 -1
  7. package/dist/cjs/MarkdownSimpleTable/index.cjs +15 -15
  8. package/dist/cjs/MarkdownSimpleTable/index.native.js +17 -18
  9. package/dist/cjs/MarkdownSimpleTable/index.native.js.map +1 -1
  10. package/dist/cjs/MdxCodeBlock/index.cjs +9 -5
  11. package/dist/cjs/MdxCodeBlock/index.native.js +9 -5
  12. package/dist/cjs/MdxCodeBlock/index.native.js.map +1 -1
  13. package/dist/cjs/Table/index.cjs +20 -8
  14. package/dist/cjs/Table/index.native.js +20 -8
  15. package/dist/cjs/Table/index.native.js.map +1 -1
  16. package/dist/cjs/Video/index.cjs +11 -7
  17. package/dist/cjs/Video/index.native.js +12 -7
  18. package/dist/cjs/Video/index.native.js.map +1 -1
  19. package/dist/cjs/components/Blockquote.cjs +5 -4
  20. package/dist/cjs/components/Blockquote.native.js +7 -6
  21. package/dist/cjs/components/Blockquote.native.js.map +1 -1
  22. package/dist/cjs/components/CodeBlock.cjs +2 -2
  23. package/dist/cjs/components/CodeBlock.native.js +3 -3
  24. package/dist/cjs/components/CodeBlock.native.js.map +1 -1
  25. package/dist/cjs/components/Heading.cjs +1 -0
  26. package/dist/cjs/components/Heading.native.js +1 -0
  27. package/dist/cjs/components/Heading.native.js.map +1 -1
  28. package/dist/cjs/components/HorizontalRule.cjs +12 -1
  29. package/dist/cjs/components/HorizontalRule.native.js +12 -1
  30. package/dist/cjs/components/HorizontalRule.native.js.map +1 -1
  31. package/dist/cjs/components/Image.cjs +2 -2
  32. package/dist/cjs/components/Image.native.js +3 -2
  33. package/dist/cjs/components/Image.native.js.map +1 -1
  34. package/dist/cjs/components/InlineCode.cjs +2 -1
  35. package/dist/cjs/components/InlineCode.native.js +2 -1
  36. package/dist/cjs/components/InlineCode.native.js.map +1 -1
  37. package/dist/cjs/components/InlineStyles.cjs +14 -1
  38. package/dist/cjs/components/InlineStyles.native.js +14 -1
  39. package/dist/cjs/components/InlineStyles.native.js.map +1 -1
  40. package/dist/cjs/components/Link.cjs +5 -0
  41. package/dist/cjs/components/Link.native.js +5 -0
  42. package/dist/cjs/components/Link.native.js.map +1 -1
  43. package/dist/cjs/components/List.cjs +8 -1
  44. package/dist/cjs/components/List.native.js +11 -3
  45. package/dist/cjs/components/List.native.js.map +1 -1
  46. package/dist/cjs/components/Table.cjs +15 -9
  47. package/dist/cjs/components/Table.native.js +17 -12
  48. package/dist/cjs/components/Table.native.js.map +1 -1
  49. package/dist/cjs/mdxComponents.cjs +175 -108
  50. package/dist/cjs/mdxComponents.native.js +184 -113
  51. package/dist/cjs/mdxComponents.native.js.map +1 -1
  52. package/dist/cjs/mermaid/MermaidBlock.cjs +1 -1
  53. package/dist/cjs/mermaid/renderMermaidDiagram.native.js +11 -81
  54. package/dist/cjs/mermaid/renderMermaidDiagram.native.js.map +1 -1
  55. package/dist/cjs/shared/index.cjs +13 -1
  56. package/dist/cjs/shared/index.native.js +12 -0
  57. package/dist/cjs/shared/index.native.js.map +1 -1
  58. package/dist/cjs/shared/tokenPx.cjs +41 -0
  59. package/dist/cjs/shared/tokenPx.native.js +46 -0
  60. package/dist/cjs/shared/tokenPx.native.js.map +1 -0
  61. package/dist/cjs/shared/useMarkdownTableKnobs.cjs +61 -0
  62. package/dist/cjs/shared/useMarkdownTableKnobs.native.js +64 -0
  63. package/dist/cjs/shared/useMarkdownTableKnobs.native.js.map +1 -0
  64. package/dist/esm/Aside/index.mjs +6 -4
  65. package/dist/esm/Aside/index.mjs.map +1 -1
  66. package/dist/esm/Aside/index.native.js +6 -4
  67. package/dist/esm/Aside/index.native.js.map +1 -1
  68. package/dist/esm/Hr/index.mjs +2 -3
  69. package/dist/esm/Hr/index.mjs.map +1 -1
  70. package/dist/esm/Hr/index.native.js +2 -3
  71. package/dist/esm/Hr/index.native.js.map +1 -1
  72. package/dist/esm/MarkdownSimpleTable/index.mjs +15 -15
  73. package/dist/esm/MarkdownSimpleTable/index.mjs.map +1 -1
  74. package/dist/esm/MarkdownSimpleTable/index.native.js +17 -18
  75. package/dist/esm/MarkdownSimpleTable/index.native.js.map +1 -1
  76. package/dist/esm/MdxCodeBlock/index.mjs +9 -5
  77. package/dist/esm/MdxCodeBlock/index.mjs.map +1 -1
  78. package/dist/esm/MdxCodeBlock/index.native.js +9 -5
  79. package/dist/esm/MdxCodeBlock/index.native.js.map +1 -1
  80. package/dist/esm/Table/index.mjs +20 -8
  81. package/dist/esm/Table/index.mjs.map +1 -1
  82. package/dist/esm/Table/index.native.js +20 -8
  83. package/dist/esm/Table/index.native.js.map +1 -1
  84. package/dist/esm/Video/index.mjs +11 -7
  85. package/dist/esm/Video/index.mjs.map +1 -1
  86. package/dist/esm/Video/index.native.js +12 -7
  87. package/dist/esm/Video/index.native.js.map +1 -1
  88. package/dist/esm/components/Blockquote.mjs +5 -4
  89. package/dist/esm/components/Blockquote.mjs.map +1 -1
  90. package/dist/esm/components/Blockquote.native.js +7 -6
  91. package/dist/esm/components/Blockquote.native.js.map +1 -1
  92. package/dist/esm/components/CodeBlock.mjs +2 -2
  93. package/dist/esm/components/CodeBlock.mjs.map +1 -1
  94. package/dist/esm/components/CodeBlock.native.js +3 -3
  95. package/dist/esm/components/CodeBlock.native.js.map +1 -1
  96. package/dist/esm/components/Heading.mjs +1 -0
  97. package/dist/esm/components/Heading.mjs.map +1 -1
  98. package/dist/esm/components/Heading.native.js +1 -0
  99. package/dist/esm/components/Heading.native.js.map +1 -1
  100. package/dist/esm/components/HorizontalRule.mjs +13 -2
  101. package/dist/esm/components/HorizontalRule.mjs.map +1 -1
  102. package/dist/esm/components/HorizontalRule.native.js +13 -2
  103. package/dist/esm/components/HorizontalRule.native.js.map +1 -1
  104. package/dist/esm/components/Image.mjs +2 -2
  105. package/dist/esm/components/Image.mjs.map +1 -1
  106. package/dist/esm/components/Image.native.js +3 -2
  107. package/dist/esm/components/Image.native.js.map +1 -1
  108. package/dist/esm/components/InlineCode.mjs +2 -1
  109. package/dist/esm/components/InlineCode.mjs.map +1 -1
  110. package/dist/esm/components/InlineCode.native.js +2 -1
  111. package/dist/esm/components/InlineCode.native.js.map +1 -1
  112. package/dist/esm/components/InlineStyles.mjs +14 -1
  113. package/dist/esm/components/InlineStyles.mjs.map +1 -1
  114. package/dist/esm/components/InlineStyles.native.js +14 -1
  115. package/dist/esm/components/InlineStyles.native.js.map +1 -1
  116. package/dist/esm/components/Link.mjs +5 -0
  117. package/dist/esm/components/Link.mjs.map +1 -1
  118. package/dist/esm/components/Link.native.js +5 -0
  119. package/dist/esm/components/Link.native.js.map +1 -1
  120. package/dist/esm/components/List.mjs +8 -1
  121. package/dist/esm/components/List.mjs.map +1 -1
  122. package/dist/esm/components/List.native.js +11 -3
  123. package/dist/esm/components/List.native.js.map +1 -1
  124. package/dist/esm/components/Table.mjs +15 -9
  125. package/dist/esm/components/Table.mjs.map +1 -1
  126. package/dist/esm/components/Table.native.js +17 -12
  127. package/dist/esm/components/Table.native.js.map +1 -1
  128. package/dist/esm/mdxComponents.mjs +175 -108
  129. package/dist/esm/mdxComponents.mjs.map +1 -1
  130. package/dist/esm/mdxComponents.native.js +184 -113
  131. package/dist/esm/mdxComponents.native.js.map +1 -1
  132. package/dist/esm/mermaid/MermaidBlock.mjs +1 -1
  133. package/dist/esm/mermaid/MermaidBlock.mjs.map +1 -1
  134. package/dist/esm/mermaid/renderMermaidDiagram.native.js +9 -68
  135. package/dist/esm/mermaid/renderMermaidDiagram.native.js.map +1 -1
  136. package/dist/esm/shared/index.mjs +3 -0
  137. package/dist/esm/shared/index.mjs.map +1 -1
  138. package/dist/esm/shared/index.native.js +3 -0
  139. package/dist/esm/shared/index.native.js.map +1 -1
  140. package/dist/esm/shared/tokenPx.mjs +16 -0
  141. package/dist/esm/shared/tokenPx.mjs.map +1 -0
  142. package/dist/esm/shared/tokenPx.native.js +18 -0
  143. package/dist/esm/shared/tokenPx.native.js.map +1 -0
  144. package/dist/esm/shared/useMarkdownTableKnobs.mjs +36 -0
  145. package/dist/esm/shared/useMarkdownTableKnobs.mjs.map +1 -0
  146. package/dist/esm/shared/useMarkdownTableKnobs.native.js +36 -0
  147. package/dist/esm/shared/useMarkdownTableKnobs.native.js.map +1 -0
  148. package/dist/jsx/Aside/index.mjs +6 -4
  149. package/dist/jsx/Aside/index.mjs.map +1 -1
  150. package/dist/jsx/Aside/index.native.js +6 -4
  151. package/dist/jsx/Aside/index.native.js.map +1 -1
  152. package/dist/jsx/Hr/index.mjs +2 -3
  153. package/dist/jsx/Hr/index.mjs.map +1 -1
  154. package/dist/jsx/Hr/index.native.js +2 -3
  155. package/dist/jsx/Hr/index.native.js.map +1 -1
  156. package/dist/jsx/MarkdownSimpleTable/index.mjs +15 -15
  157. package/dist/jsx/MarkdownSimpleTable/index.mjs.map +1 -1
  158. package/dist/jsx/MarkdownSimpleTable/index.native.js +17 -18
  159. package/dist/jsx/MarkdownSimpleTable/index.native.js.map +1 -1
  160. package/dist/jsx/MdxCodeBlock/index.mjs +9 -5
  161. package/dist/jsx/MdxCodeBlock/index.mjs.map +1 -1
  162. package/dist/jsx/MdxCodeBlock/index.native.js +9 -5
  163. package/dist/jsx/MdxCodeBlock/index.native.js.map +1 -1
  164. package/dist/jsx/Table/index.mjs +20 -8
  165. package/dist/jsx/Table/index.mjs.map +1 -1
  166. package/dist/jsx/Table/index.native.js +20 -8
  167. package/dist/jsx/Table/index.native.js.map +1 -1
  168. package/dist/jsx/Video/index.mjs +11 -7
  169. package/dist/jsx/Video/index.mjs.map +1 -1
  170. package/dist/jsx/Video/index.native.js +12 -7
  171. package/dist/jsx/Video/index.native.js.map +1 -1
  172. package/dist/jsx/components/Blockquote.mjs +5 -4
  173. package/dist/jsx/components/Blockquote.mjs.map +1 -1
  174. package/dist/jsx/components/Blockquote.native.js +7 -6
  175. package/dist/jsx/components/Blockquote.native.js.map +1 -1
  176. package/dist/jsx/components/CodeBlock.mjs +2 -2
  177. package/dist/jsx/components/CodeBlock.mjs.map +1 -1
  178. package/dist/jsx/components/CodeBlock.native.js +3 -3
  179. package/dist/jsx/components/CodeBlock.native.js.map +1 -1
  180. package/dist/jsx/components/Heading.mjs +1 -0
  181. package/dist/jsx/components/Heading.mjs.map +1 -1
  182. package/dist/jsx/components/Heading.native.js +1 -0
  183. package/dist/jsx/components/Heading.native.js.map +1 -1
  184. package/dist/jsx/components/HorizontalRule.mjs +13 -2
  185. package/dist/jsx/components/HorizontalRule.mjs.map +1 -1
  186. package/dist/jsx/components/HorizontalRule.native.js +12 -1
  187. package/dist/jsx/components/HorizontalRule.native.js.map +1 -1
  188. package/dist/jsx/components/Image.mjs +2 -2
  189. package/dist/jsx/components/Image.mjs.map +1 -1
  190. package/dist/jsx/components/Image.native.js +3 -2
  191. package/dist/jsx/components/Image.native.js.map +1 -1
  192. package/dist/jsx/components/InlineCode.mjs +2 -1
  193. package/dist/jsx/components/InlineCode.mjs.map +1 -1
  194. package/dist/jsx/components/InlineCode.native.js +2 -1
  195. package/dist/jsx/components/InlineCode.native.js.map +1 -1
  196. package/dist/jsx/components/InlineStyles.mjs +14 -1
  197. package/dist/jsx/components/InlineStyles.mjs.map +1 -1
  198. package/dist/jsx/components/InlineStyles.native.js +14 -1
  199. package/dist/jsx/components/InlineStyles.native.js.map +1 -1
  200. package/dist/jsx/components/Link.mjs +5 -0
  201. package/dist/jsx/components/Link.mjs.map +1 -1
  202. package/dist/jsx/components/Link.native.js +5 -0
  203. package/dist/jsx/components/Link.native.js.map +1 -1
  204. package/dist/jsx/components/List.mjs +8 -1
  205. package/dist/jsx/components/List.mjs.map +1 -1
  206. package/dist/jsx/components/List.native.js +11 -3
  207. package/dist/jsx/components/List.native.js.map +1 -1
  208. package/dist/jsx/components/Table.mjs +15 -9
  209. package/dist/jsx/components/Table.mjs.map +1 -1
  210. package/dist/jsx/components/Table.native.js +17 -12
  211. package/dist/jsx/components/Table.native.js.map +1 -1
  212. package/dist/jsx/mdxComponents.mjs +175 -108
  213. package/dist/jsx/mdxComponents.mjs.map +1 -1
  214. package/dist/jsx/mdxComponents.native.js +184 -113
  215. package/dist/jsx/mdxComponents.native.js.map +1 -1
  216. package/dist/jsx/mermaid/MermaidBlock.mjs +1 -1
  217. package/dist/jsx/mermaid/MermaidBlock.mjs.map +1 -1
  218. package/dist/jsx/mermaid/renderMermaidDiagram.native.js +11 -81
  219. package/dist/jsx/mermaid/renderMermaidDiagram.native.js.map +1 -1
  220. package/dist/jsx/shared/index.mjs +3 -0
  221. package/dist/jsx/shared/index.mjs.map +1 -1
  222. package/dist/jsx/shared/index.native.js +12 -0
  223. package/dist/jsx/shared/index.native.js.map +1 -1
  224. package/dist/jsx/shared/tokenPx.mjs +16 -0
  225. package/dist/jsx/shared/tokenPx.mjs.map +1 -0
  226. package/dist/jsx/shared/tokenPx.native.js +46 -0
  227. package/dist/jsx/shared/tokenPx.native.js.map +1 -0
  228. package/dist/jsx/shared/useMarkdownTableKnobs.mjs +36 -0
  229. package/dist/jsx/shared/useMarkdownTableKnobs.mjs.map +1 -0
  230. package/dist/jsx/shared/useMarkdownTableKnobs.native.js +64 -0
  231. package/dist/jsx/shared/useMarkdownTableKnobs.native.js.map +1 -0
  232. package/package.json +14 -9
  233. package/src/Aside/index.tsx +6 -4
  234. package/src/Hr/hr.spec.tsx +11 -10
  235. package/src/Hr/index.tsx +2 -2
  236. package/src/MarkdownSimpleTable/index.tsx +10 -24
  237. package/src/MdxCodeBlock/index.tsx +10 -4
  238. package/src/Table/index.tsx +11 -11
  239. package/src/Video/index.tsx +15 -5
  240. package/src/components/Blockquote.tsx +6 -5
  241. package/src/components/CodeBlock.tsx +2 -2
  242. package/src/components/Heading.tsx +7 -1
  243. package/src/components/HorizontalRule.tsx +19 -2
  244. package/src/components/Image.tsx +3 -2
  245. package/src/components/InlineCode.tsx +2 -1
  246. package/src/components/InlineStyles.tsx +7 -3
  247. package/src/components/Link.tsx +3 -0
  248. package/src/components/List.tsx +10 -3
  249. package/src/components/Table.tsx +13 -10
  250. package/src/designLaw.spec.tsx +130 -0
  251. package/src/mdxComponents.tsx +168 -87
  252. package/src/mermaid/MermaidBlock.tsx +1 -1
  253. package/src/mermaid/nativeGraph.spec.ts +90 -0
  254. package/src/mermaid/renderMermaidDiagram.native.ts +50 -0
  255. package/src/mermaid/renderMermaidDiagram.spec.ts +23 -0
  256. package/src/shared/index.ts +2 -0
  257. package/src/shared/tokenPx.ts +29 -0
  258. package/src/shared/useMarkdownTableKnobs.ts +38 -0
  259. package/src/stories/Blocks.stories.tsx +5 -5
  260. package/types/Aside/index.d.ts.map +1 -1
  261. package/types/Hr/index.d.ts +1 -1
  262. package/types/Hr/index.d.ts.map +1 -1
  263. package/types/MarkdownSimpleTable/index.d.ts.map +1 -1
  264. package/types/MdxCodeBlock/index.d.ts.map +1 -1
  265. package/types/Table/index.d.ts.map +1 -1
  266. package/types/Video/index.d.ts.map +1 -1
  267. package/types/components/Blockquote.d.ts.map +1 -1
  268. package/types/components/Heading.d.ts.map +1 -1
  269. package/types/components/HorizontalRule.d.ts +5 -1
  270. package/types/components/HorizontalRule.d.ts.map +1 -1
  271. package/types/components/Image.d.ts.map +1 -1
  272. package/types/components/InlineCode.d.ts.map +1 -1
  273. package/types/components/InlineStyles.d.ts.map +1 -1
  274. package/types/components/Link.d.ts.map +1 -1
  275. package/types/components/List.d.ts.map +1 -1
  276. package/types/components/Table.d.ts.map +1 -1
  277. package/types/mdxComponents.d.ts.map +1 -1
  278. package/types/mermaid/renderMermaidDiagram.native.d.ts +45 -0
  279. package/types/mermaid/renderMermaidDiagram.native.d.ts.map +1 -0
  280. package/types/shared/index.d.ts +2 -0
  281. package/types/shared/index.d.ts.map +1 -1
  282. package/types/shared/tokenPx.d.ts +7 -0
  283. package/types/shared/tokenPx.d.ts.map +1 -0
  284. package/types/shared/useMarkdownTableKnobs.d.ts +39 -0
  285. package/types/shared/useMarkdownTableKnobs.d.ts.map +1 -0
@@ -26,7 +26,13 @@ export function Heading({ level, children }: HeadingProps) {
26
26
  const headingFamily = isWeb ? null : { fontFamily: knobProps.heading.fontFamily };
27
27
  const size = `$${headingBaseSize[level] + (sizeShift[knobProps.sizeToken] ?? 0)}`;
28
28
  return (
29
- <Component marginTop="$3" marginBottom="$2" size={size as any} {...headingFamily}>
29
+ <Component
30
+ marginTop="$3"
31
+ marginBottom="$2"
32
+ size={size as any}
33
+ {...knobProps.heading}
34
+ {...headingFamily}
35
+ >
30
36
  {children}
31
37
  </Component>
32
38
  );
@@ -1,6 +1,23 @@
1
- import { Separator } from "tamagui";
1
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
2
+ import { View } from "tamagui";
2
3
  import type { HorizontalRuleProps } from "../types";
3
4
 
5
+ /**
6
+ * Semantic divider. House paint is a filled 1px rule (R9 G10 — weight is
7
+ * not a knob). `borderWidth=none` hides the rule without leaving a 1px gap.
8
+ */
4
9
  export function HorizontalRule(_props: HorizontalRuleProps) {
5
- return <Separator marginVertical="$4" />;
10
+ const { knobProps } = useResolvedKnobs();
11
+ if (knobProps.borderRadius.borderWidth === 0) return null;
12
+ return (
13
+ <View
14
+ role="separator"
15
+ height={1}
16
+ backgroundColor="$borderColor"
17
+ alignSelf="stretch"
18
+ flexGrow={0}
19
+ flexShrink={0}
20
+ marginVertical="$4"
21
+ />
22
+ );
6
23
  }
@@ -14,9 +14,10 @@ export function MarkdownImage({ src, alt, title }: ImageProps) {
14
14
  alt={alt || ""}
15
15
  aria-label={alt || title || undefined}
16
16
  width="100%"
17
- height={200}
17
+ aspectRatio={16 / 9}
18
18
  objectFit="contain"
19
- borderRadius={knobProps.borderRadius.borderRadius}
19
+ // R11: media tiles stay UNCLAMPED — radius rides the scale, no pad cap.
20
+ {...knobProps.borderRadius}
20
21
  />
21
22
  </View>
22
23
  );
@@ -20,7 +20,8 @@ export function InlineCode({ children }: InlineCodeProps) {
20
20
  lineHeight={knobProps.sizeToken}
21
21
  paddingHorizontal="$1.5"
22
22
  paddingVertical="$0.5"
23
- borderRadius={knobProps.borderRadius.borderRadius}
23
+ {...knobProps.body}
24
+ {...knobProps.borderRadius}
24
25
  >
25
26
  {children}
26
27
  </CodeInline>
@@ -1,25 +1,29 @@
1
1
  import { Text } from "tamagui";
2
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
2
3
  import type { InlineProps } from "../types";
3
4
 
4
5
  export function Strong({ children }: InlineProps) {
6
+ const { knobProps } = useResolvedKnobs();
5
7
  return (
6
- <Text render="strong" fontWeight="bold">
8
+ <Text render="strong" {...knobProps.body} fontWeight="700">
7
9
  {children}
8
10
  </Text>
9
11
  );
10
12
  }
11
13
 
12
14
  export function Emphasis({ children }: InlineProps) {
15
+ const { knobProps } = useResolvedKnobs();
13
16
  return (
14
- <Text render="em" fontStyle="italic">
17
+ <Text render="em" {...knobProps.body} fontStyle="italic">
15
18
  {children}
16
19
  </Text>
17
20
  );
18
21
  }
19
22
 
20
23
  export function Strikethrough({ children }: InlineProps) {
24
+ const { knobProps } = useResolvedKnobs();
21
25
  return (
22
- <Text render="del" textDecorationLine="line-through">
26
+ <Text render="del" {...knobProps.body} textDecorationLine="line-through">
23
27
  {children}
24
28
  </Text>
25
29
  );
@@ -1,5 +1,6 @@
1
1
  import { Text, isWeb } from "tamagui";
2
2
  import { openUrl } from "@multiplatform.one/platform";
3
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
3
4
  import { markdownLinkColors } from "../shared/colorRamps";
4
5
  import type { LinkProps } from "../types";
5
6
 
@@ -15,6 +16,7 @@ function getSafeHref(href?: string): string | undefined {
15
16
  }
16
17
 
17
18
  export function Link({ href, title, children }: LinkProps) {
19
+ const { knobProps } = useResolvedKnobs();
18
20
  const safeHref = getSafeHref(href);
19
21
  const isExternal = !!safeHref && /^https?:\/\//i.test(safeHref);
20
22
 
@@ -31,6 +33,7 @@ export function Link({ href, title, children }: LinkProps) {
31
33
  target={isExternal ? "_blank" : undefined}
32
34
  rel={isExternal ? "noopener noreferrer" : undefined}
33
35
  title={title || undefined}
36
+ {...knobProps.body}
34
37
  color={markdownLinkColors.text.base}
35
38
  textDecorationLine="underline"
36
39
  cursor="pointer"
@@ -49,7 +49,7 @@ function getTaskBoxMetrics() {
49
49
  const bodyFont = getConfig()?.fontsParsed?.$body;
50
50
  const fontSize = Math.round(getVariableValue(bodyFont?.size?.$true) || 14);
51
51
  const lineHeight = Math.round(getVariableValue(bodyFont?.lineHeight?.$6) || fontSize * 2);
52
- return { boxSize: Math.round(fontSize * 1.15), lineHeight };
52
+ return { fontSize, boxSize: Math.round(fontSize * 1.15), lineHeight };
53
53
  }
54
54
 
55
55
  /** Box↔label gap by space knob — mirrors the forms Checkbox inline gap. */
@@ -130,9 +130,16 @@ export function MarkdownListItem({
130
130
  );
131
131
  }
132
132
 
133
+ const { fontSize } = getTaskBoxMetrics();
134
+ const markerWidth = Math.round(fontSize * 1.7);
133
135
  return (
134
- <XStack render="li" marginBottom="$1" alignItems="flex-start">
135
- <Text width={24} color="$color11" aria-hidden>
136
+ <XStack
137
+ render="li"
138
+ marginBottom="$1"
139
+ alignItems="flex-start"
140
+ gap={taskInlineGapMap[knobProps.space] ?? "$2"}
141
+ >
142
+ <Text width={markerWidth} color="$color11" aria-hidden {...knobProps.body}>
136
143
  {bullet}
137
144
  </Text>
138
145
  <View flex={1}>{children}</View>
@@ -8,9 +8,9 @@
8
8
  */
9
9
 
10
10
  import { Children, isValidElement } from "react";
11
- import { useResolvedKnobs } from "@multiplatform.one/theme";
12
11
  import { Paragraph, ScrollView, YStack } from "tamagui";
13
12
  import { Table } from "@multiplatform.one/table-primitives";
13
+ import { useMarkdownTableKnobs } from "../shared/useMarkdownTableKnobs";
14
14
  import type { TableProps, TableRowProps, TableCellProps } from "../types";
15
15
 
16
16
  function isHeaderRow(row: unknown): boolean {
@@ -18,7 +18,7 @@ function isHeaderRow(row: unknown): boolean {
18
18
  }
19
19
 
20
20
  export function MarkdownTable({ children }: TableProps) {
21
- const { knobProps } = useResolvedKnobs();
21
+ const { frameProps, headRule } = useMarkdownTableKnobs();
22
22
  const rows = Children.toArray(children);
23
23
  const headerRows = rows.filter((row) => isHeaderRow(row));
24
24
  const bodyRows = rows.filter((row) => !isHeaderRow(row));
@@ -35,12 +35,15 @@ export function MarkdownTable({ children }: TableProps) {
35
35
  width="auto"
36
36
  cellWidth="auto"
37
37
  style={{ tableLayout: "auto" }}
38
- borderColor="$borderColor"
39
- borderRadius={knobProps.borderRadius.borderRadius}
40
38
  alignCells={{ x: "start", y: "center" }}
41
39
  alignHeaderCells={{ x: "start", y: "center" }}
40
+ {...frameProps}
42
41
  >
43
- {headerRows.length > 0 && <Table.Head render="thead">{headerRows}</Table.Head>}
42
+ {headerRows.length > 0 && (
43
+ <Table.Head render="thead" {...headRule}>
44
+ {headerRows}
45
+ </Table.Head>
46
+ )}
44
47
  <Table.Body render="tbody">{bodyRows}</Table.Body>
45
48
  </Table>
46
49
  </YStack>
@@ -54,12 +57,13 @@ export function MarkdownTableRow({ children }: TableRowProps) {
54
57
  }
55
58
 
56
59
  export function MarkdownTableCell({ children, isHeader, align }: TableCellProps) {
60
+ const { headerTextProps, cellTextProps, cellPad } = useMarkdownTableKnobs();
57
61
  const textAlign = align || "left";
58
62
 
59
63
  if (isHeader) {
60
64
  return (
61
- <Table.HeaderCell render="th">
62
- <Paragraph render="span" display="block" size="$4" fontWeight="600" textAlign={textAlign}>
65
+ <Table.HeaderCell render="th" {...cellPad}>
66
+ <Paragraph render="span" display="block" {...headerTextProps} textAlign={textAlign}>
63
67
  {children}
64
68
  </Paragraph>
65
69
  </Table.HeaderCell>
@@ -67,9 +71,8 @@ export function MarkdownTableCell({ children, isHeader, align }: TableCellProps)
67
71
  }
68
72
 
69
73
  return (
70
- <Table.Cell render="td">
71
- {/* maxWidth caps the column's max-content contribution so long cells wrap */}
72
- <Paragraph render="span" display="block" size="$4" textAlign={textAlign} maxWidth={480}>
74
+ <Table.Cell render="td" {...cellPad}>
75
+ <Paragraph render="span" display="block" {...cellTextProps} textAlign={textAlign}>
73
76
  {children}
74
77
  </Paragraph>
75
78
  </Table.Cell>
@@ -0,0 +1,130 @@
1
+ import { Preset } from "@multiplatform.one/theme";
2
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
3
+ import { describe, expect, it } from "vitest";
4
+ import { Heading } from "./components/Heading";
5
+ import { HorizontalRule } from "./components/HorizontalRule";
6
+ import { MarkdownList, MarkdownListItem } from "./components/List";
7
+ import { MarkdownImage } from "./components/Image";
8
+ import { MarkdownTable, MarkdownTableCell, MarkdownTableRow } from "./components/Table";
9
+ import { MarkdownSimpleTable } from "./MarkdownSimpleTable";
10
+ import {
11
+ MDXTable,
12
+ MDXTableBody,
13
+ MDXTableCell,
14
+ MDXTableHead,
15
+ MDXTableHeaderCell,
16
+ MDXTableRow,
17
+ } from "./Table";
18
+
19
+ function headerWeight(container: HTMLElement) {
20
+ const th = container.querySelector("th");
21
+ expect(th).toBeTruthy();
22
+ return window.getComputedStyle(th!.querySelector("span") ?? th!).fontWeight;
23
+ }
24
+
25
+ describe("markdown design-law (MPO-60)", () => {
26
+ it("Heading binds the heading recipe (T-HEADING)", () => {
27
+ const { container } = renderWithProviders(<Heading level={2}>Title</Heading>);
28
+ expect(container.textContent).toContain("Title");
29
+ expect(container.querySelector("h2")).toBeTruthy();
30
+ });
31
+
32
+ it("HorizontalRule paints a separator and hides at borderWidth=none", () => {
33
+ const shown = renderWithProviders(<HorizontalRule />);
34
+ expect(shown.container.querySelector('[role="separator"]')).toBeTruthy();
35
+
36
+ const hidden = renderWithProviders(
37
+ <Preset overrides={{ borderWidth: "none" }}>
38
+ <HorizontalRule />
39
+ </Preset>,
40
+ );
41
+ expect(hidden.container.querySelector('[role="separator"]')).toBeNull();
42
+ });
43
+
44
+ it("list marker column is not a fixed 24px", () => {
45
+ const { container } = renderWithProviders(
46
+ <MarkdownList ordered={false}>
47
+ <MarkdownListItem>alpha</MarkdownListItem>
48
+ </MarkdownList>,
49
+ );
50
+ const marker = container.querySelector('[aria-hidden="true"]') as HTMLElement | null;
51
+ expect(marker).toBeTruthy();
52
+ expect(marker!.style.width).not.toBe("24px");
53
+ expect(container.textContent).toContain("alpha");
54
+ });
55
+
56
+ it("image fallback is aspect-ratio, not a fixed 200px height", () => {
57
+ const { container } = renderWithProviders(
58
+ <MarkdownImage src="https://example.com/x.png" alt="demo" />,
59
+ );
60
+ const img = container.querySelector("img") as HTMLElement | null;
61
+ expect(img).toBeTruthy();
62
+ const style = img!.getAttribute("style") ?? "";
63
+ expect(style).not.toMatch(/height:\s*200px/);
64
+ });
65
+
66
+ it("MarkdownTable is R-OUTER: framed, square cells, header not weight 600", () => {
67
+ const { container } = renderWithProviders(
68
+ <MarkdownTable>
69
+ <MarkdownTableRow isHeader>
70
+ <MarkdownTableCell isHeader>Col</MarkdownTableCell>
71
+ </MarkdownTableRow>
72
+ <MarkdownTableRow>
73
+ <MarkdownTableCell>cell</MarkdownTableCell>
74
+ </MarkdownTableRow>
75
+ </MarkdownTable>,
76
+ );
77
+ const frame = container.querySelector("[data-markdown-table-frame='true']");
78
+ expect(frame).toBeTruthy();
79
+ expect(frame!.getAttribute("data-border-width")).not.toBe("undefined");
80
+ const th = container.querySelector("th") as HTMLElement;
81
+ const td = container.querySelector("td") as HTMLElement;
82
+ expect(th.style.borderRadius || window.getComputedStyle(th).borderRadius).not.toBe("50%");
83
+ expect(td).toBeTruthy();
84
+ const weight = headerWeight(container);
85
+ expect(weight === "600" || weight === "500").toBe(false);
86
+ });
87
+
88
+ it("MDXTable shares the same R-OUTER frame contract", () => {
89
+ const { container } = renderWithProviders(
90
+ <MDXTable>
91
+ <MDXTableHead>
92
+ <MDXTableRow>
93
+ <MDXTableHeaderCell>Col</MDXTableHeaderCell>
94
+ </MDXTableRow>
95
+ </MDXTableHead>
96
+ <MDXTableBody>
97
+ <MDXTableRow>
98
+ <MDXTableCell>cell</MDXTableCell>
99
+ </MDXTableRow>
100
+ </MDXTableBody>
101
+ </MDXTable>,
102
+ );
103
+ expect(container.querySelector("[data-markdown-table-frame='true']")).toBeTruthy();
104
+ expect(container.querySelector("thead th")!.textContent).toContain("Col");
105
+ const weight = headerWeight(container);
106
+ expect(weight === "600" || weight === "500").toBe(false);
107
+ });
108
+
109
+ it("MarkdownSimpleTable shares the same R-OUTER frame contract", () => {
110
+ const { container } = renderWithProviders(
111
+ <MarkdownSimpleTable headers={["Col"]} rows={[["cell"]]} />,
112
+ );
113
+ expect(container.querySelector("[data-markdown-table-frame='true']")).toBeTruthy();
114
+ expect(container.querySelector("thead th")!.textContent).toContain("Col");
115
+ expect(container.querySelector("tbody td")!.textContent).toContain("cell");
116
+ const weight = headerWeight(container);
117
+ expect(weight === "600" || weight === "500").toBe(false);
118
+ });
119
+
120
+ it("table frame borderWidth=none drops the painted rule", () => {
121
+ const { container } = renderWithProviders(
122
+ <Preset overrides={{ borderWidth: "none" }}>
123
+ <MarkdownSimpleTable headers={["Col"]} rows={[["cell"]]} />
124
+ </Preset>,
125
+ );
126
+ const frame = container.querySelector("[data-markdown-table-frame='true']");
127
+ expect(frame).toBeTruthy();
128
+ expect(frame!.getAttribute("data-border-width")).toBe("0");
129
+ });
130
+ });