instui-markdown 0.0.8 → 0.0.9
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.
- package/README.md +38 -5
- package/dist/index.mjs +85 -28
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -120,16 +120,49 @@ Wraps color literals in a visual swatch. Supports `#hex`, `rgb()`, `rgba()`, `hs
|
|
|
120
120
|
|
|
121
121
|
### `icons`
|
|
122
122
|
|
|
123
|
-
Renders
|
|
123
|
+
Renders icon tokens from `:iconName:` syntax. InstUI lookup runs first, then optional SimpleIcons lookup can run as a fallback through an app-provided resolver. You can omit the `Icon` prefix and the `Line`/`Solid` suffix for InstUI names, so `:Heart:`, `:HeartLine:`, and `:IconHeartLine:` all resolve to the same InstUI icon.
|
|
124
124
|
|
|
125
125
|
Add an optional hex color with a pipe: `:Heart|#F00:`.
|
|
126
126
|
|
|
127
127
|
Skips icon tokens inside code fences.
|
|
128
128
|
|
|
129
|
-
| Option
|
|
130
|
-
|
|
|
131
|
-
| `enabled`
|
|
132
|
-
| `color`
|
|
129
|
+
| Option | Type | Default | Description |
|
|
130
|
+
| ----------------------- | --------------------------------------- | ----------- | ------------------------------------------------------------------ |
|
|
131
|
+
| `enabled` | `boolean` | `false` | Enables token-based icon rendering |
|
|
132
|
+
| `color` | `string` | `undefined` | Default color for all icon providers |
|
|
133
|
+
| `providers.instui` | `boolean` | `true` | Enables InstUI lookup (`@instructure/ui-icons`) |
|
|
134
|
+
| `providers.simpleIcons` | `boolean` | `true` | Enables SimpleIcons fallback lookup |
|
|
135
|
+
| `simpleIcons.color` | `string` | `undefined` | Default color for SimpleIcons output (falls back to `icons.color`) |
|
|
136
|
+
| `simpleIcons.resolve` | `(code: string) => SimpleIconTokenData` | `undefined` | App-provided resolver for SimpleIcons SVG path data |
|
|
137
|
+
|
|
138
|
+
Example with SimpleIcons fallback:
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
<InstuiMarkdown
|
|
142
|
+
renderOptions={{
|
|
143
|
+
icons: {
|
|
144
|
+
enabled: true,
|
|
145
|
+
providers: { instui: true, simpleIcons: true },
|
|
146
|
+
simpleIcons: {
|
|
147
|
+
resolve: (code) => {
|
|
148
|
+
if (code.toLowerCase() === "github") {
|
|
149
|
+
return {
|
|
150
|
+
title: "GitHub",
|
|
151
|
+
path: "M12 0C5.37 0 0 5.37 0 12...",
|
|
152
|
+
viewBox: "0 0 24 24",
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return undefined;
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
{":GitHub: and :HeartLine:"}
|
|
162
|
+
</InstuiMarkdown>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If no enabled provider can resolve a token, the original token text is left in place.
|
|
133
166
|
|
|
134
167
|
## Peer dependencies
|
|
135
168
|
|
package/dist/index.mjs
CHANGED
|
@@ -442,41 +442,90 @@ function createBlockquoteComponent(options) {
|
|
|
442
442
|
}
|
|
443
443
|
//#endregion
|
|
444
444
|
//#region src/components/span-component.tsx
|
|
445
|
+
function toPascalCase(str) {
|
|
446
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
447
|
+
}
|
|
448
|
+
function parseIconTokenName(iconName) {
|
|
449
|
+
const withoutPrefix = iconName.startsWith("Icon") ? iconName.slice(4) : iconName;
|
|
450
|
+
const isSolid = withoutPrefix.endsWith("Solid");
|
|
451
|
+
const isInstUI = withoutPrefix.endsWith("InstUIIcon");
|
|
452
|
+
let root = withoutPrefix;
|
|
453
|
+
if (isSolid) root = withoutPrefix.slice(0, -5);
|
|
454
|
+
else if (isInstUI) root = withoutPrefix.slice(0, -10);
|
|
455
|
+
else if (withoutPrefix.endsWith("Line")) root = withoutPrefix.slice(0, -4);
|
|
456
|
+
return {
|
|
457
|
+
withoutPrefix,
|
|
458
|
+
isSolid,
|
|
459
|
+
isInstUI,
|
|
460
|
+
root
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function getSimpleIconCodes(iconName, root, withoutPrefix) {
|
|
464
|
+
const camel = root.charAt(0).toLowerCase() + root.slice(1);
|
|
465
|
+
const lower = root.toLowerCase();
|
|
466
|
+
return Array.from(new Set([
|
|
467
|
+
iconName,
|
|
468
|
+
withoutPrefix,
|
|
469
|
+
root,
|
|
470
|
+
camel,
|
|
471
|
+
lower
|
|
472
|
+
]));
|
|
473
|
+
}
|
|
445
474
|
function createSpanComponent(options) {
|
|
446
475
|
return ({ children, className, ...props }) => {
|
|
447
476
|
if (className?.includes("icon-token") && options.showIcons) {
|
|
448
477
|
const iconName = props["data-icon"];
|
|
449
478
|
const inlineIconColor = props["data-icon-color"];
|
|
450
479
|
if (iconName) {
|
|
451
|
-
const withoutPrefix
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
480
|
+
const { withoutPrefix, isSolid, isInstUI, root } = parseIconTokenName(iconName);
|
|
481
|
+
if (options.enableInstuiIcons) {
|
|
482
|
+
const normalizedRoot = toPascalCase(root);
|
|
483
|
+
const IconComponent = (isSolid ? [`Icon${normalizedRoot}Solid`] : isInstUI ? [`${normalizedRoot}InstUIIcon`] : [
|
|
484
|
+
`${normalizedRoot}InstUIIcon`,
|
|
485
|
+
`Icon${normalizedRoot}Line`,
|
|
486
|
+
`Icon${normalizedRoot}`
|
|
487
|
+
]).map((name) => InstUIIcons[name]).find(Boolean);
|
|
488
|
+
if (IconComponent) {
|
|
489
|
+
const resolvedColor = inlineIconColor ?? options.iconColor;
|
|
490
|
+
const normalizedIconColor = resolvedColor && isLiteralColorValue(resolvedColor) ? normalizeColorForSwatch(resolvedColor) : void 0;
|
|
491
|
+
const sizeProps = IconComponent.displayName?.startsWith("InstUIIcon_") ? { size: "x-small" } : {};
|
|
492
|
+
if (normalizedIconColor) return /* @__PURE__ */ jsx("span", {
|
|
493
|
+
style: { color: normalizedIconColor },
|
|
494
|
+
children: /* @__PURE__ */ jsx(IconComponent, {
|
|
495
|
+
title: iconName,
|
|
496
|
+
color: "inherit",
|
|
497
|
+
...sizeProps
|
|
498
|
+
})
|
|
499
|
+
});
|
|
500
|
+
return /* @__PURE__ */ jsx(IconComponent, {
|
|
470
501
|
title: iconName,
|
|
471
|
-
color: "inherit",
|
|
502
|
+
color: (resolvedColor === "currentColor" ? "inherit" : resolvedColor) ?? "inherit",
|
|
472
503
|
...sizeProps
|
|
473
|
-
})
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (options.enableSimpleIcons && options.resolveSimpleIcon) {
|
|
508
|
+
const simpleIcon = getSimpleIconCodes(iconName, root, withoutPrefix).map((code) => options.resolveSimpleIcon?.(code)).find(Boolean);
|
|
509
|
+
if (simpleIcon?.path) {
|
|
510
|
+
const resolvedColor = inlineIconColor ?? options.simpleIconColor ?? options.iconColor;
|
|
511
|
+
const normalizedIconColor = resolvedColor && isLiteralColorValue(resolvedColor) ? normalizeColorForSwatch(resolvedColor) : void 0;
|
|
512
|
+
const label = simpleIcon.title ?? root;
|
|
513
|
+
return /* @__PURE__ */ jsx("span", {
|
|
514
|
+
style: normalizedIconColor ? { color: normalizedIconColor } : void 0,
|
|
515
|
+
children: /* @__PURE__ */ jsxs(InlineSVG, {
|
|
516
|
+
inline: false,
|
|
517
|
+
viewBox: simpleIcon.viewBox ?? "0 0 24 24",
|
|
518
|
+
width: simpleIcon.width ?? "1em",
|
|
519
|
+
height: simpleIcon.height ?? "1em",
|
|
520
|
+
role: "img",
|
|
521
|
+
"aria-label": label,
|
|
522
|
+
children: [/* @__PURE__ */ jsx("title", { children: label }), /* @__PURE__ */ jsx("path", {
|
|
523
|
+
d: simpleIcon.path,
|
|
524
|
+
fill: "currentColor"
|
|
525
|
+
})]
|
|
526
|
+
})
|
|
527
|
+
});
|
|
528
|
+
}
|
|
480
529
|
}
|
|
481
530
|
}
|
|
482
531
|
}
|
|
@@ -654,11 +703,19 @@ function createInstuiMarkdownComponents(renderOptions = {}) {
|
|
|
654
703
|
const showColorCodes = Boolean(renderOptions.color?.enabled);
|
|
655
704
|
const showIcons = Boolean(renderOptions.icons?.enabled);
|
|
656
705
|
const iconColor = renderOptions.icons?.color;
|
|
706
|
+
const enableInstuiIcons = renderOptions.icons?.providers?.instui ?? true;
|
|
707
|
+
const enableSimpleIcons = renderOptions.icons?.providers?.simpleIcons ?? true;
|
|
708
|
+
const simpleIconColor = renderOptions.icons?.simpleIcons?.color;
|
|
709
|
+
const resolveSimpleIcon = renderOptions.icons?.simpleIcons?.resolve;
|
|
657
710
|
return {
|
|
658
711
|
span: createSpanComponent({
|
|
659
712
|
showColorCodes,
|
|
660
713
|
showIcons,
|
|
661
|
-
iconColor
|
|
714
|
+
iconColor,
|
|
715
|
+
enableInstuiIcons,
|
|
716
|
+
enableSimpleIcons,
|
|
717
|
+
simpleIconColor,
|
|
718
|
+
resolveSimpleIcon
|
|
662
719
|
}),
|
|
663
720
|
a: createLinkComponent({
|
|
664
721
|
showExternalIcon,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "instui-markdown",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "InstUI markdown renderer components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"rehype-instui-markdown": "0.0.
|
|
24
|
+
"rehype-instui-markdown": "0.0.9"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^24",
|