react-marksome
Advanced tools
Comparing version 0.1.1 to 0.2.0
import Marksome from './Marksome'; | ||
export { Marksome }; | ||
export * from './Marksome'; | ||
export * from './marksomeParser'; |
@@ -1,7 +0,8 @@ | ||
import { HTMLAttributes } from 'react'; | ||
declare type Props = HTMLAttributes<HTMLSpanElement> & { | ||
import { HTMLAttributes, Key, ReactNode } from 'react'; | ||
export declare type ReferenceRenderFunction = (key: Key, children: ReactNode) => ReactNode; | ||
export declare type References = Record<string, string | ReferenceRenderFunction>; | ||
export declare type MarksomeProps = HTMLAttributes<HTMLSpanElement> & { | ||
text: string; | ||
references?: Record<string, string>; | ||
references?: References; | ||
}; | ||
export default function Marksome({ text, references, ...spanProps }: Props): JSX.Element; | ||
export {}; | ||
export default function Marksome({ text, references, ...spanProps }: MarksomeProps): JSX.Element; |
@@ -172,5 +172,6 @@ 'use strict'; | ||
{ | ||
var href = references == null ? void 0 : references[segment.reference]; | ||
var referenceValue = references == null ? void 0 : references[segment.reference]; | ||
var children = renderSegments(segment.content, references); | ||
if (!href) { | ||
if (!referenceValue) { | ||
{ | ||
@@ -183,9 +184,13 @@ // eslint-disable-next-line no-console | ||
key: segmentIndex | ||
}, renderSegments(segment.content, references)); | ||
}, children); | ||
} | ||
return React__default.createElement("a", { | ||
key: segmentIndex, | ||
href: href | ||
}, renderSegments(segment.content, references)); | ||
if (typeof referenceValue === 'string') { | ||
return React__default.createElement("a", { | ||
key: segmentIndex, | ||
href: referenceValue | ||
}, children); | ||
} | ||
return referenceValue(segmentIndex, children); | ||
} | ||
@@ -192,0 +197,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,n=require("react"),t=(e=n)&&"object"==typeof e&&"default"in e?e.default:e,r=/([*_])\1\1?((?:\[.*?\][([].*?[)\]]|.)*?)\1?\1\1/g,a=/([*_])((?:\[.*?\][([].*?[)\]]|.)*?)\1/g,c=/\[([^\]]*)\] ?\[([^\]]*)\]/g;function s(e){var n=[];return Array.from(e.matchAll(c)).forEach((function(e){var t=e[1],r=e[2],a=e.index;t&&r&&null!=a&&n.push({type:"reference-link",innerText:t,reference:r,startIndex:a,endIndex:a+e[0].length,offset:1})})),Array.from(e.matchAll(r)).forEach((function(e){var t=f(e,"strong");t&&n.push(t)})),Array.from(e.matchAll(a)).forEach((function(e){var t=f(e,"emphasis");t&&n.push(t)})),n.sort((function(e,n){return e.startIndex-n.startIndex})),function e(n,t){if(!t.length)return[n];for(var r=t[0].startIndex,a=r>0?[n.slice(0,r)]:[];t.length;){for(var c=t.shift(),s=c.startIndex+c.offset,f=[],u=0;u<t.length;){var o=t[u];o.endIndex>c.endIndex?u++:(t.splice(u,1),o.startIndex-=s,o.endIndex-=s,f.push(o))}var i=e(c.innerText,f);a.push("reference-link"===c.type?{type:c.type,content:i,reference:c.reference}:{type:c.type,content:i});var l=t.length?n.slice(c.endIndex,t[0].startIndex):n.slice(c.endIndex);l&&a.push(l)}return a}(e,n)}function f(e,n){var t=e.index,r=e[2];if(null!=t&&r){var a=e[0],c=a.indexOf(r);return{type:n,startIndex:t,endIndex:t+a.length,innerText:r,offset:c}}}exports.Marksome=function(e){var r=e.text,a=e.references,c=function(e,n){if(null==e)return{};var t,r,a={},c=Object.keys(e);for(r=0;r<c.length;r++)n.indexOf(t=c[r])>=0||(a[t]=e[t]);return a}(e,["text","references"]),f=n.useMemo((function(){return s(r)}),[r]);return t.createElement("span",Object.assign({},c),function e(n,r){return n.map((function(n,a){if("string"==typeof n)return n;switch(n.type){case"strong":return t.createElement("strong",{key:a},e(n.content,r));case"emphasis":return t.createElement("em",{key:a},e(n.content,r));case"reference-link":var c=null==r?void 0:r[n.reference];return c?t.createElement("a",{key:a,href:c},e(n.content,r)):t.createElement("span",{key:a},e(n.content,r));default:return null}}))}(f,a))},exports.parseSegments=s; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,n=require("react"),t=(e=n)&&"object"==typeof e&&"default"in e?e.default:e,r=/([*_])\1\1?((?:\[.*?\][([].*?[)\]]|.)*?)\1?\1\1/g,a=/([*_])((?:\[.*?\][([].*?[)\]]|.)*?)\1/g,s=/\[([^\]]*)\] ?\[([^\]]*)\]/g;function c(e){var n=[];return Array.from(e.matchAll(s)).forEach((function(e){var t=e[1],r=e[2],a=e.index;t&&r&&null!=a&&n.push({type:"reference-link",innerText:t,reference:r,startIndex:a,endIndex:a+e[0].length,offset:1})})),Array.from(e.matchAll(r)).forEach((function(e){var t=f(e,"strong");t&&n.push(t)})),Array.from(e.matchAll(a)).forEach((function(e){var t=f(e,"emphasis");t&&n.push(t)})),n.sort((function(e,n){return e.startIndex-n.startIndex})),function e(n,t){if(!t.length)return[n];for(var r=t[0].startIndex,a=r>0?[n.slice(0,r)]:[];t.length;){for(var s=t.shift(),c=s.startIndex+s.offset,f=[],u=0;u<t.length;){var o=t[u];o.endIndex>s.endIndex?u++:(t.splice(u,1),o.startIndex-=c,o.endIndex-=c,f.push(o))}var i=e(s.innerText,f);a.push("reference-link"===s.type?{type:s.type,content:i,reference:s.reference}:{type:s.type,content:i});var l=t.length?n.slice(s.endIndex,t[0].startIndex):n.slice(s.endIndex);l&&a.push(l)}return a}(e,n)}function f(e,n){var t=e.index,r=e[2];if(null!=t&&r){var a=e[0],s=a.indexOf(r);return{type:n,startIndex:t,endIndex:t+a.length,innerText:r,offset:s}}}exports.Marksome=function(e){var r=e.text,a=e.references,s=function(e,n){if(null==e)return{};var t,r,a={},s=Object.keys(e);for(r=0;r<s.length;r++)n.indexOf(t=s[r])>=0||(a[t]=e[t]);return a}(e,["text","references"]),f=n.useMemo((function(){return c(r)}),[r]);return t.createElement("span",Object.assign({},s),function e(n,r){return n.map((function(n,a){if("string"==typeof n)return n;switch(n.type){case"strong":return t.createElement("strong",{key:a},e(n.content,r));case"emphasis":return t.createElement("em",{key:a},e(n.content,r));case"reference-link":var s=null==r?void 0:r[n.reference],c=e(n.content,r);return s?"string"==typeof s?t.createElement("a",{key:a,href:s},c):s(a,c):t.createElement("span",{key:a},c);default:return null}}))}(f,a))},exports.parseSegments=c; | ||
//# sourceMappingURL=react-marksome.cjs.production.min.js.map |
@@ -165,5 +165,6 @@ import React, { useMemo } from 'react'; | ||
{ | ||
var href = references == null ? void 0 : references[segment.reference]; | ||
var referenceValue = references == null ? void 0 : references[segment.reference]; | ||
var children = renderSegments(segment.content, references); | ||
if (!href) { | ||
if (!referenceValue) { | ||
if (process.env.NODE_ENV === 'development') { | ||
@@ -176,9 +177,13 @@ // eslint-disable-next-line no-console | ||
key: segmentIndex | ||
}, renderSegments(segment.content, references)); | ||
}, children); | ||
} | ||
return React.createElement("a", { | ||
key: segmentIndex, | ||
href: href | ||
}, renderSegments(segment.content, references)); | ||
if (typeof referenceValue === 'string') { | ||
return React.createElement("a", { | ||
key: segmentIndex, | ||
href: referenceValue | ||
}, children); | ||
} | ||
return referenceValue(segmentIndex, children); | ||
} | ||
@@ -185,0 +190,0 @@ |
{ | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"license": "MIT", | ||
@@ -67,2 +67,3 @@ "repository": "github:miguel-silva/react-marksome", | ||
"react-dom": "^17.0.1", | ||
"react-icons": "^4.1.0", | ||
"react-is": "^17.0.1", | ||
@@ -69,0 +70,0 @@ "size-limit": "^4.9.1", |
@@ -18,3 +18,3 @@ # react-marksome | ||
const references = { | ||
const references: References = { | ||
'1': | ||
@@ -34,2 +34,52 @@ 'https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog', | ||
## API | ||
### Marksome component | ||
React component that parses and renders a subset of markdown. | ||
It expects the markdown text to be provided via a `text` prop, which then is combined with reference links (`[label][reference]`)defined under the `references` prop. | ||
#### Props | ||
```ts | ||
type MarksomeProps = HTMLAttributes<HTMLSpanElement> & { | ||
text: string; | ||
references?: References; | ||
}; | ||
type References = Record<string, string | ReferenceRenderFunction>; | ||
type ReferenceRenderFunction = (key: Key, children: ReactNode) => ReactNode; | ||
``` | ||
#### Basic usage | ||
See [Quick start](#quick-start). | ||
#### Custom components | ||
One can actually render custom components in the place of reference links by providing a render function instead of link url: | ||
```tsx | ||
function CustomComponentsDemo() { | ||
const text = 'The following is an actual button: [*Howdie*][greeting-button]'; | ||
const references: References = { | ||
'greeting-button': (key, children) => ( | ||
<button | ||
key={key} | ||
onClick={() => { | ||
alert('Hello!'); | ||
}} | ||
> | ||
{children} | ||
</button> | ||
), | ||
}; | ||
return <Marksome text={text} references={references} />; | ||
} | ||
``` | ||
## Rationale | ||
@@ -48,3 +98,3 @@ | ||
Additionally, we build out a tree of segments instead of simply using string replacement mostly for future extensibility and configuratility, like being able to render segments with custom React components (WIP). | ||
Additionally, we build out a tree of segments instead of simply using string replacement mostly for extensibility and configuratility, like being able to render segments with [custom React components](#custom-components). | ||
@@ -51,0 +101,0 @@ All of the above means that users don't need to worry about escaping the text since: |
@@ -5,2 +5,3 @@ import Marksome from './Marksome'; | ||
export * from './Marksome'; | ||
export * from './marksomeParser'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
62309
581
133
21